diff options
author | Wadim Egorov <w.egorov@phytec.de> | 2016-08-29 07:07:59 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2016-08-31 08:48:45 -0400 |
commit | 11375293530bb8434946c8c043f1adf5ffb6be10 (patch) | |
tree | a9aa16c7eeba8a13a9d0585dcbb7ff6ca517f430 /drivers/regulator | |
parent | 2eedcbfc0612c87e22c6325fde49ecf140e5873a (diff) |
regulator: rk808: Add regulator driver for RK818
Add support for the rk818 regulator. The regulator module consists
of 4 DCDCs, 9 LDOs, 1 switch and 1 BOOST converter which is used to
power OTG and HDMI5V.
The output voltages are configurable and are meant to supply power
to the main processor and other components.
Signed-off-by: Wadim Egorov <w.egorov@phytec.de>
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/Kconfig | 4 | ||||
-rw-r--r-- | drivers/regulator/rk808-regulator.c | 143 |
2 files changed, 138 insertions, 9 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 6c88e31c01f7..d3a86a8cce86 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -635,11 +635,11 @@ config REGULATOR_RC5T583 | |||
635 | outputs which can be controlled by i2c communication. | 635 | outputs which can be controlled by i2c communication. |
636 | 636 | ||
637 | config REGULATOR_RK808 | 637 | config REGULATOR_RK808 |
638 | tristate "Rockchip RK808 Power regulators" | 638 | tristate "Rockchip RK808/RK818 Power regulators" |
639 | depends on MFD_RK808 | 639 | depends on MFD_RK808 |
640 | help | 640 | help |
641 | Select this option to enable the power regulator of ROCKCHIP | 641 | Select this option to enable the power regulator of ROCKCHIP |
642 | PMIC RK808. | 642 | PMIC RK808 and RK818. |
643 | This driver supports the control of different power rails of device | 643 | This driver supports the control of different power rails of device |
644 | through regulator interface. The device supports multiple DCDC/LDO | 644 | through regulator interface. The device supports multiple DCDC/LDO |
645 | outputs which can be controlled by i2c communication. | 645 | outputs which can be controlled by i2c communication. |
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 40d07ba036e7..5f412a5e35e3 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); |
@@ -540,8 +668,9 @@ static struct platform_driver rk808_regulator_driver = { | |||
540 | 668 | ||
541 | module_platform_driver(rk808_regulator_driver); | 669 | module_platform_driver(rk808_regulator_driver); |
542 | 670 | ||
543 | MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); | 671 | MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs"); |
544 | MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>"); | 672 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); |
545 | MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>"); | 673 | MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); |
674 | MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); | ||
546 | MODULE_LICENSE("GPL"); | 675 | MODULE_LICENSE("GPL"); |
547 | MODULE_ALIAS("platform:rk808-regulator"); | 676 | MODULE_ALIAS("platform:rk808-regulator"); |