aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/twl-regulator.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2009-12-13 16:19:23 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2009-12-13 18:26:20 -0500
commit441a450554dada1c59fc06fdf068cb0eeba53c6d (patch)
tree95243a824de1ead21b95bbd36bb85a82be09eeca /drivers/regulator/twl-regulator.c
parenta6b49ffd2d4bba53ad172b1e78ee51fe15ab195e (diff)
regulator: Add support for twl6030 regulators
This patch updates the regulator driver to add support for TWL6030 PMIC specific LDO regulators. SMPS resources are not yet supported for TWL6030 and also .set_mode and .get_status for LDO's are yet to be implemented for TWL6030. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Balaji T K <balajitk@ti.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/regulator/twl-regulator.c')
-rw-r--r--drivers/regulator/twl-regulator.c116
1 files changed, 95 insertions, 21 deletions
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 8e1b68a20ef0..7ea1c3a31081 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -52,27 +52,38 @@ struct twlreg_info {
52 * The first three registers of all power resource banks help hardware to 52 * The first three registers of all power resource banks help hardware to
53 * manage the various resource groups. 53 * manage the various resource groups.
54 */ 54 */
55/* Common offset in TWL4030/6030 */
55#define VREG_GRP 0 56#define VREG_GRP 0
57/* TWL4030 register offsets */
56#define VREG_TYPE 1 58#define VREG_TYPE 1
57#define VREG_REMAP 2 59#define VREG_REMAP 2
58#define VREG_DEDICATED 3 /* LDO control */ 60#define VREG_DEDICATED 3 /* LDO control */
59 61/* TWL6030 register offsets */
62#define VREG_TRANS 1
63#define VREG_STATE 2
64#define VREG_VOLTAGE 3
65/* TWL6030 Misc register offsets */
66#define VREG_BC_ALL 1
67#define VREG_BC_REF 2
68#define VREG_BC_PROC 3
69#define VREG_BC_CLK_RST 4
60 70
61static inline int 71static inline int
62twlreg_read(struct twlreg_info *info, unsigned offset) 72twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
63{ 73{
64 u8 value; 74 u8 value;
65 int status; 75 int status;
66 76
67 status = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, 77 status = twl_i2c_read_u8(slave_subgp,
68 &value, info->base + offset); 78 &value, info->base + offset);
69 return (status < 0) ? status : value; 79 return (status < 0) ? status : value;
70} 80}
71 81
72static inline int 82static inline int
73twlreg_write(struct twlreg_info *info, unsigned offset, u8 value) 83twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset,
84 u8 value)
74{ 85{
75 return twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 86 return twl_i2c_write_u8(slave_subgp,
76 value, info->base + offset); 87 value, info->base + offset);
77} 88}
78 89
@@ -82,17 +93,22 @@ twlreg_write(struct twlreg_info *info, unsigned offset, u8 value)
82 93
83static int twlreg_grp(struct regulator_dev *rdev) 94static int twlreg_grp(struct regulator_dev *rdev)
84{ 95{
85 return twlreg_read(rdev_get_drvdata(rdev), VREG_GRP); 96 return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_RECEIVER,
97 VREG_GRP);
86} 98}
87 99
88/* 100/*
89 * Enable/disable regulators by joining/leaving the P1 (processor) group. 101 * Enable/disable regulators by joining/leaving the P1 (processor) group.
90 * We assume nobody else is updating the DEV_GRP registers. 102 * We assume nobody else is updating the DEV_GRP registers.
91 */ 103 */
92 104/* definition for 4030 family */
93#define P3_GRP BIT(7) /* "peripherals" */ 105#define P3_GRP_4030 BIT(7) /* "peripherals" */
94#define P2_GRP BIT(6) /* secondary processor, modem, etc */ 106#define P2_GRP_4030 BIT(6) /* secondary processor, modem, etc */
95#define P1_GRP BIT(5) /* CPU/Linux */ 107#define P1_GRP_4030 BIT(5) /* CPU/Linux */
108/* definition for 6030 family */
109#define P3_GRP_6030 BIT(2) /* secondary processor, modem, etc */
110#define P2_GRP_6030 BIT(1) /* "peripherals" */
111#define P1_GRP_6030 BIT(0) /* CPU/Linux */
96 112
97static int twlreg_is_enabled(struct regulator_dev *rdev) 113static int twlreg_is_enabled(struct regulator_dev *rdev)
98{ 114{
@@ -101,7 +117,11 @@ static int twlreg_is_enabled(struct regulator_dev *rdev)
101 if (state < 0) 117 if (state < 0)
102 return state; 118 return state;
103 119
104 return (state & P1_GRP) != 0; 120 if (twl_class_is_4030())
121 state &= P1_GRP_4030;
122 else
123 state &= P1_GRP_6030;
124 return state;
105} 125}
106 126
107static int twlreg_enable(struct regulator_dev *rdev) 127static int twlreg_enable(struct regulator_dev *rdev)
@@ -109,12 +129,16 @@ static int twlreg_enable(struct regulator_dev *rdev)
109 struct twlreg_info *info = rdev_get_drvdata(rdev); 129 struct twlreg_info *info = rdev_get_drvdata(rdev);
110 int grp; 130 int grp;
111 131
112 grp = twlreg_read(info, VREG_GRP); 132 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
113 if (grp < 0) 133 if (grp < 0)
114 return grp; 134 return grp;
115 135
116 grp |= P1_GRP; 136 if (twl_class_is_4030())
117 return twlreg_write(info, VREG_GRP, grp); 137 grp |= P1_GRP_4030;
138 else
139 grp |= P1_GRP_6030;
140
141 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
118} 142}
119 143
120static int twlreg_disable(struct regulator_dev *rdev) 144static int twlreg_disable(struct regulator_dev *rdev)
@@ -122,18 +146,25 @@ static int twlreg_disable(struct regulator_dev *rdev)
122 struct twlreg_info *info = rdev_get_drvdata(rdev); 146 struct twlreg_info *info = rdev_get_drvdata(rdev);
123 int grp; 147 int grp;
124 148
125 grp = twlreg_read(info, VREG_GRP); 149 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
126 if (grp < 0) 150 if (grp < 0)
127 return grp; 151 return grp;
128 152
129 grp &= ~P1_GRP; 153 if (twl_class_is_4030())
130 return twlreg_write(info, VREG_GRP, grp); 154 grp &= ~P1_GRP_4030;
155 else
156 grp &= ~P1_GRP_6030;
157
158 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
131} 159}
132 160
133static int twlreg_get_status(struct regulator_dev *rdev) 161static int twlreg_get_status(struct regulator_dev *rdev)
134{ 162{
135 int state = twlreg_grp(rdev); 163 int state = twlreg_grp(rdev);
136 164
165 if (twl_class_is_6030())
166 return 0; /* FIXME return for 6030 regulator */
167
137 if (state < 0) 168 if (state < 0)
138 return state; 169 return state;
139 state &= 0x0f; 170 state &= 0x0f;
@@ -152,6 +183,9 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
152 unsigned message; 183 unsigned message;
153 int status; 184 int status;
154 185
186 if (twl_class_is_6030())
187 return 0; /* FIXME return for 6030 regulator */
188
155 /* We can only set the mode through state machine commands... */ 189 /* We can only set the mode through state machine commands... */
156 switch (mode) { 190 switch (mode) {
157 case REGULATOR_MODE_NORMAL: 191 case REGULATOR_MODE_NORMAL:
@@ -168,7 +202,7 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
168 status = twlreg_grp(rdev); 202 status = twlreg_grp(rdev);
169 if (status < 0) 203 if (status < 0)
170 return status; 204 return status;
171 if (!(status & (P3_GRP | P2_GRP | P1_GRP))) 205 if (!(status & (P3_GRP_4030 | P2_GRP_4030 | P1_GRP_4030)))
172 return -EACCES; 206 return -EACCES;
173 207
174 status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 208 status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
@@ -260,7 +294,29 @@ static const u16 VSIM_VSEL_table[] = {
260static const u16 VDAC_VSEL_table[] = { 294static const u16 VDAC_VSEL_table[] = {
261 1200, 1300, 1800, 1800, 295 1200, 1300, 1800, 1800,
262}; 296};
263 297static const u16 VAUX1_6030_VSEL_table[] = {
298 1000, 1300, 1800, 2500,
299 2800, 2900, 3000, 3000,
300};
301static const u16 VAUX2_6030_VSEL_table[] = {
302 1200, 1800, 2500, 2750,
303 2800, 2800, 2800, 2800,
304};
305static const u16 VAUX3_6030_VSEL_table[] = {
306 1000, 1200, 1300, 1800,
307 2500, 2800, 3000, 3000,
308};
309static const u16 VMMC_VSEL_table[] = {
310 1200, 1800, 2800, 2900,
311 3000, 3000, 3000, 3000,
312};
313static const u16 VPP_VSEL_table[] = {
314 1800, 1900, 2000, 2100,
315 2200, 2300, 2400, 2500,
316};
317static const u16 VUSIM_VSEL_table[] = {
318 1200, 1800, 2500, 2900,
319};
264 320
265static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) 321static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index)
266{ 322{
@@ -288,7 +344,8 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
288 344
289 /* use the first in-range value */ 345 /* use the first in-range value */
290 if (min_uV <= uV && uV <= max_uV) 346 if (min_uV <= uV && uV <= max_uV)
291 return twlreg_write(info, VREG_DEDICATED, vsel); 347 return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
348 VREG_VOLTAGE, vsel);
292 } 349 }
293 350
294 return -EDOM; 351 return -EDOM;
@@ -297,7 +354,8 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
297static int twlldo_get_voltage(struct regulator_dev *rdev) 354static int twlldo_get_voltage(struct regulator_dev *rdev)
298{ 355{
299 struct twlreg_info *info = rdev_get_drvdata(rdev); 356 struct twlreg_info *info = rdev_get_drvdata(rdev);
300 int vsel = twlreg_read(info, VREG_DEDICATED); 357 int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
358 VREG_VOLTAGE);
301 359
302 if (vsel < 0) 360 if (vsel < 0)
303 return vsel; 361 return vsel;
@@ -360,6 +418,10 @@ static struct regulator_ops twlfixed_ops = {
360 TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030) 418 TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030)
361#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \ 419#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \
362 TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030) 420 TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030)
421#define TWL6030_ADJUSTABLE_LDO(label, offset, num) \
422 TWL_ADJUSTABLE_LDO(label, offset, num, TWL6030)
423#define TWL6030_FIXED_LDO(label, offset, mVolts, num) \
424 TWL_FIXED_LDO(label, offset, mVolts, num, TWL6030)
363 425
364#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \ 426#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \
365 .base = offset, \ 427 .base = offset, \
@@ -420,6 +482,18 @@ static struct twlreg_info twl_regs[] = {
420 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), 482 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
421 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), 483 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
422 /* VUSBCP is managed *only* by the USB subchip */ 484 /* VUSBCP is managed *only* by the USB subchip */
485
486 /* 6030 REG with base as PMC Slave Misc : 0x0030 */
487 TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1),
488 TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2),
489 TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3),
490 TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4),
491 TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5),
492 TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7),
493 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15),
494 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16),
495 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17),
496 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18)
423}; 497};
424 498
425static int twlreg_probe(struct platform_device *pdev) 499static int twlreg_probe(struct platform_device *pdev)