1141 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2020 ROHM Semiconductors3// ROHM BD9576MUF/BD9573MUF regulator driver4 5#include <linux/err.h>6#include <linux/gpio/consumer.h>7#include <linux/interrupt.h>8#include <linux/jiffies.h>9#include <linux/kernel.h>10#include <linux/mfd/rohm-bd957x.h>11#include <linux/mfd/rohm-generic.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/platform_device.h>15#include <linux/property.h>16#include <linux/regulator/driver.h>17#include <linux/regulator/machine.h>18#include <linux/regulator/of_regulator.h>19#include <linux/slab.h>20#include <linux/spinlock.h>21#include <linux/workqueue.h>22 23#define BD957X_VOUTS1_VOLT 330000024#define BD957X_VOUTS4_BASE_VOLT 103000025#define BD957X_VOUTS34_NUM_VOLT 3226 27#define BD9576_THERM_IRQ_MASK_TW BIT(5)28#define BD9576_xVD_IRQ_MASK_VOUTL1 BIT(5)29#define BD9576_UVD_IRQ_MASK_VOUTS1_OCW BIT(6)30#define BD9576_xVD_IRQ_MASK_VOUT1TO4 0x0F31 32static const unsigned int vout1_volt_table[] = {33 5000000, 4900000, 4800000, 4700000, 4600000,34 4500000, 4500000, 4500000, 5000000, 5100000,35 5200000, 5300000, 5400000, 5500000, 5500000,36 550000037};38 39static const unsigned int vout2_volt_table[] = {40 1800000, 1780000, 1760000, 1740000, 1720000,41 1700000, 1680000, 1660000, 1800000, 1820000,42 1840000, 1860000, 1880000, 1900000, 1920000,43 194000044};45 46static const unsigned int voutl1_volt_table[] = {47 2500000, 2540000, 2580000, 2620000, 2660000,48 2700000, 2740000, 2780000, 2500000, 2460000,49 2420000, 2380000, 2340000, 2300000, 2260000,50 222000051};52 53static const struct linear_range vout1_xvd_ranges[] = {54 REGULATOR_LINEAR_RANGE(225000, 0x01, 0x2b, 0),55 REGULATOR_LINEAR_RANGE(225000, 0x2c, 0x54, 5000),56 REGULATOR_LINEAR_RANGE(425000, 0x55, 0x7f, 0),57};58 59static const struct linear_range vout234_xvd_ranges[] = {60 REGULATOR_LINEAR_RANGE(17000, 0x01, 0x0f, 0),61 REGULATOR_LINEAR_RANGE(17000, 0x10, 0x6d, 1000),62 REGULATOR_LINEAR_RANGE(110000, 0x6e, 0x7f, 0),63};64 65static const struct linear_range voutL1_xvd_ranges[] = {66 REGULATOR_LINEAR_RANGE(34000, 0x01, 0x0f, 0),67 REGULATOR_LINEAR_RANGE(34000, 0x10, 0x6d, 2000),68 REGULATOR_LINEAR_RANGE(220000, 0x6e, 0x7f, 0),69};70 71static const struct linear_range voutS1_ocw_ranges_internal[] = {72 REGULATOR_LINEAR_RANGE(200000, 0x01, 0x04, 0),73 REGULATOR_LINEAR_RANGE(250000, 0x05, 0x18, 50000),74 REGULATOR_LINEAR_RANGE(1200000, 0x19, 0x3f, 0),75};76 77static const struct linear_range voutS1_ocw_ranges[] = {78 REGULATOR_LINEAR_RANGE(50000, 0x01, 0x04, 0),79 REGULATOR_LINEAR_RANGE(60000, 0x05, 0x18, 10000),80 REGULATOR_LINEAR_RANGE(250000, 0x19, 0x3f, 0),81};82 83static const struct linear_range voutS1_ocp_ranges_internal[] = {84 REGULATOR_LINEAR_RANGE(300000, 0x01, 0x06, 0),85 REGULATOR_LINEAR_RANGE(350000, 0x7, 0x1b, 50000),86 REGULATOR_LINEAR_RANGE(1350000, 0x1c, 0x3f, 0),87};88 89static const struct linear_range voutS1_ocp_ranges[] = {90 REGULATOR_LINEAR_RANGE(70000, 0x01, 0x06, 0),91 REGULATOR_LINEAR_RANGE(80000, 0x7, 0x1b, 10000),92 REGULATOR_LINEAR_RANGE(280000, 0x1c, 0x3f, 0),93};94 95struct bd957x_regulator_data {96 struct regulator_desc desc;97 int base_voltage;98 struct regulator_dev *rdev;99 int ovd_notif;100 int uvd_notif;101 int temp_notif;102 int ovd_err;103 int uvd_err;104 int temp_err;105 const struct linear_range *xvd_ranges;106 int num_xvd_ranges;107 bool oc_supported;108 unsigned int ovd_reg;109 unsigned int uvd_reg;110 unsigned int xvd_mask;111 unsigned int ocp_reg;112 unsigned int ocp_mask;113 unsigned int ocw_reg;114 unsigned int ocw_mask;115 unsigned int ocw_rfet;116};117 118#define BD9576_NUM_REGULATORS 6119#define BD9576_NUM_OVD_REGULATORS 5120 121struct bd957x_data {122 struct bd957x_regulator_data regulator_data[BD9576_NUM_REGULATORS];123 struct regmap *regmap;124 struct delayed_work therm_irq_suppress;125 struct delayed_work ovd_irq_suppress;126 struct delayed_work uvd_irq_suppress;127 unsigned int therm_irq;128 unsigned int ovd_irq;129 unsigned int uvd_irq;130 spinlock_t err_lock;131 int regulator_global_err;132};133 134static int bd957x_vout34_list_voltage(struct regulator_dev *rdev,135 unsigned int selector)136{137 const struct regulator_desc *desc = rdev->desc;138 int multiplier = selector & desc->vsel_mask & 0x7f;139 int tune;140 141 /* VOUT3 and 4 has 10mV step */142 tune = multiplier * 10000;143 144 if (!(selector & 0x80))145 return desc->fixed_uV - tune;146 147 return desc->fixed_uV + tune;148}149 150static int bd957x_list_voltage(struct regulator_dev *rdev,151 unsigned int selector)152{153 const struct regulator_desc *desc = rdev->desc;154 int index = selector & desc->vsel_mask & 0x7f;155 156 if (!(selector & 0x80))157 index += desc->n_voltages/2;158 159 if (index >= desc->n_voltages)160 return -EINVAL;161 162 return desc->volt_table[index];163}164 165static void bd9576_fill_ovd_flags(struct bd957x_regulator_data *data,166 bool warn)167{168 if (warn) {169 data->ovd_notif = REGULATOR_EVENT_OVER_VOLTAGE_WARN;170 data->ovd_err = REGULATOR_ERROR_OVER_VOLTAGE_WARN;171 } else {172 data->ovd_notif = REGULATOR_EVENT_REGULATION_OUT;173 data->ovd_err = REGULATOR_ERROR_REGULATION_OUT;174 }175}176 177static void bd9576_fill_ocp_flags(struct bd957x_regulator_data *data,178 bool warn)179{180 if (warn) {181 data->uvd_notif = REGULATOR_EVENT_OVER_CURRENT_WARN;182 data->uvd_err = REGULATOR_ERROR_OVER_CURRENT_WARN;183 } else {184 data->uvd_notif = REGULATOR_EVENT_OVER_CURRENT;185 data->uvd_err = REGULATOR_ERROR_OVER_CURRENT;186 }187}188 189static void bd9576_fill_uvd_flags(struct bd957x_regulator_data *data,190 bool warn)191{192 if (warn) {193 data->uvd_notif = REGULATOR_EVENT_UNDER_VOLTAGE_WARN;194 data->uvd_err = REGULATOR_ERROR_UNDER_VOLTAGE_WARN;195 } else {196 data->uvd_notif = REGULATOR_EVENT_UNDER_VOLTAGE;197 data->uvd_err = REGULATOR_ERROR_UNDER_VOLTAGE;198 }199}200 201static void bd9576_fill_temp_flags(struct bd957x_regulator_data *data,202 bool enable, bool warn)203{204 if (!enable) {205 data->temp_notif = 0;206 data->temp_err = 0;207 } else if (warn) {208 data->temp_notif = REGULATOR_EVENT_OVER_TEMP_WARN;209 data->temp_err = REGULATOR_ERROR_OVER_TEMP_WARN;210 } else {211 data->temp_notif = REGULATOR_EVENT_OVER_TEMP;212 data->temp_err = REGULATOR_ERROR_OVER_TEMP;213 }214}215 216static int bd9576_set_limit(const struct linear_range *r, int num_ranges,217 struct regmap *regmap, int reg, int mask, int lim)218{219 int ret;220 bool found;221 int sel = 0;222 223 if (lim) {224 225 ret = linear_range_get_selector_low_array(r, num_ranges,226 lim, &sel, &found);227 if (ret)228 return ret;229 230 if (!found)231 dev_warn(regmap_get_device(regmap),232 "limit %d out of range. Setting lower\n",233 lim);234 }235 236 return regmap_update_bits(regmap, reg, mask, sel);237}238 239static bool check_ocp_flag_mismatch(struct regulator_dev *rdev, int severity,240 struct bd957x_regulator_data *r)241{242 if ((severity == REGULATOR_SEVERITY_ERR &&243 r->uvd_notif != REGULATOR_EVENT_OVER_CURRENT) ||244 (severity == REGULATOR_SEVERITY_WARN &&245 r->uvd_notif != REGULATOR_EVENT_OVER_CURRENT_WARN)) {246 dev_warn(rdev_get_dev(rdev),247 "Can't support both OCP WARN and ERR\n");248 /* Do not overwrite ERR config with WARN */249 if (severity == REGULATOR_SEVERITY_WARN)250 return true;251 252 bd9576_fill_ocp_flags(r, 0);253 }254 255 return false;256}257 258static bool check_uvd_flag_mismatch(struct regulator_dev *rdev, int severity,259 struct bd957x_regulator_data *r)260{261 if ((severity == REGULATOR_SEVERITY_ERR &&262 r->uvd_notif != REGULATOR_EVENT_UNDER_VOLTAGE) ||263 (severity == REGULATOR_SEVERITY_WARN &&264 r->uvd_notif != REGULATOR_EVENT_UNDER_VOLTAGE_WARN)) {265 dev_warn(rdev_get_dev(rdev),266 "Can't support both UVD WARN and ERR\n");267 if (severity == REGULATOR_SEVERITY_WARN)268 return true;269 270 bd9576_fill_uvd_flags(r, 0);271 }272 273 return false;274}275 276static bool check_ovd_flag_mismatch(struct regulator_dev *rdev, int severity,277 struct bd957x_regulator_data *r)278{279 if ((severity == REGULATOR_SEVERITY_ERR &&280 r->ovd_notif != REGULATOR_EVENT_REGULATION_OUT) ||281 (severity == REGULATOR_SEVERITY_WARN &&282 r->ovd_notif != REGULATOR_EVENT_OVER_VOLTAGE_WARN)) {283 dev_warn(rdev_get_dev(rdev),284 "Can't support both OVD WARN and ERR\n");285 if (severity == REGULATOR_SEVERITY_WARN)286 return true;287 288 bd9576_fill_ovd_flags(r, 0);289 }290 291 return false;292}293 294static bool check_temp_flag_mismatch(struct regulator_dev *rdev, int severity,295 struct bd957x_regulator_data *r)296{297 if ((severity == REGULATOR_SEVERITY_ERR &&298 r->temp_notif != REGULATOR_EVENT_OVER_TEMP) ||299 (severity == REGULATOR_SEVERITY_WARN &&300 r->temp_notif != REGULATOR_EVENT_OVER_TEMP_WARN)) {301 dev_warn(rdev_get_dev(rdev),302 "Can't support both thermal WARN and ERR\n");303 if (severity == REGULATOR_SEVERITY_WARN)304 return true;305 }306 307 return false;308}309 310static int bd9576_set_ocp(struct regulator_dev *rdev, int lim_uA, int severity,311 bool enable)312{313 struct bd957x_data *d;314 struct bd957x_regulator_data *r;315 int reg, mask;316 int Vfet, rfet;317 const struct linear_range *range;318 int num_ranges;319 320 if ((lim_uA && !enable) || (!lim_uA && enable))321 return -EINVAL;322 323 r = container_of(rdev->desc, struct bd957x_regulator_data, desc);324 if (!r->oc_supported)325 return -EINVAL;326 327 d = rdev_get_drvdata(rdev);328 329 if (severity == REGULATOR_SEVERITY_PROT) {330 reg = r->ocp_reg;331 mask = r->ocp_mask;332 if (r->ocw_rfet) {333 range = voutS1_ocp_ranges;334 num_ranges = ARRAY_SIZE(voutS1_ocp_ranges);335 rfet = r->ocw_rfet / 1000;336 } else {337 range = voutS1_ocp_ranges_internal;338 num_ranges = ARRAY_SIZE(voutS1_ocp_ranges_internal);339 /* Internal values are already micro-amperes */340 rfet = 1000;341 }342 } else {343 reg = r->ocw_reg;344 mask = r->ocw_mask;345 346 if (r->ocw_rfet) {347 range = voutS1_ocw_ranges;348 num_ranges = ARRAY_SIZE(voutS1_ocw_ranges);349 rfet = r->ocw_rfet / 1000;350 } else {351 range = voutS1_ocw_ranges_internal;352 num_ranges = ARRAY_SIZE(voutS1_ocw_ranges_internal);353 /* Internal values are already micro-amperes */354 rfet = 1000;355 }356 357 /* We abuse uvd fields for OCW on VoutS1 */358 if (r->uvd_notif) {359 /*360 * If both warning and error are requested, prioritize361 * ERROR configuration362 */363 if (check_ocp_flag_mismatch(rdev, severity, r))364 return 0;365 } else {366 bool warn = severity == REGULATOR_SEVERITY_WARN;367 368 bd9576_fill_ocp_flags(r, warn);369 }370 }371 372 /*373 * limits are given in uA, rfet is mOhm374 * Divide lim_uA by 1000 to get Vfet in uV.375 * (We expect both Rfet and limit uA to be magnitude of hundreds of376 * milli Amperes & milli Ohms => we should still have decent accuracy)377 */378 Vfet = lim_uA/1000 * rfet;379 380 return bd9576_set_limit(range, num_ranges, d->regmap,381 reg, mask, Vfet);382}383 384static int bd9576_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity,385 bool enable)386{387 struct bd957x_data *d;388 struct bd957x_regulator_data *r;389 int mask, reg;390 391 if (severity == REGULATOR_SEVERITY_PROT) {392 if (!enable || lim_uV)393 return -EINVAL;394 return 0;395 }396 397 /*398 * BD9576 has enable control as a special value in limit reg. Can't399 * set limit but keep feature disabled or enable W/O given limit.400 */401 if ((lim_uV && !enable) || (!lim_uV && enable))402 return -EINVAL;403 404 r = container_of(rdev->desc, struct bd957x_regulator_data, desc);405 d = rdev_get_drvdata(rdev);406 407 mask = r->xvd_mask;408 reg = r->uvd_reg;409 /*410 * Check that there is no mismatch for what the detection IRQs are to411 * be used.412 */413 if (r->uvd_notif) {414 if (check_uvd_flag_mismatch(rdev, severity, r))415 return 0;416 } else {417 bd9576_fill_uvd_flags(r, severity == REGULATOR_SEVERITY_WARN);418 }419 420 return bd9576_set_limit(r->xvd_ranges, r->num_xvd_ranges, d->regmap,421 reg, mask, lim_uV);422}423 424static int bd9576_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity,425 bool enable)426{427 struct bd957x_data *d;428 struct bd957x_regulator_data *r;429 int mask, reg;430 431 if (severity == REGULATOR_SEVERITY_PROT) {432 if (!enable || lim_uV)433 return -EINVAL;434 return 0;435 }436 437 /*438 * BD9576 has enable control as a special value in limit reg. Can't439 * set limit but keep feature disabled or enable W/O given limit.440 */441 if ((lim_uV && !enable) || (!lim_uV && enable))442 return -EINVAL;443 444 r = container_of(rdev->desc, struct bd957x_regulator_data, desc);445 d = rdev_get_drvdata(rdev);446 447 mask = r->xvd_mask;448 reg = r->ovd_reg;449 /*450 * Check that there is no mismatch for what the detection IRQs are to451 * be used.452 */453 if (r->ovd_notif) {454 if (check_ovd_flag_mismatch(rdev, severity, r))455 return 0;456 } else {457 bd9576_fill_ovd_flags(r, severity == REGULATOR_SEVERITY_WARN);458 }459 460 return bd9576_set_limit(r->xvd_ranges, r->num_xvd_ranges, d->regmap,461 reg, mask, lim_uV);462}463 464 465static int bd9576_set_tw(struct regulator_dev *rdev, int lim, int severity,466 bool enable)467{468 struct bd957x_data *d;469 struct bd957x_regulator_data *r;470 int i;471 472 /*473 * BD9576MUF has fixed temperature limits474 * The detection can only be enabled/disabled475 */476 if (lim)477 return -EINVAL;478 479 /* Protection can't be disabled */480 if (severity == REGULATOR_SEVERITY_PROT) {481 if (!enable)482 return -EINVAL;483 else484 return 0;485 }486 487 r = container_of(rdev->desc, struct bd957x_regulator_data, desc);488 d = rdev_get_drvdata(rdev);489 490 /*491 * Check that there is no mismatch for what the detection IRQs are to492 * be used.493 */494 if (r->temp_notif)495 if (check_temp_flag_mismatch(rdev, severity, r))496 return 0;497 498 bd9576_fill_temp_flags(r, enable, severity == REGULATOR_SEVERITY_WARN);499 500 if (enable)501 return regmap_update_bits(d->regmap, BD957X_REG_INT_THERM_MASK,502 BD9576_THERM_IRQ_MASK_TW, 0);503 504 /*505 * If any of the regulators is interested in thermal warning we keep IRQ506 * enabled.507 */508 for (i = 0; i < BD9576_NUM_REGULATORS; i++)509 if (d->regulator_data[i].temp_notif)510 return 0;511 512 return regmap_update_bits(d->regmap, BD957X_REG_INT_THERM_MASK,513 BD9576_THERM_IRQ_MASK_TW,514 BD9576_THERM_IRQ_MASK_TW);515}516 517static const struct regulator_ops bd9573_vout34_ops = {518 .is_enabled = regulator_is_enabled_regmap,519 .list_voltage = bd957x_vout34_list_voltage,520 .get_voltage_sel = regulator_get_voltage_sel_regmap,521};522 523static const struct regulator_ops bd9576_vout34_ops = {524 .is_enabled = regulator_is_enabled_regmap,525 .list_voltage = bd957x_vout34_list_voltage,526 .get_voltage_sel = regulator_get_voltage_sel_regmap,527 .set_over_voltage_protection = bd9576_set_ovp,528 .set_under_voltage_protection = bd9576_set_uvp,529 .set_thermal_protection = bd9576_set_tw,530};531 532static const struct regulator_ops bd9573_vouts1_regulator_ops = {533 .is_enabled = regulator_is_enabled_regmap,534};535 536static const struct regulator_ops bd9576_vouts1_regulator_ops = {537 .is_enabled = regulator_is_enabled_regmap,538 .set_over_current_protection = bd9576_set_ocp,539};540 541static const struct regulator_ops bd9573_ops = {542 .is_enabled = regulator_is_enabled_regmap,543 .list_voltage = bd957x_list_voltage,544 .get_voltage_sel = regulator_get_voltage_sel_regmap,545};546 547static const struct regulator_ops bd9576_ops = {548 .is_enabled = regulator_is_enabled_regmap,549 .list_voltage = bd957x_list_voltage,550 .get_voltage_sel = regulator_get_voltage_sel_regmap,551 .set_over_voltage_protection = bd9576_set_ovp,552 .set_under_voltage_protection = bd9576_set_uvp,553 .set_thermal_protection = bd9576_set_tw,554};555 556static const struct regulator_ops *bd9573_ops_arr[] = {557 [BD957X_VD50] = &bd9573_ops,558 [BD957X_VD18] = &bd9573_ops,559 [BD957X_VDDDR] = &bd9573_vout34_ops,560 [BD957X_VD10] = &bd9573_vout34_ops,561 [BD957X_VOUTL1] = &bd9573_ops,562 [BD957X_VOUTS1] = &bd9573_vouts1_regulator_ops,563};564 565static const struct regulator_ops *bd9576_ops_arr[] = {566 [BD957X_VD50] = &bd9576_ops,567 [BD957X_VD18] = &bd9576_ops,568 [BD957X_VDDDR] = &bd9576_vout34_ops,569 [BD957X_VD10] = &bd9576_vout34_ops,570 [BD957X_VOUTL1] = &bd9576_ops,571 [BD957X_VOUTS1] = &bd9576_vouts1_regulator_ops,572};573 574static int vouts1_get_fet_res(struct device_node *np,575 const struct regulator_desc *desc,576 struct regulator_config *cfg)577{578 struct bd957x_regulator_data *data;579 int ret;580 u32 uohms;581 582 data = container_of(desc, struct bd957x_regulator_data, desc);583 584 ret = of_property_read_u32(np, "rohm,ocw-fet-ron-micro-ohms", &uohms);585 if (ret) {586 if (ret != -EINVAL)587 return ret;588 589 return 0;590 }591 data->ocw_rfet = uohms;592 return 0;593}594 595static struct bd957x_data bd957x_regulators = {596 .regulator_data = {597 {598 .desc = {599 .name = "VD50",600 .of_match = of_match_ptr("regulator-vd50"),601 .regulators_node = of_match_ptr("regulators"),602 .id = BD957X_VD50,603 .type = REGULATOR_VOLTAGE,604 .volt_table = &vout1_volt_table[0],605 .n_voltages = ARRAY_SIZE(vout1_volt_table),606 .vsel_reg = BD957X_REG_VOUT1_TUNE,607 .vsel_mask = BD957X_MASK_VOUT1_TUNE,608 .enable_reg = BD957X_REG_POW_TRIGGER1,609 .enable_mask = BD957X_REGULATOR_EN_MASK,610 .enable_val = BD957X_REGULATOR_DIS_VAL,611 .enable_is_inverted = true,612 .owner = THIS_MODULE,613 },614 .xvd_ranges = vout1_xvd_ranges,615 .num_xvd_ranges = ARRAY_SIZE(vout1_xvd_ranges),616 .ovd_reg = BD9576_REG_VOUT1_OVD,617 .uvd_reg = BD9576_REG_VOUT1_UVD,618 .xvd_mask = BD9576_MASK_XVD,619 },620 {621 .desc = {622 .name = "VD18",623 .of_match = of_match_ptr("regulator-vd18"),624 .regulators_node = of_match_ptr("regulators"),625 .id = BD957X_VD18,626 .type = REGULATOR_VOLTAGE,627 .volt_table = &vout2_volt_table[0],628 .n_voltages = ARRAY_SIZE(vout2_volt_table),629 .vsel_reg = BD957X_REG_VOUT2_TUNE,630 .vsel_mask = BD957X_MASK_VOUT2_TUNE,631 .enable_reg = BD957X_REG_POW_TRIGGER2,632 .enable_mask = BD957X_REGULATOR_EN_MASK,633 .enable_val = BD957X_REGULATOR_DIS_VAL,634 .enable_is_inverted = true,635 .owner = THIS_MODULE,636 },637 .xvd_ranges = vout234_xvd_ranges,638 .num_xvd_ranges = ARRAY_SIZE(vout234_xvd_ranges),639 .ovd_reg = BD9576_REG_VOUT2_OVD,640 .uvd_reg = BD9576_REG_VOUT2_UVD,641 .xvd_mask = BD9576_MASK_XVD,642 },643 {644 .desc = {645 .name = "VDDDR",646 .of_match = of_match_ptr("regulator-vdddr"),647 .regulators_node = of_match_ptr("regulators"),648 .id = BD957X_VDDDR,649 .type = REGULATOR_VOLTAGE,650 .n_voltages = BD957X_VOUTS34_NUM_VOLT,651 .vsel_reg = BD957X_REG_VOUT3_TUNE,652 .vsel_mask = BD957X_MASK_VOUT3_TUNE,653 .enable_reg = BD957X_REG_POW_TRIGGER3,654 .enable_mask = BD957X_REGULATOR_EN_MASK,655 .enable_val = BD957X_REGULATOR_DIS_VAL,656 .enable_is_inverted = true,657 .owner = THIS_MODULE,658 },659 .ovd_reg = BD9576_REG_VOUT3_OVD,660 .uvd_reg = BD9576_REG_VOUT3_UVD,661 .xvd_mask = BD9576_MASK_XVD,662 .xvd_ranges = vout234_xvd_ranges,663 .num_xvd_ranges = ARRAY_SIZE(vout234_xvd_ranges),664 },665 {666 .desc = {667 .name = "VD10",668 .of_match = of_match_ptr("regulator-vd10"),669 .regulators_node = of_match_ptr("regulators"),670 .id = BD957X_VD10,671 .type = REGULATOR_VOLTAGE,672 .fixed_uV = BD957X_VOUTS4_BASE_VOLT,673 .n_voltages = BD957X_VOUTS34_NUM_VOLT,674 .vsel_reg = BD957X_REG_VOUT4_TUNE,675 .vsel_mask = BD957X_MASK_VOUT4_TUNE,676 .enable_reg = BD957X_REG_POW_TRIGGER4,677 .enable_mask = BD957X_REGULATOR_EN_MASK,678 .enable_val = BD957X_REGULATOR_DIS_VAL,679 .enable_is_inverted = true,680 .owner = THIS_MODULE,681 },682 .xvd_ranges = vout234_xvd_ranges,683 .num_xvd_ranges = ARRAY_SIZE(vout234_xvd_ranges),684 .ovd_reg = BD9576_REG_VOUT4_OVD,685 .uvd_reg = BD9576_REG_VOUT4_UVD,686 .xvd_mask = BD9576_MASK_XVD,687 },688 {689 .desc = {690 .name = "VOUTL1",691 .of_match = of_match_ptr("regulator-voutl1"),692 .regulators_node = of_match_ptr("regulators"),693 .id = BD957X_VOUTL1,694 .type = REGULATOR_VOLTAGE,695 .volt_table = &voutl1_volt_table[0],696 .n_voltages = ARRAY_SIZE(voutl1_volt_table),697 .vsel_reg = BD957X_REG_VOUTL1_TUNE,698 .vsel_mask = BD957X_MASK_VOUTL1_TUNE,699 .enable_reg = BD957X_REG_POW_TRIGGERL1,700 .enable_mask = BD957X_REGULATOR_EN_MASK,701 .enable_val = BD957X_REGULATOR_DIS_VAL,702 .enable_is_inverted = true,703 .owner = THIS_MODULE,704 },705 .xvd_ranges = voutL1_xvd_ranges,706 .num_xvd_ranges = ARRAY_SIZE(voutL1_xvd_ranges),707 .ovd_reg = BD9576_REG_VOUTL1_OVD,708 .uvd_reg = BD9576_REG_VOUTL1_UVD,709 .xvd_mask = BD9576_MASK_XVD,710 },711 {712 .desc = {713 .name = "VOUTS1",714 .of_match = of_match_ptr("regulator-vouts1"),715 .regulators_node = of_match_ptr("regulators"),716 .id = BD957X_VOUTS1,717 .type = REGULATOR_VOLTAGE,718 .n_voltages = 1,719 .fixed_uV = BD957X_VOUTS1_VOLT,720 .enable_reg = BD957X_REG_POW_TRIGGERS1,721 .enable_mask = BD957X_REGULATOR_EN_MASK,722 .enable_val = BD957X_REGULATOR_DIS_VAL,723 .enable_is_inverted = true,724 .owner = THIS_MODULE,725 .of_parse_cb = vouts1_get_fet_res,726 },727 .oc_supported = true,728 .ocw_reg = BD9576_REG_VOUT1S_OCW,729 .ocw_mask = BD9576_MASK_VOUT1S_OCW,730 .ocp_reg = BD9576_REG_VOUT1S_OCP,731 .ocp_mask = BD9576_MASK_VOUT1S_OCP,732 },733 },734};735 736static int bd9576_renable(struct regulator_irq_data *rid, int reg, int mask)737{738 int val, ret;739 struct bd957x_data *d = (struct bd957x_data *)rid->data;740 741 ret = regmap_read(d->regmap, reg, &val);742 if (ret)743 return REGULATOR_FAILED_RETRY;744 745 if (rid->opaque && rid->opaque == (val & mask)) {746 /*747 * It seems we stil have same status. Ack and return748 * information that we are still out of limits and core749 * should not enable IRQ750 */751 regmap_write(d->regmap, reg, mask & val);752 return REGULATOR_ERROR_ON;753 }754 rid->opaque = 0;755 /*756 * Status was changed. Either prolem was solved or we have new issues.757 * Let's re-enable IRQs and be prepared to report problems again758 */759 return REGULATOR_ERROR_CLEARED;760}761 762static int bd9576_uvd_renable(struct regulator_irq_data *rid)763{764 return bd9576_renable(rid, BD957X_REG_INT_UVD_STAT, UVD_IRQ_VALID_MASK);765}766 767static int bd9576_ovd_renable(struct regulator_irq_data *rid)768{769 return bd9576_renable(rid, BD957X_REG_INT_OVD_STAT, OVD_IRQ_VALID_MASK);770}771 772static int bd9576_temp_renable(struct regulator_irq_data *rid)773{774 return bd9576_renable(rid, BD957X_REG_INT_THERM_STAT,775 BD9576_THERM_IRQ_MASK_TW);776}777 778static int bd9576_uvd_handler(int irq, struct regulator_irq_data *rid,779 unsigned long *dev_mask)780{781 int val, ret, i;782 struct bd957x_data *d = (struct bd957x_data *)rid->data;783 784 ret = regmap_read(d->regmap, BD957X_REG_INT_UVD_STAT, &val);785 if (ret)786 return REGULATOR_FAILED_RETRY;787 788 *dev_mask = 0;789 790 rid->opaque = val & UVD_IRQ_VALID_MASK;791 792 /*793 * Go through the set status bits and report either error or warning794 * to the notifier depending on what was flagged in DT795 */796 *dev_mask = val & BD9576_xVD_IRQ_MASK_VOUT1TO4;797 /* There is 1 bit gap in register after Vout1 .. Vout4 statuses */798 *dev_mask |= ((val & BD9576_xVD_IRQ_MASK_VOUTL1) >> 1);799 /*800 * We (ab)use the uvd for OCW notification. DT parsing should801 * have added correct OCW flag to uvd_notif and uvd_err for S1802 */803 *dev_mask |= ((val & BD9576_UVD_IRQ_MASK_VOUTS1_OCW) >> 1);804 805 for_each_set_bit(i, dev_mask, 6) {806 struct bd957x_regulator_data *rdata;807 struct regulator_err_state *stat;808 809 rdata = &d->regulator_data[i];810 stat = &rid->states[i];811 812 stat->notifs = rdata->uvd_notif;813 stat->errors = rdata->uvd_err;814 }815 816 ret = regmap_write(d->regmap, BD957X_REG_INT_UVD_STAT,817 UVD_IRQ_VALID_MASK & val);818 819 return 0;820}821 822static int bd9576_ovd_handler(int irq, struct regulator_irq_data *rid,823 unsigned long *dev_mask)824{825 int val, ret, i;826 struct bd957x_data *d = (struct bd957x_data *)rid->data;827 828 ret = regmap_read(d->regmap, BD957X_REG_INT_OVD_STAT, &val);829 if (ret)830 return REGULATOR_FAILED_RETRY;831 832 rid->opaque = val & OVD_IRQ_VALID_MASK;833 *dev_mask = 0;834 835 if (!(val & OVD_IRQ_VALID_MASK))836 return 0;837 838 *dev_mask = val & BD9576_xVD_IRQ_MASK_VOUT1TO4;839 /* There is 1 bit gap in register after Vout1 .. Vout4 statuses */840 *dev_mask |= ((val & BD9576_xVD_IRQ_MASK_VOUTL1) >> 1);841 842 for_each_set_bit(i, dev_mask, 5) {843 struct bd957x_regulator_data *rdata;844 struct regulator_err_state *stat;845 846 rdata = &d->regulator_data[i];847 stat = &rid->states[i];848 849 stat->notifs = rdata->ovd_notif;850 stat->errors = rdata->ovd_err;851 }852 853 /* Clear the sub-IRQ status */854 regmap_write(d->regmap, BD957X_REG_INT_OVD_STAT,855 OVD_IRQ_VALID_MASK & val);856 857 return 0;858}859 860#define BD9576_DEV_MASK_ALL_REGULATORS 0x3F861 862static int bd9576_thermal_handler(int irq, struct regulator_irq_data *rid,863 unsigned long *dev_mask)864{865 int val, ret, i;866 struct bd957x_data *d = (struct bd957x_data *)rid->data;867 868 ret = regmap_read(d->regmap, BD957X_REG_INT_THERM_STAT, &val);869 if (ret)870 return REGULATOR_FAILED_RETRY;871 872 if (!(val & BD9576_THERM_IRQ_MASK_TW)) {873 *dev_mask = 0;874 return 0;875 }876 877 *dev_mask = BD9576_DEV_MASK_ALL_REGULATORS;878 879 for (i = 0; i < BD9576_NUM_REGULATORS; i++) {880 struct bd957x_regulator_data *rdata;881 struct regulator_err_state *stat;882 883 rdata = &d->regulator_data[i];884 stat = &rid->states[i];885 886 stat->notifs = rdata->temp_notif;887 stat->errors = rdata->temp_err;888 }889 890 /* Clear the sub-IRQ status */891 regmap_write(d->regmap, BD957X_REG_INT_THERM_STAT,892 BD9576_THERM_IRQ_MASK_TW);893 894 return 0;895}896 897static int bd957x_probe(struct platform_device *pdev)898{899 int i;900 unsigned int num_reg_data;901 bool vout_mode, ddr_sel, may_have_irqs = false;902 struct regmap *regmap;903 struct bd957x_data *ic_data;904 struct regulator_config config = { 0 };905 /* All regulators are related to UVD and thermal IRQs... */906 struct regulator_dev *rdevs[BD9576_NUM_REGULATORS];907 /* ...But VoutS1 is not flagged by OVD IRQ */908 struct regulator_dev *ovd_devs[BD9576_NUM_OVD_REGULATORS];909 static const struct regulator_irq_desc bd9576_notif_uvd = {910 .name = "bd9576-uvd",911 .irq_off_ms = 1000,912 .map_event = bd9576_uvd_handler,913 .renable = bd9576_uvd_renable,914 .data = &bd957x_regulators,915 };916 static const struct regulator_irq_desc bd9576_notif_ovd = {917 .name = "bd9576-ovd",918 .irq_off_ms = 1000,919 .map_event = bd9576_ovd_handler,920 .renable = bd9576_ovd_renable,921 .data = &bd957x_regulators,922 };923 static const struct regulator_irq_desc bd9576_notif_temp = {924 .name = "bd9576-temp",925 .irq_off_ms = 1000,926 .map_event = bd9576_thermal_handler,927 .renable = bd9576_temp_renable,928 .data = &bd957x_regulators,929 };930 enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;931 932 num_reg_data = ARRAY_SIZE(bd957x_regulators.regulator_data);933 934 ic_data = &bd957x_regulators;935 936 regmap = dev_get_regmap(pdev->dev.parent, NULL);937 if (!regmap) {938 dev_err(&pdev->dev, "No regmap\n");939 return -EINVAL;940 }941 942 ic_data->regmap = regmap;943 vout_mode = device_property_read_bool(pdev->dev.parent,944 "rohm,vout1-en-low");945 if (vout_mode) {946 struct gpio_desc *en;947 948 dev_dbg(&pdev->dev, "GPIO controlled mode\n");949 950 /* VOUT1 enable state judged by VOUT1_EN pin */951 /* See if we have GPIO defined */952 en = devm_fwnode_gpiod_get(&pdev->dev,953 dev_fwnode(pdev->dev.parent),954 "rohm,vout1-en", GPIOD_OUT_LOW,955 "vout1-en");956 957 /* VOUT1_OPS gpio ctrl */958 /*959 * Regulator core prioritizes the ena_gpio over960 * enable/disable/is_enabled callbacks so no need to clear them961 * even if GPIO is used. So, we can still use same ops.962 *963 * In theory it is possible someone wants to set vout1-en LOW964 * during OTP loading and set VOUT1 to be controlled by GPIO -965 * but control the GPIO from some where else than this driver.966 * For that to work we should unset the is_enabled callback967 * here.968 *969 * I believe such case where rohm,vout1-en-low is set and970 * vout1-en-gpios is not is likely to be a misconfiguration.971 * So let's just err out for now.972 */973 if (!IS_ERR(en))974 config.ena_gpiod = en;975 else976 return dev_err_probe(&pdev->dev, PTR_ERR(en),977 "Failed to get VOUT1 control GPIO\n");978 }979 980 /*981 * If more than one PMIC needs to be controlled by same processor then982 * allocate the regulator data array here and use bd9576_regulators as983 * template. At the moment I see no such use-case so I spare some984 * bytes and use bd9576_regulators directly for non-constant configs985 * like DDR voltage selection.986 */987 platform_set_drvdata(pdev, ic_data);988 ddr_sel = device_property_read_bool(pdev->dev.parent,989 "rohm,ddr-sel-low");990 if (ddr_sel)991 ic_data->regulator_data[2].desc.fixed_uV = 1350000;992 else993 ic_data->regulator_data[2].desc.fixed_uV = 1500000;994 995 switch (chip) {996 case ROHM_CHIP_TYPE_BD9576:997 may_have_irqs = true;998 dev_dbg(&pdev->dev, "Found BD9576MUF\n");999 break;1000 case ROHM_CHIP_TYPE_BD9573:1001 dev_dbg(&pdev->dev, "Found BD9573MUF\n");1002 break;1003 default:1004 dev_err(&pdev->dev, "Unsupported chip type\n");1005 return -EINVAL;1006 }1007 1008 for (i = 0; i < num_reg_data; i++) {1009 struct regulator_desc *d;1010 1011 d = &ic_data->regulator_data[i].desc;1012 1013 1014 if (may_have_irqs) {1015 if (d->id >= ARRAY_SIZE(bd9576_ops_arr))1016 return -EINVAL;1017 1018 d->ops = bd9576_ops_arr[d->id];1019 } else {1020 if (d->id >= ARRAY_SIZE(bd9573_ops_arr))1021 return -EINVAL;1022 1023 d->ops = bd9573_ops_arr[d->id];1024 }1025 }1026 1027 config.dev = pdev->dev.parent;1028 config.regmap = regmap;1029 config.driver_data = ic_data;1030 1031 for (i = 0; i < num_reg_data; i++) {1032 1033 struct bd957x_regulator_data *r = &ic_data->regulator_data[i];1034 const struct regulator_desc *desc = &r->desc;1035 1036 r->rdev = devm_regulator_register(&pdev->dev, desc,1037 &config);1038 if (IS_ERR(r->rdev))1039 return dev_err_probe(&pdev->dev, PTR_ERR(r->rdev),1040 "failed to register %s regulator\n",1041 desc->name);1042 /*1043 * Clear the VOUT1 GPIO setting - rest of the regulators do not1044 * support GPIO control1045 */1046 config.ena_gpiod = NULL;1047 1048 if (!may_have_irqs)1049 continue;1050 1051 rdevs[i] = r->rdev;1052 if (i < BD957X_VOUTS1)1053 ovd_devs[i] = r->rdev;1054 }1055 if (may_have_irqs) {1056 void *ret;1057 /*1058 * We can add both the possible error and warning flags here1059 * because the core uses these only for status clearing and1060 * if we use warnings - errors are always clear and the other1061 * way around. We can also add CURRENT flag for all regulators1062 * because it is never set if it is not supported. Same applies1063 * to setting UVD for VoutS1 - it is not accidentally cleared1064 * as it is never set.1065 */1066 int uvd_errs = REGULATOR_ERROR_UNDER_VOLTAGE |1067 REGULATOR_ERROR_UNDER_VOLTAGE_WARN |1068 REGULATOR_ERROR_OVER_CURRENT |1069 REGULATOR_ERROR_OVER_CURRENT_WARN;1070 int ovd_errs = REGULATOR_ERROR_OVER_VOLTAGE_WARN |1071 REGULATOR_ERROR_REGULATION_OUT;1072 int temp_errs = REGULATOR_ERROR_OVER_TEMP |1073 REGULATOR_ERROR_OVER_TEMP_WARN;1074 int irq;1075 1076 irq = platform_get_irq_byname(pdev, "bd9576-uvd");1077 1078 /* Register notifiers - can fail if IRQ is not given */1079 ret = devm_regulator_irq_helper(&pdev->dev, &bd9576_notif_uvd,1080 irq, 0, uvd_errs, NULL,1081 &rdevs[0],1082 BD9576_NUM_REGULATORS);1083 if (IS_ERR(ret)) {1084 if (PTR_ERR(ret) == -EPROBE_DEFER)1085 return -EPROBE_DEFER;1086 1087 dev_warn(&pdev->dev, "UVD disabled %pe\n", ret);1088 }1089 1090 irq = platform_get_irq_byname(pdev, "bd9576-ovd");1091 1092 ret = devm_regulator_irq_helper(&pdev->dev, &bd9576_notif_ovd,1093 irq, 0, ovd_errs, NULL,1094 &ovd_devs[0],1095 BD9576_NUM_OVD_REGULATORS);1096 if (IS_ERR(ret)) {1097 if (PTR_ERR(ret) == -EPROBE_DEFER)1098 return -EPROBE_DEFER;1099 1100 dev_warn(&pdev->dev, "OVD disabled %pe\n", ret);1101 }1102 irq = platform_get_irq_byname(pdev, "bd9576-temp");1103 1104 ret = devm_regulator_irq_helper(&pdev->dev, &bd9576_notif_temp,1105 irq, 0, temp_errs, NULL,1106 &rdevs[0],1107 BD9576_NUM_REGULATORS);1108 if (IS_ERR(ret)) {1109 if (PTR_ERR(ret) == -EPROBE_DEFER)1110 return -EPROBE_DEFER;1111 1112 dev_warn(&pdev->dev, "Thermal warning disabled %pe\n",1113 ret);1114 }1115 }1116 return 0;1117}1118 1119static const struct platform_device_id bd957x_pmic_id[] = {1120 { "bd9573-regulator", ROHM_CHIP_TYPE_BD9573 },1121 { "bd9576-regulator", ROHM_CHIP_TYPE_BD9576 },1122 { },1123};1124MODULE_DEVICE_TABLE(platform, bd957x_pmic_id);1125 1126static struct platform_driver bd957x_regulator = {1127 .driver = {1128 .name = "bd957x-pmic",1129 .probe_type = PROBE_PREFER_ASYNCHRONOUS,1130 },1131 .probe = bd957x_probe,1132 .id_table = bd957x_pmic_id,1133};1134 1135module_platform_driver(bd957x_regulator);1136 1137MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");1138MODULE_DESCRIPTION("ROHM BD9576/BD9573 voltage regulator driver");1139MODULE_LICENSE("GPL");1140MODULE_ALIAS("platform:bd957x-pmic");1141