summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-02-19 22:32:51 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-04-26 15:52:07 -0700
commit59ee140e5bded65b281bf0fafb9f2a6d849fb3e3 (patch)
tree24cadab56360720086b4a2d79c3c295f58928334
parentdb54b8b78143025e1ef164f2018197f8b6876ce2 (diff)
ARM: tegra: cardhu: Enable VDD_CPU external control
Original-Change-Id: Ie2b9c7bb441c72c105ca3205bdd42a8dcd76d9ef Reviewed-on: http://git-master/r/20230 Reviewed-by: Hoang Pham <hopham@nvidia.com> Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com> Change-Id: I9896c0568ee5103a2608cf4abcab36f592a83f21
-rw-r--r--arch/arm/mach-tegra/board-cardhu-power.c34
-rwxr-xr-xdrivers/regulator/tps6591x-regulator.c118
-rw-r--r--include/linux/regulator/tps6591x-regulator.h7
3 files changed, 122 insertions, 37 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-power.c b/arch/arm/mach-tegra/board-cardhu-power.c
index 7aec78614bd1..2181c45a44c0 100644
--- a/arch/arm/mach-tegra/board-cardhu-power.c
+++ b/arch/arm/mach-tegra/board-cardhu-power.c
@@ -136,7 +136,7 @@ static struct regulator_consumer_supply tps6591x_ldo8_supply[] = {
};
#define TPS_PDATA_INIT_SUPPLY(_id, _minmv, _maxmv, _supply_reg, _always_on, \
- _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply) \
+ _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, _ectrl) \
static struct tps6591x_regulator_platform_data pdata_##_id = \
{ \
.regulator = { \
@@ -159,11 +159,12 @@ static struct regulator_consumer_supply tps6591x_ldo8_supply[] = {
}, \
.init_uV = _init_uV * 1000, \
.init_enable = _init_enable, \
- .init_apply = _init_apply \
+ .init_apply = _init_apply, \
+ .ectrl = _ectrl \
}
#define TPS_PDATA_INIT(_id, _minmv, _maxmv, _supply_reg, _always_on, \
- _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply) \
+ _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, _ectrl) \
static struct tps6591x_regulator_platform_data pdata_##_id = \
{ \
.regulator = { \
@@ -185,24 +186,25 @@ static struct regulator_consumer_supply tps6591x_ldo8_supply[] = {
}, \
.init_uV = _init_uV * 1000, \
.init_enable = _init_enable, \
- .init_apply = _init_apply \
+ .init_apply = _init_apply, \
+ .ectrl = _ectrl \
}
-TPS_PDATA_INIT(vdd1, 600, 1500, 0, 1, 1, 0, -1, 0, 0);
-TPS_PDATA_INIT(vdd2, 600, 1500, 0, 1, 1, 0, -1, 0, 0);
-TPS_PDATA_INIT(vddctrl, 600, 1400, 0, 1, 1, 0, -1, 0, 0);
-TPS_PDATA_INIT(vio, 1500, 3300, 0, 1, 1, 0, -1, 0, 0);
+TPS_PDATA_INIT(vdd1, 600, 1500, 0, 1, 1, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT(vdd2, 600, 1500, 0, 1, 1, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT(vddctrl, 600, 1400, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_EN1);
+TPS_PDATA_INIT(vio, 1500, 3300, 0, 1, 1, 0, -1, 0, 0, 0);
-TPS_PDATA_INIT_SUPPLY(ldo1, 1000, 3300, VDD_2, 0, 0, 0, -1, 0, 0);
-TPS_PDATA_INIT_SUPPLY(ldo2, 1000, 3300, VDD_2, 0, 0, 0, -1, 0, 0);
+TPS_PDATA_INIT_SUPPLY(ldo1, 1000, 3300, VDD_2, 0, 0, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT_SUPPLY(ldo2, 1000, 3300, VDD_2, 0, 0, 0, -1, 0, 0, 0);
-TPS_PDATA_INIT(ldo3, 1000, 3300, 0, 0, 0, 0, -1, 0, 0);
-TPS_PDATA_INIT(ldo4, 1000, 3300, 0, 0, 0, 0, -1, 0, 0);
-TPS_PDATA_INIT(ldo5, 1000, 3300, 0, 0, 0, 0, -1, 0, 0);
+TPS_PDATA_INIT(ldo3, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT(ldo4, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT(ldo5, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0);
-TPS_PDATA_INIT_SUPPLY(ldo6, 1000, 3300, VIO, 0, 0, 0, -1, 0, 0);
-TPS_PDATA_INIT_SUPPLY(ldo7, 1000, 3300, VIO, 0, 0, 0, -1, 0, 0);
-TPS_PDATA_INIT_SUPPLY(ldo8, 1000, 3300, VIO, 0, 0, 0, -1, 0, 0);
+TPS_PDATA_INIT_SUPPLY(ldo6, 1000, 3300, VIO, 0, 0, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT_SUPPLY(ldo7, 1000, 3300, VIO, 0, 0, 0, -1, 0, 0, 0);
+TPS_PDATA_INIT_SUPPLY(ldo8, 1000, 3300, VIO, 0, 0, 0, -1, 0, 0, 0);
/* Currently tps6591x-rtc driver is not available need to enable once driver is ready */
/*
static struct tps6591x_rtc_platform_data rtc_data = {
diff --git a/drivers/regulator/tps6591x-regulator.c b/drivers/regulator/tps6591x-regulator.c
index 6931d92ee27f..0ff61a375313 100755
--- a/drivers/regulator/tps6591x-regulator.c
+++ b/drivers/regulator/tps6591x-regulator.c
@@ -50,8 +50,14 @@
#define TPS6591X_LDO6_ADD 0x35
#define TPS6591X_LDO7_ADD 0x34
#define TPS6591X_LDO8_ADD 0x33
+#define TPS6591X_EN1_LDO_ADD 0x45
+#define TPS6591X_EN1_SMPS_ADD 0x46
+#define TPS6591X_EN2_LDO_ADD 0x47
+#define TPS6591X_EN2_SMPS_ADD 0x48
#define TPS6591X_INVALID_ADD 0xFF
+#define EN1_EN2_OFFSET 2
+
struct tps6591x_register_info {
unsigned char addr;
unsigned char nbits;
@@ -71,6 +77,7 @@ struct tps6591x_regulator {
struct tps6591x_register_info supply_reg;
struct tps6591x_register_info op_reg;
struct tps6591x_register_info sr_reg;
+ struct tps6591x_register_info en1_reg;
int *voltages;
};
@@ -80,6 +87,52 @@ static inline struct device *to_tps6591x_dev(struct regulator_dev *rdev)
return rdev_get_dev(rdev)->parent->parent;
}
+static int __tps6591x_ext_control_set(struct device *parent,
+ struct tps6591x_regulator *ri,
+ enum tps6591x_ext_control ectrl)
+{
+ int ret;
+ uint8_t mask, reg_val, addr;
+
+ /* For regulator that has separate operational and sleep register make
+ sure that operational is used and clear sleep register to turn
+ regulator off when external control is inactive */
+ if (ri->supply_type == supply_type_sr_op_reg) {
+ ret = tps6591x_read(parent, ri->op_reg.addr, &reg_val);
+ if (ret)
+ return ret;
+
+ if (reg_val & 0x80) { /* boot has used sr - switch to op */
+ ret = tps6591x_read(parent, ri->sr_reg.addr, &reg_val);
+ if (ret)
+ return ret;
+
+ mask = ((1 << ri->sr_reg.nbits) - 1)
+ << ri->sr_reg.shift_bits;
+ reg_val &= mask;
+ ret = tps6591x_write(parent, ri->op_reg.addr, reg_val);
+ if (ret)
+ return ret;
+ }
+ ret = tps6591x_write(parent, ri->sr_reg.addr, 0);
+ if (ret)
+ return ret;
+ }
+
+ switch (ectrl) {
+ case EXT_CTRL_EN1:
+ addr = ri->en1_reg.addr;
+ break;
+ case EXT_CTRL_EN2:
+ addr = ri->en1_reg.addr + EN1_EN2_OFFSET;
+ break;
+ default:
+ return -EINVAL;
+ }
+ mask = ((1 << ri->en1_reg.nbits) - 1) << ri->en1_reg.shift_bits;
+ return tps6591x_update(parent, addr, mask, mask);
+}
+
static int __tps6591x_vio_set_voltage(struct device *parent,
struct tps6591x_regulator *ri,
int min_uV, int max_uV)
@@ -441,7 +494,7 @@ static int tps6591x_vdd_voltages[] = {
#define TPS6591X_REGULATOR(_id, vdata, _ops, s_addr, s_nbits, s_shift, \
s_type, op_addr, op_nbits, op_shift, sr_addr, \
- sr_nbits, sr_shift) \
+ sr_nbits, sr_shift, en1_addr, en1_shift) \
.desc = { \
.name = tps6591x_rails(_id), \
.ops = &tps6591x_regulator_##_ops, \
@@ -466,51 +519,63 @@ static int tps6591x_vdd_voltages[] = {
.nbits = sr_nbits, \
.shift_bits = sr_shift, \
}, \
+ .en1_reg = { \
+ .addr = TPS6591X_##en1_addr##_ADD, \
+ .nbits = 1, \
+ .shift_bits = en1_shift, \
+ }, \
.voltages = tps6591x_##vdata##_voltages,
-#define TPS6591X_VIO(_id, vdata, s_addr, s_nbits, s_shift, s_type) \
+#define TPS6591X_VIO(_id, vdata, s_addr, s_nbits, s_shift, s_type, \
+ en1_shift) \
{ \
TPS6591X_REGULATOR(_id, vdata, vio_ops, s_addr, s_nbits, \
- s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0) \
+ s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \
+ EN1_SMPS, en1_shift) \
}
-#define TPS6591X_LDO1(_id, vdata, s_addr, s_nbits, s_shift, s_type) \
+#define TPS6591X_LDO1(_id, vdata, s_addr, s_nbits, s_shift, s_type, \
+ en1_shift) \
{ \
TPS6591X_REGULATOR(_id, vdata, ldo1_ops, s_addr, s_nbits, \
- s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0) \
+ s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \
+ EN1_LDO, en1_shift) \
}
-#define TPS6591X_LDO3(_id, vdata, s_addr, s_nbits, s_shift, s_type) \
+#define TPS6591X_LDO3(_id, vdata, s_addr, s_nbits, s_shift, s_type, \
+ en1_shift) \
{ \
TPS6591X_REGULATOR(_id, vdata, ldo3_ops, s_addr, s_nbits, \
- s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0) \
+ s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \
+ EN1_LDO, en1_shift) \
}
#define TPS6591X_VDD(_id, vdata, s_addr, s_nbits, s_shift, s_type, \
op_addr, op_nbits, op_shift, sr_addr, sr_nbits, \
- sr_shift) \
+ sr_shift, en1_shift) \
{ \
TPS6591X_REGULATOR(_id, vdata, vdd_ops, s_addr, s_nbits, \
s_shift, s_type, op_addr, op_nbits, op_shift, \
- sr_addr, sr_nbits, sr_shift) \
+ sr_addr, sr_nbits, sr_shift, EN1_SMPS, \
+ en1_shift) \
}
static struct tps6591x_regulator tps6591x_regulator[] = {
- TPS6591X_VIO(VIO, vio, VIO, 2, 2, single_reg),
- TPS6591X_LDO1(LDO_1, ldo124, LDO1, 6, 2, single_reg),
- TPS6591X_LDO1(LDO_2, ldo124, LDO2, 6, 2, single_reg),
- TPS6591X_LDO3(LDO_3, ldo35678, LDO3, 5, 2, single_reg),
- TPS6591X_LDO1(LDO_4, ldo124, LDO4, 6, 2, single_reg),
- TPS6591X_LDO3(LDO_5, ldo35678, LDO5, 5, 2, single_reg),
- TPS6591X_LDO3(LDO_6, ldo35678, LDO6, 5, 2, single_reg),
- TPS6591X_LDO3(LDO_7, ldo35678, LDO7, 5, 2, single_reg),
- TPS6591X_LDO3(LDO_8, ldo35678, LDO8, 5, 2, single_reg),
+ TPS6591X_VIO(VIO, vio, VIO, 2, 2, single_reg, 0),
+ TPS6591X_LDO1(LDO_1, ldo124, LDO1, 6, 2, single_reg, 1),
+ TPS6591X_LDO1(LDO_2, ldo124, LDO2, 6, 2, single_reg, 2),
+ TPS6591X_LDO3(LDO_3, ldo35678, LDO3, 5, 2, single_reg, 7),
+ TPS6591X_LDO1(LDO_4, ldo124, LDO4, 6, 2, single_reg, 6),
+ TPS6591X_LDO3(LDO_5, ldo35678, LDO5, 5, 2, single_reg, 3),
+ TPS6591X_LDO3(LDO_6, ldo35678, LDO6, 5, 2, single_reg, 0),
+ TPS6591X_LDO3(LDO_7, ldo35678, LDO7, 5, 2, single_reg, 5),
+ TPS6591X_LDO3(LDO_8, ldo35678, LDO8, 5, 2, single_reg, 4),
TPS6591X_VDD(VDD_1, vdd, VDD1, 2, 0, sr_op_reg, VDD1_OP,
- 7, 0, VDD1_SR, 7, 0),
+ 7, 0, VDD1_SR, 7, 0, 1),
TPS6591X_VDD(VDD_2, vdd, VDD2, 2, 0, sr_op_reg, VDD2_OP,
- 7, 0, VDD2_SR, 7, 0),
+ 7, 0, VDD2_SR, 7, 0, 2),
TPS6591X_VDD(VDDCTRL, vdd, VDDCTRL, 2, 0, sr_op_reg,
- VDDCTRL_OP, 7, 0, VDDCTRL_SR, 7, 0),
+ VDDCTRL_OP, 7, 0, VDDCTRL_SR, 7, 0, 3),
};
static inline int tps6591x_regulator_preinit(struct device *parent,
@@ -519,6 +584,17 @@ static inline int tps6591x_regulator_preinit(struct device *parent,
{
int ret;
+ if (tps6591x_pdata->ectrl != EXT_CTRL_NONE) {
+ ret = __tps6591x_ext_control_set(
+ parent, ri, tps6591x_pdata->ectrl);
+ if (ret < 0) {
+ pr_err("Not able to configure external control %d"
+ " for rail %d err %d\n", tps6591x_pdata->ectrl,
+ ri->desc.id, ret);
+ return ret;
+ }
+ }
+
if (!tps6591x_pdata->init_apply)
return 0;
diff --git a/include/linux/regulator/tps6591x-regulator.h b/include/linux/regulator/tps6591x-regulator.h
index ade9978b3cb6..970736bc5c31 100644
--- a/include/linux/regulator/tps6591x-regulator.h
+++ b/include/linux/regulator/tps6591x-regulator.h
@@ -26,6 +26,12 @@
#include <linux/regulator/machine.h>
+enum tps6591x_ext_control {
+ EXT_CTRL_NONE = 0x0,
+ EXT_CTRL_EN1,
+ EXT_CTRL_EN2
+};
+
/*
* struct tps6591x_regulator_platform_data - tps6591x regulator platform data.
*
@@ -40,6 +46,7 @@ struct tps6591x_regulator_platform_data {
int init_uV;
unsigned init_enable:1;
unsigned init_apply:1;
+ enum tps6591x_ext_control ectrl;
};
#endif /* __REGULATOR_TPS6591X_H */