diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-07 11:35:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-07 11:35:35 -0400 |
commit | d042380886fb2fc6c4b0fcfe1214ba473769a8e9 (patch) | |
tree | 61e29ff167e0f83f67930ee9911062415030e1ef /drivers/regulator | |
parent | 3477d168ba61c5b0ca42d3d4642f3463609a5417 (diff) | |
parent | b8d336ed90f541097a2ce583be430bb3e895dfbd (diff) |
Merge tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"Core framework:
- Add the MFD bindings doc to MAINTAINERS
New drivers:
- X-Powers AC100 Audio CODEC and RTC
- TI LP873x PMIC
- Rockchip RK808 PMIC
- Samsung Exynos Low Power Audio
New device support:
- Add support for STMPE1600 variant to stmpe
- Add support for PM8018 PMIC to pm8921-core
- Add support for AXP806 PMIC in axp20x
- Add support for AXP209 GPIO in axp20x
New functionality:
- Add support for Reset to all STMPE variants
- Add support for MKBP event support to cros_ec
- Add support for USB to intel_soc_pmic_bxtwc
- Add support for IRQs and Power Button to tps65217
Fix-ups:
- Clean-up defunct author emails (da9063, max14577)
- Kconfig fixups (wm8350-i2c, as37220
- Constify (altera-a10sr, sm501)
- Supply PCI IDs (intel-lpss-pci)
- Improve clocking (qcom_rpm)
- Fix IRQ probing (ucb1x00-core)
- Ensure fault log is cleared (da9052)
- Remove NO_IRQ check (ucb1x00-core)
- Supply I2C properties (intel-lpss-acpi, intel-lpss-pci)
- Non standard declaration (tps65217, max8997-irq)
- Remove unused code (lp873x, db8500-prcmu, ab8500-debugfs,
cros_ec_spi)
- Make non-modular (altera-a10sr, intel_msic, smsc-ece1099,
sun6i-prcm, twl-core)
- OF bindings (ac100, stmpe, qcom-pm8xxx, qcom-rpm, rk808, axp20x,
lp873x, exynos5433-lpass, act8945a, aspeed-scu, twl6040, arizona)
Bugfixes:
- Release OF pointer (qcom_rpm)
- Avoid double shifting in suspend/resume (88pm80x)
- Fix 'defined but not used' error (exynos-lpass)
- Fix 'sleeping whilst attomic' (atmel-hlcdc)"
* tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits)
mfd: arizona: Handle probe deferral for reset GPIO
mfd: arizona: Remove arizona_of_get_named_gpio helper function
mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config
mfd: twl6040: Register child device for twl6040-pdmclk
mfd: cros_ec_spi: Remove unused variable 'request'
mfd: omap-usb-host: Return value is not 'const int'
mfd: ab8500-debugfs: Remove 'weak' function suspend_test_wake_cause_interrupt_is_mine()
mfd: ab8500-debugfs: Remove ab8500_dump_all_banks_to_mem()
mfd: db8500-prcmu: Remove unused *prcmu_set_ddr_opp() calls
mfd: ab8500-debugfs: Prevent initialised field from being over-written
mfd: max8997-irq: 'inline' should be at the beginning of the declaration
mfd: rk808: Fix RK818_IRQ_DISCHG_ILIM initializer
mfd: tps65217: Fix nonstandard declaration
mfd: lp873x: Remove unused mutex lock from struct lp873x
mfd: atmel-hlcdc: Do not sleep in atomic context
mfd: exynos-lpass: Mark PM functions as __maybe_unused
mfd: intel-lpss: Add default I2C device properties for Apollo Lake
mfd: twl-core: Make it explicitly non-modular
mfd: sun6i-prcm: Make it explicitly non-modular
mfd: smsc-ece1099: Make it explicitly non-modular
...
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/Kconfig | 4 | ||||
-rw-r--r-- | drivers/regulator/axp20x-regulator.c | 118 | ||||
-rw-r--r-- | drivers/regulator/qcom_rpm-regulator.c | 66 | ||||
-rw-r--r-- | drivers/regulator/rk808-regulator.c | 143 |
4 files changed, 315 insertions, 16 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 06c75186af80..936f7ccc9736 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -643,11 +643,11 @@ config REGULATOR_RC5T583 | |||
643 | outputs which can be controlled by i2c communication. | 643 | outputs which can be controlled by i2c communication. |
644 | 644 | ||
645 | config REGULATOR_RK808 | 645 | config REGULATOR_RK808 |
646 | tristate "Rockchip RK808 Power regulators" | 646 | tristate "Rockchip RK808/RK818 Power regulators" |
647 | depends on MFD_RK808 | 647 | depends on MFD_RK808 |
648 | help | 648 | help |
649 | Select this option to enable the power regulator of ROCKCHIP | 649 | Select this option to enable the power regulator of ROCKCHIP |
650 | PMIC RK808. | 650 | PMIC RK808 and RK818. |
651 | This driver supports the control of different power rails of device | 651 | This driver supports the control of different power rails of device |
652 | through regulator interface. The device supports multiple DCDC/LDO | 652 | through regulator interface. The device supports multiple DCDC/LDO |
653 | outputs which can be controlled by i2c communication. | 653 | outputs which can be controlled by i2c communication. |
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 6d9ac76a772f..54382ef902c6 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c | |||
@@ -244,16 +244,64 @@ static const struct regulator_desc axp22x_drivevbus_regulator = { | |||
244 | .ops = &axp20x_ops_sw, | 244 | .ops = &axp20x_ops_sw, |
245 | }; | 245 | }; |
246 | 246 | ||
247 | static const struct regulator_linear_range axp809_dcdc4_ranges[] = { | 247 | static const struct regulator_linear_range axp806_dcdca_ranges[] = { |
248 | REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000), | 248 | REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000), |
249 | REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000), | 249 | REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000), |
250 | }; | 250 | }; |
251 | 251 | ||
252 | static const struct regulator_linear_range axp809_dldo1_ranges[] = { | 252 | static const struct regulator_linear_range axp806_dcdcd_ranges[] = { |
253 | REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2d, 20000), | ||
254 | REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000), | ||
255 | }; | ||
256 | |||
257 | static const struct regulator_linear_range axp806_cldo2_ranges[] = { | ||
253 | REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000), | 258 | REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000), |
254 | REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000), | 259 | REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000), |
255 | }; | 260 | }; |
256 | 261 | ||
262 | static const struct regulator_desc axp806_regulators[] = { | ||
263 | AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges, | ||
264 | 72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1, | ||
265 | BIT(0)), | ||
266 | AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50, | ||
267 | AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(1)), | ||
268 | AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc", axp806_dcdca_ranges, | ||
269 | 72, AXP806_DCDCC_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1, | ||
270 | BIT(2)), | ||
271 | AXP_DESC_RANGES(AXP806, DCDCD, "dcdcd", "vind", axp806_dcdcd_ranges, | ||
272 | 64, AXP806_DCDCD_V_CTRL, 0x3f, AXP806_PWR_OUT_CTRL1, | ||
273 | BIT(3)), | ||
274 | AXP_DESC(AXP806, DCDCE, "dcdce", "vine", 1100, 3400, 100, | ||
275 | AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(4)), | ||
276 | AXP_DESC(AXP806, ALDO1, "aldo1", "aldoin", 700, 3300, 100, | ||
277 | AXP806_ALDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(5)), | ||
278 | AXP_DESC(AXP806, ALDO2, "aldo2", "aldoin", 700, 3400, 100, | ||
279 | AXP806_ALDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(6)), | ||
280 | AXP_DESC(AXP806, ALDO3, "aldo3", "aldoin", 700, 3300, 100, | ||
281 | AXP806_ALDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(7)), | ||
282 | AXP_DESC(AXP806, BLDO1, "bldo1", "bldoin", 700, 1900, 100, | ||
283 | AXP806_BLDO1_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(0)), | ||
284 | AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100, | ||
285 | AXP806_BLDO2_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(1)), | ||
286 | AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100, | ||
287 | AXP806_BLDO3_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(2)), | ||
288 | AXP_DESC(AXP806, BLDO4, "bldo4", "bldoin", 700, 1900, 100, | ||
289 | AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)), | ||
290 | AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100, | ||
291 | AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)), | ||
292 | AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp806_cldo2_ranges, | ||
293 | 32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, | ||
294 | BIT(5)), | ||
295 | AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100, | ||
296 | AXP806_CLDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(6)), | ||
297 | AXP_DESC_SW(AXP806, SW, "sw", "swin", AXP806_PWR_OUT_CTRL2, BIT(7)), | ||
298 | }; | ||
299 | |||
300 | static const struct regulator_linear_range axp809_dcdc4_ranges[] = { | ||
301 | REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000), | ||
302 | REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000), | ||
303 | }; | ||
304 | |||
257 | static const struct regulator_desc axp809_regulators[] = { | 305 | static const struct regulator_desc axp809_regulators[] = { |
258 | AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100, | 306 | AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100, |
259 | AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)), | 307 | AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)), |
@@ -278,7 +326,7 @@ static const struct regulator_desc axp809_regulators[] = { | |||
278 | AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)), | 326 | AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)), |
279 | AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100, | 327 | AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100, |
280 | AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)), | 328 | AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)), |
281 | AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp809_dldo1_ranges, | 329 | AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp806_cldo2_ranges, |
282 | 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, | 330 | 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, |
283 | BIT(3)), | 331 | BIT(3)), |
284 | AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100, | 332 | AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100, |
@@ -302,6 +350,7 @@ static const struct regulator_desc axp809_regulators[] = { | |||
302 | static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) | 350 | static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) |
303 | { | 351 | { |
304 | struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); | 352 | struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); |
353 | unsigned int reg = AXP20X_DCDC_FREQ; | ||
305 | u32 min, max, def, step; | 354 | u32 min, max, def, step; |
306 | 355 | ||
307 | switch (axp20x->variant) { | 356 | switch (axp20x->variant) { |
@@ -312,6 +361,14 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) | |||
312 | def = 1500; | 361 | def = 1500; |
313 | step = 75; | 362 | step = 75; |
314 | break; | 363 | break; |
364 | case AXP806_ID: | ||
365 | /* | ||
366 | * AXP806 DCDC work frequency setting has the same range and | ||
367 | * step as AXP22X, but at a different register. | ||
368 | * Fall through to the check below. | ||
369 | * (See include/linux/mfd/axp20x.h) | ||
370 | */ | ||
371 | reg = AXP806_DCDC_FREQ_CTRL; | ||
315 | case AXP221_ID: | 372 | case AXP221_ID: |
316 | case AXP223_ID: | 373 | case AXP223_ID: |
317 | case AXP809_ID: | 374 | case AXP809_ID: |
@@ -343,7 +400,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) | |||
343 | 400 | ||
344 | dcdcfreq = (dcdcfreq - min) / step; | 401 | dcdcfreq = (dcdcfreq - min) / step; |
345 | 402 | ||
346 | return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ, | 403 | return regmap_update_bits(axp20x->regmap, reg, |
347 | AXP20X_FREQ_DCDC_MASK, dcdcfreq); | 404 | AXP20X_FREQ_DCDC_MASK, dcdcfreq); |
348 | } | 405 | } |
349 | 406 | ||
@@ -377,6 +434,7 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev) | |||
377 | static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) | 434 | static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) |
378 | { | 435 | { |
379 | struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); | 436 | struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); |
437 | unsigned int reg = AXP20X_DCDC_MODE; | ||
380 | unsigned int mask; | 438 | unsigned int mask; |
381 | 439 | ||
382 | switch (axp20x->variant) { | 440 | switch (axp20x->variant) { |
@@ -392,6 +450,13 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work | |||
392 | workmode <<= ffs(mask) - 1; | 450 | workmode <<= ffs(mask) - 1; |
393 | break; | 451 | break; |
394 | 452 | ||
453 | case AXP806_ID: | ||
454 | reg = AXP806_DCDC_MODE_CTRL2; | ||
455 | /* | ||
456 | * AXP806 DCDC regulator IDs have the same range as AXP22X. | ||
457 | * Fall through to the check below. | ||
458 | * (See include/linux/mfd/axp20x.h) | ||
459 | */ | ||
395 | case AXP221_ID: | 460 | case AXP221_ID: |
396 | case AXP223_ID: | 461 | case AXP223_ID: |
397 | case AXP809_ID: | 462 | case AXP809_ID: |
@@ -408,7 +473,34 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work | |||
408 | return -EINVAL; | 473 | return -EINVAL; |
409 | } | 474 | } |
410 | 475 | ||
411 | return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode); | 476 | return regmap_update_bits(rdev->regmap, reg, mask, workmode); |
477 | } | ||
478 | |||
479 | /* | ||
480 | * This function checks whether a regulator is part of a poly-phase | ||
481 | * output setup based on the registers settings. Returns true if it is. | ||
482 | */ | ||
483 | static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id) | ||
484 | { | ||
485 | u32 reg = 0; | ||
486 | |||
487 | /* Only AXP806 has poly-phase outputs */ | ||
488 | if (axp20x->variant != AXP806_ID) | ||
489 | return false; | ||
490 | |||
491 | regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, ®); | ||
492 | |||
493 | switch (id) { | ||
494 | case AXP806_DCDCB: | ||
495 | return (((reg & GENMASK(7, 6)) == BIT(6)) || | ||
496 | ((reg & GENMASK(7, 6)) == BIT(7))); | ||
497 | case AXP806_DCDCC: | ||
498 | return ((reg & GENMASK(7, 6)) == BIT(7)); | ||
499 | case AXP806_DCDCE: | ||
500 | return !!(reg & BIT(5)); | ||
501 | } | ||
502 | |||
503 | return false; | ||
412 | } | 504 | } |
413 | 505 | ||
414 | static int axp20x_regulator_probe(struct platform_device *pdev) | 506 | static int axp20x_regulator_probe(struct platform_device *pdev) |
@@ -440,6 +532,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
440 | drivevbus = of_property_read_bool(pdev->dev.parent->of_node, | 532 | drivevbus = of_property_read_bool(pdev->dev.parent->of_node, |
441 | "x-powers,drive-vbus-en"); | 533 | "x-powers,drive-vbus-en"); |
442 | break; | 534 | break; |
535 | case AXP806_ID: | ||
536 | regulators = axp806_regulators; | ||
537 | nregulators = AXP806_REG_ID_MAX; | ||
538 | break; | ||
443 | case AXP809_ID: | 539 | case AXP809_ID: |
444 | regulators = axp809_regulators; | 540 | regulators = axp809_regulators; |
445 | nregulators = AXP809_REG_ID_MAX; | 541 | nregulators = AXP809_REG_ID_MAX; |
@@ -458,6 +554,14 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
458 | struct regulator_desc *new_desc; | 554 | struct regulator_desc *new_desc; |
459 | 555 | ||
460 | /* | 556 | /* |
557 | * If this regulator is a slave in a poly-phase setup, | ||
558 | * skip it, as its controls are bound to the master | ||
559 | * regulator and won't work. | ||
560 | */ | ||
561 | if (axp20x_is_polyphase_slave(axp20x, i)) | ||
562 | continue; | ||
563 | |||
564 | /* | ||
461 | * Regulators DC1SW and DC5LDO are connected internally, | 565 | * Regulators DC1SW and DC5LDO are connected internally, |
462 | * so we have to handle their supply names separately. | 566 | * so we have to handle their supply names separately. |
463 | * | 567 | * |
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index e254272585b2..1b2acc43fea1 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c | |||
@@ -448,6 +448,44 @@ static struct regulator_ops switch_ops = { | |||
448 | }; | 448 | }; |
449 | 449 | ||
450 | /* | 450 | /* |
451 | * PM8018 regulators | ||
452 | */ | ||
453 | static const struct qcom_rpm_reg pm8018_pldo = { | ||
454 | .desc.linear_ranges = pldo_ranges, | ||
455 | .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges), | ||
456 | .desc.n_voltages = 161, | ||
457 | .desc.ops = &uV_ops, | ||
458 | .parts = &rpm8960_ldo_parts, | ||
459 | .supports_force_mode_auto = false, | ||
460 | .supports_force_mode_bypass = false, | ||
461 | }; | ||
462 | |||
463 | static const struct qcom_rpm_reg pm8018_nldo = { | ||
464 | .desc.linear_ranges = nldo_ranges, | ||
465 | .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges), | ||
466 | .desc.n_voltages = 64, | ||
467 | .desc.ops = &uV_ops, | ||
468 | .parts = &rpm8960_ldo_parts, | ||
469 | .supports_force_mode_auto = false, | ||
470 | .supports_force_mode_bypass = false, | ||
471 | }; | ||
472 | |||
473 | static const struct qcom_rpm_reg pm8018_smps = { | ||
474 | .desc.linear_ranges = smps_ranges, | ||
475 | .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges), | ||
476 | .desc.n_voltages = 154, | ||
477 | .desc.ops = &uV_ops, | ||
478 | .parts = &rpm8960_smps_parts, | ||
479 | .supports_force_mode_auto = false, | ||
480 | .supports_force_mode_bypass = false, | ||
481 | }; | ||
482 | |||
483 | static const struct qcom_rpm_reg pm8018_switch = { | ||
484 | .desc.ops = &switch_ops, | ||
485 | .parts = &rpm8960_switch_parts, | ||
486 | }; | ||
487 | |||
488 | /* | ||
451 | * PM8058 regulators | 489 | * PM8058 regulators |
452 | */ | 490 | */ |
453 | static const struct qcom_rpm_reg pm8058_pldo = { | 491 | static const struct qcom_rpm_reg pm8058_pldo = { |
@@ -755,6 +793,32 @@ struct rpm_regulator_data { | |||
755 | const char *supply; | 793 | const char *supply; |
756 | }; | 794 | }; |
757 | 795 | ||
796 | static const struct rpm_regulator_data rpm_pm8018_regulators[] = { | ||
797 | { "s1", QCOM_RPM_PM8018_SMPS1, &pm8018_smps, "vdd_s1" }, | ||
798 | { "s2", QCOM_RPM_PM8018_SMPS2, &pm8018_smps, "vdd_s2" }, | ||
799 | { "s3", QCOM_RPM_PM8018_SMPS3, &pm8018_smps, "vdd_s3" }, | ||
800 | { "s4", QCOM_RPM_PM8018_SMPS4, &pm8018_smps, "vdd_s4" }, | ||
801 | { "s5", QCOM_RPM_PM8018_SMPS5, &pm8018_smps, "vdd_s5" }, | ||
802 | |||
803 | { "l2", QCOM_RPM_PM8018_LDO2, &pm8018_pldo, "vdd_l2" }, | ||
804 | { "l3", QCOM_RPM_PM8018_LDO3, &pm8018_pldo, "vdd_l3" }, | ||
805 | { "l4", QCOM_RPM_PM8018_LDO4, &pm8018_pldo, "vdd_l4" }, | ||
806 | { "l5", QCOM_RPM_PM8018_LDO5, &pm8018_pldo, "vdd_l5" }, | ||
807 | { "l6", QCOM_RPM_PM8018_LDO6, &pm8018_pldo, "vdd_l7" }, | ||
808 | { "l7", QCOM_RPM_PM8018_LDO7, &pm8018_pldo, "vdd_l7" }, | ||
809 | { "l8", QCOM_RPM_PM8018_LDO8, &pm8018_nldo, "vdd_l8" }, | ||
810 | { "l9", QCOM_RPM_PM8018_LDO9, &pm8921_nldo1200, | ||
811 | "vdd_l9_l10_l11_l12" }, | ||
812 | { "l10", QCOM_RPM_PM8018_LDO10, &pm8018_nldo, "vdd_l9_l10_l11_l12" }, | ||
813 | { "l11", QCOM_RPM_PM8018_LDO11, &pm8018_nldo, "vdd_l9_l10_l11_l12" }, | ||
814 | { "l12", QCOM_RPM_PM8018_LDO12, &pm8018_nldo, "vdd_l9_l10_l11_l12" }, | ||
815 | { "l14", QCOM_RPM_PM8018_LDO14, &pm8018_pldo, "vdd_l14" }, | ||
816 | |||
817 | { "lvs1", QCOM_RPM_PM8018_LVS1, &pm8018_switch, "lvs1_in" }, | ||
818 | |||
819 | { } | ||
820 | }; | ||
821 | |||
758 | static const struct rpm_regulator_data rpm_pm8058_regulators[] = { | 822 | static const struct rpm_regulator_data rpm_pm8058_regulators[] = { |
759 | { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, | 823 | { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, |
760 | { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, | 824 | { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, |
@@ -870,6 +934,8 @@ static const struct rpm_regulator_data rpm_pm8921_regulators[] = { | |||
870 | }; | 934 | }; |
871 | 935 | ||
872 | static const struct of_device_id rpm_of_match[] = { | 936 | static const struct of_device_id rpm_of_match[] = { |
937 | { .compatible = "qcom,rpm-pm8018-regulators", | ||
938 | .data = &rpm_pm8018_regulators }, | ||
873 | { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators }, | 939 | { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators }, |
874 | { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators }, | 940 | { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators }, |
875 | { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators }, | 941 | { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators }, |
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index a6767494d39b..3314bf299a51 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c | |||
@@ -1,11 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Regulator driver for Rockchip RK808 | 2 | * Regulator driver for Rockchip RK808/RK818 |
3 | * | 3 | * |
4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd | 4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd |
5 | * | 5 | * |
6 | * Author: Chris Zhong <zyw@rock-chips.com> | 6 | * Author: Chris Zhong <zyw@rock-chips.com> |
7 | * Author: Zhang Qing <zhangqing@rock-chips.com> | 7 | * Author: Zhang Qing <zhangqing@rock-chips.com> |
8 | * | 8 | * |
9 | * Copyright (C) 2016 PHYTEC Messtechnik GmbH | ||
10 | * | ||
11 | * Author: Wadim Egorov <w.egorov@phytec.de> | ||
12 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | 13 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms and conditions of the GNU General Public License, | 14 | * under the terms and conditions of the GNU General Public License, |
11 | * version 2, as published by the Free Software Foundation. | 15 | * version 2, as published by the Free Software Foundation. |
@@ -32,6 +36,12 @@ | |||
32 | #define RK808_BUCK4_VSEL_MASK 0xf | 36 | #define RK808_BUCK4_VSEL_MASK 0xf |
33 | #define RK808_LDO_VSEL_MASK 0x1f | 37 | #define RK808_LDO_VSEL_MASK 0x1f |
34 | 38 | ||
39 | #define RK818_BUCK_VSEL_MASK 0x3f | ||
40 | #define RK818_BUCK4_VSEL_MASK 0x1f | ||
41 | #define RK818_LDO_VSEL_MASK 0x1f | ||
42 | #define RK818_LDO3_ON_VSEL_MASK 0xf | ||
43 | #define RK818_BOOST_ON_VSEL_MASK 0xe0 | ||
44 | |||
35 | /* Ramp rate definitions for buck1 / buck2 only */ | 45 | /* Ramp rate definitions for buck1 / buck2 only */ |
36 | #define RK808_RAMP_RATE_OFFSET 3 | 46 | #define RK808_RAMP_RATE_OFFSET 3 |
37 | #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) | 47 | #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) |
@@ -454,6 +464,108 @@ static const struct regulator_desc rk808_reg[] = { | |||
454 | RK808_DCDC_EN_REG, BIT(6)), | 464 | RK808_DCDC_EN_REG, BIT(6)), |
455 | }; | 465 | }; |
456 | 466 | ||
467 | static const struct regulator_desc rk818_reg[] = { | ||
468 | { | ||
469 | .name = "DCDC_REG1", | ||
470 | .supply_name = "vcc1", | ||
471 | .of_match = of_match_ptr("DCDC_REG1"), | ||
472 | .regulators_node = of_match_ptr("regulators"), | ||
473 | .id = RK818_ID_DCDC1, | ||
474 | .ops = &rk808_reg_ops, | ||
475 | .type = REGULATOR_VOLTAGE, | ||
476 | .min_uV = 712500, | ||
477 | .uV_step = 12500, | ||
478 | .n_voltages = 64, | ||
479 | .vsel_reg = RK818_BUCK1_ON_VSEL_REG, | ||
480 | .vsel_mask = RK818_BUCK_VSEL_MASK, | ||
481 | .enable_reg = RK818_DCDC_EN_REG, | ||
482 | .enable_mask = BIT(0), | ||
483 | .owner = THIS_MODULE, | ||
484 | }, { | ||
485 | .name = "DCDC_REG2", | ||
486 | .supply_name = "vcc2", | ||
487 | .of_match = of_match_ptr("DCDC_REG2"), | ||
488 | .regulators_node = of_match_ptr("regulators"), | ||
489 | .id = RK818_ID_DCDC2, | ||
490 | .ops = &rk808_reg_ops, | ||
491 | .type = REGULATOR_VOLTAGE, | ||
492 | .min_uV = 712500, | ||
493 | .uV_step = 12500, | ||
494 | .n_voltages = 64, | ||
495 | .vsel_reg = RK818_BUCK2_ON_VSEL_REG, | ||
496 | .vsel_mask = RK818_BUCK_VSEL_MASK, | ||
497 | .enable_reg = RK818_DCDC_EN_REG, | ||
498 | .enable_mask = BIT(1), | ||
499 | .owner = THIS_MODULE, | ||
500 | }, { | ||
501 | .name = "DCDC_REG3", | ||
502 | .supply_name = "vcc3", | ||
503 | .of_match = of_match_ptr("DCDC_REG3"), | ||
504 | .regulators_node = of_match_ptr("regulators"), | ||
505 | .id = RK818_ID_DCDC3, | ||
506 | .ops = &rk808_switch_ops, | ||
507 | .type = REGULATOR_VOLTAGE, | ||
508 | .n_voltages = 1, | ||
509 | .enable_reg = RK818_DCDC_EN_REG, | ||
510 | .enable_mask = BIT(2), | ||
511 | .owner = THIS_MODULE, | ||
512 | }, | ||
513 | RK8XX_DESC(RK818_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3600, 100, | ||
514 | RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK, | ||
515 | RK818_DCDC_EN_REG, BIT(3), 0), | ||
516 | RK8XX_DESC(RK818_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100, | ||
517 | RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK, | ||
518 | RK818_DCDC_EN_REG, BIT(4), 0), | ||
519 | RK8XX_DESC(RK818_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100, | ||
520 | RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
521 | BIT(0), 400), | ||
522 | RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100, | ||
523 | RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
524 | BIT(1), 400), | ||
525 | { | ||
526 | .name = "LDO_REG3", | ||
527 | .supply_name = "vcc7", | ||
528 | .of_match = of_match_ptr("LDO_REG3"), | ||
529 | .regulators_node = of_match_ptr("regulators"), | ||
530 | .id = RK818_ID_LDO3, | ||
531 | .ops = &rk808_reg_ops_ranges, | ||
532 | .type = REGULATOR_VOLTAGE, | ||
533 | .n_voltages = 16, | ||
534 | .linear_ranges = rk808_ldo3_voltage_ranges, | ||
535 | .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges), | ||
536 | .vsel_reg = RK818_LDO3_ON_VSEL_REG, | ||
537 | .vsel_mask = RK818_LDO3_ON_VSEL_MASK, | ||
538 | .enable_reg = RK818_LDO_EN_REG, | ||
539 | .enable_mask = BIT(2), | ||
540 | .enable_time = 400, | ||
541 | .owner = THIS_MODULE, | ||
542 | }, | ||
543 | RK8XX_DESC(RK818_ID_LDO4, "LDO_REG4", "vcc8", 1800, 3400, 100, | ||
544 | RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
545 | BIT(3), 400), | ||
546 | RK8XX_DESC(RK818_ID_LDO5, "LDO_REG5", "vcc7", 1800, 3400, 100, | ||
547 | RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
548 | BIT(4), 400), | ||
549 | RK8XX_DESC(RK818_ID_LDO6, "LDO_REG6", "vcc8", 800, 2500, 100, | ||
550 | RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
551 | BIT(5), 400), | ||
552 | RK8XX_DESC(RK818_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100, | ||
553 | RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
554 | BIT(6), 400), | ||
555 | RK8XX_DESC(RK818_ID_LDO8, "LDO_REG8", "vcc8", 1800, 3400, 100, | ||
556 | RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, | ||
557 | BIT(7), 400), | ||
558 | RK8XX_DESC(RK818_ID_LDO9, "LDO_REG9", "vcc9", 1800, 3400, 100, | ||
559 | RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK, | ||
560 | RK818_DCDC_EN_REG, BIT(5), 400), | ||
561 | RK8XX_DESC_SWITCH(RK818_ID_SWITCH, "SWITCH_REG", "vcc9", | ||
562 | RK818_DCDC_EN_REG, BIT(6)), | ||
563 | RK8XX_DESC_SWITCH(RK818_ID_HDMI_SWITCH, "HDMI_SWITCH", "h_5v", | ||
564 | RK818_H5V_EN_REG, BIT(0)), | ||
565 | RK8XX_DESC_SWITCH(RK818_ID_OTG_SWITCH, "OTG_SWITCH", "usb", | ||
566 | RK818_DCDC_EN_REG, BIT(7)), | ||
567 | }; | ||
568 | |||
457 | static int rk808_regulator_dt_parse_pdata(struct device *dev, | 569 | static int rk808_regulator_dt_parse_pdata(struct device *dev, |
458 | struct device *client_dev, | 570 | struct device *client_dev, |
459 | struct regmap *map, | 571 | struct regmap *map, |
@@ -499,7 +611,8 @@ static int rk808_regulator_probe(struct platform_device *pdev) | |||
499 | struct regulator_config config = {}; | 611 | struct regulator_config config = {}; |
500 | struct regulator_dev *rk808_rdev; | 612 | struct regulator_dev *rk808_rdev; |
501 | struct rk808_regulator_data *pdata; | 613 | struct rk808_regulator_data *pdata; |
502 | int ret, i; | 614 | const struct regulator_desc *regulators; |
615 | int ret, i, nregulators; | ||
503 | 616 | ||
504 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 617 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
505 | if (!pdata) | 618 | if (!pdata) |
@@ -512,14 +625,29 @@ static int rk808_regulator_probe(struct platform_device *pdev) | |||
512 | 625 | ||
513 | platform_set_drvdata(pdev, pdata); | 626 | platform_set_drvdata(pdev, pdata); |
514 | 627 | ||
628 | switch (rk808->variant) { | ||
629 | case RK808_ID: | ||
630 | regulators = rk808_reg; | ||
631 | nregulators = RK808_NUM_REGULATORS; | ||
632 | break; | ||
633 | case RK818_ID: | ||
634 | regulators = rk818_reg; | ||
635 | nregulators = RK818_NUM_REGULATORS; | ||
636 | break; | ||
637 | default: | ||
638 | dev_err(&client->dev, "unsupported RK8XX ID %lu\n", | ||
639 | rk808->variant); | ||
640 | return -EINVAL; | ||
641 | } | ||
642 | |||
515 | config.dev = &client->dev; | 643 | config.dev = &client->dev; |
516 | config.driver_data = pdata; | 644 | config.driver_data = pdata; |
517 | config.regmap = rk808->regmap; | 645 | config.regmap = rk808->regmap; |
518 | 646 | ||
519 | /* Instantiate the regulators */ | 647 | /* Instantiate the regulators */ |
520 | for (i = 0; i < RK808_NUM_REGULATORS; i++) { | 648 | for (i = 0; i < nregulators; i++) { |
521 | rk808_rdev = devm_regulator_register(&pdev->dev, | 649 | rk808_rdev = devm_regulator_register(&pdev->dev, |
522 | &rk808_reg[i], &config); | 650 | ®ulators[i], &config); |
523 | if (IS_ERR(rk808_rdev)) { | 651 | if (IS_ERR(rk808_rdev)) { |
524 | dev_err(&client->dev, | 652 | dev_err(&client->dev, |
525 | "failed to register %d regulator\n", i); | 653 | "failed to register %d regulator\n", i); |
@@ -539,8 +667,9 @@ static struct platform_driver rk808_regulator_driver = { | |||
539 | 667 | ||
540 | module_platform_driver(rk808_regulator_driver); | 668 | module_platform_driver(rk808_regulator_driver); |
541 | 669 | ||
542 | MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); | 670 | MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs"); |
543 | MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>"); | 671 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); |
544 | MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>"); | 672 | MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); |
673 | MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); | ||
545 | MODULE_LICENSE("GPL"); | 674 | MODULE_LICENSE("GPL"); |
546 | MODULE_ALIAS("platform:rk808-regulator"); | 675 | MODULE_ALIAS("platform:rk808-regulator"); |