summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPradeep Goudagunta <pgoudagunta@nvidia.com>2012-11-07 13:46:11 +0530
committerSimone Willett <swillett@nvidia.com>2012-11-09 14:36:10 -0800
commit91caa57f63bc62554e4efdd1e919283f27da094d (patch)
tree66a59c3d3f6a14b10a316bf678eefa7056bd06be /drivers
parent74896910027cbc5b09d01d6e5c2c5ba46efe0cc2 (diff)
mfd: palmas: pwm based cl dvfs support
SMPS12 and SMPS6 are capable of PWM based cl dvfs. Bug 1058480 Change-Id: Ib000300ac508b471b9ebe698c603c93129f0675e Signed-off-by: Pradeep Goudagunta <pgoudagunta@nvidia.com> Reviewed-on: http://git-master/r/159832 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Neil Patel <neilp@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/palmas-regulator.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 9227dd5750d3..3fb5c11213a1 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -33,6 +33,7 @@ struct regs_info {
u8 vsel_addr;
u8 ctrl_addr;
u8 tstep_addr;
+ u8 fvsel_addr;
int sleep_id;
};
@@ -42,6 +43,7 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS12_VOLTAGE,
.ctrl_addr = PALMAS_SMPS12_CTRL,
.tstep_addr = PALMAS_SMPS12_TSTEP,
+ .fvsel_addr = PALMAS_SMPS12_FORCE,
.sleep_id = PALMAS_SLEEP_REQSTR_ID_SMPS12,
},
{
@@ -76,6 +78,7 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS6_VOLTAGE,
.ctrl_addr = PALMAS_SMPS6_CTRL,
.tstep_addr = PALMAS_SMPS6_TSTEP,
+ .fvsel_addr = PALMAS_SMPS6_FORCE,
.sleep_id = PALMAS_SLEEP_REQSTR_ID_SMPS6,
},
{
@@ -1037,6 +1040,74 @@ static void palmas_disable_ldo8_track(struct palmas *palmas)
return;
}
+static void palmas_dvfs_init(struct palmas *palmas,
+ struct palmas_pmic_platform_data *pdata)
+{
+ int slave;
+ struct palmas_dvfs_init_data *dvfs_idata = pdata->dvfs_init_data;
+ int data_size = pdata->dvfs_init_data_size;
+ unsigned int reg, addr;
+ int ret;
+ int sleep_id;
+ int i;
+
+ if (!dvfs_idata || !data_size)
+ return;
+
+ slave = PALMAS_BASE_TO_SLAVE(PALMAS_DVFS_BASE);
+ for (i = 0; i < data_size; i++) {
+ struct palmas_dvfs_init_data *dvfs_pd = &dvfs_idata[i];
+
+ sleep_id = palmas_regs_info[dvfs_pd->reg_id].sleep_id;
+ if (!dvfs_pd->en_pwm)
+ continue;
+
+ ret = palmas_ext_power_req_config(palmas, sleep_id,
+ dvfs_pd->ext_ctrl, true);
+ if (ret < 0) {
+ dev_err(palmas->dev,
+ "Error in configuring external control\n");
+ goto err;
+ }
+
+ addr = PALMAS_BASE_TO_REG(PALMAS_DVFS_BASE,
+ (PALMAS_SMPS_DVFS1_CTRL) + i*3);
+ reg = (1 << PALMAS_SMPS_DVFS1_ENABLE_SHIFT);
+ if (dvfs_pd->step_20mV)
+ reg |= (1 << PALMAS_SMPS_DVFS1_OFFSET_STEP_SHIFT);
+
+ ret = regmap_write(palmas->regmap[slave], addr, reg);
+ if (ret)
+ goto err;
+
+ addr = PALMAS_BASE_TO_REG(PALMAS_DVFS_BASE,
+ (PALMAS_SMPS_DVFS1_VOLTAGE_MAX) + i*3);
+ if (!(dvfs_pd->max_voltage_uV >= DVFS_BASE_VOLTAGE_UV &&
+ dvfs_pd->max_voltage_uV <= DVFS_MAX_VOLTAGE_UV))
+ goto err;
+
+ reg = DIV_ROUND_UP((dvfs_pd->max_voltage_uV -
+ DVFS_BASE_VOLTAGE_UV), DVFS_VOLTAGE_STEP_UV) + 6;
+ ret = regmap_write(palmas->regmap[slave], addr, reg);
+ if (ret)
+ goto err;
+
+ addr = palmas_regs_info[dvfs_pd->reg_id].fvsel_addr;
+ reg = (1 << PALMAS_SMPS12_FORCE_CMD_SHIFT);
+ reg |= DIV_ROUND_UP((dvfs_pd->base_voltage_uV -
+ DVFS_BASE_VOLTAGE_UV), DVFS_VOLTAGE_STEP_UV) + 6;
+ ret = palmas_smps_write(palmas, addr, reg);
+ if (ret)
+ goto err;
+
+ }
+
+ return;
+err:
+ dev_err(palmas->dev, "Failed to initilize cl dvfs(%d)", i);
+ return;
+}
+
static __devinit int palmas_probe(struct platform_device *pdev)
{
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
@@ -1218,6 +1289,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
if (pdata->enable_ldo8_tracking)
palmas_enable_ldo8_track(palmas);
+ palmas_dvfs_init(palmas, pdata);
return 0;
err_unregister_regulator: