summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-09-11 13:30:25 +0530
committerVarun Colbert <vcolbert@nvidia.com>2012-09-11 14:01:31 -0700
commit888bba4f49177c724e1fca622554808c5fa025fe (patch)
treea2d1e71aba1b9e955e46914420c65de821e3ed60 /drivers/regulator
parentc60a39cda81cfcb2c4e9e84233c409ef68dedaf1 (diff)
regulator: palma: support for external regulator
Palma supports the multiple external regulator named as REGEN1, REGEN2, REGEN3, SYSEN1 and SYSEN2. Supports these regulator through regulator driver. Change-Id: I4f5fae65dc6e5b8dcd1f80ac41ad406933a1fe7e Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/131331 Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/palmas-regulator.c152
1 files changed, 145 insertions, 7 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 7b4df996f2d3..df025ebfecbb 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -141,6 +141,26 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_LDOUSB_VOLTAGE,
.ctrl_addr = PALMAS_LDOUSB_CTRL,
},
+ {
+ .name = "REGEN1",
+ .ctrl_addr = PALMAS_REGEN1_CTRL,
+ },
+ {
+ .name = "REGEN2",
+ .ctrl_addr = PALMAS_REGEN2_CTRL,
+ },
+ {
+ .name = "REGEN3",
+ .ctrl_addr = PALMAS_REGEN3_CTRL,
+ },
+ {
+ .name = "SYSEN1",
+ .ctrl_addr = PALMAS_SYSEN1_CTRL,
+ },
+ {
+ .name = "SYSEN2",
+ .ctrl_addr = PALMAS_SYSEN2_CTRL,
+ },
};
#define SMPS_CTRL_MODE_OFF 0x00
@@ -205,6 +225,26 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg,
return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value);
}
+static int palmas_resource_read(struct palmas *palmas, unsigned int reg,
+ unsigned int *dest)
+{
+ unsigned int addr;
+
+ addr = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, reg);
+
+ return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest);
+}
+
+static int palmas_resource_write(struct palmas *palmas, unsigned int reg,
+ unsigned int value)
+{
+ unsigned int addr;
+
+ addr = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, reg);
+
+ return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value);
+}
+
static int palmas_is_enabled_smps(struct regulator_dev *dev)
{
struct palmas_pmic *pmic = rdev_get_drvdata(dev);
@@ -529,6 +569,71 @@ static struct regulator_ops palmas_ops_ldo = {
.list_voltage = palmas_list_voltage_ldo,
};
+static int palmas_is_enabled_extreg(struct regulator_dev *dev)
+{
+ struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+ int id = rdev_get_id(dev);
+ unsigned int reg;
+ int ret;
+
+ ret = palmas_resource_read(pmic->palmas,
+ palmas_regs_info[id].ctrl_addr, &reg);
+ reg &= PALMAS_REGEN1_CTRL_STATUS;
+ if (ret < 0)
+ return ret;
+
+ return !!(reg);
+}
+
+static int palmas_enable_extreg(struct regulator_dev *dev)
+{
+ struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+ int id = rdev_get_id(dev);
+ unsigned int reg;
+ int ret;
+
+ ret = palmas_resource_read(pmic->palmas,
+ palmas_regs_info[id].ctrl_addr, &reg);
+ if (ret < 0)
+ return ret;
+
+ reg |= PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+ ret = palmas_resource_write(pmic->palmas,
+ palmas_regs_info[id].ctrl_addr, reg);
+ return ret;
+}
+
+static int palmas_disable_extreg(struct regulator_dev *dev)
+{
+ struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+ int id = rdev_get_id(dev);
+ unsigned int reg;
+ int ret;
+
+ ret = palmas_resource_read(pmic->palmas,
+ palmas_regs_info[id].ctrl_addr, &reg);
+ if (ret < 0)
+ return ret;
+
+ reg &= ~PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+ ret = palmas_resource_write(pmic->palmas,
+ palmas_regs_info[id].ctrl_addr, reg);
+ return ret;
+}
+
+static int palmas_getvoltage_extreg(struct regulator_dev *rdev)
+{
+ return 4300 * 1000;
+}
+
+
+static struct regulator_ops palmas_ops_extreg = {
+ .is_enabled = palmas_is_enabled_extreg,
+ .enable = palmas_enable_extreg,
+ .disable = palmas_disable_extreg,
+ .get_voltage = palmas_getvoltage_extreg,
+};
+
/*
* setup the hardware based sleep configuration of the SMPS/LDO regulators
* from the platform data. This is different to the software based control
@@ -622,6 +727,28 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
return 0;
}
+static int palmas_extreg_init(struct palmas *palmas, int id,
+ struct palmas_reg_init *reg_init)
+{
+ unsigned int reg;
+ unsigned int addr;
+ int ret;
+
+ addr = palmas_regs_info[id].ctrl_addr;
+
+ ret = palmas_resource_read(palmas, addr, &reg);
+ if (ret)
+ return ret;
+
+ if (reg_init->mode_sleep)
+ reg |= PALMAS_REGEN1_CTRL_MODE_SLEEP;
+ else
+ reg &= ~PALMAS_REGEN1_CTRL_MODE_SLEEP;
+
+ ret = palmas_resource_write(palmas, addr, reg);
+ return ret;
+}
+
static __devinit int palmas_probe(struct platform_device *pdev)
{
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
@@ -754,14 +881,20 @@ static __devinit int palmas_probe(struct platform_device *pdev)
/* Register the regulators */
pmic->desc[id].name = palmas_regs_info[id].name;
pmic->desc[id].id = id;
- pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
-
- pmic->desc[id].ops = &palmas_ops_ldo;
-
pmic->desc[id].type = REGULATOR_VOLTAGE;
pmic->desc[id].owner = THIS_MODULE;
- pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr;
- pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
+
+ if (id < PALMAS_REG_REGEN1) {
+ pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
+ pmic->desc[id].ops = &palmas_ops_ldo;
+ pmic->desc[id].enable_reg =
+ palmas_regs_info[id].ctrl_addr;
+ pmic->desc[id].enable_mask =
+ PALMAS_LDO1_CTRL_MODE_ACTIVE;
+ } else {
+ pmic->desc[id].n_voltages = 1;
+ pmic->desc[id].ops = &palmas_ops_extreg;
+ }
rdev = regulator_register(&pmic->desc[id],
palmas->dev, reg_data, pmic, NULL);
@@ -781,7 +914,12 @@ static __devinit int palmas_probe(struct platform_device *pdev)
if (pdata->reg_init) {
reg_init = pdata->reg_init[id];
if (reg_init) {
- ret = palmas_ldo_init(palmas, id, reg_init);
+ if (id < PALMAS_REG_REGEN1)
+ ret = palmas_ldo_init(palmas, id,
+ reg_init);
+ else
+ ret = palmas_extreg_init(palmas, id,
+ reg_init);
if (ret)
goto err_unregister_regulator;
}