731 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (C) 2019 ROHM Semiconductors3// bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver4//5 6#include <linux/delay.h>7#include <linux/err.h>8#include <linux/interrupt.h>9#include <linux/kernel.h>10#include <linux/mfd/rohm-bd71828.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/platform_device.h>14#include <linux/regmap.h>15#include <linux/regulator/driver.h>16#include <linux/regulator/machine.h>17#include <linux/regulator/of_regulator.h>18 19struct reg_init {20 unsigned int reg;21 unsigned int mask;22 unsigned int val;23};24struct bd71828_regulator_data {25 struct regulator_desc desc;26 const struct rohm_dvs_config dvs;27 const struct reg_init *reg_inits;28 int reg_init_amnt;29};30 31static const struct reg_init buck1_inits[] = {32 /*33 * DVS Buck voltages can be changed by register values or via GPIO.34 * Use register accesses by default.35 */36 {37 .reg = BD71828_REG_PS_CTRL_1,38 .mask = BD71828_MASK_DVS_BUCK1_CTRL,39 .val = BD71828_DVS_BUCK1_CTRL_I2C,40 },41};42 43static const struct reg_init buck2_inits[] = {44 {45 .reg = BD71828_REG_PS_CTRL_1,46 .mask = BD71828_MASK_DVS_BUCK2_CTRL,47 .val = BD71828_DVS_BUCK2_CTRL_I2C,48 },49};50 51static const struct reg_init buck6_inits[] = {52 {53 .reg = BD71828_REG_PS_CTRL_1,54 .mask = BD71828_MASK_DVS_BUCK6_CTRL,55 .val = BD71828_DVS_BUCK6_CTRL_I2C,56 },57};58 59static const struct reg_init buck7_inits[] = {60 {61 .reg = BD71828_REG_PS_CTRL_1,62 .mask = BD71828_MASK_DVS_BUCK7_CTRL,63 .val = BD71828_DVS_BUCK7_CTRL_I2C,64 },65};66 67static const struct linear_range bd71828_buck1267_volts[] = {68 REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250),69 REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0),70};71 72static const struct linear_range bd71828_buck3_volts[] = {73 REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x0f, 50000),74 REGULATOR_LINEAR_RANGE(2000000, 0x10, 0x1f, 0),75};76 77static const struct linear_range bd71828_buck4_volts[] = {78 REGULATOR_LINEAR_RANGE(1000000, 0x00, 0x1f, 25000),79 REGULATOR_LINEAR_RANGE(1800000, 0x20, 0x3f, 0),80};81 82static const struct linear_range bd71828_buck5_volts[] = {83 REGULATOR_LINEAR_RANGE(2500000, 0x00, 0x0f, 50000),84 REGULATOR_LINEAR_RANGE(3300000, 0x10, 0x1f, 0),85};86 87static const struct linear_range bd71828_ldo_volts[] = {88 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000),89 REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0),90};91 92static const unsigned int bd71828_ramp_delay[] = { 2500, 5000, 10000, 20000 };93 94static int buck_set_hw_dvs_levels(struct device_node *np,95 const struct regulator_desc *desc,96 struct regulator_config *cfg)97{98 struct bd71828_regulator_data *data;99 100 data = container_of(desc, struct bd71828_regulator_data, desc);101 102 return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);103}104 105static int ldo6_parse_dt(struct device_node *np,106 const struct regulator_desc *desc,107 struct regulator_config *cfg)108{109 int ret, i;110 uint32_t uv = 0;111 unsigned int en;112 struct regmap *regmap = cfg->regmap;113 static const char * const props[] = { "rohm,dvs-run-voltage",114 "rohm,dvs-idle-voltage",115 "rohm,dvs-suspend-voltage",116 "rohm,dvs-lpsr-voltage" };117 unsigned int mask[] = { BD71828_MASK_RUN_EN, BD71828_MASK_IDLE_EN,118 BD71828_MASK_SUSP_EN, BD71828_MASK_LPSR_EN };119 120 for (i = 0; i < ARRAY_SIZE(props); i++) {121 ret = of_property_read_u32(np, props[i], &uv);122 if (ret) {123 if (ret != -EINVAL)124 return ret;125 continue;126 }127 if (uv)128 en = 0xffffffff;129 else130 en = 0;131 132 ret = regmap_update_bits(regmap, desc->enable_reg, mask[i], en);133 if (ret)134 return ret;135 }136 return 0;137}138 139static const struct regulator_ops bd71828_buck_ops = {140 .enable = regulator_enable_regmap,141 .disable = regulator_disable_regmap,142 .is_enabled = regulator_is_enabled_regmap,143 .list_voltage = regulator_list_voltage_linear_range,144 .set_voltage_sel = regulator_set_voltage_sel_regmap,145 .get_voltage_sel = regulator_get_voltage_sel_regmap,146};147 148static const struct regulator_ops bd71828_dvs_buck_ops = {149 .enable = regulator_enable_regmap,150 .disable = regulator_disable_regmap,151 .is_enabled = regulator_is_enabled_regmap,152 .list_voltage = regulator_list_voltage_linear_range,153 .set_voltage_sel = regulator_set_voltage_sel_regmap,154 .get_voltage_sel = regulator_get_voltage_sel_regmap,155 .set_voltage_time_sel = regulator_set_voltage_time_sel,156 .set_ramp_delay = regulator_set_ramp_delay_regmap,157};158 159static const struct regulator_ops bd71828_ldo_ops = {160 .enable = regulator_enable_regmap,161 .disable = regulator_disable_regmap,162 .is_enabled = regulator_is_enabled_regmap,163 .list_voltage = regulator_list_voltage_linear_range,164 .set_voltage_sel = regulator_set_voltage_sel_regmap,165 .get_voltage_sel = regulator_get_voltage_sel_regmap,166};167 168static const struct regulator_ops bd71828_ldo6_ops = {169 .enable = regulator_enable_regmap,170 .disable = regulator_disable_regmap,171 .is_enabled = regulator_is_enabled_regmap,172};173 174static const struct bd71828_regulator_data bd71828_rdata[] = {175 {176 .desc = {177 .name = "buck1",178 .of_match = of_match_ptr("BUCK1"),179 .regulators_node = of_match_ptr("regulators"),180 .id = BD71828_BUCK1,181 .ops = &bd71828_dvs_buck_ops,182 .type = REGULATOR_VOLTAGE,183 .linear_ranges = bd71828_buck1267_volts,184 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),185 .n_voltages = BD71828_BUCK1267_VOLTS,186 .enable_reg = BD71828_REG_BUCK1_EN,187 .enable_mask = BD71828_MASK_RUN_EN,188 .vsel_reg = BD71828_REG_BUCK1_VOLT,189 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,190 .ramp_delay_table = bd71828_ramp_delay,191 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),192 .ramp_reg = BD71828_REG_BUCK1_MODE,193 .ramp_mask = BD71828_MASK_RAMP_DELAY,194 .owner = THIS_MODULE,195 .of_parse_cb = buck_set_hw_dvs_levels,196 },197 .dvs = {198 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |199 ROHM_DVS_LEVEL_SUSPEND |200 ROHM_DVS_LEVEL_LPSR,201 .run_reg = BD71828_REG_BUCK1_VOLT,202 .run_mask = BD71828_MASK_BUCK1267_VOLT,203 .idle_reg = BD71828_REG_BUCK1_IDLE_VOLT,204 .idle_mask = BD71828_MASK_BUCK1267_VOLT,205 .idle_on_mask = BD71828_MASK_IDLE_EN,206 .suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT,207 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,208 .suspend_on_mask = BD71828_MASK_SUSP_EN,209 /*210 * LPSR voltage is same as SUSPEND voltage. Allow211 * only enabling/disabling regulator for LPSR state212 */213 .lpsr_on_mask = BD71828_MASK_LPSR_EN,214 },215 .reg_inits = buck1_inits,216 .reg_init_amnt = ARRAY_SIZE(buck1_inits),217 },218 {219 .desc = {220 .name = "buck2",221 .of_match = of_match_ptr("BUCK2"),222 .regulators_node = of_match_ptr("regulators"),223 .id = BD71828_BUCK2,224 .ops = &bd71828_dvs_buck_ops,225 .type = REGULATOR_VOLTAGE,226 .linear_ranges = bd71828_buck1267_volts,227 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),228 .n_voltages = BD71828_BUCK1267_VOLTS,229 .enable_reg = BD71828_REG_BUCK2_EN,230 .enable_mask = BD71828_MASK_RUN_EN,231 .vsel_reg = BD71828_REG_BUCK2_VOLT,232 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,233 .ramp_delay_table = bd71828_ramp_delay,234 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),235 .ramp_reg = BD71828_REG_BUCK2_MODE,236 .ramp_mask = BD71828_MASK_RAMP_DELAY,237 .owner = THIS_MODULE,238 .of_parse_cb = buck_set_hw_dvs_levels,239 },240 .dvs = {241 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |242 ROHM_DVS_LEVEL_SUSPEND |243 ROHM_DVS_LEVEL_LPSR,244 .run_reg = BD71828_REG_BUCK2_VOLT,245 .run_mask = BD71828_MASK_BUCK1267_VOLT,246 .idle_reg = BD71828_REG_BUCK2_IDLE_VOLT,247 .idle_mask = BD71828_MASK_BUCK1267_VOLT,248 .idle_on_mask = BD71828_MASK_IDLE_EN,249 .suspend_reg = BD71828_REG_BUCK2_SUSP_VOLT,250 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,251 .suspend_on_mask = BD71828_MASK_SUSP_EN,252 .lpsr_on_mask = BD71828_MASK_LPSR_EN,253 .lpsr_reg = BD71828_REG_BUCK2_SUSP_VOLT,254 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,255 },256 .reg_inits = buck2_inits,257 .reg_init_amnt = ARRAY_SIZE(buck2_inits),258 },259 {260 .desc = {261 .name = "buck3",262 .of_match = of_match_ptr("BUCK3"),263 .regulators_node = of_match_ptr("regulators"),264 .id = BD71828_BUCK3,265 .ops = &bd71828_buck_ops,266 .type = REGULATOR_VOLTAGE,267 .linear_ranges = bd71828_buck3_volts,268 .n_linear_ranges = ARRAY_SIZE(bd71828_buck3_volts),269 .n_voltages = BD71828_BUCK3_VOLTS,270 .enable_reg = BD71828_REG_BUCK3_EN,271 .enable_mask = BD71828_MASK_RUN_EN,272 .vsel_reg = BD71828_REG_BUCK3_VOLT,273 .vsel_mask = BD71828_MASK_BUCK3_VOLT,274 .owner = THIS_MODULE,275 .of_parse_cb = buck_set_hw_dvs_levels,276 },277 .dvs = {278 /*279 * BUCK3 only supports single voltage for all states.280 * voltage can be individually enabled for each state281 * though => allow setting all states to support282 * enabling power rail on different states.283 */284 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |285 ROHM_DVS_LEVEL_SUSPEND |286 ROHM_DVS_LEVEL_LPSR,287 .run_reg = BD71828_REG_BUCK3_VOLT,288 .run_mask = BD71828_MASK_BUCK3_VOLT,289 .idle_on_mask = BD71828_MASK_IDLE_EN,290 .suspend_on_mask = BD71828_MASK_SUSP_EN,291 .lpsr_on_mask = BD71828_MASK_LPSR_EN,292 },293 },294 {295 .desc = {296 .name = "buck4",297 .of_match = of_match_ptr("BUCK4"),298 .regulators_node = of_match_ptr("regulators"),299 .id = BD71828_BUCK4,300 .ops = &bd71828_buck_ops,301 .type = REGULATOR_VOLTAGE,302 .linear_ranges = bd71828_buck4_volts,303 .n_linear_ranges = ARRAY_SIZE(bd71828_buck4_volts),304 .n_voltages = BD71828_BUCK4_VOLTS,305 .enable_reg = BD71828_REG_BUCK4_EN,306 .enable_mask = BD71828_MASK_RUN_EN,307 .vsel_reg = BD71828_REG_BUCK4_VOLT,308 .vsel_mask = BD71828_MASK_BUCK4_VOLT,309 .owner = THIS_MODULE,310 .of_parse_cb = buck_set_hw_dvs_levels,311 },312 .dvs = {313 /*314 * BUCK4 only supports single voltage for all states.315 * voltage can be individually enabled for each state316 * though => allow setting all states to support317 * enabling power rail on different states.318 */319 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |320 ROHM_DVS_LEVEL_SUSPEND |321 ROHM_DVS_LEVEL_LPSR,322 .run_reg = BD71828_REG_BUCK4_VOLT,323 .run_mask = BD71828_MASK_BUCK4_VOLT,324 .idle_on_mask = BD71828_MASK_IDLE_EN,325 .suspend_on_mask = BD71828_MASK_SUSP_EN,326 .lpsr_on_mask = BD71828_MASK_LPSR_EN,327 },328 },329 {330 .desc = {331 .name = "buck5",332 .of_match = of_match_ptr("BUCK5"),333 .regulators_node = of_match_ptr("regulators"),334 .id = BD71828_BUCK5,335 .ops = &bd71828_buck_ops,336 .type = REGULATOR_VOLTAGE,337 .linear_ranges = bd71828_buck5_volts,338 .n_linear_ranges = ARRAY_SIZE(bd71828_buck5_volts),339 .n_voltages = BD71828_BUCK5_VOLTS,340 .enable_reg = BD71828_REG_BUCK5_EN,341 .enable_mask = BD71828_MASK_RUN_EN,342 .vsel_reg = BD71828_REG_BUCK5_VOLT,343 .vsel_mask = BD71828_MASK_BUCK5_VOLT,344 .owner = THIS_MODULE,345 .of_parse_cb = buck_set_hw_dvs_levels,346 },347 .dvs = {348 /*349 * BUCK5 only supports single voltage for all states.350 * voltage can be individually enabled for each state351 * though => allow setting all states to support352 * enabling power rail on different states.353 */354 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |355 ROHM_DVS_LEVEL_SUSPEND |356 ROHM_DVS_LEVEL_LPSR,357 .run_reg = BD71828_REG_BUCK5_VOLT,358 .run_mask = BD71828_MASK_BUCK5_VOLT,359 .idle_on_mask = BD71828_MASK_IDLE_EN,360 .suspend_on_mask = BD71828_MASK_SUSP_EN,361 .lpsr_on_mask = BD71828_MASK_LPSR_EN,362 },363 },364 {365 .desc = {366 .name = "buck6",367 .of_match = of_match_ptr("BUCK6"),368 .regulators_node = of_match_ptr("regulators"),369 .id = BD71828_BUCK6,370 .ops = &bd71828_dvs_buck_ops,371 .type = REGULATOR_VOLTAGE,372 .linear_ranges = bd71828_buck1267_volts,373 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),374 .n_voltages = BD71828_BUCK1267_VOLTS,375 .enable_reg = BD71828_REG_BUCK6_EN,376 .enable_mask = BD71828_MASK_RUN_EN,377 .vsel_reg = BD71828_REG_BUCK6_VOLT,378 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,379 .ramp_delay_table = bd71828_ramp_delay,380 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),381 .ramp_reg = BD71828_REG_BUCK6_MODE,382 .ramp_mask = BD71828_MASK_RAMP_DELAY,383 .owner = THIS_MODULE,384 .of_parse_cb = buck_set_hw_dvs_levels,385 },386 .dvs = {387 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |388 ROHM_DVS_LEVEL_SUSPEND |389 ROHM_DVS_LEVEL_LPSR,390 .run_reg = BD71828_REG_BUCK6_VOLT,391 .run_mask = BD71828_MASK_BUCK1267_VOLT,392 .idle_reg = BD71828_REG_BUCK6_IDLE_VOLT,393 .idle_mask = BD71828_MASK_BUCK1267_VOLT,394 .idle_on_mask = BD71828_MASK_IDLE_EN,395 .suspend_reg = BD71828_REG_BUCK6_SUSP_VOLT,396 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,397 .suspend_on_mask = BD71828_MASK_SUSP_EN,398 .lpsr_on_mask = BD71828_MASK_LPSR_EN,399 .lpsr_reg = BD71828_REG_BUCK6_SUSP_VOLT,400 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,401 },402 .reg_inits = buck6_inits,403 .reg_init_amnt = ARRAY_SIZE(buck6_inits),404 },405 {406 .desc = {407 .name = "buck7",408 .of_match = of_match_ptr("BUCK7"),409 .regulators_node = of_match_ptr("regulators"),410 .id = BD71828_BUCK7,411 .ops = &bd71828_dvs_buck_ops,412 .type = REGULATOR_VOLTAGE,413 .linear_ranges = bd71828_buck1267_volts,414 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),415 .n_voltages = BD71828_BUCK1267_VOLTS,416 .enable_reg = BD71828_REG_BUCK7_EN,417 .enable_mask = BD71828_MASK_RUN_EN,418 .vsel_reg = BD71828_REG_BUCK7_VOLT,419 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,420 .ramp_delay_table = bd71828_ramp_delay,421 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),422 .ramp_reg = BD71828_REG_BUCK7_MODE,423 .ramp_mask = BD71828_MASK_RAMP_DELAY,424 .owner = THIS_MODULE,425 .of_parse_cb = buck_set_hw_dvs_levels,426 },427 .dvs = {428 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |429 ROHM_DVS_LEVEL_SUSPEND |430 ROHM_DVS_LEVEL_LPSR,431 .run_reg = BD71828_REG_BUCK7_VOLT,432 .run_mask = BD71828_MASK_BUCK1267_VOLT,433 .idle_reg = BD71828_REG_BUCK7_IDLE_VOLT,434 .idle_mask = BD71828_MASK_BUCK1267_VOLT,435 .idle_on_mask = BD71828_MASK_IDLE_EN,436 .suspend_reg = BD71828_REG_BUCK7_SUSP_VOLT,437 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,438 .suspend_on_mask = BD71828_MASK_SUSP_EN,439 .lpsr_on_mask = BD71828_MASK_LPSR_EN,440 .lpsr_reg = BD71828_REG_BUCK7_SUSP_VOLT,441 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,442 },443 .reg_inits = buck7_inits,444 .reg_init_amnt = ARRAY_SIZE(buck7_inits),445 },446 {447 .desc = {448 .name = "ldo1",449 .of_match = of_match_ptr("LDO1"),450 .regulators_node = of_match_ptr("regulators"),451 .id = BD71828_LDO1,452 .ops = &bd71828_ldo_ops,453 .type = REGULATOR_VOLTAGE,454 .linear_ranges = bd71828_ldo_volts,455 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),456 .n_voltages = BD71828_LDO_VOLTS,457 .enable_reg = BD71828_REG_LDO1_EN,458 .enable_mask = BD71828_MASK_RUN_EN,459 .vsel_reg = BD71828_REG_LDO1_VOLT,460 .vsel_mask = BD71828_MASK_LDO_VOLT,461 .owner = THIS_MODULE,462 .of_parse_cb = buck_set_hw_dvs_levels,463 },464 .dvs = {465 /*466 * LDO1 only supports single voltage for all states.467 * voltage can be individually enabled for each state468 * though => allow setting all states to support469 * enabling power rail on different states.470 */471 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |472 ROHM_DVS_LEVEL_SUSPEND |473 ROHM_DVS_LEVEL_LPSR,474 .run_reg = BD71828_REG_LDO1_VOLT,475 .run_mask = BD71828_MASK_LDO_VOLT,476 .idle_on_mask = BD71828_MASK_IDLE_EN,477 .suspend_on_mask = BD71828_MASK_SUSP_EN,478 .lpsr_on_mask = BD71828_MASK_LPSR_EN,479 },480 }, {481 .desc = {482 .name = "ldo2",483 .of_match = of_match_ptr("LDO2"),484 .regulators_node = of_match_ptr("regulators"),485 .id = BD71828_LDO2,486 .ops = &bd71828_ldo_ops,487 .type = REGULATOR_VOLTAGE,488 .linear_ranges = bd71828_ldo_volts,489 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),490 .n_voltages = BD71828_LDO_VOLTS,491 .enable_reg = BD71828_REG_LDO2_EN,492 .enable_mask = BD71828_MASK_RUN_EN,493 .vsel_reg = BD71828_REG_LDO2_VOLT,494 .vsel_mask = BD71828_MASK_LDO_VOLT,495 .owner = THIS_MODULE,496 .of_parse_cb = buck_set_hw_dvs_levels,497 },498 .dvs = {499 /*500 * LDO2 only supports single voltage for all states.501 * voltage can be individually enabled for each state502 * though => allow setting all states to support503 * enabling power rail on different states.504 */505 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |506 ROHM_DVS_LEVEL_SUSPEND |507 ROHM_DVS_LEVEL_LPSR,508 .run_reg = BD71828_REG_LDO2_VOLT,509 .run_mask = BD71828_MASK_LDO_VOLT,510 .idle_on_mask = BD71828_MASK_IDLE_EN,511 .suspend_on_mask = BD71828_MASK_SUSP_EN,512 .lpsr_on_mask = BD71828_MASK_LPSR_EN,513 },514 }, {515 .desc = {516 .name = "ldo3",517 .of_match = of_match_ptr("LDO3"),518 .regulators_node = of_match_ptr("regulators"),519 .id = BD71828_LDO3,520 .ops = &bd71828_ldo_ops,521 .type = REGULATOR_VOLTAGE,522 .linear_ranges = bd71828_ldo_volts,523 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),524 .n_voltages = BD71828_LDO_VOLTS,525 .enable_reg = BD71828_REG_LDO3_EN,526 .enable_mask = BD71828_MASK_RUN_EN,527 .vsel_reg = BD71828_REG_LDO3_VOLT,528 .vsel_mask = BD71828_MASK_LDO_VOLT,529 .owner = THIS_MODULE,530 .of_parse_cb = buck_set_hw_dvs_levels,531 },532 .dvs = {533 /*534 * LDO3 only supports single voltage for all states.535 * voltage can be individually enabled for each state536 * though => allow setting all states to support537 * enabling power rail on different states.538 */539 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |540 ROHM_DVS_LEVEL_SUSPEND |541 ROHM_DVS_LEVEL_LPSR,542 .run_reg = BD71828_REG_LDO3_VOLT,543 .run_mask = BD71828_MASK_LDO_VOLT,544 .idle_on_mask = BD71828_MASK_IDLE_EN,545 .suspend_on_mask = BD71828_MASK_SUSP_EN,546 .lpsr_on_mask = BD71828_MASK_LPSR_EN,547 },548 549 }, {550 .desc = {551 .name = "ldo4",552 .of_match = of_match_ptr("LDO4"),553 .regulators_node = of_match_ptr("regulators"),554 .id = BD71828_LDO4,555 .ops = &bd71828_ldo_ops,556 .type = REGULATOR_VOLTAGE,557 .linear_ranges = bd71828_ldo_volts,558 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),559 .n_voltages = BD71828_LDO_VOLTS,560 .enable_reg = BD71828_REG_LDO4_EN,561 .enable_mask = BD71828_MASK_RUN_EN,562 .vsel_reg = BD71828_REG_LDO4_VOLT,563 .vsel_mask = BD71828_MASK_LDO_VOLT,564 .owner = THIS_MODULE,565 .of_parse_cb = buck_set_hw_dvs_levels,566 },567 .dvs = {568 /*569 * LDO1 only supports single voltage for all states.570 * voltage can be individually enabled for each state571 * though => allow setting all states to support572 * enabling power rail on different states.573 */574 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |575 ROHM_DVS_LEVEL_SUSPEND |576 ROHM_DVS_LEVEL_LPSR,577 .run_reg = BD71828_REG_LDO4_VOLT,578 .run_mask = BD71828_MASK_LDO_VOLT,579 .idle_on_mask = BD71828_MASK_IDLE_EN,580 .suspend_on_mask = BD71828_MASK_SUSP_EN,581 .lpsr_on_mask = BD71828_MASK_LPSR_EN,582 },583 }, {584 .desc = {585 .name = "ldo5",586 .of_match = of_match_ptr("LDO5"),587 .regulators_node = of_match_ptr("regulators"),588 .id = BD71828_LDO5,589 .ops = &bd71828_ldo_ops,590 .type = REGULATOR_VOLTAGE,591 .linear_ranges = bd71828_ldo_volts,592 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),593 .n_voltages = BD71828_LDO_VOLTS,594 .enable_reg = BD71828_REG_LDO5_EN,595 .enable_mask = BD71828_MASK_RUN_EN,596 .vsel_reg = BD71828_REG_LDO5_VOLT,597 .vsel_mask = BD71828_MASK_LDO_VOLT,598 .of_parse_cb = buck_set_hw_dvs_levels,599 .owner = THIS_MODULE,600 },601 /*602 * LDO5 is special. It can choose vsel settings to be configured603 * from 2 different registers (by GPIO).604 *605 * This driver supports only configuration where606 * BD71828_REG_LDO5_VOLT_L is used.607 */608 .dvs = {609 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |610 ROHM_DVS_LEVEL_SUSPEND |611 ROHM_DVS_LEVEL_LPSR,612 .run_reg = BD71828_REG_LDO5_VOLT,613 .run_mask = BD71828_MASK_LDO_VOLT,614 .idle_on_mask = BD71828_MASK_IDLE_EN,615 .suspend_on_mask = BD71828_MASK_SUSP_EN,616 .lpsr_on_mask = BD71828_MASK_LPSR_EN,617 },618 619 }, {620 .desc = {621 .name = "ldo6",622 .of_match = of_match_ptr("LDO6"),623 .regulators_node = of_match_ptr("regulators"),624 .id = BD71828_LDO6,625 .ops = &bd71828_ldo6_ops,626 .type = REGULATOR_VOLTAGE,627 .fixed_uV = BD71828_LDO_6_VOLTAGE,628 .n_voltages = 1,629 .enable_reg = BD71828_REG_LDO6_EN,630 .enable_mask = BD71828_MASK_RUN_EN,631 .owner = THIS_MODULE,632 /*633 * LDO6 only supports enable/disable for all states.634 * Voltage for LDO6 is fixed.635 */636 .of_parse_cb = ldo6_parse_dt,637 },638 }, {639 .desc = {640 /* SNVS LDO in data-sheet */641 .name = "ldo7",642 .of_match = of_match_ptr("LDO7"),643 .regulators_node = of_match_ptr("regulators"),644 .id = BD71828_LDO_SNVS,645 .ops = &bd71828_ldo_ops,646 .type = REGULATOR_VOLTAGE,647 .linear_ranges = bd71828_ldo_volts,648 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),649 .n_voltages = BD71828_LDO_VOLTS,650 .enable_reg = BD71828_REG_LDO7_EN,651 .enable_mask = BD71828_MASK_RUN_EN,652 .vsel_reg = BD71828_REG_LDO7_VOLT,653 .vsel_mask = BD71828_MASK_LDO_VOLT,654 .owner = THIS_MODULE,655 .of_parse_cb = buck_set_hw_dvs_levels,656 },657 .dvs = {658 /*659 * LDO7 only supports single voltage for all states.660 * voltage can be individually enabled for each state661 * though => allow setting all states to support662 * enabling power rail on different states.663 */664 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |665 ROHM_DVS_LEVEL_SUSPEND |666 ROHM_DVS_LEVEL_LPSR,667 .run_reg = BD71828_REG_LDO7_VOLT,668 .idle_reg = BD71828_REG_LDO7_VOLT,669 .suspend_reg = BD71828_REG_LDO7_VOLT,670 .lpsr_reg = BD71828_REG_LDO7_VOLT,671 .run_mask = BD71828_MASK_LDO_VOLT,672 .idle_on_mask = BD71828_MASK_IDLE_EN,673 .suspend_on_mask = BD71828_MASK_SUSP_EN,674 .lpsr_on_mask = BD71828_MASK_LPSR_EN,675 },676 677 },678};679 680static int bd71828_probe(struct platform_device *pdev)681{682 int i, j, ret;683 struct regulator_config config = {684 .dev = pdev->dev.parent,685 };686 687 config.regmap = dev_get_regmap(pdev->dev.parent, NULL);688 if (!config.regmap)689 return -ENODEV;690 691 for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {692 struct regulator_dev *rdev;693 const struct bd71828_regulator_data *rd;694 695 rd = &bd71828_rdata[i];696 rdev = devm_regulator_register(&pdev->dev,697 &rd->desc, &config);698 if (IS_ERR(rdev))699 return dev_err_probe(&pdev->dev, PTR_ERR(rdev),700 "failed to register %s regulator\n",701 rd->desc.name);702 703 for (j = 0; j < rd->reg_init_amnt; j++) {704 ret = regmap_update_bits(config.regmap,705 rd->reg_inits[j].reg,706 rd->reg_inits[j].mask,707 rd->reg_inits[j].val);708 if (ret)709 return dev_err_probe(&pdev->dev, ret,710 "regulator %s init failed\n",711 rd->desc.name);712 }713 }714 return 0;715}716 717static struct platform_driver bd71828_regulator = {718 .driver = {719 .name = "bd71828-pmic",720 .probe_type = PROBE_PREFER_ASYNCHRONOUS,721 },722 .probe = bd71828_probe,723};724 725module_platform_driver(bd71828_regulator);726 727MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");728MODULE_DESCRIPTION("BD71828 voltage regulator driver");729MODULE_LICENSE("GPL");730MODULE_ALIAS("platform:bd71828-pmic");731