Lines Matching +full:bd96801 +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
9 * PMIC is in STBY mode.
11 * Supporting the ERRB interrupt would require dropping the regmap-IRQ
16 * regulator safety limits (like limits for the over/under -voltages, over
18 * synchronized with entity causing the PMIC state transitions. Eg, one
19 * should be able to ensure the PMIC is in STBY state when the
20 * configurations are applied to the hardware. How and when the PMIC state
29 * the safety limit configurations - but leaves the state change handling
43 #include <linux/mfd/rohm-generic.h>
44 #include <linux/mfd/rohm-bd96801.h>
153 * and the range from 0x10 to 0x1f is bd96801_buck_init_volts - 150mV ...
154 * bd96801_buck_init_volts - 0. But as the members of linear_range
155 * are all unsigned I will apply offset of -150 mV to value in
156 * linear_range - which should increase these ranges with
165 REGULATOR_LINEAR_RANGE(500000 - 150000, 0x00, 0xc8, 5000),
166 REGULATOR_LINEAR_RANGE(1550000 - 150000, 0xc9, 0xec, 50000),
167 REGULATOR_LINEAR_RANGE(3300000 - 150000, 0xed, 0xff, 0),
196 .err_cfg = -1, \
197 .wrn_cfg = -1, \
207 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-h", 500,
208 "bd96801-buck1-overcurr-h"),
209 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-l", 500,
210 "bd96801-buck1-overcurr-l"),
211 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-n", 500,
212 "bd96801-buck1-overcurr-n"),
213 BD96801_IRQINFO(BD96801_PROT_OVP, "buck1-over-voltage", 500,
214 "bd96801-buck1-overvolt"),
215 BD96801_IRQINFO(BD96801_PROT_UVP, "buck1-under-voltage", 500,
216 "bd96801-buck1-undervolt"),
217 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck1-over-temp", 500,
218 "bd96801-buck1-thermal")
222 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-h", 500,
223 "bd96801-buck2-overcurr-h"),
224 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-l", 500,
225 "bd96801-buck2-overcurr-l"),
226 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-n", 500,
227 "bd96801-buck2-overcurr-n"),
228 BD96801_IRQINFO(BD96801_PROT_OVP, "buck2-over-voltage", 500,
229 "bd96801-buck2-overvolt"),
230 BD96801_IRQINFO(BD96801_PROT_UVP, "buck2-under-voltage", 500,
231 "bd96801-buck2-undervolt"),
232 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck2-over-temp", 500,
233 "bd96801-buck2-thermal")
237 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-h", 500,
238 "bd96801-buck3-overcurr-h"),
239 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-l", 500,
240 "bd96801-buck3-overcurr-l"),
241 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-n", 500,
242 "bd96801-buck3-overcurr-n"),
243 BD96801_IRQINFO(BD96801_PROT_OVP, "buck3-over-voltage", 500,
244 "bd96801-buck3-overvolt"),
245 BD96801_IRQINFO(BD96801_PROT_UVP, "buck3-under-voltage", 500,
246 "bd96801-buck3-undervolt"),
247 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck3-over-temp", 500,
248 "bd96801-buck3-thermal")
252 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-h", 500,
253 "bd96801-buck4-overcurr-h"),
254 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-l", 500,
255 "bd96801-buck4-overcurr-l"),
256 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-n", 500,
257 "bd96801-buck4-overcurr-n"),
258 BD96801_IRQINFO(BD96801_PROT_OVP, "buck4-over-voltage", 500,
259 "bd96801-buck4-overvolt"),
260 BD96801_IRQINFO(BD96801_PROT_UVP, "buck4-under-voltage", 500,
261 "bd96801-buck4-undervolt"),
262 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck4-over-temp", 500,
263 "bd96801-buck4-thermal")
267 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo5-overcurr", 500,
268 "bd96801-ldo5-overcurr"),
269 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo5-over-voltage", 500,
270 "bd96801-ldo5-overvolt"),
271 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo5-under-voltage", 500,
272 "bd96801-ldo5-undervolt"),
276 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo6-overcurr", 500,
277 "bd96801-ldo6-overcurr"),
278 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo6-over-voltage", 500,
279 "bd96801-ldo6-overvolt"),
280 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo6-under-voltage", 500,
281 "bd96801-ldo6-undervolt"),
285 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo7-overcurr", 500,
286 "bd96801-ldo7-overcurr"),
287 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo7-over-voltage", 500,
288 "bd96801-ldo7-overvolt"),
289 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo7-under-voltage", 500,
290 "bd96801-ldo7-undervolt"),
319 for (i = 0; i < rid->num_states; i++) { in ldo_map_notif()
323 rdev = rid->states[i].rdev; in ldo_map_notif()
324 rdata = container_of(rdev->desc, struct bd96801_regulator_data, in ldo_map_notif()
326 rid->states[i].notifs = regulator_err2notif(rdata->ldo_errs); in ldo_map_notif()
327 rid->states[i].errors = rdata->ldo_errs; in ldo_map_notif()
339 data = container_of(rdev->desc, struct bd96801_regulator_data, desc); in bd96801_list_voltage_lr()
345 * register is voltage tuning value which applies -150 mV ... +150 mV in bd96801_list_voltage_lr()
359 return voltage + data->initial_voltage; in bd96801_list_voltage_lr()
388 int reg = BD96801_INT_VOUT_BASE_REG + data->desc.id; in buck_get_initial_voltage()
390 if (data->num_ranges) { in buck_get_initial_voltage()
394 ret = linear_range_get_value_array(data->init_ranges, in buck_get_initial_voltage()
395 data->num_ranges, sel, in buck_get_initial_voltage()
400 data->initial_voltage = initial_uv; in buck_get_initial_voltage()
401 dev_dbg(dev, "Tune-scaled initial voltage %u\n", in buck_get_initial_voltage()
402 data->initial_voltage); in buck_get_initial_voltage()
415 ret = regmap_read(regmap, data->ldo_vol_lvl, &cfgreg); in get_ldo_initial_voltage()
421 data->desc.volt_table = ldo_ddr_volt_table; in get_ldo_initial_voltage()
422 data->desc.n_voltages = ARRAY_SIZE(ldo_ddr_volt_table); in get_ldo_initial_voltage()
425 data->desc.volt_table = ldo_sd_volt_table; in get_ldo_initial_voltage()
426 data->desc.n_voltages = ARRAY_SIZE(ldo_sd_volt_table); in get_ldo_initial_voltage()
434 data->desc.ops = &bd96801_ldo_table_ops, in get_ldo_initial_voltage()
435 data->desc.vsel_mask = 1; in get_ldo_initial_voltage()
436 data->desc.vsel_reg = data->ldo_vol_lvl; in get_ldo_initial_voltage()
445 if (data->desc.id <= BD96801_BUCK4) in get_initial_voltage()
459 of_get_child_by_name(dev->parent->of_node, "regulators"); in bd96801_walk_regulator_dt()
462 return -ENODEV; in bd96801_walk_regulator_dt()
482 if (of_property_read_bool(np, "rohm,keep-on-stby")) { in bd96801_walk_regulator_dt()
488 "failed to set %s on-at-stby\n", in bd96801_walk_regulator_dt()
504 * multi-PMIC case will be handled. I don't know if the processor will have I2C
506 * access provided to all PMICs for voltage scaling - but the errors will only
507 * be informed via the master PMIC. Eg, we should prepare to support multiple
508 * driver instances - either with or without the IRQs... Well, let's first
509 * just support the simple and clear single-PMIC setup and ponder the multi PMIC
715 template = pdata->regulator_data[r].irq_desc.irqinfo; in initialize_pmic_data()
716 num_infos = pdata->regulator_data[r].irq_desc.num_irqs; in initialize_pmic_data()
720 return -ENOMEM; in initialize_pmic_data()
722 pdata->regulator_data[r].irq_desc.irqinfo = new; in initialize_pmic_data()
758 if (!iinfo->err_cfg && !iinfo->wrn_cfg) in bd96801_rdev_intb_irqs()
761 if (WARN_ON(iinfo->type >= BD96801_NUM_PROT)) in bd96801_rdev_intb_irqs()
762 return -EINVAL; in bd96801_rdev_intb_irqs()
764 if (iinfo->err_cfg) in bd96801_rdev_intb_irqs()
765 err = err_flags[iinfo->type]; in bd96801_rdev_intb_irqs()
766 else if (iinfo->wrn_cfg) in bd96801_rdev_intb_irqs()
767 err = wrn_flags[iinfo->type]; in bd96801_rdev_intb_irqs()
769 iinfo->irq_desc.data = pdata; in bd96801_rdev_intb_irqs()
770 irq = platform_get_irq_byname(pdev, iinfo->irq_name); in bd96801_rdev_intb_irqs()
776 retp = devm_regulator_irq_helper(&pdev->dev, in bd96801_rdev_intb_irqs()
777 &iinfo->irq_desc, irq, in bd96801_rdev_intb_irqs()
800 parent = pdev->dev.parent; in bd96801_probe()
802 pdata = devm_kmemdup(&pdev->dev, &bd96801_data, sizeof(bd96801_data), in bd96801_probe()
805 return -ENOMEM; in bd96801_probe()
807 if (initialize_pmic_data(&pdev->dev, pdata)) in bd96801_probe()
808 return -ENOMEM; in bd96801_probe()
810 pdata->regmap = dev_get_regmap(parent, NULL); in bd96801_probe()
811 if (!pdata->regmap) { in bd96801_probe()
812 dev_err(&pdev->dev, "No register map found\n"); in bd96801_probe()
813 return -ENODEV; in bd96801_probe()
816 rdesc = &pdata->regulator_data[0]; in bd96801_probe()
819 config.regmap = pdata->regmap; in bd96801_probe()
822 ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc, in bd96801_probe()
827 for (i = 0; i < ARRAY_SIZE(pdata->regulator_data); i++) { in bd96801_probe()
832 rdev = devm_regulator_register(&pdev->dev, in bd96801_probe()
835 dev_err(&pdev->dev, in bd96801_probe()
853 for (j = 0; j < idesc->num_irqs; j++) { in bd96801_probe()
855 &idesc->irqinfo[j], rdev); in bd96801_probe()
863 .name = "bd96801-core-thermal", in bd96801_probe()
868 irq = platform_get_irq_byname(pdev, "bd96801-core-thermal"); in bd96801_probe()
872 retp = devm_regulator_irq_helper(&pdev->dev, &tw_desc, irq, 0, in bd96801_probe()
884 { "bd96801-regulator", },
891 .name = "bd96801-pmic"
900 MODULE_DESCRIPTION("BD96801 voltage regulator driver");