Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 1177 lines 28 kB view raw
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 26enum 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 33struct bcm590xx_reg_data { 34 enum bcm590xx_reg_type type; 35 enum bcm590xx_regmap_type regmap; 36 const struct regulator_desc desc; 37}; 38 39struct bcm590xx_reg { 40 struct bcm590xx *mfd; 41 unsigned int n_regulators; 42 const struct bcm590xx_reg_data *regs; 43}; 44 45static 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 */ 60static 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 66static 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 76static 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 */ 231static 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 */ 237static 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 */ 243static 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 */ 250static 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 */ 258static 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 264static 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 */ 591static 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 */ 597static 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 */ 603static 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 */ 609static 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 */ 618static 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 */ 628static 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 634static 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 */ 868static 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 1098static 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 1165static struct platform_driver bcm590xx_regulator_driver = { 1166 .driver = { 1167 .name = "bcm590xx-vregs", 1168 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 1169 }, 1170 .probe = bcm590xx_probe, 1171}; 1172module_platform_driver(bcm590xx_regulator_driver); 1173 1174MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); 1175MODULE_DESCRIPTION("BCM590xx voltage regulator driver"); 1176MODULE_LICENSE("GPL v2"); 1177MODULE_ALIAS("platform:bcm590xx-vregs");