0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0025
0026 #include <linux/linear_range.h>
0027 #include <linux/module.h>
0028 #include <linux/of.h>
0029 #include <linux/regulator/driver.h>
0030 #include <linux/regulator/machine.h>
0031 #include <linux/regulator/of_regulator.h>
0032 #include <linux/scmi_protocol.h>
0033 #include <linux/slab.h>
0034 #include <linux/types.h>
0035
0036 static const struct scmi_voltage_proto_ops *voltage_ops;
0037
0038 struct scmi_regulator {
0039 u32 id;
0040 struct scmi_device *sdev;
0041 struct scmi_protocol_handle *ph;
0042 struct regulator_dev *rdev;
0043 struct device_node *of_node;
0044 struct regulator_desc desc;
0045 struct regulator_config conf;
0046 };
0047
0048 struct scmi_regulator_info {
0049 int num_doms;
0050 struct scmi_regulator **sregv;
0051 };
0052
0053 static int scmi_reg_enable(struct regulator_dev *rdev)
0054 {
0055 struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
0056
0057 return voltage_ops->config_set(sreg->ph, sreg->id,
0058 SCMI_VOLTAGE_ARCH_STATE_ON);
0059 }
0060
0061 static int scmi_reg_disable(struct regulator_dev *rdev)
0062 {
0063 struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
0064
0065 return voltage_ops->config_set(sreg->ph, sreg->id,
0066 SCMI_VOLTAGE_ARCH_STATE_OFF);
0067 }
0068
0069 static int scmi_reg_is_enabled(struct regulator_dev *rdev)
0070 {
0071 int ret;
0072 u32 config;
0073 struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
0074
0075 ret = voltage_ops->config_get(sreg->ph, sreg->id, &config);
0076 if (ret) {
0077 dev_err(&sreg->sdev->dev,
0078 "Error %d reading regulator %s status.\n",
0079 ret, sreg->desc.name);
0080 return ret;
0081 }
0082
0083 return config & SCMI_VOLTAGE_ARCH_STATE_ON;
0084 }
0085
0086 static int scmi_reg_get_voltage_sel(struct regulator_dev *rdev)
0087 {
0088 int ret;
0089 s32 volt_uV;
0090 struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
0091
0092 ret = voltage_ops->level_get(sreg->ph, sreg->id, &volt_uV);
0093 if (ret)
0094 return ret;
0095
0096 return sreg->desc.ops->map_voltage(rdev, volt_uV, volt_uV);
0097 }
0098
0099 static int scmi_reg_set_voltage_sel(struct regulator_dev *rdev,
0100 unsigned int selector)
0101 {
0102 s32 volt_uV;
0103 struct scmi_regulator *sreg = rdev_get_drvdata(rdev);
0104
0105 volt_uV = sreg->desc.ops->list_voltage(rdev, selector);
0106 if (volt_uV <= 0)
0107 return -EINVAL;
0108
0109 return voltage_ops->level_set(sreg->ph, sreg->id, 0x0, volt_uV);
0110 }
0111
0112 static const struct regulator_ops scmi_reg_fixed_ops = {
0113 .enable = scmi_reg_enable,
0114 .disable = scmi_reg_disable,
0115 .is_enabled = scmi_reg_is_enabled,
0116 };
0117
0118 static const struct regulator_ops scmi_reg_linear_ops = {
0119 .enable = scmi_reg_enable,
0120 .disable = scmi_reg_disable,
0121 .is_enabled = scmi_reg_is_enabled,
0122 .get_voltage_sel = scmi_reg_get_voltage_sel,
0123 .set_voltage_sel = scmi_reg_set_voltage_sel,
0124 .list_voltage = regulator_list_voltage_linear,
0125 .map_voltage = regulator_map_voltage_linear,
0126 };
0127
0128 static const struct regulator_ops scmi_reg_discrete_ops = {
0129 .enable = scmi_reg_enable,
0130 .disable = scmi_reg_disable,
0131 .is_enabled = scmi_reg_is_enabled,
0132 .get_voltage_sel = scmi_reg_get_voltage_sel,
0133 .set_voltage_sel = scmi_reg_set_voltage_sel,
0134 .list_voltage = regulator_list_voltage_table,
0135 .map_voltage = regulator_map_voltage_iterate,
0136 };
0137
0138 static int
0139 scmi_config_linear_regulator_mappings(struct scmi_regulator *sreg,
0140 const struct scmi_voltage_info *vinfo)
0141 {
0142 s32 delta_uV;
0143
0144
0145
0146
0147
0148
0149
0150 delta_uV = (vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_HIGH] -
0151 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW]);
0152
0153
0154 if (delta_uV < 0) {
0155 dev_err(&sreg->sdev->dev,
0156 "Invalid volt-range %d-%duV for domain %d\n",
0157 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW],
0158 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_HIGH],
0159 sreg->id);
0160 return -EINVAL;
0161 }
0162
0163 if (!delta_uV) {
0164
0165 sreg->desc.fixed_uV =
0166 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW];
0167 sreg->desc.n_voltages = 1;
0168 sreg->desc.ops = &scmi_reg_fixed_ops;
0169 } else {
0170
0171 sreg->desc.min_uV =
0172 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW];
0173 sreg->desc.uV_step =
0174 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_STEP];
0175 sreg->desc.linear_min_sel = 0;
0176 sreg->desc.n_voltages = (delta_uV / sreg->desc.uV_step) + 1;
0177 sreg->desc.ops = &scmi_reg_linear_ops;
0178 }
0179
0180 return 0;
0181 }
0182
0183 static int
0184 scmi_config_discrete_regulator_mappings(struct scmi_regulator *sreg,
0185 const struct scmi_voltage_info *vinfo)
0186 {
0187
0188 sreg->desc.n_voltages = vinfo->num_levels;
0189
0190 if (sreg->desc.n_voltages > 1) {
0191 sreg->desc.volt_table = (const unsigned int *)vinfo->levels_uv;
0192 sreg->desc.ops = &scmi_reg_discrete_ops;
0193 } else {
0194 sreg->desc.fixed_uV = vinfo->levels_uv[0];
0195 sreg->desc.ops = &scmi_reg_fixed_ops;
0196 }
0197
0198 return 0;
0199 }
0200
0201 static int scmi_regulator_common_init(struct scmi_regulator *sreg)
0202 {
0203 int ret;
0204 struct device *dev = &sreg->sdev->dev;
0205 const struct scmi_voltage_info *vinfo;
0206
0207 vinfo = voltage_ops->info_get(sreg->ph, sreg->id);
0208 if (!vinfo) {
0209 dev_warn(dev, "Failure to get voltage domain %d\n",
0210 sreg->id);
0211 return -ENODEV;
0212 }
0213
0214
0215
0216
0217
0218
0219
0220 if (vinfo->negative_volts_allowed) {
0221 dev_warn(dev, "Negative voltages NOT supported...skip %s\n",
0222 sreg->of_node->full_name);
0223 return -EOPNOTSUPP;
0224 }
0225
0226 sreg->desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s", vinfo->name);
0227 if (!sreg->desc.name)
0228 return -ENOMEM;
0229
0230 sreg->desc.id = sreg->id;
0231 sreg->desc.type = REGULATOR_VOLTAGE;
0232 sreg->desc.owner = THIS_MODULE;
0233 sreg->desc.of_match_full_name = true;
0234 sreg->desc.of_match = sreg->of_node->full_name;
0235 sreg->desc.regulators_node = "regulators";
0236 if (vinfo->segmented)
0237 ret = scmi_config_linear_regulator_mappings(sreg, vinfo);
0238 else
0239 ret = scmi_config_discrete_regulator_mappings(sreg, vinfo);
0240 if (ret)
0241 return ret;
0242
0243
0244
0245
0246
0247 sreg->conf.dev = dev;
0248
0249
0250 sreg->conf.driver_data = sreg;
0251
0252 return 0;
0253 }
0254
0255 static int process_scmi_regulator_of_node(struct scmi_device *sdev,
0256 struct scmi_protocol_handle *ph,
0257 struct device_node *np,
0258 struct scmi_regulator_info *rinfo)
0259 {
0260 u32 dom, ret;
0261
0262 ret = of_property_read_u32(np, "reg", &dom);
0263 if (ret)
0264 return ret;
0265
0266 if (dom >= rinfo->num_doms)
0267 return -ENODEV;
0268
0269 if (rinfo->sregv[dom]) {
0270 dev_err(&sdev->dev,
0271 "SCMI Voltage Domain %d already in use. Skipping: %s\n",
0272 dom, np->full_name);
0273 return -EINVAL;
0274 }
0275
0276 rinfo->sregv[dom] = devm_kzalloc(&sdev->dev,
0277 sizeof(struct scmi_regulator),
0278 GFP_KERNEL);
0279 if (!rinfo->sregv[dom])
0280 return -ENOMEM;
0281
0282 rinfo->sregv[dom]->id = dom;
0283 rinfo->sregv[dom]->sdev = sdev;
0284 rinfo->sregv[dom]->ph = ph;
0285
0286
0287 of_node_get(np);
0288 rinfo->sregv[dom]->of_node = np;
0289
0290 dev_dbg(&sdev->dev,
0291 "Found SCMI Regulator entry -- OF node [%d] -> %s\n",
0292 dom, np->full_name);
0293
0294 return 0;
0295 }
0296
0297 static int scmi_regulator_probe(struct scmi_device *sdev)
0298 {
0299 int d, ret, num_doms;
0300 struct device_node *np, *child;
0301 const struct scmi_handle *handle = sdev->handle;
0302 struct scmi_regulator_info *rinfo;
0303 struct scmi_protocol_handle *ph;
0304
0305 if (!handle)
0306 return -ENODEV;
0307
0308 voltage_ops = handle->devm_protocol_get(sdev,
0309 SCMI_PROTOCOL_VOLTAGE, &ph);
0310 if (IS_ERR(voltage_ops))
0311 return PTR_ERR(voltage_ops);
0312
0313 num_doms = voltage_ops->num_domains_get(ph);
0314 if (num_doms <= 0) {
0315 if (!num_doms) {
0316 dev_err(&sdev->dev,
0317 "number of voltage domains invalid\n");
0318 num_doms = -EINVAL;
0319 } else {
0320 dev_err(&sdev->dev,
0321 "failed to get voltage domains - err:%d\n",
0322 num_doms);
0323 }
0324
0325 return num_doms;
0326 }
0327
0328 rinfo = devm_kzalloc(&sdev->dev, sizeof(*rinfo), GFP_KERNEL);
0329 if (!rinfo)
0330 return -ENOMEM;
0331
0332
0333 rinfo->sregv = devm_kcalloc(&sdev->dev, num_doms,
0334 sizeof(void *), GFP_KERNEL);
0335 if (!rinfo->sregv)
0336 return -ENOMEM;
0337
0338 rinfo->num_doms = num_doms;
0339
0340
0341
0342
0343
0344
0345
0346 of_node_get(handle->dev->of_node);
0347 np = of_find_node_by_name(handle->dev->of_node, "regulators");
0348 for_each_child_of_node(np, child) {
0349 ret = process_scmi_regulator_of_node(sdev, ph, child, rinfo);
0350
0351 if (ret == -ENOMEM) {
0352 of_node_put(child);
0353 return ret;
0354 }
0355 }
0356 of_node_put(np);
0357
0358
0359
0360
0361
0362 for (d = 0; d < num_doms; d++) {
0363 struct scmi_regulator *sreg = rinfo->sregv[d];
0364
0365
0366 if (!sreg)
0367 continue;
0368
0369 ret = scmi_regulator_common_init(sreg);
0370
0371 if (ret)
0372 continue;
0373
0374 sreg->rdev = devm_regulator_register(&sdev->dev, &sreg->desc,
0375 &sreg->conf);
0376 if (IS_ERR(sreg->rdev)) {
0377 sreg->rdev = NULL;
0378 continue;
0379 }
0380
0381 dev_info(&sdev->dev,
0382 "Regulator %s registered for domain [%d]\n",
0383 sreg->desc.name, sreg->id);
0384 }
0385
0386 dev_set_drvdata(&sdev->dev, rinfo);
0387
0388 return 0;
0389 }
0390
0391 static void scmi_regulator_remove(struct scmi_device *sdev)
0392 {
0393 int d;
0394 struct scmi_regulator_info *rinfo;
0395
0396 rinfo = dev_get_drvdata(&sdev->dev);
0397 if (!rinfo)
0398 return;
0399
0400 for (d = 0; d < rinfo->num_doms; d++) {
0401 if (!rinfo->sregv[d])
0402 continue;
0403 of_node_put(rinfo->sregv[d]->of_node);
0404 }
0405 }
0406
0407 static const struct scmi_device_id scmi_regulator_id_table[] = {
0408 { SCMI_PROTOCOL_VOLTAGE, "regulator" },
0409 { },
0410 };
0411 MODULE_DEVICE_TABLE(scmi, scmi_regulator_id_table);
0412
0413 static struct scmi_driver scmi_drv = {
0414 .name = "scmi-regulator",
0415 .probe = scmi_regulator_probe,
0416 .remove = scmi_regulator_remove,
0417 .id_table = scmi_regulator_id_table,
0418 };
0419
0420 module_scmi_driver(scmi_drv);
0421
0422 MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
0423 MODULE_DESCRIPTION("ARM SCMI regulator driver");
0424 MODULE_LICENSE("GPL v2");