Commit 441a450554dada1c59fc06fdf068cb0eeba53c6d

Authored by Rajendra Nayak
Committed by Samuel Ortiz
1 parent a6b49ffd2d

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>

Showing 3 changed files with 130 additions and 22 deletions Side-by-side Diff

drivers/regulator/Kconfig
... ... @@ -70,7 +70,7 @@
70 70 for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
71 71  
72 72 config REGULATOR_TWL4030
73   - bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
  73 + bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
74 74 depends on TWL4030_CORE
75 75 help
76 76 This driver supports the voltage regulators provided by
drivers/regulator/twl-regulator.c
... ... @@ -52,27 +52,38 @@
52 52 * The first three registers of all power resource banks help hardware to
53 53 * manage the various resource groups.
54 54 */
  55 +/* Common offset in TWL4030/6030 */
55 56 #define VREG_GRP 0
  57 +/* TWL4030 register offsets */
56 58 #define VREG_TYPE 1
57 59 #define VREG_REMAP 2
58 60 #define VREG_DEDICATED 3 /* LDO control */
  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
59 70  
60   -
61 71 static inline int
62   -twlreg_read(struct twlreg_info *info, unsigned offset)
  72 +twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
63 73 {
64 74 u8 value;
65 75 int status;
66 76  
67   - status = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER,
  77 + status = twl_i2c_read_u8(slave_subgp,
68 78 &value, info->base + offset);
69 79 return (status < 0) ? status : value;
70 80 }
71 81  
72 82 static inline int
73   -twlreg_write(struct twlreg_info *info, unsigned offset, u8 value)
  83 +twlreg_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 87 value, info->base + offset);
77 88 }
78 89  
79 90  
80 91  
... ... @@ -82,18 +93,23 @@
82 93  
83 94 static 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 101 * Enable/disable regulators by joining/leaving the P1 (processor) group.
90 102 * We assume nobody else is updating the DEV_GRP registers.
91 103 */
  104 +/* definition for 4030 family */
  105 +#define P3_GRP_4030 BIT(7) /* "peripherals" */
  106 +#define P2_GRP_4030 BIT(6) /* secondary processor, modem, etc */
  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 */
92 112  
93   -#define P3_GRP BIT(7) /* "peripherals" */
94   -#define P2_GRP BIT(6) /* secondary processor, modem, etc */
95   -#define P1_GRP BIT(5) /* CPU/Linux */
96   -
97 113 static int twlreg_is_enabled(struct regulator_dev *rdev)
98 114 {
99 115 int state = twlreg_grp(rdev);
... ... @@ -101,7 +117,11 @@
101 117 if (state < 0)
102 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  
107 127 static int twlreg_enable(struct regulator_dev *rdev)
108 128  
... ... @@ -109,12 +129,16 @@
109 129 struct twlreg_info *info = rdev_get_drvdata(rdev);
110 130 int grp;
111 131  
112   - grp = twlreg_read(info, VREG_GRP);
  132 + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
113 133 if (grp < 0)
114 134 return grp;
115 135  
116   - grp |= P1_GRP;
117   - return twlreg_write(info, VREG_GRP, grp);
  136 + if (twl_class_is_4030())
  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  
120 144 static int twlreg_disable(struct regulator_dev *rdev)
121 145  
122 146  
... ... @@ -122,18 +146,25 @@
122 146 struct twlreg_info *info = rdev_get_drvdata(rdev);
123 147 int grp;
124 148  
125   - grp = twlreg_read(info, VREG_GRP);
  149 + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
126 150 if (grp < 0)
127 151 return grp;
128 152  
129   - grp &= ~P1_GRP;
130   - return twlreg_write(info, VREG_GRP, grp);
  153 + if (twl_class_is_4030())
  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  
133 161 static int twlreg_get_status(struct regulator_dev *rdev)
134 162 {
135 163 int state = twlreg_grp(rdev);
136 164  
  165 + if (twl_class_is_6030())
  166 + return 0; /* FIXME return for 6030 regulator */
  167 +
137 168 if (state < 0)
138 169 return state;
139 170 state &= 0x0f;
... ... @@ -152,6 +183,9 @@
152 183 unsigned message;
153 184 int status;
154 185  
  186 + if (twl_class_is_6030())
  187 + return 0; /* FIXME return for 6030 regulator */
  188 +
155 189 /* We can only set the mode through state machine commands... */
156 190 switch (mode) {
157 191 case REGULATOR_MODE_NORMAL:
... ... @@ -168,7 +202,7 @@
168 202 status = twlreg_grp(rdev);
169 203 if (status < 0)
170 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 206 return -EACCES;
173 207  
174 208 status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
175 209  
... ... @@ -260,8 +294,30 @@
260 294 static const u16 VDAC_VSEL_table[] = {
261 295 1200, 1300, 1800, 1800,
262 296 };
  297 +static const u16 VAUX1_6030_VSEL_table[] = {
  298 + 1000, 1300, 1800, 2500,
  299 + 2800, 2900, 3000, 3000,
  300 +};
  301 +static const u16 VAUX2_6030_VSEL_table[] = {
  302 + 1200, 1800, 2500, 2750,
  303 + 2800, 2800, 2800, 2800,
  304 +};
  305 +static const u16 VAUX3_6030_VSEL_table[] = {
  306 + 1000, 1200, 1300, 1800,
  307 + 2500, 2800, 3000, 3000,
  308 +};
  309 +static const u16 VMMC_VSEL_table[] = {
  310 + 1200, 1800, 2800, 2900,
  311 + 3000, 3000, 3000, 3000,
  312 +};
  313 +static const u16 VPP_VSEL_table[] = {
  314 + 1800, 1900, 2000, 2100,
  315 + 2200, 2300, 2400, 2500,
  316 +};
  317 +static const u16 VUSIM_VSEL_table[] = {
  318 + 1200, 1800, 2500, 2900,
  319 +};
263 320  
264   -
265 321 static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index)
266 322 {
267 323 struct twlreg_info *info = rdev_get_drvdata(rdev);
... ... @@ -288,7 +344,8 @@
288 344  
289 345 /* use the first in-range value */
290 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 351 return -EDOM;
... ... @@ -297,7 +354,8 @@
297 354 static int twlldo_get_voltage(struct regulator_dev *rdev)
298 355 {
299 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 360 if (vsel < 0)
303 361 return vsel;
... ... @@ -360,6 +418,10 @@
360 418 TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030)
361 419 #define TWL4030_FIXED_LDO(label, offset, mVolts, num) \
362 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 426 #define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \
365 427 .base = offset, \
... ... @@ -420,6 +482,18 @@
420 482 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
421 483 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
422 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  
425 499 static int twlreg_probe(struct platform_device *pdev)
include/linux/i2c/twl.h
... ... @@ -427,6 +427,12 @@
427 427 #define MSG_SINGULAR(devgrp, id, state) \
428 428 ((devgrp) << 13 | 0 << 12 | (id) << 4 | (state))
429 429  
  430 +#define MSG_BROADCAST_ALL(devgrp, state) \
  431 + ((devgrp) << 5 | (state))
  432 +
  433 +#define MSG_BROADCAST_REF MSG_BROADCAST_ALL
  434 +#define MSG_BROADCAST_PROV MSG_BROADCAST_ALL
  435 +#define MSG_BROADCAST__CLK_RST MSG_BROADCAST_ALL
430 436 /*----------------------------------------------------------------------*/
431 437  
432 438 struct twl4030_clock_init_data {
... ... @@ -602,6 +608,7 @@
602 608 * VIO is generally fixed.
603 609 */
604 610  
  611 +/* TWL4030 SMPS/LDO's */
605 612 /* EXTERNAL dc-to-dc buck converters */
606 613 #define TWL4030_REG_VDD1 0
607 614 #define TWL4030_REG_VDD2 1
... ... @@ -627,6 +634,33 @@
627 634 #define TWL4030_REG_VUSB1V5 17
628 635 #define TWL4030_REG_VUSB1V8 18
629 636 #define TWL4030_REG_VUSB3V1 19
  637 +
  638 +/* TWL6030 SMPS/LDO's */
  639 +/* EXTERNAL dc-to-dc buck convertor contollable via SR */
  640 +#define TWL6030_REG_VDD1 30
  641 +#define TWL6030_REG_VDD2 31
  642 +#define TWL6030_REG_VDD3 32
  643 +
  644 +/* Non SR compliant dc-to-dc buck convertors */
  645 +#define TWL6030_REG_VMEM 33
  646 +#define TWL6030_REG_V2V1 34
  647 +#define TWL6030_REG_V1V29 35
  648 +#define TWL6030_REG_V1V8 36
  649 +
  650 +/* EXTERNAL LDOs */
  651 +#define TWL6030_REG_VAUX1_6030 37
  652 +#define TWL6030_REG_VAUX2_6030 38
  653 +#define TWL6030_REG_VAUX3_6030 39
  654 +#define TWL6030_REG_VMMC 40
  655 +#define TWL6030_REG_VPP 41
  656 +#define TWL6030_REG_VUSIM 42
  657 +#define TWL6030_REG_VANA 43
  658 +#define TWL6030_REG_VCXIO 44
  659 +#define TWL6030_REG_VDAC 45
  660 +#define TWL6030_REG_VUSB 46
  661 +
  662 +/* INTERNAL LDOs */
  663 +#define TWL6030_REG_VRTC 47
630 664  
631 665 #endif /* End of __TWL4030_H */