1072 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2020 NXP.4 * NXP PCA9450 pmic driver5 */6 7#include <linux/err.h>8#include <linux/gpio/consumer.h>9#include <linux/i2c.h>10#include <linux/interrupt.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/platform_device.h>15#include <linux/regulator/driver.h>16#include <linux/regulator/machine.h>17#include <linux/regulator/of_regulator.h>18#include <linux/regulator/pca9450.h>19 20struct pc9450_dvs_config {21 unsigned int run_reg; /* dvs0 */22 unsigned int run_mask;23 unsigned int standby_reg; /* dvs1 */24 unsigned int standby_mask;25};26 27struct pca9450_regulator_desc {28 struct regulator_desc desc;29 const struct pc9450_dvs_config dvs;30};31 32struct pca9450 {33 struct device *dev;34 struct regmap *regmap;35 struct gpio_desc *sd_vsel_gpio;36 enum pca9450_chip_type type;37 unsigned int rcnt;38 int irq;39};40 41static const struct regmap_range pca9450_status_range = {42 .range_min = PCA9450_REG_INT1,43 .range_max = PCA9450_REG_PWRON_STAT,44};45 46static const struct regmap_access_table pca9450_volatile_regs = {47 .yes_ranges = &pca9450_status_range,48 .n_yes_ranges = 1,49};50 51static const struct regmap_config pca9450_regmap_config = {52 .reg_bits = 8,53 .val_bits = 8,54 .volatile_table = &pca9450_volatile_regs,55 .max_register = PCA9450_MAX_REGISTER - 1,56 .cache_type = REGCACHE_MAPLE,57};58 59/*60 * BUCK1/2/361 * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting62 * 00: 25mV/1usec63 * 01: 25mV/2usec64 * 10: 25mV/4usec65 * 11: 25mV/8usec66 */67static const unsigned int pca9450_dvs_buck_ramp_table[] = {68 25000, 12500, 6250, 312569};70 71static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {72 .enable = regulator_enable_regmap,73 .disable = regulator_disable_regmap,74 .is_enabled = regulator_is_enabled_regmap,75 .list_voltage = regulator_list_voltage_linear_range,76 .set_voltage_sel = regulator_set_voltage_sel_regmap,77 .get_voltage_sel = regulator_get_voltage_sel_regmap,78 .set_voltage_time_sel = regulator_set_voltage_time_sel,79 .set_ramp_delay = regulator_set_ramp_delay_regmap,80};81 82static const struct regulator_ops pca9450_buck_regulator_ops = {83 .enable = regulator_enable_regmap,84 .disable = regulator_disable_regmap,85 .is_enabled = regulator_is_enabled_regmap,86 .list_voltage = regulator_list_voltage_linear_range,87 .set_voltage_sel = regulator_set_voltage_sel_regmap,88 .get_voltage_sel = regulator_get_voltage_sel_regmap,89 .set_voltage_time_sel = regulator_set_voltage_time_sel,90};91 92static const struct regulator_ops pca9450_ldo_regulator_ops = {93 .enable = regulator_enable_regmap,94 .disable = regulator_disable_regmap,95 .is_enabled = regulator_is_enabled_regmap,96 .list_voltage = regulator_list_voltage_linear_range,97 .set_voltage_sel = regulator_set_voltage_sel_regmap,98 .get_voltage_sel = regulator_get_voltage_sel_regmap,99};100 101/*102 * BUCK1/2/3103 * 0.60 to 2.1875V (12.5mV step)104 */105static const struct linear_range pca9450_dvs_buck_volts[] = {106 REGULATOR_LINEAR_RANGE(600000, 0x00, 0x7F, 12500),107};108 109/*110 * BUCK1/3111 * 0.65 to 2.2375V (12.5mV step)112 */113static const struct linear_range pca9451a_dvs_buck_volts[] = {114 REGULATOR_LINEAR_RANGE(650000, 0x00, 0x7F, 12500),115};116 117/*118 * BUCK4/5/6119 * 0.6V to 3.4V (25mV step)120 */121static const struct linear_range pca9450_buck_volts[] = {122 REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),123 REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),124};125 126/*127 * LDO1128 * 1.6 to 3.3V ()129 */130static const struct linear_range pca9450_ldo1_volts[] = {131 REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),132 REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),133};134 135/*136 * LDO2137 * 0.8 to 1.15V (50mV step)138 */139static const struct linear_range pca9450_ldo2_volts[] = {140 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),141};142 143/*144 * LDO3/4145 * 0.8 to 3.3V (100mV step)146 */147static const struct linear_range pca9450_ldo34_volts[] = {148 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),149 REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),150};151 152/*153 * LDO5154 * 1.8 to 3.3V (100mV step)155 */156static const struct linear_range pca9450_ldo5_volts[] = {157 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),158};159 160static int buck_set_dvs(const struct regulator_desc *desc,161 struct device_node *np, struct regmap *regmap,162 char *prop, unsigned int reg, unsigned int mask)163{164 int ret, i;165 uint32_t uv;166 167 ret = of_property_read_u32(np, prop, &uv);168 if (ret == -EINVAL)169 return 0;170 else if (ret)171 return ret;172 173 for (i = 0; i < desc->n_voltages; i++) {174 ret = regulator_desc_list_voltage_linear_range(desc, i);175 if (ret < 0)176 continue;177 if (ret == uv) {178 i <<= ffs(desc->vsel_mask) - 1;179 ret = regmap_update_bits(regmap, reg, mask, i);180 break;181 }182 }183 184 if (ret == 0) {185 struct pca9450_regulator_desc *regulator = container_of(desc,186 struct pca9450_regulator_desc, desc);187 188 /* Enable DVS control through PMIC_STBY_REQ for this BUCK */189 ret = regmap_update_bits(regmap, regulator->desc.enable_reg,190 BUCK1_DVS_CTRL, BUCK1_DVS_CTRL);191 }192 return ret;193}194 195static int pca9450_set_dvs_levels(struct device_node *np,196 const struct regulator_desc *desc,197 struct regulator_config *cfg)198{199 struct pca9450_regulator_desc *data = container_of(desc,200 struct pca9450_regulator_desc, desc);201 const struct pc9450_dvs_config *dvs = &data->dvs;202 unsigned int reg, mask;203 char *prop;204 int i, ret = 0;205 206 for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {207 switch (i) {208 case PCA9450_DVS_LEVEL_RUN:209 prop = "nxp,dvs-run-voltage";210 reg = dvs->run_reg;211 mask = dvs->run_mask;212 break;213 case PCA9450_DVS_LEVEL_STANDBY:214 prop = "nxp,dvs-standby-voltage";215 reg = dvs->standby_reg;216 mask = dvs->standby_mask;217 break;218 default:219 return -EINVAL;220 }221 222 ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);223 if (ret)224 break;225 }226 227 return ret;228}229 230static const struct pca9450_regulator_desc pca9450a_regulators[] = {231 {232 .desc = {233 .name = "buck1",234 .of_match = of_match_ptr("BUCK1"),235 .regulators_node = of_match_ptr("regulators"),236 .id = PCA9450_BUCK1,237 .ops = &pca9450_dvs_buck_regulator_ops,238 .type = REGULATOR_VOLTAGE,239 .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,240 .linear_ranges = pca9450_dvs_buck_volts,241 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),242 .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,243 .vsel_mask = BUCK1OUT_DVS0_MASK,244 .enable_reg = PCA9450_REG_BUCK1CTRL,245 .enable_mask = BUCK1_ENMODE_MASK,246 .ramp_reg = PCA9450_REG_BUCK1CTRL,247 .ramp_mask = BUCK1_RAMP_MASK,248 .ramp_delay_table = pca9450_dvs_buck_ramp_table,249 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),250 .owner = THIS_MODULE,251 .of_parse_cb = pca9450_set_dvs_levels,252 },253 .dvs = {254 .run_reg = PCA9450_REG_BUCK1OUT_DVS0,255 .run_mask = BUCK1OUT_DVS0_MASK,256 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,257 .standby_mask = BUCK1OUT_DVS1_MASK,258 },259 },260 {261 .desc = {262 .name = "buck2",263 .of_match = of_match_ptr("BUCK2"),264 .regulators_node = of_match_ptr("regulators"),265 .id = PCA9450_BUCK2,266 .ops = &pca9450_dvs_buck_regulator_ops,267 .type = REGULATOR_VOLTAGE,268 .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,269 .linear_ranges = pca9450_dvs_buck_volts,270 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),271 .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,272 .vsel_mask = BUCK2OUT_DVS0_MASK,273 .enable_reg = PCA9450_REG_BUCK2CTRL,274 .enable_mask = BUCK2_ENMODE_MASK,275 .ramp_reg = PCA9450_REG_BUCK2CTRL,276 .ramp_mask = BUCK2_RAMP_MASK,277 .ramp_delay_table = pca9450_dvs_buck_ramp_table,278 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),279 .owner = THIS_MODULE,280 .of_parse_cb = pca9450_set_dvs_levels,281 },282 .dvs = {283 .run_reg = PCA9450_REG_BUCK2OUT_DVS0,284 .run_mask = BUCK2OUT_DVS0_MASK,285 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,286 .standby_mask = BUCK2OUT_DVS1_MASK,287 },288 },289 {290 .desc = {291 .name = "buck3",292 .of_match = of_match_ptr("BUCK3"),293 .regulators_node = of_match_ptr("regulators"),294 .id = PCA9450_BUCK3,295 .ops = &pca9450_dvs_buck_regulator_ops,296 .type = REGULATOR_VOLTAGE,297 .n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,298 .linear_ranges = pca9450_dvs_buck_volts,299 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),300 .vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,301 .vsel_mask = BUCK3OUT_DVS0_MASK,302 .enable_reg = PCA9450_REG_BUCK3CTRL,303 .enable_mask = BUCK3_ENMODE_MASK,304 .ramp_reg = PCA9450_REG_BUCK3CTRL,305 .ramp_mask = BUCK3_RAMP_MASK,306 .ramp_delay_table = pca9450_dvs_buck_ramp_table,307 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),308 .owner = THIS_MODULE,309 .of_parse_cb = pca9450_set_dvs_levels,310 },311 .dvs = {312 .run_reg = PCA9450_REG_BUCK3OUT_DVS0,313 .run_mask = BUCK3OUT_DVS0_MASK,314 .standby_reg = PCA9450_REG_BUCK3OUT_DVS1,315 .standby_mask = BUCK3OUT_DVS1_MASK,316 },317 },318 {319 .desc = {320 .name = "buck4",321 .of_match = of_match_ptr("BUCK4"),322 .regulators_node = of_match_ptr("regulators"),323 .id = PCA9450_BUCK4,324 .ops = &pca9450_buck_regulator_ops,325 .type = REGULATOR_VOLTAGE,326 .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,327 .linear_ranges = pca9450_buck_volts,328 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),329 .vsel_reg = PCA9450_REG_BUCK4OUT,330 .vsel_mask = BUCK4OUT_MASK,331 .enable_reg = PCA9450_REG_BUCK4CTRL,332 .enable_mask = BUCK4_ENMODE_MASK,333 .owner = THIS_MODULE,334 },335 },336 {337 .desc = {338 .name = "buck5",339 .of_match = of_match_ptr("BUCK5"),340 .regulators_node = of_match_ptr("regulators"),341 .id = PCA9450_BUCK5,342 .ops = &pca9450_buck_regulator_ops,343 .type = REGULATOR_VOLTAGE,344 .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,345 .linear_ranges = pca9450_buck_volts,346 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),347 .vsel_reg = PCA9450_REG_BUCK5OUT,348 .vsel_mask = BUCK5OUT_MASK,349 .enable_reg = PCA9450_REG_BUCK5CTRL,350 .enable_mask = BUCK5_ENMODE_MASK,351 .owner = THIS_MODULE,352 },353 },354 {355 .desc = {356 .name = "buck6",357 .of_match = of_match_ptr("BUCK6"),358 .regulators_node = of_match_ptr("regulators"),359 .id = PCA9450_BUCK6,360 .ops = &pca9450_buck_regulator_ops,361 .type = REGULATOR_VOLTAGE,362 .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,363 .linear_ranges = pca9450_buck_volts,364 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),365 .vsel_reg = PCA9450_REG_BUCK6OUT,366 .vsel_mask = BUCK6OUT_MASK,367 .enable_reg = PCA9450_REG_BUCK6CTRL,368 .enable_mask = BUCK6_ENMODE_MASK,369 .owner = THIS_MODULE,370 },371 },372 {373 .desc = {374 .name = "ldo1",375 .of_match = of_match_ptr("LDO1"),376 .regulators_node = of_match_ptr("regulators"),377 .id = PCA9450_LDO1,378 .ops = &pca9450_ldo_regulator_ops,379 .type = REGULATOR_VOLTAGE,380 .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,381 .linear_ranges = pca9450_ldo1_volts,382 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),383 .vsel_reg = PCA9450_REG_LDO1CTRL,384 .vsel_mask = LDO1OUT_MASK,385 .enable_reg = PCA9450_REG_LDO1CTRL,386 .enable_mask = LDO1_EN_MASK,387 .owner = THIS_MODULE,388 },389 },390 {391 .desc = {392 .name = "ldo2",393 .of_match = of_match_ptr("LDO2"),394 .regulators_node = of_match_ptr("regulators"),395 .id = PCA9450_LDO2,396 .ops = &pca9450_ldo_regulator_ops,397 .type = REGULATOR_VOLTAGE,398 .n_voltages = PCA9450_LDO2_VOLTAGE_NUM,399 .linear_ranges = pca9450_ldo2_volts,400 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),401 .vsel_reg = PCA9450_REG_LDO2CTRL,402 .vsel_mask = LDO2OUT_MASK,403 .enable_reg = PCA9450_REG_LDO2CTRL,404 .enable_mask = LDO2_EN_MASK,405 .owner = THIS_MODULE,406 },407 },408 {409 .desc = {410 .name = "ldo3",411 .of_match = of_match_ptr("LDO3"),412 .regulators_node = of_match_ptr("regulators"),413 .id = PCA9450_LDO3,414 .ops = &pca9450_ldo_regulator_ops,415 .type = REGULATOR_VOLTAGE,416 .n_voltages = PCA9450_LDO3_VOLTAGE_NUM,417 .linear_ranges = pca9450_ldo34_volts,418 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),419 .vsel_reg = PCA9450_REG_LDO3CTRL,420 .vsel_mask = LDO3OUT_MASK,421 .enable_reg = PCA9450_REG_LDO3CTRL,422 .enable_mask = LDO3_EN_MASK,423 .owner = THIS_MODULE,424 },425 },426 {427 .desc = {428 .name = "ldo4",429 .of_match = of_match_ptr("LDO4"),430 .regulators_node = of_match_ptr("regulators"),431 .id = PCA9450_LDO4,432 .ops = &pca9450_ldo_regulator_ops,433 .type = REGULATOR_VOLTAGE,434 .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,435 .linear_ranges = pca9450_ldo34_volts,436 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),437 .vsel_reg = PCA9450_REG_LDO4CTRL,438 .vsel_mask = LDO4OUT_MASK,439 .enable_reg = PCA9450_REG_LDO4CTRL,440 .enable_mask = LDO4_EN_MASK,441 .owner = THIS_MODULE,442 },443 },444 {445 .desc = {446 .name = "ldo5",447 .of_match = of_match_ptr("LDO5"),448 .regulators_node = of_match_ptr("regulators"),449 .id = PCA9450_LDO5,450 .ops = &pca9450_ldo_regulator_ops,451 .type = REGULATOR_VOLTAGE,452 .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,453 .linear_ranges = pca9450_ldo5_volts,454 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),455 .vsel_reg = PCA9450_REG_LDO5CTRL_H,456 .vsel_mask = LDO5HOUT_MASK,457 .enable_reg = PCA9450_REG_LDO5CTRL_H,458 .enable_mask = LDO5H_EN_MASK,459 .owner = THIS_MODULE,460 },461 },462};463 464/*465 * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase466 * on PCA9450C as no Buck3.467 */468static const struct pca9450_regulator_desc pca9450bc_regulators[] = {469 {470 .desc = {471 .name = "buck1",472 .of_match = of_match_ptr("BUCK1"),473 .regulators_node = of_match_ptr("regulators"),474 .id = PCA9450_BUCK1,475 .ops = &pca9450_dvs_buck_regulator_ops,476 .type = REGULATOR_VOLTAGE,477 .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,478 .linear_ranges = pca9450_dvs_buck_volts,479 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),480 .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,481 .vsel_mask = BUCK1OUT_DVS0_MASK,482 .enable_reg = PCA9450_REG_BUCK1CTRL,483 .enable_mask = BUCK1_ENMODE_MASK,484 .ramp_reg = PCA9450_REG_BUCK1CTRL,485 .ramp_mask = BUCK1_RAMP_MASK,486 .ramp_delay_table = pca9450_dvs_buck_ramp_table,487 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),488 .owner = THIS_MODULE,489 .of_parse_cb = pca9450_set_dvs_levels,490 },491 .dvs = {492 .run_reg = PCA9450_REG_BUCK1OUT_DVS0,493 .run_mask = BUCK1OUT_DVS0_MASK,494 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,495 .standby_mask = BUCK1OUT_DVS1_MASK,496 },497 },498 {499 .desc = {500 .name = "buck2",501 .of_match = of_match_ptr("BUCK2"),502 .regulators_node = of_match_ptr("regulators"),503 .id = PCA9450_BUCK2,504 .ops = &pca9450_dvs_buck_regulator_ops,505 .type = REGULATOR_VOLTAGE,506 .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,507 .linear_ranges = pca9450_dvs_buck_volts,508 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),509 .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,510 .vsel_mask = BUCK2OUT_DVS0_MASK,511 .enable_reg = PCA9450_REG_BUCK2CTRL,512 .enable_mask = BUCK2_ENMODE_MASK,513 .ramp_reg = PCA9450_REG_BUCK2CTRL,514 .ramp_mask = BUCK2_RAMP_MASK,515 .ramp_delay_table = pca9450_dvs_buck_ramp_table,516 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),517 .owner = THIS_MODULE,518 .of_parse_cb = pca9450_set_dvs_levels,519 },520 .dvs = {521 .run_reg = PCA9450_REG_BUCK2OUT_DVS0,522 .run_mask = BUCK2OUT_DVS0_MASK,523 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,524 .standby_mask = BUCK2OUT_DVS1_MASK,525 },526 },527 {528 .desc = {529 .name = "buck4",530 .of_match = of_match_ptr("BUCK4"),531 .regulators_node = of_match_ptr("regulators"),532 .id = PCA9450_BUCK4,533 .ops = &pca9450_buck_regulator_ops,534 .type = REGULATOR_VOLTAGE,535 .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,536 .linear_ranges = pca9450_buck_volts,537 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),538 .vsel_reg = PCA9450_REG_BUCK4OUT,539 .vsel_mask = BUCK4OUT_MASK,540 .enable_reg = PCA9450_REG_BUCK4CTRL,541 .enable_mask = BUCK4_ENMODE_MASK,542 .owner = THIS_MODULE,543 },544 },545 {546 .desc = {547 .name = "buck5",548 .of_match = of_match_ptr("BUCK5"),549 .regulators_node = of_match_ptr("regulators"),550 .id = PCA9450_BUCK5,551 .ops = &pca9450_buck_regulator_ops,552 .type = REGULATOR_VOLTAGE,553 .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,554 .linear_ranges = pca9450_buck_volts,555 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),556 .vsel_reg = PCA9450_REG_BUCK5OUT,557 .vsel_mask = BUCK5OUT_MASK,558 .enable_reg = PCA9450_REG_BUCK5CTRL,559 .enable_mask = BUCK5_ENMODE_MASK,560 .owner = THIS_MODULE,561 },562 },563 {564 .desc = {565 .name = "buck6",566 .of_match = of_match_ptr("BUCK6"),567 .regulators_node = of_match_ptr("regulators"),568 .id = PCA9450_BUCK6,569 .ops = &pca9450_buck_regulator_ops,570 .type = REGULATOR_VOLTAGE,571 .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,572 .linear_ranges = pca9450_buck_volts,573 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),574 .vsel_reg = PCA9450_REG_BUCK6OUT,575 .vsel_mask = BUCK6OUT_MASK,576 .enable_reg = PCA9450_REG_BUCK6CTRL,577 .enable_mask = BUCK6_ENMODE_MASK,578 .owner = THIS_MODULE,579 },580 },581 {582 .desc = {583 .name = "ldo1",584 .of_match = of_match_ptr("LDO1"),585 .regulators_node = of_match_ptr("regulators"),586 .id = PCA9450_LDO1,587 .ops = &pca9450_ldo_regulator_ops,588 .type = REGULATOR_VOLTAGE,589 .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,590 .linear_ranges = pca9450_ldo1_volts,591 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),592 .vsel_reg = PCA9450_REG_LDO1CTRL,593 .vsel_mask = LDO1OUT_MASK,594 .enable_reg = PCA9450_REG_LDO1CTRL,595 .enable_mask = LDO1_EN_MASK,596 .owner = THIS_MODULE,597 },598 },599 {600 .desc = {601 .name = "ldo2",602 .of_match = of_match_ptr("LDO2"),603 .regulators_node = of_match_ptr("regulators"),604 .id = PCA9450_LDO2,605 .ops = &pca9450_ldo_regulator_ops,606 .type = REGULATOR_VOLTAGE,607 .n_voltages = PCA9450_LDO2_VOLTAGE_NUM,608 .linear_ranges = pca9450_ldo2_volts,609 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),610 .vsel_reg = PCA9450_REG_LDO2CTRL,611 .vsel_mask = LDO2OUT_MASK,612 .enable_reg = PCA9450_REG_LDO2CTRL,613 .enable_mask = LDO2_EN_MASK,614 .owner = THIS_MODULE,615 },616 },617 {618 .desc = {619 .name = "ldo3",620 .of_match = of_match_ptr("LDO3"),621 .regulators_node = of_match_ptr("regulators"),622 .id = PCA9450_LDO3,623 .ops = &pca9450_ldo_regulator_ops,624 .type = REGULATOR_VOLTAGE,625 .n_voltages = PCA9450_LDO3_VOLTAGE_NUM,626 .linear_ranges = pca9450_ldo34_volts,627 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),628 .vsel_reg = PCA9450_REG_LDO3CTRL,629 .vsel_mask = LDO3OUT_MASK,630 .enable_reg = PCA9450_REG_LDO3CTRL,631 .enable_mask = LDO3_EN_MASK,632 .owner = THIS_MODULE,633 },634 },635 {636 .desc = {637 .name = "ldo4",638 .of_match = of_match_ptr("LDO4"),639 .regulators_node = of_match_ptr("regulators"),640 .id = PCA9450_LDO4,641 .ops = &pca9450_ldo_regulator_ops,642 .type = REGULATOR_VOLTAGE,643 .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,644 .linear_ranges = pca9450_ldo34_volts,645 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),646 .vsel_reg = PCA9450_REG_LDO4CTRL,647 .vsel_mask = LDO4OUT_MASK,648 .enable_reg = PCA9450_REG_LDO4CTRL,649 .enable_mask = LDO4_EN_MASK,650 .owner = THIS_MODULE,651 },652 },653 {654 .desc = {655 .name = "ldo5",656 .of_match = of_match_ptr("LDO5"),657 .regulators_node = of_match_ptr("regulators"),658 .id = PCA9450_LDO5,659 .ops = &pca9450_ldo_regulator_ops,660 .type = REGULATOR_VOLTAGE,661 .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,662 .linear_ranges = pca9450_ldo5_volts,663 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),664 .vsel_reg = PCA9450_REG_LDO5CTRL_H,665 .vsel_mask = LDO5HOUT_MASK,666 .enable_reg = PCA9450_REG_LDO5CTRL_H,667 .enable_mask = LDO5H_EN_MASK,668 .owner = THIS_MODULE,669 },670 },671};672 673static const struct pca9450_regulator_desc pca9451a_regulators[] = {674 {675 .desc = {676 .name = "buck1",677 .of_match = of_match_ptr("BUCK1"),678 .regulators_node = of_match_ptr("regulators"),679 .id = PCA9450_BUCK1,680 .ops = &pca9450_dvs_buck_regulator_ops,681 .type = REGULATOR_VOLTAGE,682 .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,683 .linear_ranges = pca9451a_dvs_buck_volts,684 .n_linear_ranges = ARRAY_SIZE(pca9451a_dvs_buck_volts),685 .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,686 .vsel_mask = BUCK1OUT_DVS0_MASK,687 .enable_reg = PCA9450_REG_BUCK1CTRL,688 .enable_mask = BUCK1_ENMODE_MASK,689 .enable_val = BUCK_ENMODE_ONREQ,690 .ramp_mask = BUCK1_RAMP_MASK,691 .ramp_delay_table = pca9450_dvs_buck_ramp_table,692 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),693 .owner = THIS_MODULE,694 .of_parse_cb = pca9450_set_dvs_levels,695 },696 .dvs = {697 .run_reg = PCA9450_REG_BUCK1OUT_DVS0,698 .run_mask = BUCK1OUT_DVS0_MASK,699 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,700 .standby_mask = BUCK1OUT_DVS1_MASK,701 },702 },703 {704 .desc = {705 .name = "buck2",706 .of_match = of_match_ptr("BUCK2"),707 .regulators_node = of_match_ptr("regulators"),708 .id = PCA9450_BUCK2,709 .ops = &pca9450_dvs_buck_regulator_ops,710 .type = REGULATOR_VOLTAGE,711 .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,712 .linear_ranges = pca9450_dvs_buck_volts,713 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),714 .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,715 .vsel_mask = BUCK2OUT_DVS0_MASK,716 .enable_reg = PCA9450_REG_BUCK2CTRL,717 .enable_mask = BUCK2_ENMODE_MASK,718 .enable_val = BUCK_ENMODE_ONREQ_STBYREQ,719 .ramp_mask = BUCK2_RAMP_MASK,720 .ramp_delay_table = pca9450_dvs_buck_ramp_table,721 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),722 .owner = THIS_MODULE,723 .of_parse_cb = pca9450_set_dvs_levels,724 },725 .dvs = {726 .run_reg = PCA9450_REG_BUCK2OUT_DVS0,727 .run_mask = BUCK2OUT_DVS0_MASK,728 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,729 .standby_mask = BUCK2OUT_DVS1_MASK,730 },731 },732 {733 .desc = {734 .name = "buck4",735 .of_match = of_match_ptr("BUCK4"),736 .regulators_node = of_match_ptr("regulators"),737 .id = PCA9450_BUCK4,738 .ops = &pca9450_buck_regulator_ops,739 .type = REGULATOR_VOLTAGE,740 .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,741 .linear_ranges = pca9450_buck_volts,742 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),743 .vsel_reg = PCA9450_REG_BUCK4OUT,744 .vsel_mask = BUCK4OUT_MASK,745 .enable_reg = PCA9450_REG_BUCK4CTRL,746 .enable_mask = BUCK4_ENMODE_MASK,747 .enable_val = BUCK_ENMODE_ONREQ,748 .owner = THIS_MODULE,749 },750 },751 {752 .desc = {753 .name = "buck5",754 .of_match = of_match_ptr("BUCK5"),755 .regulators_node = of_match_ptr("regulators"),756 .id = PCA9450_BUCK5,757 .ops = &pca9450_buck_regulator_ops,758 .type = REGULATOR_VOLTAGE,759 .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,760 .linear_ranges = pca9450_buck_volts,761 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),762 .vsel_reg = PCA9450_REG_BUCK5OUT,763 .vsel_mask = BUCK5OUT_MASK,764 .enable_reg = PCA9450_REG_BUCK5CTRL,765 .enable_mask = BUCK5_ENMODE_MASK,766 .enable_val = BUCK_ENMODE_ONREQ,767 .owner = THIS_MODULE,768 },769 },770 {771 .desc = {772 .name = "buck6",773 .of_match = of_match_ptr("BUCK6"),774 .regulators_node = of_match_ptr("regulators"),775 .id = PCA9450_BUCK6,776 .ops = &pca9450_buck_regulator_ops,777 .type = REGULATOR_VOLTAGE,778 .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,779 .linear_ranges = pca9450_buck_volts,780 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),781 .vsel_reg = PCA9450_REG_BUCK6OUT,782 .vsel_mask = BUCK6OUT_MASK,783 .enable_reg = PCA9450_REG_BUCK6CTRL,784 .enable_mask = BUCK6_ENMODE_MASK,785 .enable_val = BUCK_ENMODE_ONREQ,786 .owner = THIS_MODULE,787 },788 },789 {790 .desc = {791 .name = "ldo1",792 .of_match = of_match_ptr("LDO1"),793 .regulators_node = of_match_ptr("regulators"),794 .id = PCA9450_LDO1,795 .ops = &pca9450_ldo_regulator_ops,796 .type = REGULATOR_VOLTAGE,797 .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,798 .linear_ranges = pca9450_ldo1_volts,799 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),800 .vsel_reg = PCA9450_REG_LDO1CTRL,801 .vsel_mask = LDO1OUT_MASK,802 .enable_reg = PCA9450_REG_LDO1CTRL,803 .enable_mask = LDO1_EN_MASK,804 .owner = THIS_MODULE,805 },806 },807 {808 .desc = {809 .name = "ldo4",810 .of_match = of_match_ptr("LDO4"),811 .regulators_node = of_match_ptr("regulators"),812 .id = PCA9450_LDO4,813 .ops = &pca9450_ldo_regulator_ops,814 .type = REGULATOR_VOLTAGE,815 .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,816 .linear_ranges = pca9450_ldo34_volts,817 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),818 .vsel_reg = PCA9450_REG_LDO4CTRL,819 .vsel_mask = LDO4OUT_MASK,820 .enable_reg = PCA9450_REG_LDO4CTRL,821 .enable_mask = LDO4_EN_MASK,822 .owner = THIS_MODULE,823 },824 },825 {826 .desc = {827 .name = "ldo5",828 .of_match = of_match_ptr("LDO5"),829 .regulators_node = of_match_ptr("regulators"),830 .id = PCA9450_LDO5,831 .ops = &pca9450_ldo_regulator_ops,832 .type = REGULATOR_VOLTAGE,833 .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,834 .linear_ranges = pca9450_ldo5_volts,835 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),836 .vsel_reg = PCA9450_REG_LDO5CTRL_H,837 .vsel_mask = LDO5HOUT_MASK,838 .enable_reg = PCA9450_REG_LDO5CTRL_H,839 .enable_mask = LDO5H_EN_MASK,840 .owner = THIS_MODULE,841 },842 },843};844 845static irqreturn_t pca9450_irq_handler(int irq, void *data)846{847 struct pca9450 *pca9450 = data;848 struct regmap *regmap = pca9450->regmap;849 unsigned int status;850 int ret;851 852 ret = regmap_read(regmap, PCA9450_REG_INT1, &status);853 if (ret < 0) {854 dev_err(pca9450->dev,855 "Failed to read INT1(%d)\n", ret);856 return IRQ_NONE;857 }858 859 if (status & IRQ_PWRON)860 dev_warn(pca9450->dev, "PWRON interrupt.\n");861 862 if (status & IRQ_WDOGB)863 dev_warn(pca9450->dev, "WDOGB interrupt.\n");864 865 if (status & IRQ_VR_FLT1)866 dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");867 868 if (status & IRQ_VR_FLT2)869 dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");870 871 if (status & IRQ_LOWVSYS)872 dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");873 874 if (status & IRQ_THERM_105)875 dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");876 877 if (status & IRQ_THERM_125)878 dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");879 880 return IRQ_HANDLED;881}882 883static int pca9450_i2c_probe(struct i2c_client *i2c)884{885 enum pca9450_chip_type type = (unsigned int)(uintptr_t)886 of_device_get_match_data(&i2c->dev);887 const struct pca9450_regulator_desc *regulator_desc;888 struct regulator_config config = { };889 struct pca9450 *pca9450;890 unsigned int device_id, i;891 unsigned int reset_ctrl;892 int ret;893 894 pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);895 if (!pca9450)896 return -ENOMEM;897 898 switch (type) {899 case PCA9450_TYPE_PCA9450A:900 regulator_desc = pca9450a_regulators;901 pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);902 break;903 case PCA9450_TYPE_PCA9450BC:904 regulator_desc = pca9450bc_regulators;905 pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);906 break;907 case PCA9450_TYPE_PCA9451A:908 regulator_desc = pca9451a_regulators;909 pca9450->rcnt = ARRAY_SIZE(pca9451a_regulators);910 break;911 default:912 dev_err(&i2c->dev, "Unknown device type");913 return -EINVAL;914 }915 916 pca9450->irq = i2c->irq;917 pca9450->type = type;918 pca9450->dev = &i2c->dev;919 920 dev_set_drvdata(&i2c->dev, pca9450);921 922 pca9450->regmap = devm_regmap_init_i2c(i2c,923 &pca9450_regmap_config);924 if (IS_ERR(pca9450->regmap)) {925 dev_err(&i2c->dev, "regmap initialization failed\n");926 return PTR_ERR(pca9450->regmap);927 }928 929 ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);930 if (ret) {931 dev_err(&i2c->dev, "Read device id error\n");932 return ret;933 }934 935 /* Check your board and dts for match the right pmic */936 if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||937 ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC) ||938 ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A)) {939 dev_err(&i2c->dev, "Device id(%x) mismatched\n",940 device_id >> 4);941 return -EINVAL;942 }943 944 for (i = 0; i < pca9450->rcnt; i++) {945 const struct regulator_desc *desc;946 struct regulator_dev *rdev;947 const struct pca9450_regulator_desc *r;948 949 r = ®ulator_desc[i];950 desc = &r->desc;951 952 config.regmap = pca9450->regmap;953 config.dev = pca9450->dev;954 955 rdev = devm_regulator_register(pca9450->dev, desc, &config);956 if (IS_ERR(rdev)) {957 ret = PTR_ERR(rdev);958 dev_err(pca9450->dev,959 "Failed to register regulator(%s): %d\n",960 desc->name, ret);961 return ret;962 }963 }964 965 if (pca9450->irq) {966 ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,967 pca9450_irq_handler,968 (IRQF_TRIGGER_FALLING | IRQF_ONESHOT),969 "pca9450-irq", pca9450);970 if (ret != 0) {971 dev_err(pca9450->dev, "Failed to request IRQ: %d\n",972 pca9450->irq);973 return ret;974 }975 /* Unmask all interrupt except PWRON/WDOG/RSVD */976 ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,977 IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |978 IRQ_THERM_105 | IRQ_THERM_125,979 IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);980 if (ret) {981 dev_err(&i2c->dev, "Unmask irq error\n");982 return ret;983 }984 }985 986 /* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */987 ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,988 BUCK123_PRESET_EN);989 if (ret) {990 dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);991 return ret;992 }993 994 if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))995 reset_ctrl = WDOG_B_CFG_WARM;996 else997 reset_ctrl = WDOG_B_CFG_COLD_LDO12;998 999 /* Set reset behavior on assertion of WDOG_B signal */1000 ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,1001 WDOG_B_CFG_MASK, reset_ctrl);1002 if (ret) {1003 dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");1004 return ret;1005 }1006 1007 if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {1008 /* Enable I2C Level Translator */1009 ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,1010 I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);1011 if (ret) {1012 dev_err(&i2c->dev,1013 "Failed to enable I2C level translator\n");1014 return ret;1015 }1016 }1017 1018 /*1019 * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.1020 * This is only valid if the SD_VSEL input of the PMIC is high. Let's1021 * check if the pin is available as GPIO and set it to high.1022 */1023 pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);1024 1025 if (IS_ERR(pca9450->sd_vsel_gpio)) {1026 dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");1027 return PTR_ERR(pca9450->sd_vsel_gpio);1028 }1029 1030 dev_info(&i2c->dev, "%s probed.\n",1031 type == PCA9450_TYPE_PCA9450A ? "pca9450a" :1032 (type == PCA9450_TYPE_PCA9451A ? "pca9451a" : "pca9450bc"));1033 1034 return 0;1035}1036 1037static const struct of_device_id pca9450_of_match[] = {1038 {1039 .compatible = "nxp,pca9450a",1040 .data = (void *)PCA9450_TYPE_PCA9450A,1041 },1042 {1043 .compatible = "nxp,pca9450b",1044 .data = (void *)PCA9450_TYPE_PCA9450BC,1045 },1046 {1047 .compatible = "nxp,pca9450c",1048 .data = (void *)PCA9450_TYPE_PCA9450BC,1049 },1050 {1051 .compatible = "nxp,pca9451a",1052 .data = (void *)PCA9450_TYPE_PCA9451A,1053 },1054 { }1055};1056MODULE_DEVICE_TABLE(of, pca9450_of_match);1057 1058static struct i2c_driver pca9450_i2c_driver = {1059 .driver = {1060 .name = "nxp-pca9450",1061 .probe_type = PROBE_PREFER_ASYNCHRONOUS,1062 .of_match_table = pca9450_of_match,1063 },1064 .probe = pca9450_i2c_probe,1065};1066 1067module_i2c_driver(pca9450_i2c_driver);1068 1069MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");1070MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");1071MODULE_LICENSE("GPL");1072