Lines Matching +full:bd96802 +full:- +full:pmic
1 // SPDX-License-Identifier: GPL-2.0
3 // bd96801-regulator.c ROHM BD96801 regulator driver
6 * This version of the "BD86801 scalable PMIC"'s driver supports only very
7 * basic set of the PMIC features. Most notably, there is no support for
8 * the configurations which should be done when the PMIC is in STBY mode.
11 * regulator safety limits (like limits for the over/under -voltages, over
13 * synchronized with entity causing the PMIC state transitions. Eg, one
14 * should be able to ensure the PMIC is in STBY state when the
15 * configurations are applied to the hardware. How and when the PMIC state
23 * which implements some of the safety limit configurations - but leaves the
36 #include <linux/mfd/rohm-generic.h>
37 #include <linux/mfd/rohm-bd96801.h>
148 * and the range from 0x10 to 0x1f is bd96801_buck_init_volts - 150mV ...
149 * bd96801_buck_init_volts - 0. But as the members of linear_range
150 * are all unsigned I will apply offset of -150 mV to value in
151 * linear_range - which should increase these ranges with
160 REGULATOR_LINEAR_RANGE(500000 - 150000, 0x00, 0xc8, 5000),
161 REGULATOR_LINEAR_RANGE(1550000 - 150000, 0xc9, 0xec, 50000),
162 REGULATOR_LINEAR_RANGE(3300000 - 150000, 0xed, 0xff, 0),
165 /* BD96802 uses same voltage ranges for bucks as BD96801 */
171 * that the max tuning is -310 ... +310 mV (instead of the 150mV). We use same
180 REGULATOR_LINEAR_RANGE(500000 - 310000, 0x00, 0xc8, 5000),
181 REGULATOR_LINEAR_RANGE(1550000 - 310000, 0xc9, 0xec, 50000),
182 REGULATOR_LINEAR_RANGE(3300000 - 310000, 0xed, 0xff, 0),
215 .err_cfg = -1, \
216 .wrn_cfg = -1, \
226 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-h", 500,
227 "buck1-overcurr-h"),
228 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-l", 500,
229 "buck1-overcurr-l"),
230 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-n", 500,
231 "buck1-overcurr-n"),
232 BD96801_IRQINFO(BD96801_PROT_OVP, "buck1-over-voltage", 500,
233 "buck1-overvolt"),
234 BD96801_IRQINFO(BD96801_PROT_UVP, "buck1-under-voltage", 500,
235 "buck1-undervolt"),
236 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck1-over-temp", 500,
237 "buck1-thermal")
241 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-h", 500,
242 "buck2-overcurr-h"),
243 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-l", 500,
244 "buck2-overcurr-l"),
245 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-n", 500,
246 "buck2-overcurr-n"),
247 BD96801_IRQINFO(BD96801_PROT_OVP, "buck2-over-voltage", 500,
248 "buck2-overvolt"),
249 BD96801_IRQINFO(BD96801_PROT_UVP, "buck2-under-voltage", 500,
250 "buck2-undervolt"),
251 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck2-over-temp", 500,
252 "buck2-thermal")
256 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-h", 500,
257 "buck3-overcurr-h"),
258 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-l", 500,
259 "buck3-overcurr-l"),
260 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-n", 500,
261 "buck3-overcurr-n"),
262 BD96801_IRQINFO(BD96801_PROT_OVP, "buck3-over-voltage", 500,
263 "buck3-overvolt"),
264 BD96801_IRQINFO(BD96801_PROT_UVP, "buck3-under-voltage", 500,
265 "buck3-undervolt"),
266 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck3-over-temp", 500,
267 "buck3-thermal")
271 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-h", 500,
272 "buck4-overcurr-h"),
273 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-l", 500,
274 "buck4-overcurr-l"),
275 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-n", 500,
276 "buck4-overcurr-n"),
277 BD96801_IRQINFO(BD96801_PROT_OVP, "buck4-over-voltage", 500,
278 "buck4-overvolt"),
279 BD96801_IRQINFO(BD96801_PROT_UVP, "buck4-under-voltage", 500,
280 "buck4-undervolt"),
281 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck4-over-temp", 500,
282 "buck4-thermal")
286 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo5-overcurr", 500,
287 "ldo5-overcurr"),
288 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo5-over-voltage", 500,
289 "ldo5-overvolt"),
290 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo5-under-voltage", 500,
291 "ldo5-undervolt"),
295 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo6-overcurr", 500,
296 "ldo6-overcurr"),
297 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo6-over-voltage", 500,
298 "ldo6-overvolt"),
299 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo6-under-voltage", 500,
300 "ldo6-undervolt"),
304 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo7-overcurr", 500,
305 "ldo7-overcurr"),
306 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo7-over-voltage", 500,
307 "ldo7-overvolt"),
308 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo7-under-voltage", 500,
309 "ldo7-undervolt"),
339 for (i = 0; i < rid->num_states; i++) { in ldo_map_notif()
343 rdev = rid->states[i].rdev; in ldo_map_notif()
344 rdata = container_of(rdev->desc, struct bd96801_regulator_data, in ldo_map_notif()
346 rid->states[i].notifs = regulator_err2notif(rdata->ldo_errs); in ldo_map_notif()
347 rid->states[i].errors = rdata->ldo_errs; in ldo_map_notif()
359 data = container_of(rdev->desc, struct bd96801_regulator_data, desc); in bd96801_list_voltage_lr()
365 * register is voltage tuning value which applies -150 mV ... +150 mV in bd96801_list_voltage_lr()
379 return voltage + data->initial_voltage; in bd96801_list_voltage_lr()
408 int reg = BD96801_INT_VOUT_BASE_REG + data->desc.id; in buck_get_initial_voltage()
410 if (data->num_ranges) { in buck_get_initial_voltage()
414 ret = linear_range_get_value_array(data->init_ranges, in buck_get_initial_voltage()
415 data->num_ranges, sel, in buck_get_initial_voltage()
420 data->initial_voltage = initial_uv; in buck_get_initial_voltage()
421 dev_dbg(dev, "Tune-scaled initial voltage %u\n", in buck_get_initial_voltage()
422 data->initial_voltage); in buck_get_initial_voltage()
435 ret = regmap_read(regmap, data->ldo_vol_lvl, &cfgreg); in get_ldo_initial_voltage()
441 data->desc.volt_table = ldo_ddr_volt_table; in get_ldo_initial_voltage()
442 data->desc.n_voltages = ARRAY_SIZE(ldo_ddr_volt_table); in get_ldo_initial_voltage()
445 data->desc.volt_table = ldo_sd_volt_table; in get_ldo_initial_voltage()
446 data->desc.n_voltages = ARRAY_SIZE(ldo_sd_volt_table); in get_ldo_initial_voltage()
454 data->desc.ops = &bd96801_ldo_table_ops, in get_ldo_initial_voltage()
455 data->desc.vsel_mask = 1; in get_ldo_initial_voltage()
456 data->desc.vsel_reg = data->ldo_vol_lvl; in get_ldo_initial_voltage()
465 if (data->desc.id <= BD96801_BUCK4) in get_initial_voltage()
479 of_get_child_by_name(dev->parent->of_node, "regulators"); in bd96801_walk_regulator_dt()
482 return -ENODEV; in bd96801_walk_regulator_dt()
502 if (of_property_read_bool(np, "rohm,keep-on-stby")) { in bd96801_walk_regulator_dt()
508 "failed to set %s on-at-stby\n", in bd96801_walk_regulator_dt()
524 * multi-PMIC case will be handled. I don't know if the processor will have I2C
526 * access provided to all PMICs for voltage scaling - but the errors will only
527 * be informed via the master PMIC. Eg, we should prepare to support multiple
528 * driver instances - either with or without the IRQs... Well, let's first
529 * just support the simple and clear single-PMIC setup and ponder the multi PMIC
1040 struct device *dev = &pdev->dev; in initialize_pmic_data()
1048 for (r = 0; r < pdata->num_regulators; r++) { in initialize_pmic_data()
1053 template = pdata->regulator_data[r].irq_desc.irqinfo; in initialize_pmic_data()
1054 num_infos = pdata->regulator_data[r].irq_desc.num_irqs; in initialize_pmic_data()
1058 return -ENOMEM; in initialize_pmic_data()
1060 pdata->regulator_data[r].irq_desc.irqinfo = new; in initialize_pmic_data()
1074 for (i = 0; i < rid->num_states; i++) { in bd96801_map_event_all()
1075 rid->states[i].notifs = REGULATOR_EVENT_FAIL; in bd96801_map_event_all()
1076 rid->states[i].errors = REGULATOR_ERROR_FAIL; in bd96801_map_event_all()
1089 "%s-pvin-err", "%s-ovp-err", "%s-uvp-err", "%s-shdn-err", in bd96801_rdev_errb_irqs()
1101 snprintf(tmp, 255, single_out_errb_irqs[i], rdev->desc->name); in bd96801_rdev_errb_irqs()
1110 retp = devm_regulator_irq_helper(&pdev->dev, &id, irq, 0, in bd96801_rdev_errb_irqs()
1126 "otp-err", "dbist-err", "eep-err", "abist-err", "prstb-err", in bd96801_global_errb_irqs()
1127 "drmoserr1", "drmoserr2", "slave-err", "vref-err", "tsd", in bd96801_global_errb_irqs()
1128 "uvlo-err", "ovlo-err", "osc-err", "pon-err", "poff-err", in bd96801_global_errb_irqs()
1129 "cmd-shdn-err", "int-shdn-err" in bd96801_global_errb_irqs()
1145 retp = devm_regulator_irq_helper(&pdev->dev, &id, irq, 0, in bd96801_global_errb_irqs()
1182 if (!iinfo->err_cfg && !iinfo->wrn_cfg) in bd96801_rdev_intb_irqs()
1185 if (WARN_ON(iinfo->type >= BD96801_NUM_PROT)) in bd96801_rdev_intb_irqs()
1186 return -EINVAL; in bd96801_rdev_intb_irqs()
1188 if (iinfo->err_cfg) in bd96801_rdev_intb_irqs()
1189 err = err_flags[iinfo->type]; in bd96801_rdev_intb_irqs()
1190 else if (iinfo->wrn_cfg) in bd96801_rdev_intb_irqs()
1191 err = wrn_flags[iinfo->type]; in bd96801_rdev_intb_irqs()
1193 iinfo->irq_desc.data = pdata; in bd96801_rdev_intb_irqs()
1194 irq = platform_get_irq_byname(pdev, iinfo->irq_name); in bd96801_rdev_intb_irqs()
1200 retp = devm_regulator_irq_helper(&pdev->dev, in bd96801_rdev_intb_irqs()
1201 &iinfo->irq_desc, irq, in bd96801_rdev_intb_irqs()
1225 parent = pdev->dev.parent; in bd96801_probe()
1227 pdata_template = (struct bd96801_pmic_data *)platform_get_device_id(pdev)->driver_data; in bd96801_probe()
1229 return -ENODEV; in bd96801_probe()
1231 pdata = devm_kmemdup(&pdev->dev, pdata_template, sizeof(bd96801_data), in bd96801_probe()
1234 return -ENOMEM; in bd96801_probe()
1237 return -ENOMEM; in bd96801_probe()
1239 pdata->regmap = dev_get_regmap(parent, NULL); in bd96801_probe()
1240 if (!pdata->regmap) { in bd96801_probe()
1241 dev_err(&pdev->dev, "No register map found\n"); in bd96801_probe()
1242 return -ENODEV; in bd96801_probe()
1245 rdesc = &pdata->regulator_data[0]; in bd96801_probe()
1248 config.regmap = pdata->regmap; in bd96801_probe()
1251 ret = of_property_match_string(pdev->dev.parent->of_node, in bd96801_probe()
1252 "interrupt-names", "errb"); in bd96801_probe()
1258 ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc, in bd96801_probe()
1259 pdata->num_regulators); in bd96801_probe()
1263 for (i = 0; i < pdata->num_regulators; i++) { in bd96801_probe()
1268 rdev = devm_regulator_register(&pdev->dev, in bd96801_probe()
1271 dev_err(&pdev->dev, in bd96801_probe()
1291 for (j = 0; j < idesc->num_irqs; j++) { in bd96801_probe()
1293 &idesc->irqinfo[j], rdev); in bd96801_probe()
1307 .name = "core-thermal", in bd96801_probe()
1312 irq = platform_get_irq_byname(pdev, "core-thermal"); in bd96801_probe()
1316 retp = devm_regulator_irq_helper(&pdev->dev, &tw_desc, irq, 0, in bd96801_probe()
1326 pdata->num_regulators); in bd96801_probe()
1332 { "bd96801-regulator", (kernel_ulong_t)&bd96801_data },
1333 { "bd96802-regulator", (kernel_ulong_t)&bd96802_data },
1334 { "bd96805-regulator", (kernel_ulong_t)&bd96805_data },
1335 { "bd96806-regulator", (kernel_ulong_t)&bd96806_data },
1342 .name = "bd96801-pmic"