1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // Regulator driver for ATC260x PMICs 4 // 5 // Copyright (C) 2019 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 6 // Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 7 8 #include <linux/mfd/atc260x/core.h> 9 #include <linux/module.h> 10 #include <linux/of_device.h> 11 #include <linux/regmap.h> 12 #include <linux/regulator/driver.h> 13 14 struct atc260x_regulator_data { 15 int voltage_time_dcdc; 16 int voltage_time_ldo; 17 }; 18 19 static const struct linear_range atc2603c_dcdc_voltage_ranges[] = { 20 REGULATOR_LINEAR_RANGE(1300000, 0, 13, 50000), 21 REGULATOR_LINEAR_RANGE(1950000, 14, 15, 100000), 22 }; 23 24 static const struct linear_range atc2609a_dcdc_voltage_ranges[] = { 25 REGULATOR_LINEAR_RANGE(600000, 0, 127, 6250), 26 REGULATOR_LINEAR_RANGE(1400000, 128, 232, 25000), 27 }; 28 29 static const struct linear_range atc2609a_ldo_voltage_ranges0[] = { 30 REGULATOR_LINEAR_RANGE(700000, 0, 15, 100000), 31 REGULATOR_LINEAR_RANGE(2100000, 0, 12, 100000), 32 }; 33 34 static const struct linear_range atc2609a_ldo_voltage_ranges1[] = { 35 REGULATOR_LINEAR_RANGE(850000, 0, 15, 100000), 36 REGULATOR_LINEAR_RANGE(2100000, 0, 11, 100000), 37 }; 38 39 static const unsigned int atc260x_ldo_voltage_range_sel[] = { 40 0x0, 0x20, 41 }; 42 43 static int atc260x_dcdc_set_voltage_time_sel(struct regulator_dev *rdev, 44 unsigned int old_selector, 45 unsigned int new_selector) 46 { 47 struct atc260x_regulator_data *data = rdev_get_drvdata(rdev); 48 49 if (new_selector > old_selector) 50 return data->voltage_time_dcdc; 51 52 return 0; 53 } 54 55 static int atc260x_ldo_set_voltage_time_sel(struct regulator_dev *rdev, 56 unsigned int old_selector, 57 unsigned int new_selector) 58 { 59 struct atc260x_regulator_data *data = rdev_get_drvdata(rdev); 60 61 if (new_selector > old_selector) 62 return data->voltage_time_ldo; 63 64 return 0; 65 } 66 67 static const struct regulator_ops atc260x_dcdc_ops = { 68 .enable = regulator_enable_regmap, 69 .disable = regulator_disable_regmap, 70 .is_enabled = regulator_is_enabled_regmap, 71 .list_voltage = regulator_list_voltage_linear, 72 .set_voltage_sel = regulator_set_voltage_sel_regmap, 73 .get_voltage_sel = regulator_get_voltage_sel_regmap, 74 .set_voltage_time_sel = atc260x_dcdc_set_voltage_time_sel, 75 }; 76 77 static const struct regulator_ops atc260x_ldo_ops = { 78 .enable = regulator_enable_regmap, 79 .disable = regulator_disable_regmap, 80 .is_enabled = regulator_is_enabled_regmap, 81 .list_voltage = regulator_list_voltage_linear, 82 .set_voltage_sel = regulator_set_voltage_sel_regmap, 83 .get_voltage_sel = regulator_get_voltage_sel_regmap, 84 .set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel, 85 }; 86 87 static const struct regulator_ops atc260x_ldo_bypass_ops = { 88 .enable = regulator_enable_regmap, 89 .disable = regulator_disable_regmap, 90 .is_enabled = regulator_is_enabled_regmap, 91 .list_voltage = regulator_list_voltage_linear, 92 .set_voltage_sel = regulator_set_voltage_sel_regmap, 93 .get_voltage_sel = regulator_get_voltage_sel_regmap, 94 .set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel, 95 .set_bypass = regulator_set_bypass_regmap, 96 .get_bypass = regulator_get_bypass_regmap, 97 }; 98 99 static const struct regulator_ops atc260x_ldo_bypass_discharge_ops = { 100 .enable = regulator_enable_regmap, 101 .disable = regulator_disable_regmap, 102 .is_enabled = regulator_is_enabled_regmap, 103 .list_voltage = regulator_list_voltage_linear, 104 .set_voltage_sel = regulator_set_voltage_sel_regmap, 105 .get_voltage_sel = regulator_get_voltage_sel_regmap, 106 .set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel, 107 .set_bypass = regulator_set_bypass_regmap, 108 .get_bypass = regulator_get_bypass_regmap, 109 .set_active_discharge = regulator_set_active_discharge_regmap, 110 }; 111 112 static const struct regulator_ops atc260x_dcdc_range_ops = { 113 .enable = regulator_enable_regmap, 114 .disable = regulator_disable_regmap, 115 .is_enabled = regulator_is_enabled_regmap, 116 .list_voltage = regulator_list_voltage_linear_range, 117 .set_voltage_sel = regulator_set_voltage_sel_regmap, 118 .get_voltage_sel = regulator_get_voltage_sel_regmap, 119 .set_voltage_time_sel = atc260x_dcdc_set_voltage_time_sel, 120 }; 121 122 static const struct regulator_ops atc260x_ldo_range_pick_ops = { 123 .enable = regulator_enable_regmap, 124 .disable = regulator_disable_regmap, 125 .is_enabled = regulator_is_enabled_regmap, 126 .list_voltage = regulator_list_voltage_pickable_linear_range, 127 .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, 128 .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, 129 .set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel, 130 }; 131 132 static const struct regulator_ops atc260x_dcdc_fixed_ops = { 133 .list_voltage = regulator_list_voltage_linear, 134 .set_voltage_sel = regulator_set_voltage_sel_regmap, 135 .get_voltage_sel = regulator_get_voltage_sel_regmap, 136 .set_voltage_time_sel = atc260x_dcdc_set_voltage_time_sel, 137 }; 138 139 static const struct regulator_ops atc260x_ldo_fixed_ops = { 140 .list_voltage = regulator_list_voltage_linear, 141 .set_voltage_sel = regulator_set_voltage_sel_regmap, 142 .get_voltage_sel = regulator_get_voltage_sel_regmap, 143 .set_voltage_time_sel = atc260x_ldo_set_voltage_time_sel, 144 }; 145 146 static const struct regulator_ops atc260x_no_ops = { 147 }; 148 149 /* 150 * Note LDO8 is not documented in datasheet (v2.4), but supported 151 * in the vendor's driver implementation (xapp-le-kernel). 152 */ 153 enum atc2603c_reg_ids { 154 ATC2603C_ID_DCDC1, 155 ATC2603C_ID_DCDC2, 156 ATC2603C_ID_DCDC3, 157 ATC2603C_ID_LDO1, 158 ATC2603C_ID_LDO2, 159 ATC2603C_ID_LDO3, 160 ATC2603C_ID_LDO5, 161 ATC2603C_ID_LDO6, 162 ATC2603C_ID_LDO7, 163 ATC2603C_ID_LDO8, 164 ATC2603C_ID_LDO11, 165 ATC2603C_ID_LDO12, 166 ATC2603C_ID_SWITCHLDO1, 167 ATC2603C_ID_MAX, 168 }; 169 170 #define atc2603c_reg_desc_dcdc(num, min, step, n_volt, vsel_h, vsel_l) { \ 171 .name = "DCDC"#num, \ 172 .supply_name = "dcdc"#num, \ 173 .of_match = of_match_ptr("dcdc"#num), \ 174 .regulators_node = of_match_ptr("regulators"), \ 175 .id = ATC2603C_ID_DCDC##num, \ 176 .ops = &atc260x_dcdc_ops, \ 177 .type = REGULATOR_VOLTAGE, \ 178 .min_uV = min, \ 179 .uV_step = step, \ 180 .n_voltages = n_volt, \ 181 .vsel_reg = ATC2603C_PMU_DC##num##_CTL0, \ 182 .vsel_mask = GENMASK(vsel_h, vsel_l), \ 183 .enable_reg = ATC2603C_PMU_DC##num##_CTL0, \ 184 .enable_mask = BIT(15), \ 185 .enable_time = 800, \ 186 .owner = THIS_MODULE, \ 187 } 188 189 #define atc2603c_reg_desc_dcdc_range(num, vsel_h, vsel_l) { \ 190 .name = "DCDC"#num, \ 191 .supply_name = "dcdc"#num, \ 192 .of_match = of_match_ptr("dcdc"#num), \ 193 .regulators_node = of_match_ptr("regulators"), \ 194 .id = ATC2603C_ID_DCDC##num, \ 195 .ops = &atc260x_dcdc_range_ops, \ 196 .type = REGULATOR_VOLTAGE, \ 197 .n_voltages = 16, \ 198 .linear_ranges = atc2603c_dcdc_voltage_ranges, \ 199 .n_linear_ranges = ARRAY_SIZE(atc2603c_dcdc_voltage_ranges), \ 200 .vsel_reg = ATC2603C_PMU_DC##num##_CTL0, \ 201 .vsel_mask = GENMASK(vsel_h, vsel_l), \ 202 .enable_reg = ATC2603C_PMU_DC##num##_CTL0, \ 203 .enable_mask = BIT(15), \ 204 .enable_time = 800, \ 205 .owner = THIS_MODULE, \ 206 } 207 208 #define atc2603c_reg_desc_dcdc_fixed(num, min, step, n_volt, vsel_h, vsel_l) { \ 209 .name = "DCDC"#num, \ 210 .supply_name = "dcdc"#num, \ 211 .of_match = of_match_ptr("dcdc"#num), \ 212 .regulators_node = of_match_ptr("regulators"), \ 213 .id = ATC2603C_ID_DCDC##num, \ 214 .ops = &atc260x_dcdc_fixed_ops, \ 215 .type = REGULATOR_VOLTAGE, \ 216 .min_uV = min, \ 217 .uV_step = step, \ 218 .n_voltages = n_volt, \ 219 .vsel_reg = ATC2603C_PMU_DC##num##_CTL0, \ 220 .vsel_mask = GENMASK(vsel_h, vsel_l), \ 221 .enable_time = 800, \ 222 .owner = THIS_MODULE, \ 223 } 224 225 #define atc2603c_reg_desc_ldo(num, min, step, n_volt, vsel_h, vsel_l) { \ 226 .name = "LDO"#num, \ 227 .supply_name = "ldo"#num, \ 228 .of_match = of_match_ptr("ldo"#num), \ 229 .regulators_node = of_match_ptr("regulators"), \ 230 .id = ATC2603C_ID_LDO##num, \ 231 .ops = &atc260x_ldo_ops, \ 232 .type = REGULATOR_VOLTAGE, \ 233 .min_uV = min, \ 234 .uV_step = step, \ 235 .n_voltages = n_volt, \ 236 .vsel_reg = ATC2603C_PMU_LDO##num##_CTL, \ 237 .vsel_mask = GENMASK(vsel_h, vsel_l), \ 238 .enable_reg = ATC2603C_PMU_LDO##num##_CTL, \ 239 .enable_mask = BIT(0), \ 240 .enable_time = 2000, \ 241 .owner = THIS_MODULE, \ 242 } 243 244 #define atc2603c_reg_desc_ldo_fixed(num, min, step, n_volt, vsel_h, vsel_l) { \ 245 .name = "LDO"#num, \ 246 .supply_name = "ldo"#num, \ 247 .of_match = of_match_ptr("ldo"#num), \ 248 .regulators_node = of_match_ptr("regulators"), \ 249 .id = ATC2603C_ID_LDO##num, \ 250 .ops = &atc260x_ldo_fixed_ops, \ 251 .type = REGULATOR_VOLTAGE, \ 252 .min_uV = min, \ 253 .uV_step = step, \ 254 .n_voltages = n_volt, \ 255 .vsel_reg = ATC2603C_PMU_LDO##num##_CTL, \ 256 .vsel_mask = GENMASK(vsel_h, vsel_l), \ 257 .enable_time = 2000, \ 258 .owner = THIS_MODULE, \ 259 } 260 261 #define atc2603c_reg_desc_ldo_noops(num, vfixed) { \ 262 .name = "LDO"#num, \ 263 .supply_name = "ldo"#num, \ 264 .of_match = of_match_ptr("ldo"#num), \ 265 .regulators_node = of_match_ptr("regulators"), \ 266 .id = ATC2603C_ID_LDO##num, \ 267 .ops = &atc260x_no_ops, \ 268 .type = REGULATOR_VOLTAGE, \ 269 .fixed_uV = vfixed, \ 270 .n_voltages = 1, \ 271 .owner = THIS_MODULE, \ 272 } 273 274 #define atc2603c_reg_desc_ldo_switch(num, min, step, n_volt, vsel_h, vsel_l) { \ 275 .name = "SWITCHLDO"#num, \ 276 .supply_name = "switchldo"#num, \ 277 .of_match = of_match_ptr("switchldo"#num), \ 278 .regulators_node = of_match_ptr("regulators"), \ 279 .id = ATC2603C_ID_SWITCHLDO##num, \ 280 .ops = &atc260x_ldo_bypass_discharge_ops, \ 281 .type = REGULATOR_VOLTAGE, \ 282 .min_uV = min, \ 283 .uV_step = step, \ 284 .n_voltages = n_volt, \ 285 .vsel_reg = ATC2603C_PMU_SWITCH_CTL, \ 286 .vsel_mask = GENMASK(vsel_h, vsel_l), \ 287 .enable_reg = ATC2603C_PMU_SWITCH_CTL, \ 288 .enable_mask = BIT(15), \ 289 .enable_is_inverted = true, \ 290 .enable_time = 2000, \ 291 .bypass_reg = ATC2603C_PMU_SWITCH_CTL, \ 292 .bypass_mask = BIT(5), \ 293 .active_discharge_reg = ATC2603C_PMU_SWITCH_CTL, \ 294 .active_discharge_mask = BIT(1), \ 295 .owner = THIS_MODULE, \ 296 } 297 298 static const struct regulator_desc atc2603c_reg[] = { 299 atc2603c_reg_desc_dcdc_fixed(1, 700000, 25000, 29, 11, 7), 300 atc2603c_reg_desc_dcdc_range(2, 12, 8), 301 atc2603c_reg_desc_dcdc_fixed(3, 2600000, 100000, 8, 11, 9), 302 atc2603c_reg_desc_ldo_fixed(1, 2600000, 100000, 8, 15, 13), 303 atc2603c_reg_desc_ldo_fixed(2, 2600000, 100000, 8, 15, 13), 304 atc2603c_reg_desc_ldo_fixed(3, 1500000, 100000, 6, 15, 13), 305 atc2603c_reg_desc_ldo(5, 2600000, 100000, 8, 15, 13), 306 atc2603c_reg_desc_ldo_fixed(6, 700000, 25000, 29, 15, 11), 307 atc2603c_reg_desc_ldo(7, 1500000, 100000, 6, 15, 13), 308 atc2603c_reg_desc_ldo(8, 2300000, 100000, 11, 15, 12), 309 atc2603c_reg_desc_ldo_fixed(11, 2600000, 100000, 8, 15, 13), 310 atc2603c_reg_desc_ldo_noops(12, 1800000), 311 atc2603c_reg_desc_ldo_switch(1, 3000000, 100000, 4, 4, 3), 312 }; 313 314 static const struct regulator_desc atc2603c_reg_dcdc2_ver_b = 315 atc2603c_reg_desc_dcdc(2, 1000000, 50000, 18, 12, 8); 316 317 enum atc2609a_reg_ids { 318 ATC2609A_ID_DCDC0, 319 ATC2609A_ID_DCDC1, 320 ATC2609A_ID_DCDC2, 321 ATC2609A_ID_DCDC3, 322 ATC2609A_ID_DCDC4, 323 ATC2609A_ID_LDO0, 324 ATC2609A_ID_LDO1, 325 ATC2609A_ID_LDO2, 326 ATC2609A_ID_LDO3, 327 ATC2609A_ID_LDO4, 328 ATC2609A_ID_LDO5, 329 ATC2609A_ID_LDO6, 330 ATC2609A_ID_LDO7, 331 ATC2609A_ID_LDO8, 332 ATC2609A_ID_LDO9, 333 ATC2609A_ID_MAX, 334 }; 335 336 #define atc2609a_reg_desc_dcdc(num, en_bit) { \ 337 .name = "DCDC"#num, \ 338 .supply_name = "dcdc"#num, \ 339 .of_match = of_match_ptr("dcdc"#num), \ 340 .regulators_node = of_match_ptr("regulators"), \ 341 .id = ATC2609A_ID_DCDC##num, \ 342 .ops = &atc260x_dcdc_ops, \ 343 .type = REGULATOR_VOLTAGE, \ 344 .min_uV = 600000, \ 345 .uV_step = 6250, \ 346 .n_voltages = 256, \ 347 .vsel_reg = ATC2609A_PMU_DC##num##_CTL0, \ 348 .vsel_mask = GENMASK(15, 8), \ 349 .enable_reg = ATC2609A_PMU_DC_OSC, \ 350 .enable_mask = BIT(en_bit), \ 351 .enable_time = 800, \ 352 .owner = THIS_MODULE, \ 353 } 354 355 #define atc2609a_reg_desc_dcdc_range(num, en_bit) { \ 356 .name = "DCDC"#num, \ 357 .supply_name = "dcdc"#num, \ 358 .of_match = of_match_ptr("dcdc"#num), \ 359 .regulators_node = of_match_ptr("regulators"), \ 360 .id = ATC2609A_ID_DCDC##num, \ 361 .ops = &atc260x_dcdc_range_ops, \ 362 .type = REGULATOR_VOLTAGE, \ 363 .n_voltages = 233, \ 364 .linear_ranges = atc2609a_dcdc_voltage_ranges, \ 365 .n_linear_ranges = ARRAY_SIZE(atc2609a_dcdc_voltage_ranges), \ 366 .vsel_reg = ATC2609A_PMU_DC##num##_CTL0, \ 367 .vsel_mask = GENMASK(15, 8), \ 368 .enable_reg = ATC2609A_PMU_DC_OSC, \ 369 .enable_mask = BIT(en_bit), \ 370 .enable_time = 800, \ 371 .owner = THIS_MODULE, \ 372 } 373 374 #define atc2609a_reg_desc_ldo(num) { \ 375 .name = "LDO"#num, \ 376 .supply_name = "ldo"#num, \ 377 .of_match = of_match_ptr("ldo"#num), \ 378 .regulators_node = of_match_ptr("regulators"), \ 379 .id = ATC2609A_ID_LDO##num, \ 380 .ops = &atc260x_ldo_ops, \ 381 .type = REGULATOR_VOLTAGE, \ 382 .min_uV = 700000, \ 383 .uV_step = 100000, \ 384 .n_voltages = 16, \ 385 .vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 386 .vsel_mask = GENMASK(4, 1), \ 387 .enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 388 .enable_mask = BIT(0), \ 389 .enable_time = 2000, \ 390 .owner = THIS_MODULE, \ 391 } 392 393 #define atc2609a_reg_desc_ldo_bypass(num) { \ 394 .name = "LDO"#num, \ 395 .supply_name = "ldo"#num, \ 396 .of_match = of_match_ptr("ldo"#num), \ 397 .regulators_node = of_match_ptr("regulators"), \ 398 .id = ATC2609A_ID_LDO##num, \ 399 .ops = &atc260x_ldo_bypass_ops, \ 400 .type = REGULATOR_VOLTAGE, \ 401 .min_uV = 2300000, \ 402 .uV_step = 100000, \ 403 .n_voltages = 12, \ 404 .vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 405 .vsel_mask = GENMASK(5, 2), \ 406 .enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 407 .enable_mask = BIT(0), \ 408 .enable_time = 2000, \ 409 .bypass_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 410 .bypass_mask = BIT(1), \ 411 .owner = THIS_MODULE, \ 412 } 413 414 #define atc2609a_reg_desc_ldo_range_pick(num, n_range, n_volt) { \ 415 .name = "LDO"#num, \ 416 .supply_name = "ldo"#num, \ 417 .of_match = of_match_ptr("ldo"#num), \ 418 .regulators_node = of_match_ptr("regulators"), \ 419 .id = ATC2609A_ID_LDO##num, \ 420 .ops = &atc260x_ldo_range_pick_ops, \ 421 .type = REGULATOR_VOLTAGE, \ 422 .linear_ranges = atc2609a_ldo_voltage_ranges##n_range, \ 423 .n_linear_ranges = ARRAY_SIZE(atc2609a_ldo_voltage_ranges##n_range), \ 424 .n_voltages = n_volt, \ 425 .vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 426 .vsel_mask = GENMASK(4, 1), \ 427 .vsel_range_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 428 .vsel_range_mask = BIT(5), \ 429 .linear_range_selectors = atc260x_ldo_voltage_range_sel, \ 430 .enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \ 431 .enable_mask = BIT(0), \ 432 .enable_time = 2000, \ 433 .owner = THIS_MODULE, \ 434 } 435 436 #define atc2609a_reg_desc_ldo_fixed(num) { \ 437 .name = "LDO"#num, \ 438 .supply_name = "ldo"#num, \ 439 .of_match = of_match_ptr("ldo"#num), \ 440 .regulators_node = of_match_ptr("regulators"), \ 441 .id = ATC2609A_ID_LDO##num, \ 442 .ops = &atc260x_ldo_fixed_ops, \ 443 .type = REGULATOR_VOLTAGE, \ 444 .min_uV = 2600000, \ 445 .uV_step = 100000, \ 446 .n_voltages = 8, \ 447 .vsel_reg = ATC2609A_PMU_LDO##num##_CTL, \ 448 .vsel_mask = GENMASK(15, 13), \ 449 .enable_time = 2000, \ 450 .owner = THIS_MODULE, \ 451 } 452 453 static const struct regulator_desc atc2609a_reg[] = { 454 atc2609a_reg_desc_dcdc(0, 4), 455 atc2609a_reg_desc_dcdc(1, 5), 456 atc2609a_reg_desc_dcdc(2, 6), 457 atc2609a_reg_desc_dcdc_range(3, 7), 458 atc2609a_reg_desc_dcdc(4, 8), 459 atc2609a_reg_desc_ldo_bypass(0), 460 atc2609a_reg_desc_ldo_bypass(1), 461 atc2609a_reg_desc_ldo_bypass(2), 462 atc2609a_reg_desc_ldo_range_pick(3, 0, 29), 463 atc2609a_reg_desc_ldo_range_pick(4, 0, 29), 464 atc2609a_reg_desc_ldo(5), 465 atc2609a_reg_desc_ldo_range_pick(6, 1, 28), 466 atc2609a_reg_desc_ldo_range_pick(7, 0, 29), 467 atc2609a_reg_desc_ldo_range_pick(8, 0, 29), 468 atc2609a_reg_desc_ldo_fixed(9), 469 }; 470 471 static int atc260x_regulator_probe(struct platform_device *pdev) 472 { 473 struct atc260x *atc260x = dev_get_drvdata(pdev->dev.parent); 474 struct device *dev = atc260x->dev; 475 struct atc260x_regulator_data *atc260x_data; 476 struct regulator_config config = {}; 477 struct regulator_dev *atc260x_rdev; 478 const struct regulator_desc *regulators; 479 bool atc2603c_ver_b = false; 480 int i, nregulators; 481 482 atc260x_data = devm_kzalloc(&pdev->dev, sizeof(*atc260x_data), GFP_KERNEL); 483 if (!atc260x_data) 484 return -ENOMEM; 485 486 atc260x_data->voltage_time_dcdc = 350; 487 atc260x_data->voltage_time_ldo = 800; 488 489 switch (atc260x->ic_type) { 490 case ATC2603C: 491 regulators = atc2603c_reg; 492 nregulators = ATC2603C_ID_MAX; 493 atc2603c_ver_b = atc260x->ic_ver == ATC260X_B; 494 break; 495 case ATC2609A: 496 atc260x_data->voltage_time_dcdc = 250; 497 regulators = atc2609a_reg; 498 nregulators = ATC2609A_ID_MAX; 499 break; 500 default: 501 dev_err(dev, "unsupported ATC260X ID %d\n", atc260x->ic_type); 502 return -EINVAL; 503 } 504 505 config.dev = dev; 506 config.regmap = atc260x->regmap; 507 config.driver_data = atc260x_data; 508 509 /* Instantiate the regulators */ 510 for (i = 0; i < nregulators; i++) { 511 if (atc2603c_ver_b && regulators[i].id == ATC2603C_ID_DCDC2) 512 atc260x_rdev = devm_regulator_register(&pdev->dev, 513 &atc2603c_reg_dcdc2_ver_b, 514 &config); 515 else 516 atc260x_rdev = devm_regulator_register(&pdev->dev, 517 ®ulators[i], 518 &config); 519 if (IS_ERR(atc260x_rdev)) { 520 dev_err(dev, "failed to register regulator: %d\n", i); 521 return PTR_ERR(atc260x_rdev); 522 } 523 } 524 525 return 0; 526 } 527 528 static struct platform_driver atc260x_regulator_driver = { 529 .probe = atc260x_regulator_probe, 530 .driver = { 531 .name = "atc260x-regulator", 532 }, 533 }; 534 535 module_platform_driver(atc260x_regulator_driver); 536 537 MODULE_DESCRIPTION("Regulator driver for ATC260x PMICs"); 538 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); 539 MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@gmail.com>"); 540 MODULE_LICENSE("GPL"); 541