0001
0002
0003
0004
0005
0006
0007 #include <linux/err.h>
0008 #include <linux/gpio/consumer.h>
0009 #include <linux/i2c.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/of_device.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/regulator/driver.h>
0017 #include <linux/regulator/machine.h>
0018 #include <linux/regulator/of_regulator.h>
0019 #include <linux/regulator/pca9450.h>
0020
0021 struct pc9450_dvs_config {
0022 unsigned int run_reg;
0023 unsigned int run_mask;
0024 unsigned int standby_reg;
0025 unsigned int standby_mask;
0026 };
0027
0028 struct pca9450_regulator_desc {
0029 struct regulator_desc desc;
0030 const struct pc9450_dvs_config dvs;
0031 };
0032
0033 struct pca9450 {
0034 struct device *dev;
0035 struct regmap *regmap;
0036 struct gpio_desc *sd_vsel_gpio;
0037 enum pca9450_chip_type type;
0038 unsigned int rcnt;
0039 int irq;
0040 };
0041
0042 static const struct regmap_range pca9450_status_range = {
0043 .range_min = PCA9450_REG_INT1,
0044 .range_max = PCA9450_REG_PWRON_STAT,
0045 };
0046
0047 static const struct regmap_access_table pca9450_volatile_regs = {
0048 .yes_ranges = &pca9450_status_range,
0049 .n_yes_ranges = 1,
0050 };
0051
0052 static const struct regmap_config pca9450_regmap_config = {
0053 .reg_bits = 8,
0054 .val_bits = 8,
0055 .volatile_table = &pca9450_volatile_regs,
0056 .max_register = PCA9450_MAX_REGISTER - 1,
0057 .cache_type = REGCACHE_RBTREE,
0058 };
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 static const unsigned int pca9450_dvs_buck_ramp_table[] = {
0069 25000, 12500, 6250, 3125
0070 };
0071
0072 static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
0073 .enable = regulator_enable_regmap,
0074 .disable = regulator_disable_regmap,
0075 .is_enabled = regulator_is_enabled_regmap,
0076 .list_voltage = regulator_list_voltage_linear_range,
0077 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0078 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0079 .set_voltage_time_sel = regulator_set_voltage_time_sel,
0080 .set_ramp_delay = regulator_set_ramp_delay_regmap,
0081 };
0082
0083 static const struct regulator_ops pca9450_buck_regulator_ops = {
0084 .enable = regulator_enable_regmap,
0085 .disable = regulator_disable_regmap,
0086 .is_enabled = regulator_is_enabled_regmap,
0087 .list_voltage = regulator_list_voltage_linear_range,
0088 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0089 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0090 .set_voltage_time_sel = regulator_set_voltage_time_sel,
0091 };
0092
0093 static const struct regulator_ops pca9450_ldo_regulator_ops = {
0094 .enable = regulator_enable_regmap,
0095 .disable = regulator_disable_regmap,
0096 .is_enabled = regulator_is_enabled_regmap,
0097 .list_voltage = regulator_list_voltage_linear_range,
0098 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0099 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0100 };
0101
0102
0103
0104
0105
0106 static const struct linear_range pca9450_dvs_buck_volts[] = {
0107 REGULATOR_LINEAR_RANGE(600000, 0x00, 0x7F, 12500),
0108 };
0109
0110
0111
0112
0113
0114 static const struct linear_range pca9450_buck_volts[] = {
0115 REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
0116 REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
0117 };
0118
0119
0120
0121
0122
0123 static const struct linear_range pca9450_ldo1_volts[] = {
0124 REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
0125 REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
0126 };
0127
0128
0129
0130
0131
0132 static const struct linear_range pca9450_ldo2_volts[] = {
0133 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
0134 };
0135
0136
0137
0138
0139
0140 static const struct linear_range pca9450_ldo34_volts[] = {
0141 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
0142 REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
0143 };
0144
0145
0146
0147
0148
0149 static const struct linear_range pca9450_ldo5_volts[] = {
0150 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
0151 };
0152
0153 static int buck_set_dvs(const struct regulator_desc *desc,
0154 struct device_node *np, struct regmap *regmap,
0155 char *prop, unsigned int reg, unsigned int mask)
0156 {
0157 int ret, i;
0158 uint32_t uv;
0159
0160 ret = of_property_read_u32(np, prop, &uv);
0161 if (ret == -EINVAL)
0162 return 0;
0163 else if (ret)
0164 return ret;
0165
0166 for (i = 0; i < desc->n_voltages; i++) {
0167 ret = regulator_desc_list_voltage_linear_range(desc, i);
0168 if (ret < 0)
0169 continue;
0170 if (ret == uv) {
0171 i <<= ffs(desc->vsel_mask) - 1;
0172 ret = regmap_update_bits(regmap, reg, mask, i);
0173 break;
0174 }
0175 }
0176
0177 if (ret == 0) {
0178 struct pca9450_regulator_desc *regulator = container_of(desc,
0179 struct pca9450_regulator_desc, desc);
0180
0181
0182 ret = regmap_update_bits(regmap, regulator->desc.enable_reg,
0183 BUCK1_DVS_CTRL, BUCK1_DVS_CTRL);
0184 }
0185 return ret;
0186 }
0187
0188 static int pca9450_set_dvs_levels(struct device_node *np,
0189 const struct regulator_desc *desc,
0190 struct regulator_config *cfg)
0191 {
0192 struct pca9450_regulator_desc *data = container_of(desc,
0193 struct pca9450_regulator_desc, desc);
0194 const struct pc9450_dvs_config *dvs = &data->dvs;
0195 unsigned int reg, mask;
0196 char *prop;
0197 int i, ret = 0;
0198
0199 for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
0200 switch (i) {
0201 case PCA9450_DVS_LEVEL_RUN:
0202 prop = "nxp,dvs-run-voltage";
0203 reg = dvs->run_reg;
0204 mask = dvs->run_mask;
0205 break;
0206 case PCA9450_DVS_LEVEL_STANDBY:
0207 prop = "nxp,dvs-standby-voltage";
0208 reg = dvs->standby_reg;
0209 mask = dvs->standby_mask;
0210 break;
0211 default:
0212 return -EINVAL;
0213 }
0214
0215 ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
0216 if (ret)
0217 break;
0218 }
0219
0220 return ret;
0221 }
0222
0223 static const struct pca9450_regulator_desc pca9450a_regulators[] = {
0224 {
0225 .desc = {
0226 .name = "buck1",
0227 .of_match = of_match_ptr("BUCK1"),
0228 .regulators_node = of_match_ptr("regulators"),
0229 .id = PCA9450_BUCK1,
0230 .ops = &pca9450_dvs_buck_regulator_ops,
0231 .type = REGULATOR_VOLTAGE,
0232 .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
0233 .linear_ranges = pca9450_dvs_buck_volts,
0234 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
0235 .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
0236 .vsel_mask = BUCK1OUT_DVS0_MASK,
0237 .enable_reg = PCA9450_REG_BUCK1CTRL,
0238 .enable_mask = BUCK1_ENMODE_MASK,
0239 .ramp_reg = PCA9450_REG_BUCK1CTRL,
0240 .ramp_mask = BUCK1_RAMP_MASK,
0241 .ramp_delay_table = pca9450_dvs_buck_ramp_table,
0242 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
0243 .owner = THIS_MODULE,
0244 .of_parse_cb = pca9450_set_dvs_levels,
0245 },
0246 .dvs = {
0247 .run_reg = PCA9450_REG_BUCK1OUT_DVS0,
0248 .run_mask = BUCK1OUT_DVS0_MASK,
0249 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
0250 .standby_mask = BUCK1OUT_DVS1_MASK,
0251 },
0252 },
0253 {
0254 .desc = {
0255 .name = "buck2",
0256 .of_match = of_match_ptr("BUCK2"),
0257 .regulators_node = of_match_ptr("regulators"),
0258 .id = PCA9450_BUCK2,
0259 .ops = &pca9450_dvs_buck_regulator_ops,
0260 .type = REGULATOR_VOLTAGE,
0261 .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
0262 .linear_ranges = pca9450_dvs_buck_volts,
0263 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
0264 .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
0265 .vsel_mask = BUCK2OUT_DVS0_MASK,
0266 .enable_reg = PCA9450_REG_BUCK2CTRL,
0267 .enable_mask = BUCK1_ENMODE_MASK,
0268 .ramp_reg = PCA9450_REG_BUCK2CTRL,
0269 .ramp_mask = BUCK2_RAMP_MASK,
0270 .ramp_delay_table = pca9450_dvs_buck_ramp_table,
0271 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
0272 .owner = THIS_MODULE,
0273 .of_parse_cb = pca9450_set_dvs_levels,
0274 },
0275 .dvs = {
0276 .run_reg = PCA9450_REG_BUCK2OUT_DVS0,
0277 .run_mask = BUCK2OUT_DVS0_MASK,
0278 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
0279 .standby_mask = BUCK2OUT_DVS1_MASK,
0280 },
0281 },
0282 {
0283 .desc = {
0284 .name = "buck3",
0285 .of_match = of_match_ptr("BUCK3"),
0286 .regulators_node = of_match_ptr("regulators"),
0287 .id = PCA9450_BUCK3,
0288 .ops = &pca9450_dvs_buck_regulator_ops,
0289 .type = REGULATOR_VOLTAGE,
0290 .n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
0291 .linear_ranges = pca9450_dvs_buck_volts,
0292 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
0293 .vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
0294 .vsel_mask = BUCK3OUT_DVS0_MASK,
0295 .enable_reg = PCA9450_REG_BUCK3CTRL,
0296 .enable_mask = BUCK3_ENMODE_MASK,
0297 .ramp_reg = PCA9450_REG_BUCK3CTRL,
0298 .ramp_mask = BUCK3_RAMP_MASK,
0299 .ramp_delay_table = pca9450_dvs_buck_ramp_table,
0300 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
0301 .owner = THIS_MODULE,
0302 .of_parse_cb = pca9450_set_dvs_levels,
0303 },
0304 .dvs = {
0305 .run_reg = PCA9450_REG_BUCK3OUT_DVS0,
0306 .run_mask = BUCK3OUT_DVS0_MASK,
0307 .standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
0308 .standby_mask = BUCK3OUT_DVS1_MASK,
0309 },
0310 },
0311 {
0312 .desc = {
0313 .name = "buck4",
0314 .of_match = of_match_ptr("BUCK4"),
0315 .regulators_node = of_match_ptr("regulators"),
0316 .id = PCA9450_BUCK4,
0317 .ops = &pca9450_buck_regulator_ops,
0318 .type = REGULATOR_VOLTAGE,
0319 .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
0320 .linear_ranges = pca9450_buck_volts,
0321 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
0322 .vsel_reg = PCA9450_REG_BUCK4OUT,
0323 .vsel_mask = BUCK4OUT_MASK,
0324 .enable_reg = PCA9450_REG_BUCK4CTRL,
0325 .enable_mask = BUCK4_ENMODE_MASK,
0326 .owner = THIS_MODULE,
0327 },
0328 },
0329 {
0330 .desc = {
0331 .name = "buck5",
0332 .of_match = of_match_ptr("BUCK5"),
0333 .regulators_node = of_match_ptr("regulators"),
0334 .id = PCA9450_BUCK5,
0335 .ops = &pca9450_buck_regulator_ops,
0336 .type = REGULATOR_VOLTAGE,
0337 .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
0338 .linear_ranges = pca9450_buck_volts,
0339 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
0340 .vsel_reg = PCA9450_REG_BUCK5OUT,
0341 .vsel_mask = BUCK5OUT_MASK,
0342 .enable_reg = PCA9450_REG_BUCK5CTRL,
0343 .enable_mask = BUCK5_ENMODE_MASK,
0344 .owner = THIS_MODULE,
0345 },
0346 },
0347 {
0348 .desc = {
0349 .name = "buck6",
0350 .of_match = of_match_ptr("BUCK6"),
0351 .regulators_node = of_match_ptr("regulators"),
0352 .id = PCA9450_BUCK6,
0353 .ops = &pca9450_buck_regulator_ops,
0354 .type = REGULATOR_VOLTAGE,
0355 .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
0356 .linear_ranges = pca9450_buck_volts,
0357 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
0358 .vsel_reg = PCA9450_REG_BUCK6OUT,
0359 .vsel_mask = BUCK6OUT_MASK,
0360 .enable_reg = PCA9450_REG_BUCK6CTRL,
0361 .enable_mask = BUCK6_ENMODE_MASK,
0362 .owner = THIS_MODULE,
0363 },
0364 },
0365 {
0366 .desc = {
0367 .name = "ldo1",
0368 .of_match = of_match_ptr("LDO1"),
0369 .regulators_node = of_match_ptr("regulators"),
0370 .id = PCA9450_LDO1,
0371 .ops = &pca9450_ldo_regulator_ops,
0372 .type = REGULATOR_VOLTAGE,
0373 .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
0374 .linear_ranges = pca9450_ldo1_volts,
0375 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
0376 .vsel_reg = PCA9450_REG_LDO1CTRL,
0377 .vsel_mask = LDO1OUT_MASK,
0378 .enable_reg = PCA9450_REG_LDO1CTRL,
0379 .enable_mask = LDO1_EN_MASK,
0380 .owner = THIS_MODULE,
0381 },
0382 },
0383 {
0384 .desc = {
0385 .name = "ldo2",
0386 .of_match = of_match_ptr("LDO2"),
0387 .regulators_node = of_match_ptr("regulators"),
0388 .id = PCA9450_LDO2,
0389 .ops = &pca9450_ldo_regulator_ops,
0390 .type = REGULATOR_VOLTAGE,
0391 .n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
0392 .linear_ranges = pca9450_ldo2_volts,
0393 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
0394 .vsel_reg = PCA9450_REG_LDO2CTRL,
0395 .vsel_mask = LDO2OUT_MASK,
0396 .enable_reg = PCA9450_REG_LDO2CTRL,
0397 .enable_mask = LDO2_EN_MASK,
0398 .owner = THIS_MODULE,
0399 },
0400 },
0401 {
0402 .desc = {
0403 .name = "ldo3",
0404 .of_match = of_match_ptr("LDO3"),
0405 .regulators_node = of_match_ptr("regulators"),
0406 .id = PCA9450_LDO3,
0407 .ops = &pca9450_ldo_regulator_ops,
0408 .type = REGULATOR_VOLTAGE,
0409 .n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
0410 .linear_ranges = pca9450_ldo34_volts,
0411 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
0412 .vsel_reg = PCA9450_REG_LDO3CTRL,
0413 .vsel_mask = LDO3OUT_MASK,
0414 .enable_reg = PCA9450_REG_LDO3CTRL,
0415 .enable_mask = LDO3_EN_MASK,
0416 .owner = THIS_MODULE,
0417 },
0418 },
0419 {
0420 .desc = {
0421 .name = "ldo4",
0422 .of_match = of_match_ptr("LDO4"),
0423 .regulators_node = of_match_ptr("regulators"),
0424 .id = PCA9450_LDO4,
0425 .ops = &pca9450_ldo_regulator_ops,
0426 .type = REGULATOR_VOLTAGE,
0427 .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
0428 .linear_ranges = pca9450_ldo34_volts,
0429 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
0430 .vsel_reg = PCA9450_REG_LDO4CTRL,
0431 .vsel_mask = LDO4OUT_MASK,
0432 .enable_reg = PCA9450_REG_LDO4CTRL,
0433 .enable_mask = LDO4_EN_MASK,
0434 .owner = THIS_MODULE,
0435 },
0436 },
0437 {
0438 .desc = {
0439 .name = "ldo5",
0440 .of_match = of_match_ptr("LDO5"),
0441 .regulators_node = of_match_ptr("regulators"),
0442 .id = PCA9450_LDO5,
0443 .ops = &pca9450_ldo_regulator_ops,
0444 .type = REGULATOR_VOLTAGE,
0445 .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
0446 .linear_ranges = pca9450_ldo5_volts,
0447 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
0448 .vsel_reg = PCA9450_REG_LDO5CTRL_H,
0449 .vsel_mask = LDO5HOUT_MASK,
0450 .enable_reg = PCA9450_REG_LDO5CTRL_H,
0451 .enable_mask = LDO5H_EN_MASK,
0452 .owner = THIS_MODULE,
0453 },
0454 },
0455 };
0456
0457
0458
0459
0460
0461 static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
0462 {
0463 .desc = {
0464 .name = "buck1",
0465 .of_match = of_match_ptr("BUCK1"),
0466 .regulators_node = of_match_ptr("regulators"),
0467 .id = PCA9450_BUCK1,
0468 .ops = &pca9450_dvs_buck_regulator_ops,
0469 .type = REGULATOR_VOLTAGE,
0470 .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
0471 .linear_ranges = pca9450_dvs_buck_volts,
0472 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
0473 .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
0474 .vsel_mask = BUCK1OUT_DVS0_MASK,
0475 .enable_reg = PCA9450_REG_BUCK1CTRL,
0476 .enable_mask = BUCK1_ENMODE_MASK,
0477 .ramp_reg = PCA9450_REG_BUCK1CTRL,
0478 .ramp_mask = BUCK1_RAMP_MASK,
0479 .ramp_delay_table = pca9450_dvs_buck_ramp_table,
0480 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
0481 .owner = THIS_MODULE,
0482 .of_parse_cb = pca9450_set_dvs_levels,
0483 },
0484 .dvs = {
0485 .run_reg = PCA9450_REG_BUCK1OUT_DVS0,
0486 .run_mask = BUCK1OUT_DVS0_MASK,
0487 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
0488 .standby_mask = BUCK1OUT_DVS1_MASK,
0489 },
0490 },
0491 {
0492 .desc = {
0493 .name = "buck2",
0494 .of_match = of_match_ptr("BUCK2"),
0495 .regulators_node = of_match_ptr("regulators"),
0496 .id = PCA9450_BUCK2,
0497 .ops = &pca9450_dvs_buck_regulator_ops,
0498 .type = REGULATOR_VOLTAGE,
0499 .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
0500 .linear_ranges = pca9450_dvs_buck_volts,
0501 .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
0502 .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
0503 .vsel_mask = BUCK2OUT_DVS0_MASK,
0504 .enable_reg = PCA9450_REG_BUCK2CTRL,
0505 .enable_mask = BUCK1_ENMODE_MASK,
0506 .ramp_reg = PCA9450_REG_BUCK2CTRL,
0507 .ramp_mask = BUCK2_RAMP_MASK,
0508 .ramp_delay_table = pca9450_dvs_buck_ramp_table,
0509 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
0510 .owner = THIS_MODULE,
0511 .of_parse_cb = pca9450_set_dvs_levels,
0512 },
0513 .dvs = {
0514 .run_reg = PCA9450_REG_BUCK2OUT_DVS0,
0515 .run_mask = BUCK2OUT_DVS0_MASK,
0516 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
0517 .standby_mask = BUCK2OUT_DVS1_MASK,
0518 },
0519 },
0520 {
0521 .desc = {
0522 .name = "buck4",
0523 .of_match = of_match_ptr("BUCK4"),
0524 .regulators_node = of_match_ptr("regulators"),
0525 .id = PCA9450_BUCK4,
0526 .ops = &pca9450_buck_regulator_ops,
0527 .type = REGULATOR_VOLTAGE,
0528 .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
0529 .linear_ranges = pca9450_buck_volts,
0530 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
0531 .vsel_reg = PCA9450_REG_BUCK4OUT,
0532 .vsel_mask = BUCK4OUT_MASK,
0533 .enable_reg = PCA9450_REG_BUCK4CTRL,
0534 .enable_mask = BUCK4_ENMODE_MASK,
0535 .owner = THIS_MODULE,
0536 },
0537 },
0538 {
0539 .desc = {
0540 .name = "buck5",
0541 .of_match = of_match_ptr("BUCK5"),
0542 .regulators_node = of_match_ptr("regulators"),
0543 .id = PCA9450_BUCK5,
0544 .ops = &pca9450_buck_regulator_ops,
0545 .type = REGULATOR_VOLTAGE,
0546 .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
0547 .linear_ranges = pca9450_buck_volts,
0548 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
0549 .vsel_reg = PCA9450_REG_BUCK5OUT,
0550 .vsel_mask = BUCK5OUT_MASK,
0551 .enable_reg = PCA9450_REG_BUCK5CTRL,
0552 .enable_mask = BUCK5_ENMODE_MASK,
0553 .owner = THIS_MODULE,
0554 },
0555 },
0556 {
0557 .desc = {
0558 .name = "buck6",
0559 .of_match = of_match_ptr("BUCK6"),
0560 .regulators_node = of_match_ptr("regulators"),
0561 .id = PCA9450_BUCK6,
0562 .ops = &pca9450_buck_regulator_ops,
0563 .type = REGULATOR_VOLTAGE,
0564 .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
0565 .linear_ranges = pca9450_buck_volts,
0566 .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
0567 .vsel_reg = PCA9450_REG_BUCK6OUT,
0568 .vsel_mask = BUCK6OUT_MASK,
0569 .enable_reg = PCA9450_REG_BUCK6CTRL,
0570 .enable_mask = BUCK6_ENMODE_MASK,
0571 .owner = THIS_MODULE,
0572 },
0573 },
0574 {
0575 .desc = {
0576 .name = "ldo1",
0577 .of_match = of_match_ptr("LDO1"),
0578 .regulators_node = of_match_ptr("regulators"),
0579 .id = PCA9450_LDO1,
0580 .ops = &pca9450_ldo_regulator_ops,
0581 .type = REGULATOR_VOLTAGE,
0582 .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
0583 .linear_ranges = pca9450_ldo1_volts,
0584 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
0585 .vsel_reg = PCA9450_REG_LDO1CTRL,
0586 .vsel_mask = LDO1OUT_MASK,
0587 .enable_reg = PCA9450_REG_LDO1CTRL,
0588 .enable_mask = LDO1_EN_MASK,
0589 .owner = THIS_MODULE,
0590 },
0591 },
0592 {
0593 .desc = {
0594 .name = "ldo2",
0595 .of_match = of_match_ptr("LDO2"),
0596 .regulators_node = of_match_ptr("regulators"),
0597 .id = PCA9450_LDO2,
0598 .ops = &pca9450_ldo_regulator_ops,
0599 .type = REGULATOR_VOLTAGE,
0600 .n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
0601 .linear_ranges = pca9450_ldo2_volts,
0602 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
0603 .vsel_reg = PCA9450_REG_LDO2CTRL,
0604 .vsel_mask = LDO2OUT_MASK,
0605 .enable_reg = PCA9450_REG_LDO2CTRL,
0606 .enable_mask = LDO2_EN_MASK,
0607 .owner = THIS_MODULE,
0608 },
0609 },
0610 {
0611 .desc = {
0612 .name = "ldo3",
0613 .of_match = of_match_ptr("LDO3"),
0614 .regulators_node = of_match_ptr("regulators"),
0615 .id = PCA9450_LDO3,
0616 .ops = &pca9450_ldo_regulator_ops,
0617 .type = REGULATOR_VOLTAGE,
0618 .n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
0619 .linear_ranges = pca9450_ldo34_volts,
0620 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
0621 .vsel_reg = PCA9450_REG_LDO3CTRL,
0622 .vsel_mask = LDO3OUT_MASK,
0623 .enable_reg = PCA9450_REG_LDO3CTRL,
0624 .enable_mask = LDO3_EN_MASK,
0625 .owner = THIS_MODULE,
0626 },
0627 },
0628 {
0629 .desc = {
0630 .name = "ldo4",
0631 .of_match = of_match_ptr("LDO4"),
0632 .regulators_node = of_match_ptr("regulators"),
0633 .id = PCA9450_LDO4,
0634 .ops = &pca9450_ldo_regulator_ops,
0635 .type = REGULATOR_VOLTAGE,
0636 .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
0637 .linear_ranges = pca9450_ldo34_volts,
0638 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
0639 .vsel_reg = PCA9450_REG_LDO4CTRL,
0640 .vsel_mask = LDO4OUT_MASK,
0641 .enable_reg = PCA9450_REG_LDO4CTRL,
0642 .enable_mask = LDO4_EN_MASK,
0643 .owner = THIS_MODULE,
0644 },
0645 },
0646 {
0647 .desc = {
0648 .name = "ldo5",
0649 .of_match = of_match_ptr("LDO5"),
0650 .regulators_node = of_match_ptr("regulators"),
0651 .id = PCA9450_LDO5,
0652 .ops = &pca9450_ldo_regulator_ops,
0653 .type = REGULATOR_VOLTAGE,
0654 .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
0655 .linear_ranges = pca9450_ldo5_volts,
0656 .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
0657 .vsel_reg = PCA9450_REG_LDO5CTRL_H,
0658 .vsel_mask = LDO5HOUT_MASK,
0659 .enable_reg = PCA9450_REG_LDO5CTRL_H,
0660 .enable_mask = LDO5H_EN_MASK,
0661 .owner = THIS_MODULE,
0662 },
0663 },
0664 };
0665
0666 static irqreturn_t pca9450_irq_handler(int irq, void *data)
0667 {
0668 struct pca9450 *pca9450 = data;
0669 struct regmap *regmap = pca9450->regmap;
0670 unsigned int status;
0671 int ret;
0672
0673 ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
0674 if (ret < 0) {
0675 dev_err(pca9450->dev,
0676 "Failed to read INT1(%d)\n", ret);
0677 return IRQ_NONE;
0678 }
0679
0680 if (status & IRQ_PWRON)
0681 dev_warn(pca9450->dev, "PWRON interrupt.\n");
0682
0683 if (status & IRQ_WDOGB)
0684 dev_warn(pca9450->dev, "WDOGB interrupt.\n");
0685
0686 if (status & IRQ_VR_FLT1)
0687 dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
0688
0689 if (status & IRQ_VR_FLT2)
0690 dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
0691
0692 if (status & IRQ_LOWVSYS)
0693 dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
0694
0695 if (status & IRQ_THERM_105)
0696 dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
0697
0698 if (status & IRQ_THERM_125)
0699 dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
0700
0701 return IRQ_HANDLED;
0702 }
0703
0704 static int pca9450_i2c_probe(struct i2c_client *i2c,
0705 const struct i2c_device_id *id)
0706 {
0707 enum pca9450_chip_type type = (unsigned int)(uintptr_t)
0708 of_device_get_match_data(&i2c->dev);
0709 const struct pca9450_regulator_desc *regulator_desc;
0710 struct regulator_config config = { };
0711 struct pca9450 *pca9450;
0712 unsigned int device_id, i;
0713 unsigned int reset_ctrl;
0714 int ret;
0715
0716 if (!i2c->irq) {
0717 dev_err(&i2c->dev, "No IRQ configured?\n");
0718 return -EINVAL;
0719 }
0720
0721 pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
0722 if (!pca9450)
0723 return -ENOMEM;
0724
0725 switch (type) {
0726 case PCA9450_TYPE_PCA9450A:
0727 regulator_desc = pca9450a_regulators;
0728 pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
0729 break;
0730 case PCA9450_TYPE_PCA9450BC:
0731 regulator_desc = pca9450bc_regulators;
0732 pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
0733 break;
0734 default:
0735 dev_err(&i2c->dev, "Unknown device type");
0736 return -EINVAL;
0737 }
0738
0739 pca9450->irq = i2c->irq;
0740 pca9450->type = type;
0741 pca9450->dev = &i2c->dev;
0742
0743 dev_set_drvdata(&i2c->dev, pca9450);
0744
0745 pca9450->regmap = devm_regmap_init_i2c(i2c,
0746 &pca9450_regmap_config);
0747 if (IS_ERR(pca9450->regmap)) {
0748 dev_err(&i2c->dev, "regmap initialization failed\n");
0749 return PTR_ERR(pca9450->regmap);
0750 }
0751
0752 ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
0753 if (ret) {
0754 dev_err(&i2c->dev, "Read device id error\n");
0755 return ret;
0756 }
0757
0758
0759 if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
0760 ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
0761 dev_err(&i2c->dev, "Device id(%x) mismatched\n",
0762 device_id >> 4);
0763 return -EINVAL;
0764 }
0765
0766 for (i = 0; i < pca9450->rcnt; i++) {
0767 const struct regulator_desc *desc;
0768 struct regulator_dev *rdev;
0769 const struct pca9450_regulator_desc *r;
0770
0771 r = ®ulator_desc[i];
0772 desc = &r->desc;
0773
0774 config.regmap = pca9450->regmap;
0775 config.dev = pca9450->dev;
0776
0777 rdev = devm_regulator_register(pca9450->dev, desc, &config);
0778 if (IS_ERR(rdev)) {
0779 ret = PTR_ERR(rdev);
0780 dev_err(pca9450->dev,
0781 "Failed to register regulator(%s): %d\n",
0782 desc->name, ret);
0783 return ret;
0784 }
0785 }
0786
0787 ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
0788 pca9450_irq_handler,
0789 (IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
0790 "pca9450-irq", pca9450);
0791 if (ret != 0) {
0792 dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
0793 pca9450->irq);
0794 return ret;
0795 }
0796
0797 ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
0798 IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
0799 IRQ_THERM_105 | IRQ_THERM_125,
0800 IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
0801 if (ret) {
0802 dev_err(&i2c->dev, "Unmask irq error\n");
0803 return ret;
0804 }
0805
0806
0807 ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
0808 BUCK123_PRESET_EN);
0809 if (ret) {
0810 dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
0811 return ret;
0812 }
0813
0814 if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset"))
0815 reset_ctrl = WDOG_B_CFG_WARM;
0816 else
0817 reset_ctrl = WDOG_B_CFG_COLD_LDO12;
0818
0819
0820 ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
0821 WDOG_B_CFG_MASK, reset_ctrl);
0822 if (ret) {
0823 dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
0824 return ret;
0825 }
0826
0827 if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) {
0828
0829 ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2,
0830 I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN);
0831 if (ret) {
0832 dev_err(&i2c->dev,
0833 "Failed to enable I2C level translator\n");
0834 return ret;
0835 }
0836 }
0837
0838
0839
0840
0841
0842
0843 pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
0844
0845 if (IS_ERR(pca9450->sd_vsel_gpio)) {
0846 dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
0847 return PTR_ERR(pca9450->sd_vsel_gpio);
0848 }
0849
0850 dev_info(&i2c->dev, "%s probed.\n",
0851 type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
0852
0853 return 0;
0854 }
0855
0856 static const struct of_device_id pca9450_of_match[] = {
0857 {
0858 .compatible = "nxp,pca9450a",
0859 .data = (void *)PCA9450_TYPE_PCA9450A,
0860 },
0861 {
0862 .compatible = "nxp,pca9450b",
0863 .data = (void *)PCA9450_TYPE_PCA9450BC,
0864 },
0865 {
0866 .compatible = "nxp,pca9450c",
0867 .data = (void *)PCA9450_TYPE_PCA9450BC,
0868 },
0869 { }
0870 };
0871 MODULE_DEVICE_TABLE(of, pca9450_of_match);
0872
0873 static struct i2c_driver pca9450_i2c_driver = {
0874 .driver = {
0875 .name = "nxp-pca9450",
0876 .of_match_table = pca9450_of_match,
0877 },
0878 .probe = pca9450_i2c_probe,
0879 };
0880
0881 module_i2c_driver(pca9450_i2c_driver);
0882
0883 MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
0884 MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
0885 MODULE_LICENSE("GPL");