Commit 11375293 authored by Wadim Egorov's avatar Wadim Egorov Committed by Lee Jones

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: default avatarWadim Egorov <w.egorov@phytec.de>
Acked-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 2eedcbfc
...@@ -635,11 +635,11 @@ config REGULATOR_RC5T583 ...@@ -635,11 +635,11 @@ config REGULATOR_RC5T583
outputs which can be controlled by i2c communication. outputs which can be controlled by i2c communication.
config REGULATOR_RK808 config REGULATOR_RK808
tristate "Rockchip RK808 Power regulators" tristate "Rockchip RK808/RK818 Power regulators"
depends on MFD_RK808 depends on MFD_RK808
help help
Select this option to enable the power regulator of ROCKCHIP Select this option to enable the power regulator of ROCKCHIP
PMIC RK808. PMIC RK808 and RK818.
This driver supports the control of different power rails of device This driver supports the control of different power rails of device
through regulator interface. The device supports multiple DCDC/LDO through regulator interface. The device supports multiple DCDC/LDO
outputs which can be controlled by i2c communication. outputs which can be controlled by i2c communication.
......
/* /*
* Regulator driver for Rockchip RK808 * Regulator driver for Rockchip RK808/RK818
* *
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
* *
* Author: Chris Zhong <zyw@rock-chips.com> * Author: Chris Zhong <zyw@rock-chips.com>
* Author: Zhang Qing <zhangqing@rock-chips.com> * Author: Zhang Qing <zhangqing@rock-chips.com>
* *
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
*
* Author: Wadim Egorov <w.egorov@phytec.de>
*
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation. * version 2, as published by the Free Software Foundation.
...@@ -32,6 +36,12 @@ ...@@ -32,6 +36,12 @@
#define RK808_BUCK4_VSEL_MASK 0xf #define RK808_BUCK4_VSEL_MASK 0xf
#define RK808_LDO_VSEL_MASK 0x1f #define RK808_LDO_VSEL_MASK 0x1f
#define RK818_BUCK_VSEL_MASK 0x3f
#define RK818_BUCK4_VSEL_MASK 0x1f
#define RK818_LDO_VSEL_MASK 0x1f
#define RK818_LDO3_ON_VSEL_MASK 0xf
#define RK818_BOOST_ON_VSEL_MASK 0xe0
/* Ramp rate definitions for buck1 / buck2 only */ /* Ramp rate definitions for buck1 / buck2 only */
#define RK808_RAMP_RATE_OFFSET 3 #define RK808_RAMP_RATE_OFFSET 3
#define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET)
...@@ -454,6 +464,108 @@ static const struct regulator_desc rk808_reg[] = { ...@@ -454,6 +464,108 @@ static const struct regulator_desc rk808_reg[] = {
RK808_DCDC_EN_REG, BIT(6)), RK808_DCDC_EN_REG, BIT(6)),
}; };
static const struct regulator_desc rk818_reg[] = {
{
.name = "DCDC_REG1",
.supply_name = "vcc1",
.of_match = of_match_ptr("DCDC_REG1"),
.regulators_node = of_match_ptr("regulators"),
.id = RK818_ID_DCDC1,
.ops = &rk808_reg_ops,
.type = REGULATOR_VOLTAGE,
.min_uV = 712500,
.uV_step = 12500,
.n_voltages = 64,
.vsel_reg = RK818_BUCK1_ON_VSEL_REG,
.vsel_mask = RK818_BUCK_VSEL_MASK,
.enable_reg = RK818_DCDC_EN_REG,
.enable_mask = BIT(0),
.owner = THIS_MODULE,
}, {
.name = "DCDC_REG2",
.supply_name = "vcc2",
.of_match = of_match_ptr("DCDC_REG2"),
.regulators_node = of_match_ptr("regulators"),
.id = RK818_ID_DCDC2,
.ops = &rk808_reg_ops,
.type = REGULATOR_VOLTAGE,
.min_uV = 712500,
.uV_step = 12500,
.n_voltages = 64,
.vsel_reg = RK818_BUCK2_ON_VSEL_REG,
.vsel_mask = RK818_BUCK_VSEL_MASK,
.enable_reg = RK818_DCDC_EN_REG,
.enable_mask = BIT(1),
.owner = THIS_MODULE,
}, {
.name = "DCDC_REG3",
.supply_name = "vcc3",
.of_match = of_match_ptr("DCDC_REG3"),
.regulators_node = of_match_ptr("regulators"),
.id = RK818_ID_DCDC3,
.ops = &rk808_switch_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = 1,
.enable_reg = RK818_DCDC_EN_REG,
.enable_mask = BIT(2),
.owner = THIS_MODULE,
},
RK8XX_DESC(RK818_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3600, 100,
RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
RK818_DCDC_EN_REG, BIT(3), 0),
RK8XX_DESC(RK818_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100,
RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK,
RK818_DCDC_EN_REG, BIT(4), 0),
RK8XX_DESC(RK818_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(0), 400),
RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(1), 400),
{
.name = "LDO_REG3",
.supply_name = "vcc7",
.of_match = of_match_ptr("LDO_REG3"),
.regulators_node = of_match_ptr("regulators"),
.id = RK818_ID_LDO3,
.ops = &rk808_reg_ops_ranges,
.type = REGULATOR_VOLTAGE,
.n_voltages = 16,
.linear_ranges = rk808_ldo3_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges),
.vsel_reg = RK818_LDO3_ON_VSEL_REG,
.vsel_mask = RK818_LDO3_ON_VSEL_MASK,
.enable_reg = RK818_LDO_EN_REG,
.enable_mask = BIT(2),
.enable_time = 400,
.owner = THIS_MODULE,
},
RK8XX_DESC(RK818_ID_LDO4, "LDO_REG4", "vcc8", 1800, 3400, 100,
RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(3), 400),
RK8XX_DESC(RK818_ID_LDO5, "LDO_REG5", "vcc7", 1800, 3400, 100,
RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(4), 400),
RK8XX_DESC(RK818_ID_LDO6, "LDO_REG6", "vcc8", 800, 2500, 100,
RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(5), 400),
RK8XX_DESC(RK818_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(6), 400),
RK8XX_DESC(RK818_ID_LDO8, "LDO_REG8", "vcc8", 1800, 3400, 100,
RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
BIT(7), 400),
RK8XX_DESC(RK818_ID_LDO9, "LDO_REG9", "vcc9", 1800, 3400, 100,
RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
RK818_DCDC_EN_REG, BIT(5), 400),
RK8XX_DESC_SWITCH(RK818_ID_SWITCH, "SWITCH_REG", "vcc9",
RK818_DCDC_EN_REG, BIT(6)),
RK8XX_DESC_SWITCH(RK818_ID_HDMI_SWITCH, "HDMI_SWITCH", "h_5v",
RK818_H5V_EN_REG, BIT(0)),
RK8XX_DESC_SWITCH(RK818_ID_OTG_SWITCH, "OTG_SWITCH", "usb",
RK818_DCDC_EN_REG, BIT(7)),
};
static int rk808_regulator_dt_parse_pdata(struct device *dev, static int rk808_regulator_dt_parse_pdata(struct device *dev,
struct device *client_dev, struct device *client_dev,
struct regmap *map, struct regmap *map,
...@@ -499,7 +611,8 @@ static int rk808_regulator_probe(struct platform_device *pdev) ...@@ -499,7 +611,8 @@ static int rk808_regulator_probe(struct platform_device *pdev)
struct regulator_config config = {}; struct regulator_config config = {};
struct regulator_dev *rk808_rdev; struct regulator_dev *rk808_rdev;
struct rk808_regulator_data *pdata; struct rk808_regulator_data *pdata;
int ret, i; const struct regulator_desc *regulators;
int ret, i, nregulators;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) if (!pdata)
...@@ -512,14 +625,29 @@ static int rk808_regulator_probe(struct platform_device *pdev) ...@@ -512,14 +625,29 @@ static int rk808_regulator_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdata); platform_set_drvdata(pdev, pdata);
switch (rk808->variant) {
case RK808_ID:
regulators = rk808_reg;
nregulators = RK808_NUM_REGULATORS;
break;
case RK818_ID:
regulators = rk818_reg;
nregulators = RK818_NUM_REGULATORS;
break;
default:
dev_err(&client->dev, "unsupported RK8XX ID %lu\n",
rk808->variant);
return -EINVAL;
}
config.dev = &client->dev; config.dev = &client->dev;
config.driver_data = pdata; config.driver_data = pdata;
config.regmap = rk808->regmap; config.regmap = rk808->regmap;
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < RK808_NUM_REGULATORS; i++) { for (i = 0; i < nregulators; i++) {
rk808_rdev = devm_regulator_register(&pdev->dev, rk808_rdev = devm_regulator_register(&pdev->dev,
&rk808_reg[i], &config); &regulators[i], &config);
if (IS_ERR(rk808_rdev)) { if (IS_ERR(rk808_rdev)) {
dev_err(&client->dev, dev_err(&client->dev,
"failed to register %d regulator\n", i); "failed to register %d regulator\n", i);
...@@ -540,8 +668,9 @@ static struct platform_driver rk808_regulator_driver = { ...@@ -540,8 +668,9 @@ static struct platform_driver rk808_regulator_driver = {
module_platform_driver(rk808_regulator_driver); module_platform_driver(rk808_regulator_driver);
MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>"); MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>"); MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:rk808-regulator"); MODULE_ALIAS("platform:rk808-regulator");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment