summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRobin Gong <b38343@freescale.com>2012-10-26 19:19:43 +0800
committerRobin Gong <b38343@freescale.com>2012-10-26 19:37:31 +0800
commite9a48abfe3fd546a75c84e99dc2bd316b0a6996b (patch)
tree1775820849fdef0bbcf9ecaa97364f08c8e52111 /drivers
parent7d8ba52da45ad728917f0fdf372224254f1f092e (diff)
ENGR00230981-3 pfuze: add suspend voltage set interface
Implement set_suspend_voltage for buck switch of PF100, and set_suspend_enable /set_suspend_disable interface for LDO(VGENx). Signed-off-by: Robin Gong <b38343@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/pfuze-regulator.h24
-rw-r--r--drivers/regulator/pfuze100-regulator.c122
2 files changed, 130 insertions, 16 deletions
diff --git a/drivers/regulator/pfuze-regulator.h b/drivers/regulator/pfuze-regulator.h
index 20d4766e91ea..113355ca250f 100644
--- a/drivers/regulator/pfuze-regulator.h
+++ b/drivers/regulator/pfuze-regulator.h
@@ -23,9 +23,13 @@
struct pfuze_regulator {
struct regulator_desc desc;
unsigned int reg;
+ unsigned int stby_reg;
unsigned char enable_bit;
+ unsigned char stby_bit;
unsigned char vsel_shift;
unsigned char vsel_mask;
+ unsigned char stby_vsel_shift;
+ unsigned char stby_vsel_mask;
int const *voltages;
};
@@ -47,6 +51,7 @@ struct pfuze_regulator_priv {
}, \
.reg = prefix ## _reg, \
.enable_bit = prefix ## _reg ## _ ## EN, \
+ .stby_bit = prefix ## _reg ## _ ## STBY, \
.vsel_shift = prefix ## _reg ## _ ## VSEL,\
.vsel_mask = prefix ## _reg ## _ ## VSEL_M,\
.voltages = _voltages, \
@@ -64,6 +69,25 @@ struct pfuze_regulator_priv {
.reg = prefix ## _reg, \
.vsel_shift = prefix ## _reg ## _ ## VSEL,\
.vsel_mask = prefix ## _reg ## _ ## VSEL_M,\
+ .stby_reg = prefix ## _reg ## _ ## STBY, \
+ .stby_vsel_shift = prefix ## _reg ## _ ## STBY_VSEL,\
+ .stby_vsel_mask = prefix ## _reg ## _ ## STBY_VSEL_M,\
+ .voltages = _voltages, \
+ }
+
+#define PFUZE_SWBST_DEFINE(prefix, _name, _reg, _voltages, _ops) \
+ [prefix ## _name] = { \
+ .desc = { \
+ .name = #prefix "_" #_name, \
+ .n_voltages = ARRAY_SIZE(_voltages), \
+ .ops = &_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = prefix ## _name, \
+ .owner = THIS_MODULE, \
+ }, \
+ .reg = prefix ## _reg, \
+ .vsel_shift = prefix ## _reg ## _ ## VSEL,\
+ .vsel_mask = prefix ## _reg ## _ ## VSEL_M,\
.voltages = _voltages, \
}
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 34ca0fb45961..17a8da1e2099 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -159,6 +159,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
PFUZE_SW_DEFINE(PFUZE100_, name, reg, voltages, \
pfuze100_sw_regulator_ops)
+#define PFUZE100_SWBST_DEFINE(name, reg, voltages) \
+ PFUZE_SWBST_DEFINE(PFUZE100_, name, reg, voltages, \
+ pfuze100_sw_regulator_ops)
+
#define PFUZE100_VGEN_DEFINE(name, reg, voltages) \
PFUZE_DEFINE(PFUZE100_, name, reg, voltages, \
pfuze100_ldo_regulator_ops)
@@ -167,6 +171,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW1AVOL_VSEL 0
#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1AVOL_STBY 33
+#define PFUZE100_SW1AVOL_STBY_VSEL 0
+#define PFUZE100_SW1AVOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW1AOFF 34
#define PFUZE100_SW1AOFF_OFF_VAL (0x0<<0)
#define PFUZE100_SW1AOFF_OFF_M (0x3f<<0)
@@ -192,6 +200,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW1BVOL_VSEL 0
#define PFUZE100_SW1BVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1BVOL_STBY 40
+#define PFUZE100_SW1BVOL_STBY_VSEL 0
+#define PFUZE100_SW1BVOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW1BOFF 41
#define PFUZE100_SW1BOFF_OFF_VAL 0x0
#define PFUZE100_SW1BOFF_OFF_M (0x3f<<0)
@@ -217,6 +229,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW1CVOL_VSEL 0
#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1CVOL_STBY 47
+#define PFUZE100_SW1CVOL_STBY_VSEL 0
+#define PFUZE100_SW1CVOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW1COFF 48
#define PFUZE100_SW1COFF_OFF_VAL 0x0
#define PFUZE100_SW1COFF_OFF_M (0x3f<<0)
@@ -242,6 +258,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW2VOL_VSEL 0
#define PFUZE100_SW2VOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW2VOL_STBY 54
+#define PFUZE100_SW2VOL_STBY_VSEL 0
+#define PFUZE100_SW2VOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW2OFF 55
#define PFUZE100_SW2OFF_OFF_VAL 0x0
#define PFUZE100_SW2OFF_OFF_M (0x7f<<0)
@@ -267,6 +287,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW3AVOL_VSEL 0
#define PFUZE100_SW3AVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW3AVOL_STBY 61
+#define PFUZE100_SW3AVOL_STBY_VSEL 0
+#define PFUZE100_SW3AVOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW3AOFF 62
#define PFUZE100_SW3AOFF_OFF_VAL 0x0
#define PFUZE100_SW3AOFF_OFF_M (0x3f<<0)
@@ -292,6 +316,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW3BVOL_VSEL 0
#define PFUZE100_SW3BVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW3BVOL_STBY 68
+#define PFUZE100_SW3BVOL_STBY_VSEL 0
+#define PFUZE100_SW3BVOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW3BOFF 69
#define PFUZE100_SW3BOFF_OFF_VAL 0x0
#define PFUZE100_SW3BOFF_OFF_M (0x3f<<0)
@@ -317,6 +345,10 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_SW4VOL_VSEL 0
#define PFUZE100_SW4VOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW4VOL_STBY 75
+#define PFUZE100_SW4VOL_STBY_VSEL 0
+#define PFUZE100_SW4VOL_STBY_VSEL_M (0x3f<<0)
+
#define PFUZE100_SW4OFF 76
#define PFUZE100_SW4OFF_OFF_VAL 0x0
#define PFUZE100_SW4OFF_OFF_M (0x3f<<0)
@@ -339,8 +371,6 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
/*SWBST*/
#define PFUZE100_SWBSTCON1 102
-#define PFUZE100_SWBSTCON1_STBY_VAL 0x0
-#define PFUZE100_SWBSTCON1_STBY_M (0x3<<5)
#define PFUZE100_SWBSTCON1_SWBSTMOD_VAL (0x1<<2)
#define PFUZE100_SWBSTCON1_SWBSTMOD_M (0x3<<2)
#define PFUZE100_SWBSTCON1_VSEL 0
@@ -354,8 +384,7 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#define PFUZE100_VSNVSVOL_VSEL_M (0x3<<0)
/*VGEN1*/
#define PFUZE100_VGEN1VOL 108
-#define PFUZE100_VGEN1VOL_STBY_VAL 0x0
-#define PFUZE100_VGEN1VOL_STBY_M (0x1<<5)
+#define PFUZE100_VGEN1VOL_STBY (0x1<<5)
#define PFUZE100_VGEN1VOL_EN (0x1<<4)
#define PFUZE100_VGEN1VOL_VSEL 0
#ifdef PFUZE100_FIRST_VERSION
@@ -365,8 +394,7 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#endif
/*VGEN2*/
#define PFUZE100_VGEN2VOL 109
-#define PFUZE100_VGEN2VOL_STBY_VAL 0x0
-#define PFUZE100_VGEN2VOL_STBY_M (0x1<<5)
+#define PFUZE100_VGEN2VOL_STBY (0x1<<5)
#define PFUZE100_VGEN2VOL_EN (0x1<<4)
#define PFUZE100_VGEN2VOL_VSEL 0
#ifdef PFUZE100_FIRST_VERSION
@@ -376,29 +404,25 @@ static struct regulator_ops pfuze100_sw_regulator_ops;
#endif
/*VGEN3*/
#define PFUZE100_VGEN3VOL 110
-#define PFUZE100_VGEN3VOL_STBY_VAL 0x0
-#define PFUZE100_VGEN3VOL_STBY_M (0x1<<5)
+#define PFUZE100_VGEN3VOL_STBY (0x1<<5)
#define PFUZE100_VGEN3VOL_EN (0x1<<4)
#define PFUZE100_VGEN3VOL_VSEL 0
#define PFUZE100_VGEN3VOL_VSEL_M (0xf<<0)
/*VGEN4*/
#define PFUZE100_VGEN4VOL 111
-#define PFUZE100_VGEN4VOL_STBY_VAL 0x0
-#define PFUZE100_VGEN4VOL_STBY_M (0x1<<5)
+#define PFUZE100_VGEN4VOL_STBY (0x1<<5)
#define PFUZE100_VGEN4VOL_EN (0x1<<4)
#define PFUZE100_VGEN4VOL_VSEL 0
#define PFUZE100_VGEN4VOL_VSEL_M (0xf<<0)
/*VGEN5*/
#define PFUZE100_VGEN5VOL 112
-#define PFUZE100_VGEN5VOL_STBY_VAL 0x0
-#define PFUZE100_VGEN5VOL_STBY_M (0x1<<5)
+#define PFUZE100_VGEN5VOL_STBY (0x1<<5)
#define PFUZE100_VGEN5VOL_EN (0x1<<4)
#define PFUZE100_VGEN5VOL_VSEL 0
#define PFUZE100_VGEN5VOL_VSEL_M (0xf<<0)
/*VGEN6*/
#define PFUZE100_VGEN6VOL 113
-#define PFUZE100_VGEN6VOL_STBY_VAL 0x0
-#define PFUZE100_VGEN6VOL_STBY_M (0x1<<5)
+#define PFUZE100_VGEN6VOL_STBY (0x1<<5)
#define PFUZE100_VGEN6VOL_EN (0x1<<4)
#define PFUZE100_VGEN6VOL_VSEL 0
#define PFUZE100_VGEN6VOL_VSEL_M (0xf<<0)
@@ -410,8 +434,8 @@ static struct pfuze_regulator pfuze100_regulators[] = {
PFUZE100_SW_DEFINE(SW3A, SW3AVOL, pfuze100_sw3),
PFUZE100_SW_DEFINE(SW3B, SW3BVOL, pfuze100_sw3),
PFUZE100_SW_DEFINE(SW4, SW4VOL, pfuze100_sw4),
- PFUZE100_SW_DEFINE(SWBST, SWBSTCON1, pfuze100_swbst),
- PFUZE100_SW_DEFINE(VSNVS, VSNVSVOL, pfuze100_vsnvs),
+ PFUZE100_SWBST_DEFINE(SWBST, SWBSTCON1, pfuze100_swbst),
+ PFUZE100_SWBST_DEFINE(VSNVS, VSNVSVOL, pfuze100_vsnvs),
PFUZE100_FIXED_VOL_DEFINE(VREFDDR, VREFDDRCON, pfuze100_vrefddr),
PFUZE100_VGEN_DEFINE(VGEN1, VGEN1VOL, pfuze100_vgen12),
PFUZE100_VGEN_DEFINE(VGEN2, VGEN2VOL, pfuze100_vgen12),
@@ -545,6 +569,36 @@ static int pfuze100_regulator_get_voltage(struct regulator_dev *rdev)
return pfuze100_regulators[id].voltages[val];
}
+static int pfuze100_regulator_ldo_standby_enable(struct regulator_dev *rdev)
+{
+ struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+ pfuze_lock(priv->pfuze);
+ ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].reg,
+ pfuze100_regulators[id].stby_bit,
+ 0);
+ pfuze_unlock(priv->pfuze);
+ return ret;
+}
+
+static int pfuze100_regulator_ldo_standby_disable(struct regulator_dev *rdev)
+{
+ struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+ pfuze_lock(priv->pfuze);
+ ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].reg,
+ pfuze100_regulators[id].stby_bit,
+ pfuze100_regulators[id].stby_bit);
+ pfuze_unlock(priv->pfuze);
+ return ret;
+}
+
static struct regulator_ops pfuze100_ldo_regulator_ops = {
.enable = pfuze100_regulator_enable,
.disable = pfuze100_regulator_disable,
@@ -552,6 +606,8 @@ static struct regulator_ops pfuze100_ldo_regulator_ops = {
.list_voltage = pfuze100_regulator_list_voltage,
.set_voltage = pfuze100_regulator_set_voltage,
.get_voltage = pfuze100_regulator_get_voltage,
+ .set_suspend_enable = pfuze100_regulator_ldo_standby_enable,
+ .set_suspend_disable = pfuze100_regulator_ldo_standby_disable,
};
static int pfuze100_fixed_regulator_set_voltage(struct regulator_dev *rdev,
@@ -591,11 +647,45 @@ static int pfuze100_sw_regulator_is_enabled(struct regulator_dev *rdev)
return 1;
}
+static int
+pfuze100_regulator_sw_standby_voltage(struct regulator_dev *rdev, int uV)
+{
+
+ struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
+ int value, id = rdev_get_id(rdev);
+ int ret;
+
+ dev_dbg(rdev_get_dev(rdev), "%s id: %d set standby: %d\n",
+ __func__, id, uV);
+ /* Find the best index */
+ value = pfuze100_get_best_voltage_index(rdev, uV, uV);
+ if (value < 0)
+ return value;
+ pfuze_lock(priv->pfuze);
+ ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].stby_reg,
+ pfuze100_regulators[id].stby_vsel_mask,
+ value << pfuze100_regulators[id].stby_vsel_shift);
+ pfuze_unlock(priv->pfuze);
+ return ret;
+
+}
+
+static int pfuze100_regulator_sw_standby_enable(struct regulator_dev *rdev)
+{
+ return 0;
+}
+static int pfuze100_regulator_sw_standby_disable(struct regulator_dev *rdev)
+{
+ return 0;
+}
static struct regulator_ops pfuze100_sw_regulator_ops = {
.is_enabled = pfuze100_sw_regulator_is_enabled,
.list_voltage = pfuze100_regulator_list_voltage,
.set_voltage = pfuze100_regulator_set_voltage,
.get_voltage = pfuze100_regulator_get_voltage,
+ .set_suspend_enable = pfuze100_regulator_sw_standby_enable,
+ .set_suspend_disable = pfuze100_regulator_sw_standby_disable,
+ .set_suspend_voltage = pfuze100_regulator_sw_standby_voltage,
};
static int __devinit pfuze100_regulator_probe(struct platform_device *pdev)