summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-11-24 19:23:46 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-08 16:53:33 +0530
commitd454cee86edac49aca7bdc1d2357e69adfe829ee (patch)
tree7cba30a2f92311f487a89ca8469d9c71f16207ac /drivers
parentc0d0a8a770697079991a6338af01f86360c839f2 (diff)
mfd: tps80031: Support sleep configuration through platform data
Supporting the sleep configuration through platform data. Rearranging clock initialization to take external power control. Reviewed-on: http://git-master/r/67076 (cherry picked from commit 9da9d369bdbe988b98eec9b63085dfdb26de8237) Change-Id: I40c5a8608522dbc322e148b5d569e8f5a00faa21 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/67331
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/tps80031.c106
-rw-r--r--drivers/regulator/tps80031-regulator.c33
2 files changed, 107 insertions, 32 deletions
diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c
index 1cffa45f1e96..6fe80dc51931 100644
--- a/drivers/mfd/tps80031.c
+++ b/drivers/mfd/tps80031.c
@@ -106,6 +106,11 @@ static u8 pmc_ext_control_base[] = {
SYSEN_BASE_ADD,
};
+static u8 pmc_clk32k_control_base[] = {
+ CLK32KAO_BASE_ADD,
+ CLK32KG_BASE_ADD,
+ CLK32KAUDIO_BASE_ADD,
+};
struct tps80031_irq_data {
u8 mask_reg;
u8 mask_mask;
@@ -416,23 +421,23 @@ out:
EXPORT_SYMBOL_GPL(tps80031_force_update);
int tps80031_ext_power_req_config(struct device *dev,
- enum tps80031_ext_control ext_pwr_ctrl, int preq_bit,
+ unsigned long ext_ctrl_flag, int preq_bit,
int state_reg_add, int trans_reg_add)
{
u8 res_ass_reg = 0;
int preq_mask_bit = 0;
int ret;
- if (!(ext_pwr_ctrl & EXT_PWR_REQ))
+ if (!(ext_ctrl_flag & EXT_PWR_REQ))
return 0;
- if (ext_pwr_ctrl & PWR_REQ_INPUT_PREQ1) {
+ if (ext_ctrl_flag & PWR_REQ_INPUT_PREQ1) {
res_ass_reg = TPS80031_PREQ1_RES_ASS_A + (preq_bit >> 3);
preq_mask_bit = 5;
- } else if (ext_pwr_ctrl & PWR_REQ_INPUT_PREQ2) {
+ } else if (ext_ctrl_flag & PWR_REQ_INPUT_PREQ2) {
res_ass_reg = TPS80031_PREQ2_RES_ASS_A + (preq_bit >> 3);
preq_mask_bit = 6;
- } else if (ext_pwr_ctrl & PWR_REQ_INPUT_PREQ3) {
+ } else if (ext_ctrl_flag & PWR_REQ_INPUT_PREQ3) {
res_ass_reg = TPS80031_PREQ3_RES_ASS_A + (preq_bit >> 3);
preq_mask_bit = 7;
}
@@ -459,7 +464,7 @@ int tps80031_ext_power_req_config(struct device *dev,
}
/* Switch regulator control to resource now */
- if (ext_pwr_ctrl & (PWR_REQ_INPUT_PREQ2 | PWR_REQ_INPUT_PREQ3)) {
+ if (ext_ctrl_flag & (PWR_REQ_INPUT_PREQ2 | PWR_REQ_INPUT_PREQ3)) {
ret = tps80031_update(dev, SLAVE_ID1, state_reg_add, 0x0,
STATE_MASK);
if (ret < 0)
@@ -596,7 +601,6 @@ static void tps80031_gpio_disable(struct gpio_chip *gc, unsigned offset)
STATE_OFF, STATE_MASK);
}
-
static void tps80031_gpio_init(struct tps80031 *tps80031,
struct tps80031_platform_data *pdata)
{
@@ -614,16 +618,35 @@ static void tps80031_gpio_init(struct tps80031 *tps80031,
/* Configure the external request mode */
for (i = 0; i < data_size; ++i) {
- if (!(gpio_init_data[i].ext_control & EXT_PWR_REQ))
- continue;
- base_add = pmc_ext_control_base[gpio_init_data[i].gpio_nr];
- ret = tps80031_ext_power_req_config(tps80031->dev,
- gpio_init_data[i].ext_control,
- preq_bit_pos[gpio_init_data[i].gpio_nr],
- base_add + EXT_CONTROL_CFG_STATE,
- base_add + EXT_CONTROL_CFG_TRANS);
- if (!ret)
- dev_warn(tps80031->dev, "GPIO sleep control fails\n");
+ struct tps80031_gpio_init_data *gpio_pd = &gpio_init_data[i];
+ base_add = pmc_ext_control_base[gpio_pd->gpio_nr];
+
+ if (gpio_pd->ext_ctrl_flag & EXT_PWR_REQ) {
+ ret = tps80031_ext_power_req_config(tps80031->dev,
+ gpio_pd->ext_ctrl_flag,
+ preq_bit_pos[gpio_pd->gpio_nr],
+ base_add + EXT_CONTROL_CFG_STATE,
+ base_add + EXT_CONTROL_CFG_TRANS);
+ if (ret < 0)
+ dev_warn(tps80031->dev, "Ext pwrreq GPIO "
+ "sleep control fails\n");
+ }
+
+ if (gpio_pd->ext_ctrl_flag & PWR_OFF_ON_SLEEP) {
+ ret = tps80031_update(tps80031->dev, SLAVE_ID1,
+ base_add + EXT_CONTROL_CFG_TRANS, 0x0, 0xC);
+ if (ret < 0)
+ dev_warn(tps80031->dev, "GPIO OFF on sleep "
+ "control fails\n");
+ }
+
+ if (gpio_pd->ext_ctrl_flag & PWR_ON_ON_SLEEP) {
+ ret = tps80031_update(tps80031->dev, SLAVE_ID1,
+ base_add + EXT_CONTROL_CFG_TRANS, 0x4, 0xC);
+ if (ret < 0)
+ dev_warn(tps80031->dev, "GPIO ON on sleep "
+ "control fails\n");
+ }
}
tps80031->gpio.owner = THIS_MODULE;
@@ -917,20 +940,51 @@ static void tps80031_clk32k_enable(struct tps80031 *tps80031, int base_add)
static void tps80031_clk32k_init(struct tps80031 *tps80031,
struct tps80031_platform_data *pdata)
{
- struct tps80031_32kclock_plat_data *clk32k_pdata;
+ int ret;
+ struct tps80031_clk32k_init_data *clk32_idata = pdata->clk32k_init_data;
+ int data_size = pdata->clk32k_init_data_size;
+ static int clk32k_preq_bit_pos[TPS80031_CLOCK32K_NR] = {-1, 20, 19};
+ int base_add;
+ int i;
- if (!(pdata && pdata->clk32k_pdata))
+ if (!clk32_idata || !data_size)
return;
- clk32k_pdata = pdata->clk32k_pdata;
- if (clk32k_pdata->en_clk32kao)
- tps80031_clk32k_enable(tps80031, CLK32KAO_BASE_ADD);
+ /* Configure the external request mode */
+ for (i = 0; i < data_size; ++i) {
+ struct tps80031_clk32k_init_data *clk32_pd = &clk32_idata[i];
+ base_add = pmc_clk32k_control_base[clk32_pd->clk32k_nr];
+ if (clk32_pd->enable)
+ tps80031_clk32k_enable(tps80031, base_add);
+
+ if ((clk32_pd->ext_ctrl_flag & EXT_PWR_REQ) &&
+ (clk32k_preq_bit_pos[clk32_pd->clk32k_nr] != -1)) {
+ ret = tps80031_ext_power_req_config(tps80031->dev,
+ clk32_pd->ext_ctrl_flag,
+ clk32k_preq_bit_pos[clk32_pd->clk32k_nr],
+ base_add + EXT_CONTROL_CFG_STATE,
+ base_add + EXT_CONTROL_CFG_TRANS);
+ if (ret < 0)
+ dev_warn(tps80031->dev, "Clk32 ext control "
+ "fails\n");
+ }
- if (clk32k_pdata->en_clk32kg)
- tps80031_clk32k_enable(tps80031, CLK32KG_BASE_ADD);
+ if (clk32_pd->ext_ctrl_flag & PWR_OFF_ON_SLEEP) {
+ ret = tps80031_update(tps80031->dev, SLAVE_ID1,
+ base_add + EXT_CONTROL_CFG_TRANS, 0x0, 0xC);
+ if (ret < 0)
+ dev_warn(tps80031->dev, "clk OFF on sleep "
+ "control fails\n");
+ }
- if (clk32k_pdata->en_clk32kaudio)
- tps80031_clk32k_enable(tps80031, CLK32KAUDIO_BASE_ADD);
+ if (clk32_pd->ext_ctrl_flag & PWR_ON_ON_SLEEP) {
+ ret = tps80031_update(tps80031->dev, SLAVE_ID1,
+ base_add + EXT_CONTROL_CFG_TRANS, 0x4, 0xC);
+ if (ret < 0)
+ dev_warn(tps80031->dev, "clk ON sleep "
+ "control fails\n");
+ }
+ }
}
static int __devinit tps80031_add_subdevs(struct tps80031 *tps80031,
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c
index 9ea5cb9725a6..deca7adebb14 100644
--- a/drivers/regulator/tps80031-regulator.c
+++ b/drivers/regulator/tps80031-regulator.c
@@ -106,7 +106,7 @@ struct tps80031_regulator {
u8 flags;
unsigned int platform_flags;
- enum tps80031_ext_control ext_pwr_ctrl;
+ unsigned int ext_ctrl_flag;
/* used by regulator core */
struct regulator_desc desc;
@@ -160,7 +160,7 @@ static int tps80031_reg_is_enabled(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
- if (ri->ext_pwr_ctrl & EXT_PWR_REQ)
+ if (ri->ext_ctrl_flag & EXT_PWR_REQ)
return true;
return ((ri->state_reg_cache & STATE_MASK) == STATE_ON);
}
@@ -172,7 +172,7 @@ static int tps80031_reg_enable(struct regulator_dev *rdev)
int ret;
uint8_t reg_val;
- if (ri->ext_pwr_ctrl & EXT_PWR_REQ)
+ if (ri->ext_ctrl_flag & EXT_PWR_REQ)
return 0;
reg_val = (ri->state_reg_cache & ~STATE_MASK) |
@@ -194,7 +194,7 @@ static int tps80031_reg_disable(struct regulator_dev *rdev)
int ret;
uint8_t reg_val;
- if (ri->ext_pwr_ctrl & EXT_PWR_REQ)
+ if (ri->ext_ctrl_flag & EXT_PWR_REQ)
return 0;
reg_val = (ri->state_reg_cache & ~STATE_MASK) |
@@ -793,10 +793,12 @@ static int tps80031_power_req_config(struct device *parent,
struct tps80031_regulator_platform_data *tps80031_pdata)
{
int ret;
+ uint8_t reg_val;
+
if (ri->preq_bit < 0)
return 0;
- ret = tps80031_ext_power_req_config(parent, ri->ext_pwr_ctrl,
+ ret = tps80031_ext_power_req_config(parent, ri->ext_ctrl_flag,
ri->preq_bit, ri->state_reg, ri->trans_reg);
if (!ret)
ret = tps80031_read(parent, SLAVE_ID1, ri->trans_reg,
@@ -805,6 +807,25 @@ static int tps80031_power_req_config(struct device *parent,
if (!ret && ri->state_reg)
ret = tps80031_read(parent, SLAVE_ID1, ri->state_reg,
&ri->state_reg_cache);
+ if (ret < 0) {
+ dev_err(ri->dev, "%s() fails\n", __func__);
+ return ret;
+ }
+
+ if (tps80031_pdata->ext_ctrl_flag &
+ (PWR_OFF_ON_SLEEP | PWR_ON_ON_SLEEP)) {
+ reg_val = (ri->trans_reg_cache & ~0xC);
+ if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP)
+ reg_val |= 0x4;
+
+ ret = tps80031_write(parent, SLAVE_ID1, ri->trans_reg,
+ reg_val);
+ if (ret < 0)
+ dev_err(ri->dev, "Not able to write reg 0x%02x\n",
+ ri->trans_reg);
+ else
+ ri->trans_reg_cache = reg_val;
+ }
return ret;
}
@@ -997,7 +1018,7 @@ static int __devinit tps80031_regulator_probe(struct platform_device *pdev)
check_smps_mode_mult(pdev->dev.parent, ri);
ri->platform_flags = tps_pdata->flags;
- ri->ext_pwr_ctrl = tps_pdata->ext_pwr_ctrl;
+ ri->ext_ctrl_flag = tps_pdata->ext_ctrl_flag;
err = tps80031_cache_regulator_register(pdev->dev.parent, ri);
if (err) {