632 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// Copyright 2014 Embest Technology Co. Ltd. Inc.4// bd71815-regulator.c ROHM BD71815 regulator driver5//6// Author: Tony Luo <luofc@embedinfo.com>7//8// Partially rewritten at 2021 by9// Matti Vaittinen <matti.vaitinen@fi.rohmeurope.com>10 11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/init.h>14#include <linux/err.h>15#include <linux/platform_device.h>16#include <linux/of.h>17#include <linux/gpio/consumer.h>18#include <linux/regulator/driver.h>19#include <linux/delay.h>20#include <linux/slab.h>21#include <linux/mfd/rohm-generic.h>22#include <linux/mfd/rohm-bd71815.h>23#include <linux/regulator/of_regulator.h>24 25struct bd71815_regulator {26 struct regulator_desc desc;27 const struct rohm_dvs_config *dvs;28};29 30static const int bd7181x_wled_currents[] = {31 10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000,32 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,33 16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000,34};35 36static const struct rohm_dvs_config buck1_dvs = {37 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |38 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,39 .run_reg = BD71815_REG_BUCK1_VOLT_H,40 .run_mask = BD71815_VOLT_MASK,41 .run_on_mask = BD71815_BUCK_RUN_ON,42 .snvs_on_mask = BD71815_BUCK_SNVS_ON,43 .suspend_reg = BD71815_REG_BUCK1_VOLT_L,44 .suspend_mask = BD71815_VOLT_MASK,45 .suspend_on_mask = BD71815_BUCK_SUSP_ON,46 .lpsr_reg = BD71815_REG_BUCK1_VOLT_L,47 .lpsr_mask = BD71815_VOLT_MASK,48 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,49};50 51static const struct rohm_dvs_config buck2_dvs = {52 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |53 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,54 .run_reg = BD71815_REG_BUCK2_VOLT_H,55 .run_mask = BD71815_VOLT_MASK,56 .run_on_mask = BD71815_BUCK_RUN_ON,57 .snvs_on_mask = BD71815_BUCK_SNVS_ON,58 .suspend_reg = BD71815_REG_BUCK2_VOLT_L,59 .suspend_mask = BD71815_VOLT_MASK,60 .suspend_on_mask = BD71815_BUCK_SUSP_ON,61 .lpsr_reg = BD71815_REG_BUCK2_VOLT_L,62 .lpsr_mask = BD71815_VOLT_MASK,63 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,64};65 66static const struct rohm_dvs_config buck3_dvs = {67 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |68 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,69 .run_reg = BD71815_REG_BUCK3_VOLT,70 .run_mask = BD71815_VOLT_MASK,71 .run_on_mask = BD71815_BUCK_RUN_ON,72 .snvs_on_mask = BD71815_BUCK_SNVS_ON,73 .suspend_on_mask = BD71815_BUCK_SUSP_ON,74 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,75};76 77static const struct rohm_dvs_config buck4_dvs = {78 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |79 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,80 .run_reg = BD71815_REG_BUCK4_VOLT,81 .run_mask = BD71815_VOLT_MASK,82 .run_on_mask = BD71815_BUCK_RUN_ON,83 .snvs_on_mask = BD71815_BUCK_SNVS_ON,84 .suspend_on_mask = BD71815_BUCK_SUSP_ON,85 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,86};87 88static const struct rohm_dvs_config ldo1_dvs = {89 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |90 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,91 .run_reg = BD71815_REG_LDO_MODE1,92 .run_mask = BD71815_VOLT_MASK,93 .run_on_mask = LDO1_RUN_ON,94 .snvs_on_mask = LDO1_SNVS_ON,95 .suspend_on_mask = LDO1_SUSP_ON,96 .lpsr_on_mask = LDO1_LPSR_ON,97};98 99static const struct rohm_dvs_config ldo2_dvs = {100 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |101 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,102 .run_reg = BD71815_REG_LDO_MODE2,103 .run_mask = BD71815_VOLT_MASK,104 .run_on_mask = LDO2_RUN_ON,105 .snvs_on_mask = LDO2_SNVS_ON,106 .suspend_on_mask = LDO2_SUSP_ON,107 .lpsr_on_mask = LDO2_LPSR_ON,108};109 110static const struct rohm_dvs_config ldo3_dvs = {111 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |112 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,113 .run_reg = BD71815_REG_LDO_MODE2,114 .run_mask = BD71815_VOLT_MASK,115 .run_on_mask = LDO3_RUN_ON,116 .snvs_on_mask = LDO3_SNVS_ON,117 .suspend_on_mask = LDO3_SUSP_ON,118 .lpsr_on_mask = LDO3_LPSR_ON,119};120 121static const struct rohm_dvs_config ldo4_dvs = {122 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |123 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,124 .run_reg = BD71815_REG_LDO_MODE3,125 .run_mask = BD71815_VOLT_MASK,126 .run_on_mask = LDO4_RUN_ON,127 .snvs_on_mask = LDO4_SNVS_ON,128 .suspend_on_mask = LDO4_SUSP_ON,129 .lpsr_on_mask = LDO4_LPSR_ON,130};131 132static const struct rohm_dvs_config ldo5_dvs = {133 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |134 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,135 .run_reg = BD71815_REG_LDO_MODE3,136 .run_mask = BD71815_VOLT_MASK,137 .run_on_mask = LDO5_RUN_ON,138 .snvs_on_mask = LDO5_SNVS_ON,139 .suspend_on_mask = LDO5_SUSP_ON,140 .lpsr_on_mask = LDO5_LPSR_ON,141};142 143static const struct rohm_dvs_config dvref_dvs = {144 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |145 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,146 .run_on_mask = DVREF_RUN_ON,147 .snvs_on_mask = DVREF_SNVS_ON,148 .suspend_on_mask = DVREF_SUSP_ON,149 .lpsr_on_mask = DVREF_LPSR_ON,150};151 152static const struct rohm_dvs_config ldolpsr_dvs = {153 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |154 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,155 .run_on_mask = DVREF_RUN_ON,156 .snvs_on_mask = DVREF_SNVS_ON,157 .suspend_on_mask = DVREF_SUSP_ON,158 .lpsr_on_mask = DVREF_LPSR_ON,159};160 161static const struct rohm_dvs_config buck5_dvs = {162 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |163 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,164 .run_reg = BD71815_REG_BUCK5_VOLT,165 .run_mask = BD71815_VOLT_MASK,166 .run_on_mask = BD71815_BUCK_RUN_ON,167 .snvs_on_mask = BD71815_BUCK_SNVS_ON,168 .suspend_on_mask = BD71815_BUCK_SUSP_ON,169 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,170};171 172static int set_hw_dvs_levels(struct device_node *np,173 const struct regulator_desc *desc,174 struct regulator_config *cfg)175{176 struct bd71815_regulator *data;177 178 data = container_of(desc, struct bd71815_regulator, desc);179 return rohm_regulator_set_dvs_levels(data->dvs, np, desc, cfg->regmap);180}181 182/*183 * Bucks 1 and 2 have two voltage selection registers where selected184 * voltage can be set. Which of the registers is used can be either controlled185 * by a control bit in register - or by HW state. If HW state specific voltages186 * are given - then we assume HW state based control should be used.187 *188 * If volatge value is updated to currently selected register - then output189 * voltage is immediately changed no matter what is set as ramp rate. Thus we190 * default changing voltage by writing new value to inactive register and191 * then updating the 'register selection' bit. This naturally only works when192 * HW state machine is not used to select the voltage.193 */194static int buck12_set_hw_dvs_levels(struct device_node *np,195 const struct regulator_desc *desc,196 struct regulator_config *cfg)197{198 struct bd71815_regulator *data;199 int ret = 0, val;200 201 data = container_of(desc, struct bd71815_regulator, desc);202 203 if (of_property_present(np, "rohm,dvs-run-voltage") ||204 of_property_present(np, "rohm,dvs-suspend-voltage") ||205 of_property_present(np, "rohm,dvs-lpsr-voltage") ||206 of_property_present(np, "rohm,dvs-snvs-voltage")) {207 ret = regmap_read(cfg->regmap, desc->vsel_reg, &val);208 if (ret)209 return ret;210 211 if (!(BD71815_BUCK_STBY_DVS & val) &&212 !(BD71815_BUCK_DVSSEL & val)) {213 int val2;214 215 /*216 * We are currently using voltage from _L.217 * We'd better copy it to _H and switch to it to218 * avoid shutting us down if LPSR or SUSPEND is set to219 * disabled. _L value is at reg _H + 1220 */221 ret = regmap_read(cfg->regmap, desc->vsel_reg + 1,222 &val2);223 if (ret)224 return ret;225 226 ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,227 BD71815_VOLT_MASK |228 BD71815_BUCK_DVSSEL,229 val2 | BD71815_BUCK_DVSSEL);230 if (ret)231 return ret;232 }233 ret = rohm_regulator_set_dvs_levels(data->dvs, np, desc,234 cfg->regmap);235 if (ret)236 return ret;237 /*238 * DVS levels were given => use HW-state machine for voltage239 * controls. NOTE: AFAIK, This means that if voltage is changed240 * by SW the ramp-rate is not respected. Should we disable241 * SW voltage control when the HW state machine is used?242 */243 ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,244 BD71815_BUCK_STBY_DVS,245 BD71815_BUCK_STBY_DVS);246 }247 248 return ret;249}250 251/*252 * BUCK1/2253 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting254 * 00: 10.00mV/usec 10mV 1uS255 * 01: 5.00mV/usec 10mV 2uS256 * 10: 2.50mV/usec 10mV 4uS257 * 11: 1.25mV/usec 10mV 8uS258 */259static const unsigned int bd7181x_ramp_table[] = { 10000, 5000, 2500, 1250 };260 261static int bd7181x_led_set_current_limit(struct regulator_dev *rdev,262 int min_uA, int max_uA)263{264 int ret;265 int onstatus;266 267 onstatus = regulator_is_enabled_regmap(rdev);268 269 ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA);270 if (!ret) {271 int newstatus;272 273 newstatus = regulator_is_enabled_regmap(rdev);274 if (onstatus != newstatus) {275 /*276 * HW FIX: spurious led status change detected. Toggle277 * state as a workaround278 */279 if (onstatus)280 ret = regulator_enable_regmap(rdev);281 else282 ret = regulator_disable_regmap(rdev);283 284 if (ret)285 dev_err(rdev_get_dev(rdev),286 "failed to revert the LED state (%d)\n",287 ret);288 }289 }290 291 return ret;292}293 294static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)295{296 int rid = rdev_get_id(rdev);297 int ret, regh, regl, val;298 299 regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2;300 regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2;301 302 ret = regmap_read(rdev->regmap, regh, &val);303 if (ret)304 return ret;305 306 /*307 * If we use HW state machine based voltage reg selection - then we308 * return BD71815_REG_BUCK1_VOLT_H which is used at RUN.309 * Else we do return the BD71815_REG_BUCK1_VOLT_H or310 * BD71815_REG_BUCK1_VOLT_L depending on which is selected to be used311 * by BD71815_BUCK_DVSSEL bit312 */313 if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))314 ret = regmap_read(rdev->regmap, regl, &val);315 316 if (ret)317 return ret;318 319 return val & BD71815_VOLT_MASK;320}321 322/*323 * For Buck 1/2.324 */325static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,326 unsigned int sel)327{328 int rid = rdev_get_id(rdev);329 int ret, val, reg, regh, regl;330 331 regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2;332 regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2;333 334 ret = regmap_read(rdev->regmap, regh, &val);335 if (ret)336 return ret;337 338 /*339 * If bucks 1 & 2 are controlled by state machine - then the RUN state340 * voltage is set to BD71815_REG_BUCK1_VOLT_H. Changing SUSPEND/LPSR341 * voltages at runtime is not supported by this driver.342 */343 if (((val & BD71815_BUCK_STBY_DVS))) {344 return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,345 sel);346 }347 /* Update new voltage to the register which is not selected now */348 if (val & BD71815_BUCK_DVSSEL)349 reg = regl;350 else351 reg = regh;352 353 ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel);354 if (ret)355 return ret;356 357 /* Select the other DVS register to be used */358 return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,359 ~val);360}361 362static const struct regulator_ops bd7181x_ldo_regulator_ops = {363 .enable = regulator_enable_regmap,364 .disable = regulator_disable_regmap,365 .is_enabled = regulator_is_enabled_regmap,366 .list_voltage = regulator_list_voltage_linear,367 .set_voltage_sel = regulator_set_voltage_sel_regmap,368 .get_voltage_sel = regulator_get_voltage_sel_regmap,369};370 371static const struct regulator_ops bd7181x_fixed_regulator_ops = {372 .enable = regulator_enable_regmap,373 .disable = regulator_disable_regmap,374 .is_enabled = regulator_is_enabled_regmap,375 .list_voltage = regulator_list_voltage_linear,376};377 378static const struct regulator_ops bd7181x_buck_regulator_ops = {379 .enable = regulator_enable_regmap,380 .disable = regulator_disable_regmap,381 .is_enabled = regulator_is_enabled_regmap,382 .list_voltage = regulator_list_voltage_linear,383 .set_voltage_sel = regulator_set_voltage_sel_regmap,384 .get_voltage_sel = regulator_get_voltage_sel_regmap,385 .set_voltage_time_sel = regulator_set_voltage_time_sel,386};387 388static const struct regulator_ops bd7181x_buck12_regulator_ops = {389 .enable = regulator_enable_regmap,390 .disable = regulator_disable_regmap,391 .is_enabled = regulator_is_enabled_regmap,392 .list_voltage = regulator_list_voltage_linear,393 .set_voltage_sel = bd7181x_buck12_set_voltage_sel,394 .get_voltage_sel = bd7181x_buck12_get_voltage_sel,395 .set_voltage_time_sel = regulator_set_voltage_time_sel,396 .set_ramp_delay = regulator_set_ramp_delay_regmap,397};398 399static const struct regulator_ops bd7181x_led_regulator_ops = {400 .enable = regulator_enable_regmap,401 .disable = regulator_disable_regmap,402 .is_enabled = regulator_is_enabled_regmap,403 .set_current_limit = bd7181x_led_set_current_limit,404 .get_current_limit = regulator_get_current_limit_regmap,405};406 407#define BD71815_FIXED_REG(_name, _id, ereg, emsk, voltage, _dvs) \408 [(_id)] = { \409 .desc = { \410 .name = #_name, \411 .of_match = of_match_ptr(#_name), \412 .regulators_node = of_match_ptr("regulators"), \413 .n_voltages = 1, \414 .ops = &bd7181x_fixed_regulator_ops, \415 .type = REGULATOR_VOLTAGE, \416 .id = (_id), \417 .owner = THIS_MODULE, \418 .min_uV = (voltage), \419 .enable_reg = (ereg), \420 .enable_mask = (emsk), \421 .of_parse_cb = set_hw_dvs_levels, \422 }, \423 .dvs = (_dvs), \424 }425 426#define BD71815_BUCK_REG(_name, _id, vsel, ereg, min, max, step, _dvs) \427 [(_id)] = { \428 .desc = { \429 .name = #_name, \430 .of_match = of_match_ptr(#_name), \431 .regulators_node = of_match_ptr("regulators"), \432 .n_voltages = ((max) - (min)) / (step) + 1, \433 .ops = &bd7181x_buck_regulator_ops, \434 .type = REGULATOR_VOLTAGE, \435 .id = (_id), \436 .owner = THIS_MODULE, \437 .min_uV = (min), \438 .uV_step = (step), \439 .vsel_reg = (vsel), \440 .vsel_mask = BD71815_VOLT_MASK, \441 .enable_reg = (ereg), \442 .enable_mask = BD71815_BUCK_RUN_ON, \443 .of_parse_cb = set_hw_dvs_levels, \444 }, \445 .dvs = (_dvs), \446 }447 448#define BD71815_BUCK12_REG(_name, _id, vsel, ereg, min, max, step, \449 _dvs) \450 [(_id)] = { \451 .desc = { \452 .name = #_name, \453 .of_match = of_match_ptr(#_name), \454 .regulators_node = of_match_ptr("regulators"), \455 .n_voltages = ((max) - (min)) / (step) + 1, \456 .ops = &bd7181x_buck12_regulator_ops, \457 .type = REGULATOR_VOLTAGE, \458 .id = (_id), \459 .owner = THIS_MODULE, \460 .min_uV = (min), \461 .uV_step = (step), \462 .vsel_reg = (vsel), \463 .vsel_mask = BD71815_VOLT_MASK, \464 .enable_reg = (ereg), \465 .enable_mask = BD71815_BUCK_RUN_ON, \466 .ramp_reg = (ereg), \467 .ramp_mask = BD71815_BUCK_RAMPRATE_MASK, \468 .ramp_delay_table = bd7181x_ramp_table, \469 .n_ramp_values = ARRAY_SIZE(bd7181x_ramp_table),\470 .of_parse_cb = buck12_set_hw_dvs_levels, \471 }, \472 .dvs = (_dvs), \473 }474 475#define BD71815_LED_REG(_name, _id, csel, mask, ereg, emsk, currents) \476 [(_id)] = { \477 .desc = { \478 .name = #_name, \479 .of_match = of_match_ptr(#_name), \480 .regulators_node = of_match_ptr("regulators"), \481 .n_current_limits = ARRAY_SIZE(currents), \482 .ops = &bd7181x_led_regulator_ops, \483 .type = REGULATOR_CURRENT, \484 .id = (_id), \485 .owner = THIS_MODULE, \486 .curr_table = currents, \487 .csel_reg = (csel), \488 .csel_mask = (mask), \489 .enable_reg = (ereg), \490 .enable_mask = (emsk), \491 }, \492 }493 494#define BD71815_LDO_REG(_name, _id, vsel, ereg, emsk, min, max, step, \495 _dvs) \496 [(_id)] = { \497 .desc = { \498 .name = #_name, \499 .of_match = of_match_ptr(#_name), \500 .regulators_node = of_match_ptr("regulators"), \501 .n_voltages = ((max) - (min)) / (step) + 1, \502 .ops = &bd7181x_ldo_regulator_ops, \503 .type = REGULATOR_VOLTAGE, \504 .id = (_id), \505 .owner = THIS_MODULE, \506 .min_uV = (min), \507 .uV_step = (step), \508 .vsel_reg = (vsel), \509 .vsel_mask = BD71815_VOLT_MASK, \510 .enable_reg = (ereg), \511 .enable_mask = (emsk), \512 .of_parse_cb = set_hw_dvs_levels, \513 }, \514 .dvs = (_dvs), \515 }516 517static const struct bd71815_regulator bd71815_regulators[] = {518 BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H,519 BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000,520 &buck1_dvs),521 BD71815_BUCK12_REG(buck2, BD71815_BUCK2, BD71815_REG_BUCK2_VOLT_H,522 BD71815_REG_BUCK2_MODE, 800000, 2000000, 25000,523 &buck2_dvs),524 BD71815_BUCK_REG(buck3, BD71815_BUCK3, BD71815_REG_BUCK3_VOLT,525 BD71815_REG_BUCK3_MODE, 1200000, 2700000, 50000,526 &buck3_dvs),527 BD71815_BUCK_REG(buck4, BD71815_BUCK4, BD71815_REG_BUCK4_VOLT,528 BD71815_REG_BUCK4_MODE, 1100000, 1850000, 25000,529 &buck4_dvs),530 BD71815_BUCK_REG(buck5, BD71815_BUCK5, BD71815_REG_BUCK5_VOLT,531 BD71815_REG_BUCK5_MODE, 1800000, 3300000, 50000,532 &buck5_dvs),533 BD71815_LDO_REG(ldo1, BD71815_LDO1, BD71815_REG_LDO1_VOLT,534 BD71815_REG_LDO_MODE1, LDO1_RUN_ON, 800000, 3300000,535 50000, &ldo1_dvs),536 BD71815_LDO_REG(ldo2, BD71815_LDO2, BD71815_REG_LDO2_VOLT,537 BD71815_REG_LDO_MODE2, LDO2_RUN_ON, 800000, 3300000,538 50000, &ldo2_dvs),539 /*540 * Let's default LDO3 to be enabled by SW. We can override ops if DT541 * says LDO3 should be enabled by HW when DCIN is connected.542 */543 BD71815_LDO_REG(ldo3, BD71815_LDO3, BD71815_REG_LDO3_VOLT,544 BD71815_REG_LDO_MODE2, LDO3_RUN_ON, 800000, 3300000,545 50000, &ldo3_dvs),546 BD71815_LDO_REG(ldo4, BD71815_LDO4, BD71815_REG_LDO4_VOLT,547 BD71815_REG_LDO_MODE3, LDO4_RUN_ON, 800000, 3300000,548 50000, &ldo4_dvs),549 BD71815_LDO_REG(ldo5, BD71815_LDO5, BD71815_REG_LDO5_VOLT_H,550 BD71815_REG_LDO_MODE3, LDO5_RUN_ON, 800000, 3300000,551 50000, &ldo5_dvs),552 BD71815_FIXED_REG(ldodvref, BD71815_LDODVREF, BD71815_REG_LDO_MODE4,553 DVREF_RUN_ON, 3000000, &dvref_dvs),554 BD71815_FIXED_REG(ldolpsr, BD71815_LDOLPSR, BD71815_REG_LDO_MODE4,555 LDO_LPSR_RUN_ON, 1800000, &ldolpsr_dvs),556 BD71815_LED_REG(wled, BD71815_WLED, BD71815_REG_LED_DIMM, LED_DIMM_MASK,557 BD71815_REG_LED_CTRL, LED_RUN_ON,558 bd7181x_wled_currents),559};560 561static int bd7181x_probe(struct platform_device *pdev)562{563 struct regulator_config config = {};564 int i, ret;565 struct gpio_desc *ldo4_en;566 struct regmap *regmap;567 568 regmap = dev_get_regmap(pdev->dev.parent, NULL);569 if (!regmap) {570 dev_err(&pdev->dev, "No parent regmap\n");571 return -ENODEV;572 }573 574 ldo4_en = devm_fwnode_gpiod_get(&pdev->dev,575 dev_fwnode(pdev->dev.parent),576 "rohm,vsel", GPIOD_ASIS, "ldo4-en");577 if (IS_ERR(ldo4_en)) {578 ret = PTR_ERR(ldo4_en);579 if (ret != -ENOENT)580 return ret;581 ldo4_en = NULL;582 }583 584 /* Disable to go to ship-mode */585 ret = regmap_update_bits(regmap, BD71815_REG_PWRCTRL, RESTARTEN, 0);586 if (ret)587 return ret;588 589 config.dev = pdev->dev.parent;590 config.regmap = regmap;591 592 for (i = 0; i < BD71815_REGULATOR_CNT; i++) {593 const struct regulator_desc *desc;594 struct regulator_dev *rdev;595 596 desc = &bd71815_regulators[i].desc;597 598 if (i == BD71815_LDO4)599 config.ena_gpiod = ldo4_en;600 else601 config.ena_gpiod = NULL;602 603 rdev = devm_regulator_register(&pdev->dev, desc, &config);604 if (IS_ERR(rdev))605 return dev_err_probe(&pdev->dev, PTR_ERR(rdev),606 "failed to register %s regulator\n",607 desc->name);608 }609 return 0;610}611 612static const struct platform_device_id bd7181x_pmic_id[] = {613 { "bd71815-pmic", ROHM_CHIP_TYPE_BD71815 },614 { },615};616MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);617 618static struct platform_driver bd7181x_regulator = {619 .driver = {620 .name = "bd7181x-pmic",621 .probe_type = PROBE_PREFER_ASYNCHRONOUS,622 },623 .probe = bd7181x_probe,624 .id_table = bd7181x_pmic_id,625};626module_platform_driver(bd7181x_regulator);627 628MODULE_AUTHOR("Tony Luo <luofc@embedinfo.com>");629MODULE_DESCRIPTION("BD71815 voltage regulator driver");630MODULE_LICENSE("GPL v2");631MODULE_ALIAS("platform:bd7181x-pmic");632