1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Broadcom BCM590xx regulator driver 4 * 5 * Copyright 2014 Linaro Limited 6 * Author: Matt Porter <mporter@linaro.org> 7 */ 8 9 #include <linux/err.h> 10 #include <linux/init.h> 11 #include <linux/kernel.h> 12 #include <linux/mfd/bcm590xx.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/platform_device.h> 16 #include <linux/regulator/driver.h> 17 #include <linux/regulator/machine.h> 18 #include <linux/regulator/of_regulator.h> 19 #include <linux/slab.h> 20 21 #define BCM590XX_REG_ENABLE BIT(7) 22 #define BCM590XX_VBUS_ENABLE BIT(2) 23 #define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3) 24 #define BCM590XX_SR_VSEL_MASK GENMASK(5, 0) 25 26 enum bcm590xx_reg_type { 27 BCM590XX_REG_TYPE_LDO, 28 BCM590XX_REG_TYPE_GPLDO, 29 BCM590XX_REG_TYPE_SR, 30 BCM590XX_REG_TYPE_VBUS 31 }; 32 33 struct bcm590xx_reg_data { 34 enum bcm590xx_reg_type type; 35 enum bcm590xx_regmap_type regmap; 36 const struct regulator_desc desc; 37 }; 38 39 struct bcm590xx_reg { 40 struct bcm590xx *mfd; 41 unsigned int n_regulators; 42 const struct bcm590xx_reg_data *regs; 43 }; 44 45 static const struct regulator_ops bcm590xx_ops_ldo = { 46 .is_enabled = regulator_is_enabled_regmap, 47 .enable = regulator_enable_regmap, 48 .disable = regulator_disable_regmap, 49 .get_voltage_sel = regulator_get_voltage_sel_regmap, 50 .set_voltage_sel = regulator_set_voltage_sel_regmap, 51 .list_voltage = regulator_list_voltage_table, 52 .map_voltage = regulator_map_voltage_iterate, 53 }; 54 55 /* 56 * LDO ops without voltage selection, used for MICLDO on BCM59054. 57 * (These are currently the same as VBUS ops, but will be different 58 * in the future once full PMMODE support is implemented.) 59 */ 60 static const struct regulator_ops bcm590xx_ops_ldo_novolt = { 61 .is_enabled = regulator_is_enabled_regmap, 62 .enable = regulator_enable_regmap, 63 .disable = regulator_disable_regmap, 64 }; 65 66 static const struct regulator_ops bcm590xx_ops_dcdc = { 67 .is_enabled = regulator_is_enabled_regmap, 68 .enable = regulator_enable_regmap, 69 .disable = regulator_disable_regmap, 70 .get_voltage_sel = regulator_get_voltage_sel_regmap, 71 .set_voltage_sel = regulator_set_voltage_sel_regmap, 72 .list_voltage = regulator_list_voltage_linear_range, 73 .map_voltage = regulator_map_voltage_linear_range, 74 }; 75 76 static const struct regulator_ops bcm590xx_ops_vbus = { 77 .is_enabled = regulator_is_enabled_regmap, 78 .enable = regulator_enable_regmap, 79 .disable = regulator_disable_regmap, 80 }; 81 82 #define BCM590XX_REG_DESC(_model, _name, _name_lower) \ 83 .id = _model##_REG_##_name, \ 84 .name = #_name_lower, \ 85 .of_match = of_match_ptr(#_name_lower), \ 86 .regulators_node = of_match_ptr("regulators"), \ 87 .type = REGULATOR_VOLTAGE, \ 88 .owner = THIS_MODULE \ 89 90 #define BCM590XX_LDO_DESC(_model, _model_lower, _name, _name_lower, _table) \ 91 BCM590XX_REG_DESC(_model, _name, _name_lower), \ 92 .ops = &bcm590xx_ops_ldo, \ 93 .n_voltages = ARRAY_SIZE(_model_lower##_##_table), \ 94 .volt_table = _model_lower##_##_table, \ 95 .vsel_reg = _model##_##_name##CTRL, \ 96 .vsel_mask = BCM590XX_LDO_VSEL_MASK, \ 97 .enable_reg = _model##_##_name##PMCTRL1, \ 98 .enable_mask = BCM590XX_REG_ENABLE, \ 99 .enable_is_inverted = true 100 101 #define BCM590XX_SR_DESC(_model, _model_lower, _name, _name_lower, _ranges) \ 102 BCM590XX_REG_DESC(_model, _name, _name_lower), \ 103 .ops = &bcm590xx_ops_dcdc, \ 104 .n_voltages = 64, \ 105 .linear_ranges = _model_lower##_##_ranges, \ 106 .n_linear_ranges = ARRAY_SIZE(_model_lower##_##_ranges), \ 107 .vsel_reg = _model##_##_name##VOUT1, \ 108 .vsel_mask = BCM590XX_SR_VSEL_MASK, \ 109 .enable_reg = _model##_##_name##PMCTRL1, \ 110 .enable_mask = BCM590XX_REG_ENABLE, \ 111 .enable_is_inverted = true 112 113 #define BCM59056_REG_DESC(_name, _name_lower) \ 114 BCM590XX_REG_DESC(BCM59056, _name, _name_lower) 115 #define BCM59056_LDO_DESC(_name, _name_lower, _table) \ 116 BCM590XX_LDO_DESC(BCM59056, bcm59056, _name, _name_lower, _table) 117 #define BCM59056_SR_DESC(_name, _name_lower, _ranges) \ 118 BCM590XX_SR_DESC(BCM59056, bcm59056, _name, _name_lower, _ranges) 119 120 #define BCM59054_REG_DESC(_name, _name_lower) \ 121 BCM590XX_REG_DESC(BCM59054, _name, _name_lower) 122 #define BCM59054_LDO_DESC(_name, _name_lower, _table) \ 123 BCM590XX_LDO_DESC(BCM59054, bcm59054, _name, _name_lower, _table) 124 #define BCM59054_SR_DESC(_name, _name_lower, _ranges) \ 125 BCM590XX_SR_DESC(BCM59054, bcm59054, _name, _name_lower, _ranges) 126 127 /* BCM59056 data */ 128 129 /* I2C slave 0 registers */ 130 #define BCM59056_RFLDOPMCTRL1 0x60 131 #define BCM59056_CAMLDO1PMCTRL1 0x62 132 #define BCM59056_CAMLDO2PMCTRL1 0x64 133 #define BCM59056_SIMLDO1PMCTRL1 0x66 134 #define BCM59056_SIMLDO2PMCTRL1 0x68 135 #define BCM59056_SDLDOPMCTRL1 0x6a 136 #define BCM59056_SDXLDOPMCTRL1 0x6c 137 #define BCM59056_MMCLDO1PMCTRL1 0x6e 138 #define BCM59056_MMCLDO2PMCTRL1 0x70 139 #define BCM59056_AUDLDOPMCTRL1 0x72 140 #define BCM59056_MICLDOPMCTRL1 0x74 141 #define BCM59056_USBLDOPMCTRL1 0x76 142 #define BCM59056_VIBLDOPMCTRL1 0x78 143 #define BCM59056_IOSR1PMCTRL1 0x7a 144 #define BCM59056_IOSR2PMCTRL1 0x7c 145 #define BCM59056_CSRPMCTRL1 0x7e 146 #define BCM59056_SDSR1PMCTRL1 0x82 147 #define BCM59056_SDSR2PMCTRL1 0x86 148 #define BCM59056_MSRPMCTRL1 0x8a 149 #define BCM59056_VSRPMCTRL1 0x8e 150 #define BCM59056_RFLDOCTRL 0x96 151 #define BCM59056_CAMLDO1CTRL 0x97 152 #define BCM59056_CAMLDO2CTRL 0x98 153 #define BCM59056_SIMLDO1CTRL 0x99 154 #define BCM59056_SIMLDO2CTRL 0x9a 155 #define BCM59056_SDLDOCTRL 0x9b 156 #define BCM59056_SDXLDOCTRL 0x9c 157 #define BCM59056_MMCLDO1CTRL 0x9d 158 #define BCM59056_MMCLDO2CTRL 0x9e 159 #define BCM59056_AUDLDOCTRL 0x9f 160 #define BCM59056_MICLDOCTRL 0xa0 161 #define BCM59056_USBLDOCTRL 0xa1 162 #define BCM59056_VIBLDOCTRL 0xa2 163 #define BCM59056_CSRVOUT1 0xc0 164 #define BCM59056_IOSR1VOUT1 0xc3 165 #define BCM59056_IOSR2VOUT1 0xc6 166 #define BCM59056_MSRVOUT1 0xc9 167 #define BCM59056_SDSR1VOUT1 0xcc 168 #define BCM59056_SDSR2VOUT1 0xcf 169 #define BCM59056_VSRVOUT1 0xd2 170 171 /* I2C slave 1 registers */ 172 #define BCM59056_GPLDO5PMCTRL1 0x16 173 #define BCM59056_GPLDO6PMCTRL1 0x18 174 #define BCM59056_GPLDO1CTRL 0x1a 175 #define BCM59056_GPLDO2CTRL 0x1b 176 #define BCM59056_GPLDO3CTRL 0x1c 177 #define BCM59056_GPLDO4CTRL 0x1d 178 #define BCM59056_GPLDO5CTRL 0x1e 179 #define BCM59056_GPLDO6CTRL 0x1f 180 #define BCM59056_OTG_CTRL 0x40 181 #define BCM59056_GPLDO1PMCTRL1 0x57 182 #define BCM59056_GPLDO2PMCTRL1 0x59 183 #define BCM59056_GPLDO3PMCTRL1 0x5b 184 #define BCM59056_GPLDO4PMCTRL1 0x5d 185 186 /* 187 * RFLDO to VSR regulators are 188 * accessed via I2C slave 0 189 */ 190 191 /* LDO regulator IDs */ 192 #define BCM59056_REG_RFLDO 0 193 #define BCM59056_REG_CAMLDO1 1 194 #define BCM59056_REG_CAMLDO2 2 195 #define BCM59056_REG_SIMLDO1 3 196 #define BCM59056_REG_SIMLDO2 4 197 #define BCM59056_REG_SDLDO 5 198 #define BCM59056_REG_SDXLDO 6 199 #define BCM59056_REG_MMCLDO1 7 200 #define BCM59056_REG_MMCLDO2 8 201 #define BCM59056_REG_AUDLDO 9 202 #define BCM59056_REG_MICLDO 10 203 #define BCM59056_REG_USBLDO 11 204 #define BCM59056_REG_VIBLDO 12 205 206 /* DCDC regulator IDs */ 207 #define BCM59056_REG_CSR 13 208 #define BCM59056_REG_IOSR1 14 209 #define BCM59056_REG_IOSR2 15 210 #define BCM59056_REG_MSR 16 211 #define BCM59056_REG_SDSR1 17 212 #define BCM59056_REG_SDSR2 18 213 #define BCM59056_REG_VSR 19 214 215 /* 216 * GPLDO1 to VBUS regulators are 217 * accessed via I2C slave 1 218 */ 219 220 #define BCM59056_REG_GPLDO1 20 221 #define BCM59056_REG_GPLDO2 21 222 #define BCM59056_REG_GPLDO3 22 223 #define BCM59056_REG_GPLDO4 23 224 #define BCM59056_REG_GPLDO5 24 225 #define BCM59056_REG_GPLDO6 25 226 #define BCM59056_REG_VBUS 26 227 228 #define BCM59056_NUM_REGS 27 229 230 /* LDO group A: supported voltages in microvolts */ 231 static const unsigned int bcm59056_ldo_a_table[] = { 232 1200000, 1800000, 2500000, 2700000, 2800000, 233 2900000, 3000000, 3300000, 234 }; 235 236 /* LDO group C: supported voltages in microvolts */ 237 static const unsigned int bcm59056_ldo_c_table[] = { 238 3100000, 1800000, 2500000, 2700000, 2800000, 239 2900000, 3000000, 3300000, 240 }; 241 242 /* DCDC group CSR: supported voltages in microvolts */ 243 static const struct linear_range bcm59056_dcdc_csr_ranges[] = { 244 REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), 245 REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000), 246 REGULATOR_LINEAR_RANGE(900000, 56, 63, 0), 247 }; 248 249 /* DCDC group IOSR1: supported voltages in microvolts */ 250 static const struct linear_range bcm59056_dcdc_iosr1_ranges[] = { 251 REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000), 252 REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0), 253 REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0), 254 REGULATOR_LINEAR_RANGE(900000, 54, 63, 0), 255 }; 256 257 /* DCDC group SDSR1: supported voltages in microvolts */ 258 static const struct linear_range bcm59056_dcdc_sdsr1_ranges[] = { 259 REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), 260 REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0), 261 REGULATOR_LINEAR_RANGE(900000, 52, 63, 0), 262 }; 263 264 static const struct bcm590xx_reg_data bcm59056_regs[BCM59056_NUM_REGS] = { 265 { 266 .type = BCM590XX_REG_TYPE_LDO, 267 .regmap = BCM590XX_REGMAP_PRI, 268 .desc = { 269 BCM59056_LDO_DESC(RFLDO, rfldo, ldo_a_table), 270 }, 271 }, 272 273 { 274 .type = BCM590XX_REG_TYPE_LDO, 275 .regmap = BCM590XX_REGMAP_PRI, 276 .desc = { 277 BCM59056_LDO_DESC(CAMLDO1, camldo1, ldo_c_table), 278 }, 279 }, 280 281 { 282 .type = BCM590XX_REG_TYPE_LDO, 283 .regmap = BCM590XX_REGMAP_PRI, 284 .desc = { 285 BCM59056_LDO_DESC(CAMLDO2, camldo2, ldo_c_table), 286 }, 287 }, 288 289 { 290 .type = BCM590XX_REG_TYPE_LDO, 291 .regmap = BCM590XX_REGMAP_PRI, 292 .desc = { 293 BCM59056_LDO_DESC(SIMLDO1, simldo1, ldo_a_table), 294 }, 295 }, 296 297 { 298 .type = BCM590XX_REG_TYPE_LDO, 299 .regmap = BCM590XX_REGMAP_PRI, 300 .desc = { 301 BCM59056_LDO_DESC(SIMLDO2, simldo2, ldo_a_table), 302 }, 303 }, 304 305 { 306 .type = BCM590XX_REG_TYPE_LDO, 307 .regmap = BCM590XX_REGMAP_PRI, 308 .desc = { 309 BCM59056_LDO_DESC(SDLDO, sdldo, ldo_c_table), 310 }, 311 }, 312 313 { 314 .type = BCM590XX_REG_TYPE_LDO, 315 .regmap = BCM590XX_REGMAP_PRI, 316 .desc = { 317 BCM59056_LDO_DESC(SDXLDO, sdxldo, ldo_a_table), 318 }, 319 }, 320 321 { 322 .type = BCM590XX_REG_TYPE_LDO, 323 .regmap = BCM590XX_REGMAP_PRI, 324 .desc = { 325 BCM59056_LDO_DESC(MMCLDO1, mmcldo1, ldo_a_table), 326 }, 327 }, 328 329 { 330 .type = BCM590XX_REG_TYPE_LDO, 331 .regmap = BCM590XX_REGMAP_PRI, 332 .desc = { 333 BCM59056_LDO_DESC(MMCLDO2, mmcldo2, ldo_a_table), 334 }, 335 }, 336 337 { 338 .type = BCM590XX_REG_TYPE_LDO, 339 .regmap = BCM590XX_REGMAP_PRI, 340 .desc = { 341 BCM59056_LDO_DESC(AUDLDO, audldo, ldo_a_table), 342 }, 343 }, 344 345 { 346 .type = BCM590XX_REG_TYPE_LDO, 347 .regmap = BCM590XX_REGMAP_PRI, 348 .desc = { 349 BCM59056_LDO_DESC(MICLDO, micldo, ldo_a_table), 350 }, 351 }, 352 353 { 354 .type = BCM590XX_REG_TYPE_LDO, 355 .regmap = BCM590XX_REGMAP_PRI, 356 .desc = { 357 BCM59056_LDO_DESC(USBLDO, usbldo, ldo_a_table), 358 }, 359 }, 360 361 { 362 .type = BCM590XX_REG_TYPE_LDO, 363 .regmap = BCM590XX_REGMAP_PRI, 364 .desc = { 365 BCM59056_LDO_DESC(VIBLDO, vibldo, ldo_c_table), 366 }, 367 }, 368 369 { 370 .type = BCM590XX_REG_TYPE_SR, 371 .regmap = BCM590XX_REGMAP_PRI, 372 .desc = { 373 BCM59056_SR_DESC(CSR, csr, dcdc_csr_ranges), 374 }, 375 }, 376 377 { 378 .type = BCM590XX_REG_TYPE_SR, 379 .regmap = BCM590XX_REGMAP_PRI, 380 .desc = { 381 BCM59056_SR_DESC(IOSR1, iosr1, dcdc_iosr1_ranges), 382 }, 383 }, 384 385 { 386 .type = BCM590XX_REG_TYPE_SR, 387 .regmap = BCM590XX_REGMAP_PRI, 388 .desc = { 389 BCM59056_SR_DESC(IOSR2, iosr2, dcdc_iosr1_ranges), 390 }, 391 }, 392 393 { 394 .type = BCM590XX_REG_TYPE_SR, 395 .regmap = BCM590XX_REGMAP_PRI, 396 .desc = { 397 BCM59056_SR_DESC(MSR, msr, dcdc_iosr1_ranges), 398 }, 399 }, 400 401 { 402 .type = BCM590XX_REG_TYPE_SR, 403 .regmap = BCM590XX_REGMAP_PRI, 404 .desc = { 405 BCM59056_SR_DESC(SDSR1, sdsr1, dcdc_sdsr1_ranges), 406 }, 407 }, 408 409 { 410 .type = BCM590XX_REG_TYPE_SR, 411 .regmap = BCM590XX_REGMAP_PRI, 412 .desc = { 413 BCM59056_SR_DESC(SDSR2, sdsr2, dcdc_iosr1_ranges), 414 }, 415 }, 416 417 { 418 .type = BCM590XX_REG_TYPE_SR, 419 .regmap = BCM590XX_REGMAP_PRI, 420 .desc = { 421 BCM59056_SR_DESC(VSR, vsr, dcdc_iosr1_ranges), 422 }, 423 }, 424 425 { 426 .type = BCM590XX_REG_TYPE_GPLDO, 427 .regmap = BCM590XX_REGMAP_SEC, 428 .desc = { 429 BCM59056_LDO_DESC(GPLDO1, gpldo1, ldo_a_table), 430 }, 431 }, 432 433 { 434 .type = BCM590XX_REG_TYPE_GPLDO, 435 .regmap = BCM590XX_REGMAP_SEC, 436 .desc = { 437 BCM59056_LDO_DESC(GPLDO2, gpldo2, ldo_a_table), 438 }, 439 }, 440 441 { 442 .type = BCM590XX_REG_TYPE_GPLDO, 443 .regmap = BCM590XX_REGMAP_SEC, 444 .desc = { 445 BCM59056_LDO_DESC(GPLDO3, gpldo3, ldo_a_table), 446 }, 447 }, 448 449 { 450 .type = BCM590XX_REG_TYPE_GPLDO, 451 .regmap = BCM590XX_REGMAP_SEC, 452 .desc = { 453 BCM59056_LDO_DESC(GPLDO4, gpldo4, ldo_a_table), 454 }, 455 }, 456 457 { 458 .type = BCM590XX_REG_TYPE_GPLDO, 459 .regmap = BCM590XX_REGMAP_SEC, 460 .desc = { 461 BCM59056_LDO_DESC(GPLDO5, gpldo5, ldo_a_table), 462 }, 463 }, 464 465 { 466 .type = BCM590XX_REG_TYPE_GPLDO, 467 .regmap = BCM590XX_REGMAP_SEC, 468 .desc = { 469 BCM59056_LDO_DESC(GPLDO6, gpldo6, ldo_a_table), 470 }, 471 }, 472 473 { 474 .type = BCM590XX_REG_TYPE_VBUS, 475 .regmap = BCM590XX_REGMAP_SEC, 476 .desc = { 477 BCM59056_REG_DESC(VBUS, vbus), 478 .ops = &bcm590xx_ops_vbus, 479 .n_voltages = 1, 480 .fixed_uV = 5000000, 481 .enable_reg = BCM59056_OTG_CTRL, 482 .enable_mask = BCM590XX_VBUS_ENABLE, 483 }, 484 }, 485 }; 486 487 /* BCM59054 data */ 488 489 /* I2C slave 0 registers */ 490 #define BCM59054_RFLDOPMCTRL1 0x60 491 #define BCM59054_CAMLDO1PMCTRL1 0x62 492 #define BCM59054_CAMLDO2PMCTRL1 0x64 493 #define BCM59054_SIMLDO1PMCTRL1 0x66 494 #define BCM59054_SIMLDO2PMCTRL1 0x68 495 #define BCM59054_SDLDOPMCTRL1 0x6a 496 #define BCM59054_SDXLDOPMCTRL1 0x6c 497 #define BCM59054_MMCLDO1PMCTRL1 0x6e 498 #define BCM59054_MMCLDO2PMCTRL1 0x70 499 #define BCM59054_AUDLDOPMCTRL1 0x72 500 #define BCM59054_MICLDOPMCTRL1 0x74 501 #define BCM59054_USBLDOPMCTRL1 0x76 502 #define BCM59054_VIBLDOPMCTRL1 0x78 503 #define BCM59054_IOSR1PMCTRL1 0x7a 504 #define BCM59054_IOSR2PMCTRL1 0x7c 505 #define BCM59054_CSRPMCTRL1 0x7e 506 #define BCM59054_SDSR1PMCTRL1 0x82 507 #define BCM59054_SDSR2PMCTRL1 0x86 508 #define BCM59054_MMSRPMCTRL1 0x8a 509 #define BCM59054_VSRPMCTRL1 0x8e 510 #define BCM59054_RFLDOCTRL 0x96 511 #define BCM59054_CAMLDO1CTRL 0x97 512 #define BCM59054_CAMLDO2CTRL 0x98 513 #define BCM59054_SIMLDO1CTRL 0x99 514 #define BCM59054_SIMLDO2CTRL 0x9a 515 #define BCM59054_SDLDOCTRL 0x9b 516 #define BCM59054_SDXLDOCTRL 0x9c 517 #define BCM59054_MMCLDO1CTRL 0x9d 518 #define BCM59054_MMCLDO2CTRL 0x9e 519 #define BCM59054_AUDLDOCTRL 0x9f 520 #define BCM59054_MICLDOCTRL 0xa0 521 #define BCM59054_USBLDOCTRL 0xa1 522 #define BCM59054_VIBLDOCTRL 0xa2 523 #define BCM59054_CSRVOUT1 0xc0 524 #define BCM59054_IOSR1VOUT1 0xc3 525 #define BCM59054_IOSR2VOUT1 0xc6 526 #define BCM59054_MMSRVOUT1 0xc9 527 #define BCM59054_SDSR1VOUT1 0xcc 528 #define BCM59054_SDSR2VOUT1 0xcf 529 #define BCM59054_VSRVOUT1 0xd2 530 531 /* I2C slave 1 registers */ 532 #define BCM59054_LVLDO1PMCTRL1 0x16 533 #define BCM59054_LVLDO2PMCTRL1 0x18 534 #define BCM59054_GPLDO1CTRL 0x1a 535 #define BCM59054_GPLDO2CTRL 0x1b 536 #define BCM59054_GPLDO3CTRL 0x1c 537 #define BCM59054_TCXLDOCTRL 0x1d 538 #define BCM59054_LVLDO1CTRL 0x1e 539 #define BCM59054_LVLDO2CTRL 0x1f 540 #define BCM59054_OTG_CTRL 0x40 541 #define BCM59054_GPLDO1PMCTRL1 0x57 542 #define BCM59054_GPLDO2PMCTRL1 0x59 543 #define BCM59054_GPLDO3PMCTRL1 0x5b 544 #define BCM59054_TCXLDOPMCTRL1 0x5d 545 546 /* 547 * RFLDO to VSR regulators are 548 * accessed via I2C slave 0 549 */ 550 551 /* LDO regulator IDs */ 552 #define BCM59054_REG_RFLDO 0 553 #define BCM59054_REG_CAMLDO1 1 554 #define BCM59054_REG_CAMLDO2 2 555 #define BCM59054_REG_SIMLDO1 3 556 #define BCM59054_REG_SIMLDO2 4 557 #define BCM59054_REG_SDLDO 5 558 #define BCM59054_REG_SDXLDO 6 559 #define BCM59054_REG_MMCLDO1 7 560 #define BCM59054_REG_MMCLDO2 8 561 #define BCM59054_REG_AUDLDO 9 562 #define BCM59054_REG_MICLDO 10 563 #define BCM59054_REG_USBLDO 11 564 #define BCM59054_REG_VIBLDO 12 565 566 /* DCDC regulator IDs */ 567 #define BCM59054_REG_CSR 13 568 #define BCM59054_REG_IOSR1 14 569 #define BCM59054_REG_IOSR2 15 570 #define BCM59054_REG_MMSR 16 571 #define BCM59054_REG_SDSR1 17 572 #define BCM59054_REG_SDSR2 18 573 #define BCM59054_REG_VSR 19 574 575 /* 576 * GPLDO1 to VBUS regulators are 577 * accessed via I2C slave 1 578 */ 579 580 #define BCM59054_REG_GPLDO1 20 581 #define BCM59054_REG_GPLDO2 21 582 #define BCM59054_REG_GPLDO3 22 583 #define BCM59054_REG_TCXLDO 23 584 #define BCM59054_REG_LVLDO1 24 585 #define BCM59054_REG_LVLDO2 25 586 #define BCM59054_REG_VBUS 26 587 588 #define BCM59054_NUM_REGS 27 589 590 /* LDO group 1: supported voltages in microvolts */ 591 static const unsigned int bcm59054_ldo_1_table[] = { 592 1200000, 1800000, 2500000, 2700000, 2800000, 593 2900000, 3000000, 3300000, 594 }; 595 596 /* LDO group 2: supported voltages in microvolts */ 597 static const unsigned int bcm59054_ldo_2_table[] = { 598 3100000, 1800000, 2500000, 2700000, 2800000, 599 2900000, 3000000, 3300000, 600 }; 601 602 /* LDO group 3: supported voltages in microvolts */ 603 static const unsigned int bcm59054_ldo_3_table[] = { 604 1000000, 1107000, 1143000, 1214000, 1250000, 605 1464000, 1500000, 1786000, 606 }; 607 608 /* DCDC group SR: supported voltages in microvolts */ 609 static const struct linear_range bcm59054_dcdc_sr_ranges[] = { 610 REGULATOR_LINEAR_RANGE(0, 0, 1, 0), 611 REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000), 612 REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0), 613 REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0), 614 REGULATOR_LINEAR_RANGE(900000, 63, 63, 0), 615 }; 616 617 /* DCDC group VSR (BCM59054A1): supported voltages in microvolts */ 618 static const struct linear_range bcm59054_dcdc_vsr_a1_ranges[] = { 619 REGULATOR_LINEAR_RANGE(0, 0, 1, 0), 620 REGULATOR_LINEAR_RANGE(860000, 2, 59, 10000), 621 REGULATOR_LINEAR_RANGE(1700000, 60, 60, 0), 622 REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0), 623 REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0), 624 REGULATOR_LINEAR_RANGE(1600000, 63, 63, 0), 625 }; 626 627 /* DCDC group CSR: supported voltages in microvolts */ 628 static const struct linear_range bcm59054_dcdc_csr_ranges[] = { 629 REGULATOR_LINEAR_RANGE(700000, 0, 1, 100000), 630 REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000), 631 REGULATOR_LINEAR_RANGE(900000, 61, 63, 0), 632 }; 633 634 static const struct bcm590xx_reg_data bcm59054_regs[BCM59054_NUM_REGS] = { 635 { 636 .type = BCM590XX_REG_TYPE_LDO, 637 .regmap = BCM590XX_REGMAP_PRI, 638 .desc = { 639 BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table), 640 }, 641 }, 642 643 { 644 .type = BCM590XX_REG_TYPE_LDO, 645 .regmap = BCM590XX_REGMAP_PRI, 646 .desc = { 647 BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table), 648 }, 649 }, 650 651 { 652 .type = BCM590XX_REG_TYPE_LDO, 653 .regmap = BCM590XX_REGMAP_PRI, 654 .desc = { 655 BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table), 656 }, 657 }, 658 659 { 660 .type = BCM590XX_REG_TYPE_LDO, 661 .regmap = BCM590XX_REGMAP_PRI, 662 .desc = { 663 BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table), 664 }, 665 }, 666 667 { 668 .type = BCM590XX_REG_TYPE_LDO, 669 .regmap = BCM590XX_REGMAP_PRI, 670 .desc = { 671 BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table), 672 }, 673 }, 674 675 { 676 .type = BCM590XX_REG_TYPE_LDO, 677 .regmap = BCM590XX_REGMAP_PRI, 678 .desc = { 679 BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table), 680 }, 681 }, 682 683 { 684 .type = BCM590XX_REG_TYPE_LDO, 685 .regmap = BCM590XX_REGMAP_PRI, 686 .desc = { 687 BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table), 688 }, 689 }, 690 691 { 692 .type = BCM590XX_REG_TYPE_LDO, 693 .regmap = BCM590XX_REGMAP_PRI, 694 .desc = { 695 BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table), 696 }, 697 }, 698 699 { 700 .type = BCM590XX_REG_TYPE_LDO, 701 .regmap = BCM590XX_REGMAP_PRI, 702 .desc = { 703 BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table), 704 }, 705 }, 706 707 { 708 .type = BCM590XX_REG_TYPE_LDO, 709 .regmap = BCM590XX_REGMAP_PRI, 710 .desc = { 711 BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table), 712 }, 713 }, 714 715 { 716 .type = BCM590XX_REG_TYPE_LDO, 717 .regmap = BCM590XX_REGMAP_PRI, 718 .desc = { 719 BCM59054_REG_DESC(MICLDO, micldo), 720 .ops = &bcm590xx_ops_ldo_novolt, 721 /* MICLDO is locked at 1.8V */ 722 .n_voltages = 1, 723 .fixed_uV = 1800000, 724 .enable_reg = BCM59054_MICLDOPMCTRL1, 725 .enable_mask = BCM590XX_REG_ENABLE, 726 .enable_is_inverted = true, 727 }, 728 }, 729 730 { 731 .type = BCM590XX_REG_TYPE_LDO, 732 .regmap = BCM590XX_REGMAP_PRI, 733 .desc = { 734 BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table), 735 }, 736 }, 737 738 { 739 .type = BCM590XX_REG_TYPE_LDO, 740 .regmap = BCM590XX_REGMAP_PRI, 741 .desc = { 742 BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table), 743 }, 744 }, 745 746 { 747 .type = BCM590XX_REG_TYPE_SR, 748 .regmap = BCM590XX_REGMAP_PRI, 749 .desc = { 750 BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges), 751 }, 752 }, 753 754 { 755 .type = BCM590XX_REG_TYPE_SR, 756 .regmap = BCM590XX_REGMAP_PRI, 757 .desc = { 758 BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges), 759 }, 760 }, 761 762 { 763 .type = BCM590XX_REG_TYPE_SR, 764 .regmap = BCM590XX_REGMAP_PRI, 765 .desc = { 766 BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges), 767 }, 768 }, 769 770 { 771 .type = BCM590XX_REG_TYPE_SR, 772 .regmap = BCM590XX_REGMAP_PRI, 773 .desc = { 774 BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges), 775 }, 776 }, 777 778 { 779 .type = BCM590XX_REG_TYPE_SR, 780 .regmap = BCM590XX_REGMAP_PRI, 781 .desc = { 782 BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges), 783 }, 784 }, 785 786 { 787 .type = BCM590XX_REG_TYPE_SR, 788 .regmap = BCM590XX_REGMAP_PRI, 789 .desc = { 790 BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges), 791 }, 792 }, 793 794 { 795 .type = BCM590XX_REG_TYPE_SR, 796 .regmap = BCM590XX_REGMAP_PRI, 797 .desc = { 798 BCM59054_SR_DESC(VSR, vsr, dcdc_sr_ranges), 799 }, 800 }, 801 802 { 803 .type = BCM590XX_REG_TYPE_GPLDO, 804 .regmap = BCM590XX_REGMAP_SEC, 805 .desc = { 806 BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table), 807 }, 808 }, 809 810 { 811 .type = BCM590XX_REG_TYPE_GPLDO, 812 .regmap = BCM590XX_REGMAP_SEC, 813 .desc = { 814 BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table), 815 }, 816 }, 817 818 { 819 .type = BCM590XX_REG_TYPE_GPLDO, 820 .regmap = BCM590XX_REGMAP_SEC, 821 .desc = { 822 BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table), 823 }, 824 }, 825 826 { 827 .type = BCM590XX_REG_TYPE_GPLDO, 828 .regmap = BCM590XX_REGMAP_SEC, 829 .desc = { 830 BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table), 831 }, 832 }, 833 834 { 835 .type = BCM590XX_REG_TYPE_GPLDO, 836 .regmap = BCM590XX_REGMAP_SEC, 837 .desc = { 838 BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table), 839 }, 840 }, 841 842 { 843 .type = BCM590XX_REG_TYPE_GPLDO, 844 .regmap = BCM590XX_REGMAP_SEC, 845 .desc = { 846 BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table), 847 }, 848 }, 849 850 { 851 .type = BCM590XX_REG_TYPE_VBUS, 852 .regmap = BCM590XX_REGMAP_SEC, 853 .desc = { 854 BCM59054_REG_DESC(VBUS, vbus), 855 .ops = &bcm590xx_ops_vbus, 856 .n_voltages = 1, 857 .fixed_uV = 5000000, 858 .enable_reg = BCM59054_OTG_CTRL, 859 .enable_mask = BCM590XX_VBUS_ENABLE, 860 }, 861 }, 862 }; 863 864 /* 865 * BCM59054A1 regulators; same as previous revision, but with different 866 * VSR voltage table. 867 */ 868 static const struct bcm590xx_reg_data bcm59054_a1_regs[BCM59054_NUM_REGS] = { 869 { 870 .type = BCM590XX_REG_TYPE_LDO, 871 .regmap = BCM590XX_REGMAP_PRI, 872 .desc = { 873 BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table), 874 }, 875 }, 876 877 { 878 .type = BCM590XX_REG_TYPE_LDO, 879 .regmap = BCM590XX_REGMAP_PRI, 880 .desc = { 881 BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table), 882 }, 883 }, 884 885 { 886 .type = BCM590XX_REG_TYPE_LDO, 887 .regmap = BCM590XX_REGMAP_PRI, 888 .desc = { 889 BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table), 890 }, 891 }, 892 893 { 894 .type = BCM590XX_REG_TYPE_LDO, 895 .regmap = BCM590XX_REGMAP_PRI, 896 .desc = { 897 BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table), 898 }, 899 }, 900 901 { 902 .type = BCM590XX_REG_TYPE_LDO, 903 .regmap = BCM590XX_REGMAP_PRI, 904 .desc = { 905 BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table), 906 }, 907 }, 908 909 { 910 .type = BCM590XX_REG_TYPE_LDO, 911 .regmap = BCM590XX_REGMAP_PRI, 912 .desc = { 913 BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table), 914 }, 915 }, 916 917 { 918 .type = BCM590XX_REG_TYPE_LDO, 919 .regmap = BCM590XX_REGMAP_PRI, 920 .desc = { 921 BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table), 922 }, 923 }, 924 925 { 926 .type = BCM590XX_REG_TYPE_LDO, 927 .regmap = BCM590XX_REGMAP_PRI, 928 .desc = { 929 BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table), 930 }, 931 }, 932 933 { 934 .type = BCM590XX_REG_TYPE_LDO, 935 .regmap = BCM590XX_REGMAP_PRI, 936 .desc = { 937 BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table), 938 }, 939 }, 940 941 { 942 .type = BCM590XX_REG_TYPE_LDO, 943 .regmap = BCM590XX_REGMAP_PRI, 944 .desc = { 945 BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table), 946 }, 947 }, 948 949 { 950 .type = BCM590XX_REG_TYPE_LDO, 951 .regmap = BCM590XX_REGMAP_PRI, 952 .desc = { 953 BCM59054_REG_DESC(MICLDO, micldo), 954 .ops = &bcm590xx_ops_ldo_novolt, 955 /* MICLDO is locked at 1.8V */ 956 .n_voltages = 1, 957 .fixed_uV = 1800000, 958 .enable_reg = BCM59054_MICLDOPMCTRL1, 959 .enable_mask = BCM590XX_REG_ENABLE, 960 .enable_is_inverted = true, 961 }, 962 }, 963 964 { 965 .type = BCM590XX_REG_TYPE_LDO, 966 .regmap = BCM590XX_REGMAP_PRI, 967 .desc = { 968 BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table), 969 }, 970 }, 971 972 { 973 .type = BCM590XX_REG_TYPE_LDO, 974 .regmap = BCM590XX_REGMAP_PRI, 975 .desc = { 976 BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table), 977 }, 978 }, 979 980 { 981 .type = BCM590XX_REG_TYPE_SR, 982 .regmap = BCM590XX_REGMAP_PRI, 983 .desc = { 984 BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges), 985 }, 986 }, 987 988 { 989 .type = BCM590XX_REG_TYPE_SR, 990 .regmap = BCM590XX_REGMAP_PRI, 991 .desc = { 992 BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges), 993 }, 994 }, 995 996 { 997 .type = BCM590XX_REG_TYPE_SR, 998 .regmap = BCM590XX_REGMAP_PRI, 999 .desc = { 1000 BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges), 1001 }, 1002 }, 1003 1004 { 1005 .type = BCM590XX_REG_TYPE_SR, 1006 .regmap = BCM590XX_REGMAP_PRI, 1007 .desc = { 1008 BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges), 1009 }, 1010 }, 1011 1012 { 1013 .type = BCM590XX_REG_TYPE_SR, 1014 .regmap = BCM590XX_REGMAP_PRI, 1015 .desc = { 1016 BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges), 1017 }, 1018 }, 1019 1020 { 1021 .type = BCM590XX_REG_TYPE_SR, 1022 .regmap = BCM590XX_REGMAP_PRI, 1023 .desc = { 1024 BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges), 1025 }, 1026 }, 1027 1028 { 1029 .type = BCM590XX_REG_TYPE_SR, 1030 .regmap = BCM590XX_REGMAP_PRI, 1031 .desc = { 1032 BCM59054_SR_DESC(VSR, vsr, dcdc_vsr_a1_ranges), 1033 }, 1034 }, 1035 1036 { 1037 .type = BCM590XX_REG_TYPE_GPLDO, 1038 .regmap = BCM590XX_REGMAP_SEC, 1039 .desc = { 1040 BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table), 1041 }, 1042 }, 1043 1044 { 1045 .type = BCM590XX_REG_TYPE_GPLDO, 1046 .regmap = BCM590XX_REGMAP_SEC, 1047 .desc = { 1048 BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table), 1049 }, 1050 }, 1051 1052 { 1053 .type = BCM590XX_REG_TYPE_GPLDO, 1054 .regmap = BCM590XX_REGMAP_SEC, 1055 .desc = { 1056 BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table), 1057 }, 1058 }, 1059 1060 { 1061 .type = BCM590XX_REG_TYPE_GPLDO, 1062 .regmap = BCM590XX_REGMAP_SEC, 1063 .desc = { 1064 BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table), 1065 }, 1066 }, 1067 1068 { 1069 .type = BCM590XX_REG_TYPE_GPLDO, 1070 .regmap = BCM590XX_REGMAP_SEC, 1071 .desc = { 1072 BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table), 1073 }, 1074 }, 1075 1076 { 1077 .type = BCM590XX_REG_TYPE_GPLDO, 1078 .regmap = BCM590XX_REGMAP_SEC, 1079 .desc = { 1080 BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table), 1081 }, 1082 }, 1083 1084 { 1085 .type = BCM590XX_REG_TYPE_VBUS, 1086 .regmap = BCM590XX_REGMAP_SEC, 1087 .desc = { 1088 BCM59054_REG_DESC(VBUS, vbus), 1089 .ops = &bcm590xx_ops_vbus, 1090 .n_voltages = 1, 1091 .fixed_uV = 5000000, 1092 .enable_reg = BCM59054_OTG_CTRL, 1093 .enable_mask = BCM590XX_VBUS_ENABLE, 1094 }, 1095 }, 1096 }; 1097 1098 static int bcm590xx_probe(struct platform_device *pdev) 1099 { 1100 struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent); 1101 struct bcm590xx_reg *pmu; 1102 const struct bcm590xx_reg_data *info; 1103 struct regulator_config config = { }; 1104 struct regulator_dev *rdev; 1105 unsigned int i; 1106 1107 pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); 1108 if (!pmu) 1109 return -ENOMEM; 1110 1111 pmu->mfd = bcm590xx; 1112 1113 switch (pmu->mfd->pmu_id) { 1114 case BCM590XX_PMUID_BCM59054: 1115 pmu->n_regulators = BCM59054_NUM_REGS; 1116 if (pmu->mfd->rev_analog == BCM59054_REV_ANALOG_A1) 1117 pmu->regs = bcm59054_a1_regs; 1118 else 1119 pmu->regs = bcm59054_regs; 1120 break; 1121 case BCM590XX_PMUID_BCM59056: 1122 pmu->n_regulators = BCM59056_NUM_REGS; 1123 pmu->regs = bcm59056_regs; 1124 break; 1125 default: 1126 dev_err(bcm590xx->dev, 1127 "unknown device type, could not initialize\n"); 1128 return -EINVAL; 1129 } 1130 1131 platform_set_drvdata(pdev, pmu); 1132 1133 /* Register the regulators */ 1134 for (i = 0; i < pmu->n_regulators; i++) { 1135 info = &pmu->regs[i]; 1136 1137 config.dev = bcm590xx->dev; 1138 config.driver_data = pmu; 1139 1140 switch (info->regmap) { 1141 case BCM590XX_REGMAP_PRI: 1142 config.regmap = bcm590xx->regmap_pri; 1143 break; 1144 case BCM590XX_REGMAP_SEC: 1145 config.regmap = bcm590xx->regmap_sec; 1146 break; 1147 default: 1148 dev_err(bcm590xx->dev, 1149 "invalid regmap for %s regulator; this is a driver bug\n", 1150 pdev->name); 1151 return -EINVAL; 1152 } 1153 1154 rdev = devm_regulator_register(&pdev->dev, &info->desc, 1155 &config); 1156 if (IS_ERR(rdev)) 1157 return dev_err_probe(bcm590xx->dev, PTR_ERR(rdev), 1158 "failed to register %s regulator\n", 1159 pdev->name); 1160 } 1161 1162 return 0; 1163 } 1164 1165 static struct platform_driver bcm590xx_regulator_driver = { 1166 .driver = { 1167 .name = "bcm590xx-vregs", 1168 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 1169 }, 1170 .probe = bcm590xx_probe, 1171 }; 1172 module_platform_driver(bcm590xx_regulator_driver); 1173 1174 MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); 1175 MODULE_DESCRIPTION("BCM590xx voltage regulator driver"); 1176 MODULE_LICENSE("GPL v2"); 1177 MODULE_ALIAS("platform:bcm590xx-vregs"); 1178