Commit 38f8f43cbafe9ad07fdde31d28ed0c6933ac1e2e
Committed by
Mark Brown
1 parent
78292f4ed2
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
regulator: twl: Convert twlsmps_ops to get_voltage_sel and map_voltage
Signed-off-by: Axel Lin <axel.lin@gmail.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Showing 1 changed file with 13 additions and 11 deletions Inline Diff
drivers/regulator/twl-regulator.c
1 | /* | 1 | /* |
2 | * twl-regulator.c -- support regulators in twl4030/twl6030 family chips | 2 | * twl-regulator.c -- support regulators in twl4030/twl6030 family chips |
3 | * | 3 | * |
4 | * Copyright (C) 2008 David Brownell | 4 | * Copyright (C) 2008 David Brownell |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
18 | #include <linux/regulator/driver.h> | 18 | #include <linux/regulator/driver.h> |
19 | #include <linux/regulator/machine.h> | 19 | #include <linux/regulator/machine.h> |
20 | #include <linux/regulator/of_regulator.h> | 20 | #include <linux/regulator/of_regulator.h> |
21 | #include <linux/i2c/twl.h> | 21 | #include <linux/i2c/twl.h> |
22 | 22 | ||
23 | 23 | ||
24 | /* | 24 | /* |
25 | * The TWL4030/TW5030/TPS659x0/TWL6030 family chips include power management, a | 25 | * The TWL4030/TW5030/TPS659x0/TWL6030 family chips include power management, a |
26 | * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions | 26 | * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions |
27 | * include an audio codec, battery charger, and more voltage regulators. | 27 | * include an audio codec, battery charger, and more voltage regulators. |
28 | * These chips are often used in OMAP-based systems. | 28 | * These chips are often used in OMAP-based systems. |
29 | * | 29 | * |
30 | * This driver implements software-based resource control for various | 30 | * This driver implements software-based resource control for various |
31 | * voltage regulators. This is usually augmented with state machine | 31 | * voltage regulators. This is usually augmented with state machine |
32 | * based control. | 32 | * based control. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | struct twlreg_info { | 35 | struct twlreg_info { |
36 | /* start of regulator's PM_RECEIVER control register bank */ | 36 | /* start of regulator's PM_RECEIVER control register bank */ |
37 | u8 base; | 37 | u8 base; |
38 | 38 | ||
39 | /* twl resource ID, for resource control state machine */ | 39 | /* twl resource ID, for resource control state machine */ |
40 | u8 id; | 40 | u8 id; |
41 | 41 | ||
42 | /* voltage in mV = table[VSEL]; table_len must be a power-of-two */ | 42 | /* voltage in mV = table[VSEL]; table_len must be a power-of-two */ |
43 | u8 table_len; | 43 | u8 table_len; |
44 | const u16 *table; | 44 | const u16 *table; |
45 | 45 | ||
46 | /* State REMAP default configuration */ | 46 | /* State REMAP default configuration */ |
47 | u8 remap; | 47 | u8 remap; |
48 | 48 | ||
49 | /* chip constraints on regulator behavior */ | 49 | /* chip constraints on regulator behavior */ |
50 | u16 min_mV; | 50 | u16 min_mV; |
51 | u16 max_mV; | 51 | u16 max_mV; |
52 | 52 | ||
53 | u8 flags; | 53 | u8 flags; |
54 | 54 | ||
55 | /* used by regulator core */ | 55 | /* used by regulator core */ |
56 | struct regulator_desc desc; | 56 | struct regulator_desc desc; |
57 | 57 | ||
58 | /* chip specific features */ | 58 | /* chip specific features */ |
59 | unsigned long features; | 59 | unsigned long features; |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * optional override functions for voltage set/get | 62 | * optional override functions for voltage set/get |
63 | * these are currently only used for SMPS regulators | 63 | * these are currently only used for SMPS regulators |
64 | */ | 64 | */ |
65 | int (*get_voltage)(void *data); | 65 | int (*get_voltage)(void *data); |
66 | int (*set_voltage)(void *data, int target_uV); | 66 | int (*set_voltage)(void *data, int target_uV); |
67 | 67 | ||
68 | /* data passed from board for external get/set voltage */ | 68 | /* data passed from board for external get/set voltage */ |
69 | void *data; | 69 | void *data; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | 72 | ||
73 | /* LDO control registers ... offset is from the base of its register bank. | 73 | /* LDO control registers ... offset is from the base of its register bank. |
74 | * The first three registers of all power resource banks help hardware to | 74 | * The first three registers of all power resource banks help hardware to |
75 | * manage the various resource groups. | 75 | * manage the various resource groups. |
76 | */ | 76 | */ |
77 | /* Common offset in TWL4030/6030 */ | 77 | /* Common offset in TWL4030/6030 */ |
78 | #define VREG_GRP 0 | 78 | #define VREG_GRP 0 |
79 | /* TWL4030 register offsets */ | 79 | /* TWL4030 register offsets */ |
80 | #define VREG_TYPE 1 | 80 | #define VREG_TYPE 1 |
81 | #define VREG_REMAP 2 | 81 | #define VREG_REMAP 2 |
82 | #define VREG_DEDICATED 3 /* LDO control */ | 82 | #define VREG_DEDICATED 3 /* LDO control */ |
83 | #define VREG_VOLTAGE_SMPS_4030 9 | 83 | #define VREG_VOLTAGE_SMPS_4030 9 |
84 | /* TWL6030 register offsets */ | 84 | /* TWL6030 register offsets */ |
85 | #define VREG_TRANS 1 | 85 | #define VREG_TRANS 1 |
86 | #define VREG_STATE 2 | 86 | #define VREG_STATE 2 |
87 | #define VREG_VOLTAGE 3 | 87 | #define VREG_VOLTAGE 3 |
88 | #define VREG_VOLTAGE_SMPS 4 | 88 | #define VREG_VOLTAGE_SMPS 4 |
89 | /* TWL6030 Misc register offsets */ | 89 | /* TWL6030 Misc register offsets */ |
90 | #define VREG_BC_ALL 1 | 90 | #define VREG_BC_ALL 1 |
91 | #define VREG_BC_REF 2 | 91 | #define VREG_BC_REF 2 |
92 | #define VREG_BC_PROC 3 | 92 | #define VREG_BC_PROC 3 |
93 | #define VREG_BC_CLK_RST 4 | 93 | #define VREG_BC_CLK_RST 4 |
94 | 94 | ||
95 | /* TWL6030 LDO register values for CFG_STATE */ | 95 | /* TWL6030 LDO register values for CFG_STATE */ |
96 | #define TWL6030_CFG_STATE_OFF 0x00 | 96 | #define TWL6030_CFG_STATE_OFF 0x00 |
97 | #define TWL6030_CFG_STATE_ON 0x01 | 97 | #define TWL6030_CFG_STATE_ON 0x01 |
98 | #define TWL6030_CFG_STATE_OFF2 0x02 | 98 | #define TWL6030_CFG_STATE_OFF2 0x02 |
99 | #define TWL6030_CFG_STATE_SLEEP 0x03 | 99 | #define TWL6030_CFG_STATE_SLEEP 0x03 |
100 | #define TWL6030_CFG_STATE_GRP_SHIFT 5 | 100 | #define TWL6030_CFG_STATE_GRP_SHIFT 5 |
101 | #define TWL6030_CFG_STATE_APP_SHIFT 2 | 101 | #define TWL6030_CFG_STATE_APP_SHIFT 2 |
102 | #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT) | 102 | #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT) |
103 | #define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\ | 103 | #define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\ |
104 | TWL6030_CFG_STATE_APP_SHIFT) | 104 | TWL6030_CFG_STATE_APP_SHIFT) |
105 | 105 | ||
106 | /* Flags for SMPS Voltage reading */ | 106 | /* Flags for SMPS Voltage reading */ |
107 | #define SMPS_OFFSET_EN BIT(0) | 107 | #define SMPS_OFFSET_EN BIT(0) |
108 | #define SMPS_EXTENDED_EN BIT(1) | 108 | #define SMPS_EXTENDED_EN BIT(1) |
109 | 109 | ||
110 | /* twl6025 SMPS EPROM values */ | 110 | /* twl6025 SMPS EPROM values */ |
111 | #define TWL6030_SMPS_OFFSET 0xB0 | 111 | #define TWL6030_SMPS_OFFSET 0xB0 |
112 | #define TWL6030_SMPS_MULT 0xB3 | 112 | #define TWL6030_SMPS_MULT 0xB3 |
113 | #define SMPS_MULTOFFSET_SMPS4 BIT(0) | 113 | #define SMPS_MULTOFFSET_SMPS4 BIT(0) |
114 | #define SMPS_MULTOFFSET_VIO BIT(1) | 114 | #define SMPS_MULTOFFSET_VIO BIT(1) |
115 | #define SMPS_MULTOFFSET_SMPS3 BIT(6) | 115 | #define SMPS_MULTOFFSET_SMPS3 BIT(6) |
116 | 116 | ||
117 | static inline int | 117 | static inline int |
118 | twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) | 118 | twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) |
119 | { | 119 | { |
120 | u8 value; | 120 | u8 value; |
121 | int status; | 121 | int status; |
122 | 122 | ||
123 | status = twl_i2c_read_u8(slave_subgp, | 123 | status = twl_i2c_read_u8(slave_subgp, |
124 | &value, info->base + offset); | 124 | &value, info->base + offset); |
125 | return (status < 0) ? status : value; | 125 | return (status < 0) ? status : value; |
126 | } | 126 | } |
127 | 127 | ||
128 | static inline int | 128 | static inline int |
129 | twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset, | 129 | twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset, |
130 | u8 value) | 130 | u8 value) |
131 | { | 131 | { |
132 | return twl_i2c_write_u8(slave_subgp, | 132 | return twl_i2c_write_u8(slave_subgp, |
133 | value, info->base + offset); | 133 | value, info->base + offset); |
134 | } | 134 | } |
135 | 135 | ||
136 | /*----------------------------------------------------------------------*/ | 136 | /*----------------------------------------------------------------------*/ |
137 | 137 | ||
138 | /* generic power resource operations, which work on all regulators */ | 138 | /* generic power resource operations, which work on all regulators */ |
139 | 139 | ||
140 | static int twlreg_grp(struct regulator_dev *rdev) | 140 | static int twlreg_grp(struct regulator_dev *rdev) |
141 | { | 141 | { |
142 | return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_RECEIVER, | 142 | return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_RECEIVER, |
143 | VREG_GRP); | 143 | VREG_GRP); |
144 | } | 144 | } |
145 | 145 | ||
146 | /* | 146 | /* |
147 | * Enable/disable regulators by joining/leaving the P1 (processor) group. | 147 | * Enable/disable regulators by joining/leaving the P1 (processor) group. |
148 | * We assume nobody else is updating the DEV_GRP registers. | 148 | * We assume nobody else is updating the DEV_GRP registers. |
149 | */ | 149 | */ |
150 | /* definition for 4030 family */ | 150 | /* definition for 4030 family */ |
151 | #define P3_GRP_4030 BIT(7) /* "peripherals" */ | 151 | #define P3_GRP_4030 BIT(7) /* "peripherals" */ |
152 | #define P2_GRP_4030 BIT(6) /* secondary processor, modem, etc */ | 152 | #define P2_GRP_4030 BIT(6) /* secondary processor, modem, etc */ |
153 | #define P1_GRP_4030 BIT(5) /* CPU/Linux */ | 153 | #define P1_GRP_4030 BIT(5) /* CPU/Linux */ |
154 | /* definition for 6030 family */ | 154 | /* definition for 6030 family */ |
155 | #define P3_GRP_6030 BIT(2) /* secondary processor, modem, etc */ | 155 | #define P3_GRP_6030 BIT(2) /* secondary processor, modem, etc */ |
156 | #define P2_GRP_6030 BIT(1) /* "peripherals" */ | 156 | #define P2_GRP_6030 BIT(1) /* "peripherals" */ |
157 | #define P1_GRP_6030 BIT(0) /* CPU/Linux */ | 157 | #define P1_GRP_6030 BIT(0) /* CPU/Linux */ |
158 | 158 | ||
159 | static int twl4030reg_is_enabled(struct regulator_dev *rdev) | 159 | static int twl4030reg_is_enabled(struct regulator_dev *rdev) |
160 | { | 160 | { |
161 | int state = twlreg_grp(rdev); | 161 | int state = twlreg_grp(rdev); |
162 | 162 | ||
163 | if (state < 0) | 163 | if (state < 0) |
164 | return state; | 164 | return state; |
165 | 165 | ||
166 | return state & P1_GRP_4030; | 166 | return state & P1_GRP_4030; |
167 | } | 167 | } |
168 | 168 | ||
169 | static int twl6030reg_is_enabled(struct regulator_dev *rdev) | 169 | static int twl6030reg_is_enabled(struct regulator_dev *rdev) |
170 | { | 170 | { |
171 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 171 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
172 | int grp = 0, val; | 172 | int grp = 0, val; |
173 | 173 | ||
174 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) { | 174 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) { |
175 | grp = twlreg_grp(rdev); | 175 | grp = twlreg_grp(rdev); |
176 | if (grp < 0) | 176 | if (grp < 0) |
177 | return grp; | 177 | return grp; |
178 | grp &= P1_GRP_6030; | 178 | grp &= P1_GRP_6030; |
179 | } else { | 179 | } else { |
180 | grp = 1; | 180 | grp = 1; |
181 | } | 181 | } |
182 | 182 | ||
183 | val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); | 183 | val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); |
184 | val = TWL6030_CFG_STATE_APP(val); | 184 | val = TWL6030_CFG_STATE_APP(val); |
185 | 185 | ||
186 | return grp && (val == TWL6030_CFG_STATE_ON); | 186 | return grp && (val == TWL6030_CFG_STATE_ON); |
187 | } | 187 | } |
188 | 188 | ||
189 | static int twl4030reg_enable(struct regulator_dev *rdev) | 189 | static int twl4030reg_enable(struct regulator_dev *rdev) |
190 | { | 190 | { |
191 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 191 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
192 | int grp; | 192 | int grp; |
193 | int ret; | 193 | int ret; |
194 | 194 | ||
195 | grp = twlreg_grp(rdev); | 195 | grp = twlreg_grp(rdev); |
196 | if (grp < 0) | 196 | if (grp < 0) |
197 | return grp; | 197 | return grp; |
198 | 198 | ||
199 | grp |= P1_GRP_4030; | 199 | grp |= P1_GRP_4030; |
200 | 200 | ||
201 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); | 201 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); |
202 | 202 | ||
203 | return ret; | 203 | return ret; |
204 | } | 204 | } |
205 | 205 | ||
206 | static int twl6030reg_enable(struct regulator_dev *rdev) | 206 | static int twl6030reg_enable(struct regulator_dev *rdev) |
207 | { | 207 | { |
208 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 208 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
209 | int grp = 0; | 209 | int grp = 0; |
210 | int ret; | 210 | int ret; |
211 | 211 | ||
212 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | 212 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) |
213 | grp = twlreg_grp(rdev); | 213 | grp = twlreg_grp(rdev); |
214 | if (grp < 0) | 214 | if (grp < 0) |
215 | return grp; | 215 | return grp; |
216 | 216 | ||
217 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | 217 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, |
218 | grp << TWL6030_CFG_STATE_GRP_SHIFT | | 218 | grp << TWL6030_CFG_STATE_GRP_SHIFT | |
219 | TWL6030_CFG_STATE_ON); | 219 | TWL6030_CFG_STATE_ON); |
220 | return ret; | 220 | return ret; |
221 | } | 221 | } |
222 | 222 | ||
223 | static int twl4030reg_disable(struct regulator_dev *rdev) | 223 | static int twl4030reg_disable(struct regulator_dev *rdev) |
224 | { | 224 | { |
225 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 225 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
226 | int grp; | 226 | int grp; |
227 | int ret; | 227 | int ret; |
228 | 228 | ||
229 | grp = twlreg_grp(rdev); | 229 | grp = twlreg_grp(rdev); |
230 | if (grp < 0) | 230 | if (grp < 0) |
231 | return grp; | 231 | return grp; |
232 | 232 | ||
233 | grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); | 233 | grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); |
234 | 234 | ||
235 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); | 235 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); |
236 | 236 | ||
237 | return ret; | 237 | return ret; |
238 | } | 238 | } |
239 | 239 | ||
240 | static int twl6030reg_disable(struct regulator_dev *rdev) | 240 | static int twl6030reg_disable(struct regulator_dev *rdev) |
241 | { | 241 | { |
242 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 242 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
243 | int grp = 0; | 243 | int grp = 0; |
244 | int ret; | 244 | int ret; |
245 | 245 | ||
246 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | 246 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) |
247 | grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030; | 247 | grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030; |
248 | 248 | ||
249 | /* For 6030, set the off state for all grps enabled */ | 249 | /* For 6030, set the off state for all grps enabled */ |
250 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | 250 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, |
251 | (grp) << TWL6030_CFG_STATE_GRP_SHIFT | | 251 | (grp) << TWL6030_CFG_STATE_GRP_SHIFT | |
252 | TWL6030_CFG_STATE_OFF); | 252 | TWL6030_CFG_STATE_OFF); |
253 | 253 | ||
254 | return ret; | 254 | return ret; |
255 | } | 255 | } |
256 | 256 | ||
257 | static int twl4030reg_get_status(struct regulator_dev *rdev) | 257 | static int twl4030reg_get_status(struct regulator_dev *rdev) |
258 | { | 258 | { |
259 | int state = twlreg_grp(rdev); | 259 | int state = twlreg_grp(rdev); |
260 | 260 | ||
261 | if (state < 0) | 261 | if (state < 0) |
262 | return state; | 262 | return state; |
263 | state &= 0x0f; | 263 | state &= 0x0f; |
264 | 264 | ||
265 | /* assume state != WARM_RESET; we'd not be running... */ | 265 | /* assume state != WARM_RESET; we'd not be running... */ |
266 | if (!state) | 266 | if (!state) |
267 | return REGULATOR_STATUS_OFF; | 267 | return REGULATOR_STATUS_OFF; |
268 | return (state & BIT(3)) | 268 | return (state & BIT(3)) |
269 | ? REGULATOR_STATUS_NORMAL | 269 | ? REGULATOR_STATUS_NORMAL |
270 | : REGULATOR_STATUS_STANDBY; | 270 | : REGULATOR_STATUS_STANDBY; |
271 | } | 271 | } |
272 | 272 | ||
273 | static int twl6030reg_get_status(struct regulator_dev *rdev) | 273 | static int twl6030reg_get_status(struct regulator_dev *rdev) |
274 | { | 274 | { |
275 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 275 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
276 | int val; | 276 | int val; |
277 | 277 | ||
278 | val = twlreg_grp(rdev); | 278 | val = twlreg_grp(rdev); |
279 | if (val < 0) | 279 | if (val < 0) |
280 | return val; | 280 | return val; |
281 | 281 | ||
282 | val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); | 282 | val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); |
283 | 283 | ||
284 | switch (TWL6030_CFG_STATE_APP(val)) { | 284 | switch (TWL6030_CFG_STATE_APP(val)) { |
285 | case TWL6030_CFG_STATE_ON: | 285 | case TWL6030_CFG_STATE_ON: |
286 | return REGULATOR_STATUS_NORMAL; | 286 | return REGULATOR_STATUS_NORMAL; |
287 | 287 | ||
288 | case TWL6030_CFG_STATE_SLEEP: | 288 | case TWL6030_CFG_STATE_SLEEP: |
289 | return REGULATOR_STATUS_STANDBY; | 289 | return REGULATOR_STATUS_STANDBY; |
290 | 290 | ||
291 | case TWL6030_CFG_STATE_OFF: | 291 | case TWL6030_CFG_STATE_OFF: |
292 | case TWL6030_CFG_STATE_OFF2: | 292 | case TWL6030_CFG_STATE_OFF2: |
293 | default: | 293 | default: |
294 | break; | 294 | break; |
295 | } | 295 | } |
296 | 296 | ||
297 | return REGULATOR_STATUS_OFF; | 297 | return REGULATOR_STATUS_OFF; |
298 | } | 298 | } |
299 | 299 | ||
300 | static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) | 300 | static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) |
301 | { | 301 | { |
302 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 302 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
303 | unsigned message; | 303 | unsigned message; |
304 | int status; | 304 | int status; |
305 | 305 | ||
306 | /* We can only set the mode through state machine commands... */ | 306 | /* We can only set the mode through state machine commands... */ |
307 | switch (mode) { | 307 | switch (mode) { |
308 | case REGULATOR_MODE_NORMAL: | 308 | case REGULATOR_MODE_NORMAL: |
309 | message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE); | 309 | message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE); |
310 | break; | 310 | break; |
311 | case REGULATOR_MODE_STANDBY: | 311 | case REGULATOR_MODE_STANDBY: |
312 | message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP); | 312 | message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP); |
313 | break; | 313 | break; |
314 | default: | 314 | default: |
315 | return -EINVAL; | 315 | return -EINVAL; |
316 | } | 316 | } |
317 | 317 | ||
318 | /* Ensure the resource is associated with some group */ | 318 | /* Ensure the resource is associated with some group */ |
319 | status = twlreg_grp(rdev); | 319 | status = twlreg_grp(rdev); |
320 | if (status < 0) | 320 | if (status < 0) |
321 | return status; | 321 | return status; |
322 | if (!(status & (P3_GRP_4030 | P2_GRP_4030 | P1_GRP_4030))) | 322 | if (!(status & (P3_GRP_4030 | P2_GRP_4030 | P1_GRP_4030))) |
323 | return -EACCES; | 323 | return -EACCES; |
324 | 324 | ||
325 | status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, | 325 | status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, |
326 | message >> 8, TWL4030_PM_MASTER_PB_WORD_MSB); | 326 | message >> 8, TWL4030_PM_MASTER_PB_WORD_MSB); |
327 | if (status < 0) | 327 | if (status < 0) |
328 | return status; | 328 | return status; |
329 | 329 | ||
330 | return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, | 330 | return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, |
331 | message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB); | 331 | message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB); |
332 | } | 332 | } |
333 | 333 | ||
334 | static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) | 334 | static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) |
335 | { | 335 | { |
336 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 336 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
337 | int grp = 0; | 337 | int grp = 0; |
338 | int val; | 338 | int val; |
339 | 339 | ||
340 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) | 340 | if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) |
341 | grp = twlreg_grp(rdev); | 341 | grp = twlreg_grp(rdev); |
342 | 342 | ||
343 | if (grp < 0) | 343 | if (grp < 0) |
344 | return grp; | 344 | return grp; |
345 | 345 | ||
346 | /* Compose the state register settings */ | 346 | /* Compose the state register settings */ |
347 | val = grp << TWL6030_CFG_STATE_GRP_SHIFT; | 347 | val = grp << TWL6030_CFG_STATE_GRP_SHIFT; |
348 | /* We can only set the mode through state machine commands... */ | 348 | /* We can only set the mode through state machine commands... */ |
349 | switch (mode) { | 349 | switch (mode) { |
350 | case REGULATOR_MODE_NORMAL: | 350 | case REGULATOR_MODE_NORMAL: |
351 | val |= TWL6030_CFG_STATE_ON; | 351 | val |= TWL6030_CFG_STATE_ON; |
352 | break; | 352 | break; |
353 | case REGULATOR_MODE_STANDBY: | 353 | case REGULATOR_MODE_STANDBY: |
354 | val |= TWL6030_CFG_STATE_SLEEP; | 354 | val |= TWL6030_CFG_STATE_SLEEP; |
355 | break; | 355 | break; |
356 | 356 | ||
357 | default: | 357 | default: |
358 | return -EINVAL; | 358 | return -EINVAL; |
359 | } | 359 | } |
360 | 360 | ||
361 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val); | 361 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val); |
362 | } | 362 | } |
363 | 363 | ||
364 | /*----------------------------------------------------------------------*/ | 364 | /*----------------------------------------------------------------------*/ |
365 | 365 | ||
366 | /* | 366 | /* |
367 | * Support for adjustable-voltage LDOs uses a four bit (or less) voltage | 367 | * Support for adjustable-voltage LDOs uses a four bit (or less) voltage |
368 | * select field in its control register. We use tables indexed by VSEL | 368 | * select field in its control register. We use tables indexed by VSEL |
369 | * to record voltages in milliVolts. (Accuracy is about three percent.) | 369 | * to record voltages in milliVolts. (Accuracy is about three percent.) |
370 | * | 370 | * |
371 | * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon; | 371 | * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon; |
372 | * currently handled by listing two slightly different VAUX2 regulators, | 372 | * currently handled by listing two slightly different VAUX2 regulators, |
373 | * only one of which will be configured. | 373 | * only one of which will be configured. |
374 | * | 374 | * |
375 | * VSEL values documented as "TI cannot support these values" are flagged | 375 | * VSEL values documented as "TI cannot support these values" are flagged |
376 | * in these tables as UNSUP() values; we normally won't assign them. | 376 | * in these tables as UNSUP() values; we normally won't assign them. |
377 | * | 377 | * |
378 | * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported. | 378 | * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported. |
379 | * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting. | 379 | * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting. |
380 | */ | 380 | */ |
381 | #define UNSUP_MASK 0x8000 | 381 | #define UNSUP_MASK 0x8000 |
382 | 382 | ||
383 | #define UNSUP(x) (UNSUP_MASK | (x)) | 383 | #define UNSUP(x) (UNSUP_MASK | (x)) |
384 | #define IS_UNSUP(info, x) \ | 384 | #define IS_UNSUP(info, x) \ |
385 | ((UNSUP_MASK & (x)) && \ | 385 | ((UNSUP_MASK & (x)) && \ |
386 | !((info)->features & TWL4030_ALLOW_UNSUPPORTED)) | 386 | !((info)->features & TWL4030_ALLOW_UNSUPPORTED)) |
387 | #define LDO_MV(x) (~UNSUP_MASK & (x)) | 387 | #define LDO_MV(x) (~UNSUP_MASK & (x)) |
388 | 388 | ||
389 | 389 | ||
390 | static const u16 VAUX1_VSEL_table[] = { | 390 | static const u16 VAUX1_VSEL_table[] = { |
391 | UNSUP(1500), UNSUP(1800), 2500, 2800, | 391 | UNSUP(1500), UNSUP(1800), 2500, 2800, |
392 | 3000, 3000, 3000, 3000, | 392 | 3000, 3000, 3000, 3000, |
393 | }; | 393 | }; |
394 | static const u16 VAUX2_4030_VSEL_table[] = { | 394 | static const u16 VAUX2_4030_VSEL_table[] = { |
395 | UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300, | 395 | UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300, |
396 | 1500, 1800, UNSUP(1850), 2500, | 396 | 1500, 1800, UNSUP(1850), 2500, |
397 | UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000), | 397 | UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000), |
398 | UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150), | 398 | UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150), |
399 | }; | 399 | }; |
400 | static const u16 VAUX2_VSEL_table[] = { | 400 | static const u16 VAUX2_VSEL_table[] = { |
401 | 1700, 1700, 1900, 1300, | 401 | 1700, 1700, 1900, 1300, |
402 | 1500, 1800, 2000, 2500, | 402 | 1500, 1800, 2000, 2500, |
403 | 2100, 2800, 2200, 2300, | 403 | 2100, 2800, 2200, 2300, |
404 | 2400, 2400, 2400, 2400, | 404 | 2400, 2400, 2400, 2400, |
405 | }; | 405 | }; |
406 | static const u16 VAUX3_VSEL_table[] = { | 406 | static const u16 VAUX3_VSEL_table[] = { |
407 | 1500, 1800, 2500, 2800, | 407 | 1500, 1800, 2500, 2800, |
408 | 3000, 3000, 3000, 3000, | 408 | 3000, 3000, 3000, 3000, |
409 | }; | 409 | }; |
410 | static const u16 VAUX4_VSEL_table[] = { | 410 | static const u16 VAUX4_VSEL_table[] = { |
411 | 700, 1000, 1200, UNSUP(1300), | 411 | 700, 1000, 1200, UNSUP(1300), |
412 | 1500, 1800, UNSUP(1850), 2500, | 412 | 1500, 1800, UNSUP(1850), 2500, |
413 | UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000), | 413 | UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000), |
414 | UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150), | 414 | UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150), |
415 | }; | 415 | }; |
416 | static const u16 VMMC1_VSEL_table[] = { | 416 | static const u16 VMMC1_VSEL_table[] = { |
417 | 1850, 2850, 3000, 3150, | 417 | 1850, 2850, 3000, 3150, |
418 | }; | 418 | }; |
419 | static const u16 VMMC2_VSEL_table[] = { | 419 | static const u16 VMMC2_VSEL_table[] = { |
420 | UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300), | 420 | UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300), |
421 | UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500), | 421 | UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500), |
422 | 2600, 2800, 2850, 3000, | 422 | 2600, 2800, 2850, 3000, |
423 | 3150, 3150, 3150, 3150, | 423 | 3150, 3150, 3150, 3150, |
424 | }; | 424 | }; |
425 | static const u16 VPLL1_VSEL_table[] = { | 425 | static const u16 VPLL1_VSEL_table[] = { |
426 | 1000, 1200, 1300, 1800, | 426 | 1000, 1200, 1300, 1800, |
427 | UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000), | 427 | UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000), |
428 | }; | 428 | }; |
429 | static const u16 VPLL2_VSEL_table[] = { | 429 | static const u16 VPLL2_VSEL_table[] = { |
430 | 700, 1000, 1200, 1300, | 430 | 700, 1000, 1200, 1300, |
431 | UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500), | 431 | UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500), |
432 | UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000), | 432 | UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000), |
433 | UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150), | 433 | UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150), |
434 | }; | 434 | }; |
435 | static const u16 VSIM_VSEL_table[] = { | 435 | static const u16 VSIM_VSEL_table[] = { |
436 | UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800, | 436 | UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800, |
437 | 2800, 3000, 3000, 3000, | 437 | 2800, 3000, 3000, 3000, |
438 | }; | 438 | }; |
439 | static const u16 VDAC_VSEL_table[] = { | 439 | static const u16 VDAC_VSEL_table[] = { |
440 | 1200, 1300, 1800, 1800, | 440 | 1200, 1300, 1800, 1800, |
441 | }; | 441 | }; |
442 | static const u16 VDD1_VSEL_table[] = { | 442 | static const u16 VDD1_VSEL_table[] = { |
443 | 800, 1450, | 443 | 800, 1450, |
444 | }; | 444 | }; |
445 | static const u16 VDD2_VSEL_table[] = { | 445 | static const u16 VDD2_VSEL_table[] = { |
446 | 800, 1450, 1500, | 446 | 800, 1450, 1500, |
447 | }; | 447 | }; |
448 | static const u16 VIO_VSEL_table[] = { | 448 | static const u16 VIO_VSEL_table[] = { |
449 | 1800, 1850, | 449 | 1800, 1850, |
450 | }; | 450 | }; |
451 | static const u16 VINTANA2_VSEL_table[] = { | 451 | static const u16 VINTANA2_VSEL_table[] = { |
452 | 2500, 2750, | 452 | 2500, 2750, |
453 | }; | 453 | }; |
454 | 454 | ||
455 | static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | 455 | static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) |
456 | { | 456 | { |
457 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 457 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
458 | int mV = info->table[index]; | 458 | int mV = info->table[index]; |
459 | 459 | ||
460 | return IS_UNSUP(info, mV) ? 0 : (LDO_MV(mV) * 1000); | 460 | return IS_UNSUP(info, mV) ? 0 : (LDO_MV(mV) * 1000); |
461 | } | 461 | } |
462 | 462 | ||
463 | static int | 463 | static int |
464 | twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) | 464 | twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) |
465 | { | 465 | { |
466 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 466 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
467 | 467 | ||
468 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, | 468 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, |
469 | selector); | 469 | selector); |
470 | } | 470 | } |
471 | 471 | ||
472 | static int twl4030ldo_get_voltage(struct regulator_dev *rdev) | 472 | static int twl4030ldo_get_voltage(struct regulator_dev *rdev) |
473 | { | 473 | { |
474 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 474 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
475 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | 475 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, |
476 | VREG_VOLTAGE); | 476 | VREG_VOLTAGE); |
477 | 477 | ||
478 | if (vsel < 0) | 478 | if (vsel < 0) |
479 | return vsel; | 479 | return vsel; |
480 | 480 | ||
481 | vsel &= info->table_len - 1; | 481 | vsel &= info->table_len - 1; |
482 | return LDO_MV(info->table[vsel]) * 1000; | 482 | return LDO_MV(info->table[vsel]) * 1000; |
483 | } | 483 | } |
484 | 484 | ||
485 | static struct regulator_ops twl4030ldo_ops = { | 485 | static struct regulator_ops twl4030ldo_ops = { |
486 | .list_voltage = twl4030ldo_list_voltage, | 486 | .list_voltage = twl4030ldo_list_voltage, |
487 | 487 | ||
488 | .set_voltage_sel = twl4030ldo_set_voltage_sel, | 488 | .set_voltage_sel = twl4030ldo_set_voltage_sel, |
489 | .get_voltage = twl4030ldo_get_voltage, | 489 | .get_voltage = twl4030ldo_get_voltage, |
490 | 490 | ||
491 | .enable = twl4030reg_enable, | 491 | .enable = twl4030reg_enable, |
492 | .disable = twl4030reg_disable, | 492 | .disable = twl4030reg_disable, |
493 | .is_enabled = twl4030reg_is_enabled, | 493 | .is_enabled = twl4030reg_is_enabled, |
494 | 494 | ||
495 | .set_mode = twl4030reg_set_mode, | 495 | .set_mode = twl4030reg_set_mode, |
496 | 496 | ||
497 | .get_status = twl4030reg_get_status, | 497 | .get_status = twl4030reg_get_status, |
498 | }; | 498 | }; |
499 | 499 | ||
500 | static int | 500 | static int |
501 | twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | 501 | twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, |
502 | unsigned *selector) | 502 | unsigned *selector) |
503 | { | 503 | { |
504 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 504 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
505 | int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); | 505 | int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); |
506 | 506 | ||
507 | if (info->set_voltage) { | 507 | if (info->set_voltage) { |
508 | return info->set_voltage(info->data, min_uV); | 508 | return info->set_voltage(info->data, min_uV); |
509 | } else { | 509 | } else { |
510 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, | 510 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, |
511 | VREG_VOLTAGE_SMPS_4030, vsel); | 511 | VREG_VOLTAGE_SMPS_4030, vsel); |
512 | } | 512 | } |
513 | 513 | ||
514 | return 0; | 514 | return 0; |
515 | } | 515 | } |
516 | 516 | ||
517 | static int twl4030smps_get_voltage(struct regulator_dev *rdev) | 517 | static int twl4030smps_get_voltage(struct regulator_dev *rdev) |
518 | { | 518 | { |
519 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 519 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
520 | int vsel; | 520 | int vsel; |
521 | 521 | ||
522 | if (info->get_voltage) | 522 | if (info->get_voltage) |
523 | return info->get_voltage(info->data); | 523 | return info->get_voltage(info->data); |
524 | 524 | ||
525 | vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | 525 | vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, |
526 | VREG_VOLTAGE_SMPS_4030); | 526 | VREG_VOLTAGE_SMPS_4030); |
527 | 527 | ||
528 | return vsel * 12500 + 600000; | 528 | return vsel * 12500 + 600000; |
529 | } | 529 | } |
530 | 530 | ||
531 | static struct regulator_ops twl4030smps_ops = { | 531 | static struct regulator_ops twl4030smps_ops = { |
532 | .set_voltage = twl4030smps_set_voltage, | 532 | .set_voltage = twl4030smps_set_voltage, |
533 | .get_voltage = twl4030smps_get_voltage, | 533 | .get_voltage = twl4030smps_get_voltage, |
534 | }; | 534 | }; |
535 | 535 | ||
536 | static int twl6030coresmps_set_voltage(struct regulator_dev *rdev, int min_uV, | 536 | static int twl6030coresmps_set_voltage(struct regulator_dev *rdev, int min_uV, |
537 | int max_uV, unsigned *selector) | 537 | int max_uV, unsigned *selector) |
538 | { | 538 | { |
539 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 539 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
540 | 540 | ||
541 | if (info->set_voltage) | 541 | if (info->set_voltage) |
542 | return info->set_voltage(info->data, min_uV); | 542 | return info->set_voltage(info->data, min_uV); |
543 | 543 | ||
544 | return -ENODEV; | 544 | return -ENODEV; |
545 | } | 545 | } |
546 | 546 | ||
547 | static int twl6030coresmps_get_voltage(struct regulator_dev *rdev) | 547 | static int twl6030coresmps_get_voltage(struct regulator_dev *rdev) |
548 | { | 548 | { |
549 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 549 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
550 | 550 | ||
551 | if (info->get_voltage) | 551 | if (info->get_voltage) |
552 | return info->get_voltage(info->data); | 552 | return info->get_voltage(info->data); |
553 | 553 | ||
554 | return -ENODEV; | 554 | return -ENODEV; |
555 | } | 555 | } |
556 | 556 | ||
557 | static struct regulator_ops twl6030coresmps_ops = { | 557 | static struct regulator_ops twl6030coresmps_ops = { |
558 | .set_voltage = twl6030coresmps_set_voltage, | 558 | .set_voltage = twl6030coresmps_set_voltage, |
559 | .get_voltage = twl6030coresmps_get_voltage, | 559 | .get_voltage = twl6030coresmps_get_voltage, |
560 | }; | 560 | }; |
561 | 561 | ||
562 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) | 562 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) |
563 | { | 563 | { |
564 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 564 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
565 | 565 | ||
566 | switch (sel) { | 566 | switch (sel) { |
567 | case 0: | 567 | case 0: |
568 | return 0; | 568 | return 0; |
569 | case 1 ... 24: | 569 | case 1 ... 24: |
570 | /* Linear mapping from 00000001 to 00011000: | 570 | /* Linear mapping from 00000001 to 00011000: |
571 | * Absolute voltage value = 1.0 V + 0.1 V ร (sel โ 00000001) | 571 | * Absolute voltage value = 1.0 V + 0.1 V ร (sel โ 00000001) |
572 | */ | 572 | */ |
573 | return (info->min_mV + 100 * (sel - 1)) * 1000; | 573 | return (info->min_mV + 100 * (sel - 1)) * 1000; |
574 | case 25 ... 30: | 574 | case 25 ... 30: |
575 | return -EINVAL; | 575 | return -EINVAL; |
576 | case 31: | 576 | case 31: |
577 | return 2750000; | 577 | return 2750000; |
578 | default: | 578 | default: |
579 | return -EINVAL; | 579 | return -EINVAL; |
580 | } | 580 | } |
581 | } | 581 | } |
582 | 582 | ||
583 | static int | 583 | static int |
584 | twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) | 584 | twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) |
585 | { | 585 | { |
586 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 586 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
587 | 587 | ||
588 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, | 588 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, |
589 | selector); | 589 | selector); |
590 | } | 590 | } |
591 | 591 | ||
592 | static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev) | 592 | static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev) |
593 | { | 593 | { |
594 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 594 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
595 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE); | 595 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE); |
596 | 596 | ||
597 | return vsel; | 597 | return vsel; |
598 | } | 598 | } |
599 | 599 | ||
600 | static struct regulator_ops twl6030ldo_ops = { | 600 | static struct regulator_ops twl6030ldo_ops = { |
601 | .list_voltage = twl6030ldo_list_voltage, | 601 | .list_voltage = twl6030ldo_list_voltage, |
602 | 602 | ||
603 | .set_voltage_sel = twl6030ldo_set_voltage_sel, | 603 | .set_voltage_sel = twl6030ldo_set_voltage_sel, |
604 | .get_voltage_sel = twl6030ldo_get_voltage_sel, | 604 | .get_voltage_sel = twl6030ldo_get_voltage_sel, |
605 | 605 | ||
606 | .enable = twl6030reg_enable, | 606 | .enable = twl6030reg_enable, |
607 | .disable = twl6030reg_disable, | 607 | .disable = twl6030reg_disable, |
608 | .is_enabled = twl6030reg_is_enabled, | 608 | .is_enabled = twl6030reg_is_enabled, |
609 | 609 | ||
610 | .set_mode = twl6030reg_set_mode, | 610 | .set_mode = twl6030reg_set_mode, |
611 | 611 | ||
612 | .get_status = twl6030reg_get_status, | 612 | .get_status = twl6030reg_get_status, |
613 | }; | 613 | }; |
614 | 614 | ||
615 | /*----------------------------------------------------------------------*/ | 615 | /*----------------------------------------------------------------------*/ |
616 | 616 | ||
617 | /* | 617 | /* |
618 | * Fixed voltage LDOs don't have a VSEL field to update. | 618 | * Fixed voltage LDOs don't have a VSEL field to update. |
619 | */ | 619 | */ |
620 | static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index) | 620 | static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index) |
621 | { | 621 | { |
622 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 622 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
623 | 623 | ||
624 | return info->min_mV * 1000; | 624 | return info->min_mV * 1000; |
625 | } | 625 | } |
626 | 626 | ||
627 | static int twlfixed_get_voltage(struct regulator_dev *rdev) | 627 | static int twlfixed_get_voltage(struct regulator_dev *rdev) |
628 | { | 628 | { |
629 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 629 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
630 | 630 | ||
631 | return info->min_mV * 1000; | 631 | return info->min_mV * 1000; |
632 | } | 632 | } |
633 | 633 | ||
634 | static struct regulator_ops twl4030fixed_ops = { | 634 | static struct regulator_ops twl4030fixed_ops = { |
635 | .list_voltage = twlfixed_list_voltage, | 635 | .list_voltage = twlfixed_list_voltage, |
636 | 636 | ||
637 | .get_voltage = twlfixed_get_voltage, | 637 | .get_voltage = twlfixed_get_voltage, |
638 | 638 | ||
639 | .enable = twl4030reg_enable, | 639 | .enable = twl4030reg_enable, |
640 | .disable = twl4030reg_disable, | 640 | .disable = twl4030reg_disable, |
641 | .is_enabled = twl4030reg_is_enabled, | 641 | .is_enabled = twl4030reg_is_enabled, |
642 | 642 | ||
643 | .set_mode = twl4030reg_set_mode, | 643 | .set_mode = twl4030reg_set_mode, |
644 | 644 | ||
645 | .get_status = twl4030reg_get_status, | 645 | .get_status = twl4030reg_get_status, |
646 | }; | 646 | }; |
647 | 647 | ||
648 | static struct regulator_ops twl6030fixed_ops = { | 648 | static struct regulator_ops twl6030fixed_ops = { |
649 | .list_voltage = twlfixed_list_voltage, | 649 | .list_voltage = twlfixed_list_voltage, |
650 | 650 | ||
651 | .get_voltage = twlfixed_get_voltage, | 651 | .get_voltage = twlfixed_get_voltage, |
652 | 652 | ||
653 | .enable = twl6030reg_enable, | 653 | .enable = twl6030reg_enable, |
654 | .disable = twl6030reg_disable, | 654 | .disable = twl6030reg_disable, |
655 | .is_enabled = twl6030reg_is_enabled, | 655 | .is_enabled = twl6030reg_is_enabled, |
656 | 656 | ||
657 | .set_mode = twl6030reg_set_mode, | 657 | .set_mode = twl6030reg_set_mode, |
658 | 658 | ||
659 | .get_status = twl6030reg_get_status, | 659 | .get_status = twl6030reg_get_status, |
660 | }; | 660 | }; |
661 | 661 | ||
662 | static struct regulator_ops twl6030_fixed_resource = { | 662 | static struct regulator_ops twl6030_fixed_resource = { |
663 | .enable = twl6030reg_enable, | 663 | .enable = twl6030reg_enable, |
664 | .disable = twl6030reg_disable, | 664 | .disable = twl6030reg_disable, |
665 | .is_enabled = twl6030reg_is_enabled, | 665 | .is_enabled = twl6030reg_is_enabled, |
666 | .get_status = twl6030reg_get_status, | 666 | .get_status = twl6030reg_get_status, |
667 | }; | 667 | }; |
668 | 668 | ||
669 | /* | 669 | /* |
670 | * SMPS status and control | 670 | * SMPS status and control |
671 | */ | 671 | */ |
672 | 672 | ||
673 | static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index) | 673 | static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index) |
674 | { | 674 | { |
675 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 675 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
676 | 676 | ||
677 | int voltage = 0; | 677 | int voltage = 0; |
678 | 678 | ||
679 | switch (info->flags) { | 679 | switch (info->flags) { |
680 | case SMPS_OFFSET_EN: | 680 | case SMPS_OFFSET_EN: |
681 | voltage = 100000; | 681 | voltage = 100000; |
682 | /* fall through */ | 682 | /* fall through */ |
683 | case 0: | 683 | case 0: |
684 | switch (index) { | 684 | switch (index) { |
685 | case 0: | 685 | case 0: |
686 | voltage = 0; | 686 | voltage = 0; |
687 | break; | 687 | break; |
688 | case 58: | 688 | case 58: |
689 | voltage = 1350 * 1000; | 689 | voltage = 1350 * 1000; |
690 | break; | 690 | break; |
691 | case 59: | 691 | case 59: |
692 | voltage = 1500 * 1000; | 692 | voltage = 1500 * 1000; |
693 | break; | 693 | break; |
694 | case 60: | 694 | case 60: |
695 | voltage = 1800 * 1000; | 695 | voltage = 1800 * 1000; |
696 | break; | 696 | break; |
697 | case 61: | 697 | case 61: |
698 | voltage = 1900 * 1000; | 698 | voltage = 1900 * 1000; |
699 | break; | 699 | break; |
700 | case 62: | 700 | case 62: |
701 | voltage = 2100 * 1000; | 701 | voltage = 2100 * 1000; |
702 | break; | 702 | break; |
703 | default: | 703 | default: |
704 | voltage += (600000 + (12500 * (index - 1))); | 704 | voltage += (600000 + (12500 * (index - 1))); |
705 | } | 705 | } |
706 | break; | 706 | break; |
707 | case SMPS_EXTENDED_EN: | 707 | case SMPS_EXTENDED_EN: |
708 | switch (index) { | 708 | switch (index) { |
709 | case 0: | 709 | case 0: |
710 | voltage = 0; | 710 | voltage = 0; |
711 | break; | 711 | break; |
712 | case 58: | 712 | case 58: |
713 | voltage = 2084 * 1000; | 713 | voltage = 2084 * 1000; |
714 | break; | 714 | break; |
715 | case 59: | 715 | case 59: |
716 | voltage = 2315 * 1000; | 716 | voltage = 2315 * 1000; |
717 | break; | 717 | break; |
718 | case 60: | 718 | case 60: |
719 | voltage = 2778 * 1000; | 719 | voltage = 2778 * 1000; |
720 | break; | 720 | break; |
721 | case 61: | 721 | case 61: |
722 | voltage = 2932 * 1000; | 722 | voltage = 2932 * 1000; |
723 | break; | 723 | break; |
724 | case 62: | 724 | case 62: |
725 | voltage = 3241 * 1000; | 725 | voltage = 3241 * 1000; |
726 | break; | 726 | break; |
727 | default: | 727 | default: |
728 | voltage = (1852000 + (38600 * (index - 1))); | 728 | voltage = (1852000 + (38600 * (index - 1))); |
729 | } | 729 | } |
730 | break; | 730 | break; |
731 | case SMPS_OFFSET_EN | SMPS_EXTENDED_EN: | 731 | case SMPS_OFFSET_EN | SMPS_EXTENDED_EN: |
732 | switch (index) { | 732 | switch (index) { |
733 | case 0: | 733 | case 0: |
734 | voltage = 0; | 734 | voltage = 0; |
735 | break; | 735 | break; |
736 | case 58: | 736 | case 58: |
737 | voltage = 4167 * 1000; | 737 | voltage = 4167 * 1000; |
738 | break; | 738 | break; |
739 | case 59: | 739 | case 59: |
740 | voltage = 2315 * 1000; | 740 | voltage = 2315 * 1000; |
741 | break; | 741 | break; |
742 | case 60: | 742 | case 60: |
743 | voltage = 2778 * 1000; | 743 | voltage = 2778 * 1000; |
744 | break; | 744 | break; |
745 | case 61: | 745 | case 61: |
746 | voltage = 2932 * 1000; | 746 | voltage = 2932 * 1000; |
747 | break; | 747 | break; |
748 | case 62: | 748 | case 62: |
749 | voltage = 3241 * 1000; | 749 | voltage = 3241 * 1000; |
750 | break; | 750 | break; |
751 | default: | 751 | default: |
752 | voltage = (2161000 + (38600 * (index - 1))); | 752 | voltage = (2161000 + (38600 * (index - 1))); |
753 | } | 753 | } |
754 | break; | 754 | break; |
755 | } | 755 | } |
756 | 756 | ||
757 | return voltage; | 757 | return voltage; |
758 | } | 758 | } |
759 | 759 | ||
760 | static int | 760 | static int twl6030smps_map_voltage(struct regulator_dev *rdev, int min_uV, |
761 | twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | 761 | int max_uV) |
762 | unsigned int *selector) | ||
763 | { | 762 | { |
764 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 763 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
765 | int vsel = 0, calc_uV; | 764 | int vsel = 0; |
766 | 765 | ||
767 | switch (info->flags) { | 766 | switch (info->flags) { |
768 | case 0: | 767 | case 0: |
769 | if (min_uV == 0) | 768 | if (min_uV == 0) |
770 | vsel = 0; | 769 | vsel = 0; |
771 | else if ((min_uV >= 600000) && (min_uV <= 1300000)) { | 770 | else if ((min_uV >= 600000) && (min_uV <= 1300000)) { |
772 | vsel = DIV_ROUND_UP(min_uV - 600000, 12500); | 771 | vsel = DIV_ROUND_UP(min_uV - 600000, 12500); |
773 | vsel++; | 772 | vsel++; |
774 | } | 773 | } |
775 | /* Values 1..57 for vsel are linear and can be calculated | 774 | /* Values 1..57 for vsel are linear and can be calculated |
776 | * values 58..62 are non linear. | 775 | * values 58..62 are non linear. |
777 | */ | 776 | */ |
778 | else if ((min_uV > 1900000) && (min_uV <= 2100000)) | 777 | else if ((min_uV > 1900000) && (min_uV <= 2100000)) |
779 | vsel = 62; | 778 | vsel = 62; |
780 | else if ((min_uV > 1800000) && (min_uV <= 1900000)) | 779 | else if ((min_uV > 1800000) && (min_uV <= 1900000)) |
781 | vsel = 61; | 780 | vsel = 61; |
782 | else if ((min_uV > 1500000) && (min_uV <= 1800000)) | 781 | else if ((min_uV > 1500000) && (min_uV <= 1800000)) |
783 | vsel = 60; | 782 | vsel = 60; |
784 | else if ((min_uV > 1350000) && (min_uV <= 1500000)) | 783 | else if ((min_uV > 1350000) && (min_uV <= 1500000)) |
785 | vsel = 59; | 784 | vsel = 59; |
786 | else if ((min_uV > 1300000) && (min_uV <= 1350000)) | 785 | else if ((min_uV > 1300000) && (min_uV <= 1350000)) |
787 | vsel = 58; | 786 | vsel = 58; |
788 | else | 787 | else |
789 | return -EINVAL; | 788 | return -EINVAL; |
790 | break; | 789 | break; |
791 | case SMPS_OFFSET_EN: | 790 | case SMPS_OFFSET_EN: |
792 | if (min_uV == 0) | 791 | if (min_uV == 0) |
793 | vsel = 0; | 792 | vsel = 0; |
794 | else if ((min_uV >= 700000) && (min_uV <= 1420000)) { | 793 | else if ((min_uV >= 700000) && (min_uV <= 1420000)) { |
795 | vsel = DIV_ROUND_UP(min_uV - 700000, 12500); | 794 | vsel = DIV_ROUND_UP(min_uV - 700000, 12500); |
796 | vsel++; | 795 | vsel++; |
797 | } | 796 | } |
798 | /* Values 1..57 for vsel are linear and can be calculated | 797 | /* Values 1..57 for vsel are linear and can be calculated |
799 | * values 58..62 are non linear. | 798 | * values 58..62 are non linear. |
800 | */ | 799 | */ |
801 | else if ((min_uV > 1900000) && (min_uV <= 2100000)) | 800 | else if ((min_uV > 1900000) && (min_uV <= 2100000)) |
802 | vsel = 62; | 801 | vsel = 62; |
803 | else if ((min_uV > 1800000) && (min_uV <= 1900000)) | 802 | else if ((min_uV > 1800000) && (min_uV <= 1900000)) |
804 | vsel = 61; | 803 | vsel = 61; |
805 | else if ((min_uV > 1350000) && (min_uV <= 1800000)) | 804 | else if ((min_uV > 1350000) && (min_uV <= 1800000)) |
806 | vsel = 60; | 805 | vsel = 60; |
807 | else if ((min_uV > 1350000) && (min_uV <= 1500000)) | 806 | else if ((min_uV > 1350000) && (min_uV <= 1500000)) |
808 | vsel = 59; | 807 | vsel = 59; |
809 | else if ((min_uV > 1300000) && (min_uV <= 1350000)) | 808 | else if ((min_uV > 1300000) && (min_uV <= 1350000)) |
810 | vsel = 58; | 809 | vsel = 58; |
811 | else | 810 | else |
812 | return -EINVAL; | 811 | return -EINVAL; |
813 | break; | 812 | break; |
814 | case SMPS_EXTENDED_EN: | 813 | case SMPS_EXTENDED_EN: |
815 | if (min_uV == 0) { | 814 | if (min_uV == 0) { |
816 | vsel = 0; | 815 | vsel = 0; |
817 | } else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { | 816 | } else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { |
818 | vsel = DIV_ROUND_UP(min_uV - 1852000, 38600); | 817 | vsel = DIV_ROUND_UP(min_uV - 1852000, 38600); |
819 | vsel++; | 818 | vsel++; |
820 | } | 819 | } |
821 | break; | 820 | break; |
822 | case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: | 821 | case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: |
823 | if (min_uV == 0) { | 822 | if (min_uV == 0) { |
824 | vsel = 0; | 823 | vsel = 0; |
825 | } else if ((min_uV >= 2161000) && (min_uV <= 4321000)) { | 824 | } else if ((min_uV >= 2161000) && (min_uV <= 4321000)) { |
826 | vsel = DIV_ROUND_UP(min_uV - 2161000, 38600); | 825 | vsel = DIV_ROUND_UP(min_uV - 2161000, 38600); |
827 | vsel++; | 826 | vsel++; |
828 | } | 827 | } |
829 | break; | 828 | break; |
830 | } | 829 | } |
831 | 830 | ||
832 | calc_uV = twl6030smps_list_voltage(rdev, vsel); | 831 | return vsel; |
833 | if (calc_uV > max_uV) | 832 | } |
834 | return -EINVAL; | ||
835 | 833 | ||
836 | *selector = vsel; | 834 | static int twl6030smps_set_voltage_sel(struct regulator_dev *rdev, |
835 | unsigned int selector) | ||
836 | { | ||
837 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
837 | 838 | ||
838 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS, | 839 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS, |
839 | vsel); | 840 | selector); |
840 | } | 841 | } |
841 | 842 | ||
842 | static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) | 843 | static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) |
843 | { | 844 | { |
844 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 845 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
845 | 846 | ||
846 | return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS); | 847 | return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS); |
847 | } | 848 | } |
848 | 849 | ||
849 | static struct regulator_ops twlsmps_ops = { | 850 | static struct regulator_ops twlsmps_ops = { |
850 | .list_voltage = twl6030smps_list_voltage, | 851 | .list_voltage = twl6030smps_list_voltage, |
852 | .map_voltage = twl6030smps_map_voltage, | ||
851 | 853 | ||
852 | .set_voltage = twl6030smps_set_voltage, | 854 | .set_voltage_sel = twl6030smps_set_voltage_sel, |
853 | .get_voltage_sel = twl6030smps_get_voltage_sel, | 855 | .get_voltage_sel = twl6030smps_get_voltage_sel, |
854 | 856 | ||
855 | .enable = twl6030reg_enable, | 857 | .enable = twl6030reg_enable, |
856 | .disable = twl6030reg_disable, | 858 | .disable = twl6030reg_disable, |
857 | .is_enabled = twl6030reg_is_enabled, | 859 | .is_enabled = twl6030reg_is_enabled, |
858 | 860 | ||
859 | .set_mode = twl6030reg_set_mode, | 861 | .set_mode = twl6030reg_set_mode, |
860 | 862 | ||
861 | .get_status = twl6030reg_get_status, | 863 | .get_status = twl6030reg_get_status, |
862 | }; | 864 | }; |
863 | 865 | ||
864 | /*----------------------------------------------------------------------*/ | 866 | /*----------------------------------------------------------------------*/ |
865 | 867 | ||
866 | #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 868 | #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
867 | remap_conf) \ | 869 | remap_conf) \ |
868 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 870 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
869 | remap_conf, TWL4030, twl4030fixed_ops) | 871 | remap_conf, TWL4030, twl4030fixed_ops) |
870 | #define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \ | 872 | #define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \ |
871 | TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \ | 873 | TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \ |
872 | 0x0, TWL6030, twl6030fixed_ops) | 874 | 0x0, TWL6030, twl6030fixed_ops) |
873 | 875 | ||
874 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ | 876 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ |
875 | static struct twlreg_info TWL4030_INFO_##label = { \ | 877 | static struct twlreg_info TWL4030_INFO_##label = { \ |
876 | .base = offset, \ | 878 | .base = offset, \ |
877 | .id = num, \ | 879 | .id = num, \ |
878 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ | 880 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ |
879 | .table = label##_VSEL_table, \ | 881 | .table = label##_VSEL_table, \ |
880 | .remap = remap_conf, \ | 882 | .remap = remap_conf, \ |
881 | .desc = { \ | 883 | .desc = { \ |
882 | .name = #label, \ | 884 | .name = #label, \ |
883 | .id = TWL4030_REG_##label, \ | 885 | .id = TWL4030_REG_##label, \ |
884 | .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ | 886 | .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ |
885 | .ops = &twl4030ldo_ops, \ | 887 | .ops = &twl4030ldo_ops, \ |
886 | .type = REGULATOR_VOLTAGE, \ | 888 | .type = REGULATOR_VOLTAGE, \ |
887 | .owner = THIS_MODULE, \ | 889 | .owner = THIS_MODULE, \ |
888 | .enable_time = turnon_delay, \ | 890 | .enable_time = turnon_delay, \ |
889 | }, \ | 891 | }, \ |
890 | } | 892 | } |
891 | 893 | ||
892 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ | 894 | #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ |
893 | static struct twlreg_info TWL4030_INFO_##label = { \ | 895 | static struct twlreg_info TWL4030_INFO_##label = { \ |
894 | .base = offset, \ | 896 | .base = offset, \ |
895 | .id = num, \ | 897 | .id = num, \ |
896 | .remap = remap_conf, \ | 898 | .remap = remap_conf, \ |
897 | .desc = { \ | 899 | .desc = { \ |
898 | .name = #label, \ | 900 | .name = #label, \ |
899 | .id = TWL4030_REG_##label, \ | 901 | .id = TWL4030_REG_##label, \ |
900 | .ops = &twl4030smps_ops, \ | 902 | .ops = &twl4030smps_ops, \ |
901 | .type = REGULATOR_VOLTAGE, \ | 903 | .type = REGULATOR_VOLTAGE, \ |
902 | .owner = THIS_MODULE, \ | 904 | .owner = THIS_MODULE, \ |
903 | .enable_time = turnon_delay, \ | 905 | .enable_time = turnon_delay, \ |
904 | }, \ | 906 | }, \ |
905 | } | 907 | } |
906 | 908 | ||
907 | #define TWL6030_ADJUSTABLE_SMPS(label) \ | 909 | #define TWL6030_ADJUSTABLE_SMPS(label) \ |
908 | static struct twlreg_info TWL6030_INFO_##label = { \ | 910 | static struct twlreg_info TWL6030_INFO_##label = { \ |
909 | .desc = { \ | 911 | .desc = { \ |
910 | .name = #label, \ | 912 | .name = #label, \ |
911 | .id = TWL6030_REG_##label, \ | 913 | .id = TWL6030_REG_##label, \ |
912 | .ops = &twl6030coresmps_ops, \ | 914 | .ops = &twl6030coresmps_ops, \ |
913 | .type = REGULATOR_VOLTAGE, \ | 915 | .type = REGULATOR_VOLTAGE, \ |
914 | .owner = THIS_MODULE, \ | 916 | .owner = THIS_MODULE, \ |
915 | }, \ | 917 | }, \ |
916 | } | 918 | } |
917 | 919 | ||
918 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ | 920 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ |
919 | static struct twlreg_info TWL6030_INFO_##label = { \ | 921 | static struct twlreg_info TWL6030_INFO_##label = { \ |
920 | .base = offset, \ | 922 | .base = offset, \ |
921 | .min_mV = min_mVolts, \ | 923 | .min_mV = min_mVolts, \ |
922 | .max_mV = max_mVolts, \ | 924 | .max_mV = max_mVolts, \ |
923 | .desc = { \ | 925 | .desc = { \ |
924 | .name = #label, \ | 926 | .name = #label, \ |
925 | .id = TWL6030_REG_##label, \ | 927 | .id = TWL6030_REG_##label, \ |
926 | .n_voltages = 32, \ | 928 | .n_voltages = 32, \ |
927 | .ops = &twl6030ldo_ops, \ | 929 | .ops = &twl6030ldo_ops, \ |
928 | .type = REGULATOR_VOLTAGE, \ | 930 | .type = REGULATOR_VOLTAGE, \ |
929 | .owner = THIS_MODULE, \ | 931 | .owner = THIS_MODULE, \ |
930 | }, \ | 932 | }, \ |
931 | } | 933 | } |
932 | 934 | ||
933 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ | 935 | #define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \ |
934 | static struct twlreg_info TWL6025_INFO_##label = { \ | 936 | static struct twlreg_info TWL6025_INFO_##label = { \ |
935 | .base = offset, \ | 937 | .base = offset, \ |
936 | .min_mV = min_mVolts, \ | 938 | .min_mV = min_mVolts, \ |
937 | .max_mV = max_mVolts, \ | 939 | .max_mV = max_mVolts, \ |
938 | .desc = { \ | 940 | .desc = { \ |
939 | .name = #label, \ | 941 | .name = #label, \ |
940 | .id = TWL6025_REG_##label, \ | 942 | .id = TWL6025_REG_##label, \ |
941 | .n_voltages = 32, \ | 943 | .n_voltages = 32, \ |
942 | .ops = &twl6030ldo_ops, \ | 944 | .ops = &twl6030ldo_ops, \ |
943 | .type = REGULATOR_VOLTAGE, \ | 945 | .type = REGULATOR_VOLTAGE, \ |
944 | .owner = THIS_MODULE, \ | 946 | .owner = THIS_MODULE, \ |
945 | }, \ | 947 | }, \ |
946 | } | 948 | } |
947 | 949 | ||
948 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ | 950 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ |
949 | family, operations) \ | 951 | family, operations) \ |
950 | static struct twlreg_info TWLFIXED_INFO_##label = { \ | 952 | static struct twlreg_info TWLFIXED_INFO_##label = { \ |
951 | .base = offset, \ | 953 | .base = offset, \ |
952 | .id = num, \ | 954 | .id = num, \ |
953 | .min_mV = mVolts, \ | 955 | .min_mV = mVolts, \ |
954 | .remap = remap_conf, \ | 956 | .remap = remap_conf, \ |
955 | .desc = { \ | 957 | .desc = { \ |
956 | .name = #label, \ | 958 | .name = #label, \ |
957 | .id = family##_REG_##label, \ | 959 | .id = family##_REG_##label, \ |
958 | .n_voltages = 1, \ | 960 | .n_voltages = 1, \ |
959 | .ops = &operations, \ | 961 | .ops = &operations, \ |
960 | .type = REGULATOR_VOLTAGE, \ | 962 | .type = REGULATOR_VOLTAGE, \ |
961 | .owner = THIS_MODULE, \ | 963 | .owner = THIS_MODULE, \ |
962 | .enable_time = turnon_delay, \ | 964 | .enable_time = turnon_delay, \ |
963 | }, \ | 965 | }, \ |
964 | } | 966 | } |
965 | 967 | ||
966 | #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \ | 968 | #define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \ |
967 | static struct twlreg_info TWLRES_INFO_##label = { \ | 969 | static struct twlreg_info TWLRES_INFO_##label = { \ |
968 | .base = offset, \ | 970 | .base = offset, \ |
969 | .desc = { \ | 971 | .desc = { \ |
970 | .name = #label, \ | 972 | .name = #label, \ |
971 | .id = TWL6030_REG_##label, \ | 973 | .id = TWL6030_REG_##label, \ |
972 | .ops = &twl6030_fixed_resource, \ | 974 | .ops = &twl6030_fixed_resource, \ |
973 | .type = REGULATOR_VOLTAGE, \ | 975 | .type = REGULATOR_VOLTAGE, \ |
974 | .owner = THIS_MODULE, \ | 976 | .owner = THIS_MODULE, \ |
975 | .enable_time = turnon_delay, \ | 977 | .enable_time = turnon_delay, \ |
976 | }, \ | 978 | }, \ |
977 | } | 979 | } |
978 | 980 | ||
979 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ | 981 | #define TWL6025_ADJUSTABLE_SMPS(label, offset) \ |
980 | static struct twlreg_info TWLSMPS_INFO_##label = { \ | 982 | static struct twlreg_info TWLSMPS_INFO_##label = { \ |
981 | .base = offset, \ | 983 | .base = offset, \ |
982 | .min_mV = 600, \ | 984 | .min_mV = 600, \ |
983 | .max_mV = 2100, \ | 985 | .max_mV = 2100, \ |
984 | .desc = { \ | 986 | .desc = { \ |
985 | .name = #label, \ | 987 | .name = #label, \ |
986 | .id = TWL6025_REG_##label, \ | 988 | .id = TWL6025_REG_##label, \ |
987 | .n_voltages = 63, \ | 989 | .n_voltages = 63, \ |
988 | .ops = &twlsmps_ops, \ | 990 | .ops = &twlsmps_ops, \ |
989 | .type = REGULATOR_VOLTAGE, \ | 991 | .type = REGULATOR_VOLTAGE, \ |
990 | .owner = THIS_MODULE, \ | 992 | .owner = THIS_MODULE, \ |
991 | }, \ | 993 | }, \ |
992 | } | 994 | } |
993 | 995 | ||
994 | /* | 996 | /* |
995 | * We list regulators here if systems need some level of | 997 | * We list regulators here if systems need some level of |
996 | * software control over them after boot. | 998 | * software control over them after boot. |
997 | */ | 999 | */ |
998 | TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08); | 1000 | TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08); |
999 | TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08); | 1001 | TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08); |
1000 | TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08); | 1002 | TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08); |
1001 | TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08); | 1003 | TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08); |
1002 | TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08); | 1004 | TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08); |
1003 | TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08); | 1005 | TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08); |
1004 | TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08); | 1006 | TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08); |
1005 | TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00); | 1007 | TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00); |
1006 | TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08); | 1008 | TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08); |
1007 | TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00); | 1009 | TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00); |
1008 | TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08); | 1010 | TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08); |
1009 | TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08); | 1011 | TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08); |
1010 | TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08); | 1012 | TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08); |
1011 | TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08); | 1013 | TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08); |
1012 | TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08); | 1014 | TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08); |
1013 | /* VUSBCP is managed *only* by the USB subchip */ | 1015 | /* VUSBCP is managed *only* by the USB subchip */ |
1014 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ | 1016 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ |
1015 | /* Turnon-delay and remap configuration values for 6030 are not | 1017 | /* Turnon-delay and remap configuration values for 6030 are not |
1016 | verified since the specification is not public */ | 1018 | verified since the specification is not public */ |
1017 | TWL6030_ADJUSTABLE_SMPS(VDD1); | 1019 | TWL6030_ADJUSTABLE_SMPS(VDD1); |
1018 | TWL6030_ADJUSTABLE_SMPS(VDD2); | 1020 | TWL6030_ADJUSTABLE_SMPS(VDD2); |
1019 | TWL6030_ADJUSTABLE_SMPS(VDD3); | 1021 | TWL6030_ADJUSTABLE_SMPS(VDD3); |
1020 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300); | 1022 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300); |
1021 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300); | 1023 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300); |
1022 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300); | 1024 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300); |
1023 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300); | 1025 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300); |
1024 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300); | 1026 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300); |
1025 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300); | 1027 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300); |
1026 | /* 6025 are renamed compared to 6030 versions */ | 1028 | /* 6025 are renamed compared to 6030 versions */ |
1027 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300); | 1029 | TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300); |
1028 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300); | 1030 | TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300); |
1029 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300); | 1031 | TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300); |
1030 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300); | 1032 | TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300); |
1031 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300); | 1033 | TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300); |
1032 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); | 1034 | TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); |
1033 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); | 1035 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); |
1034 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); | 1036 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); |
1035 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); | 1037 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); |
1036 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08); | 1038 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08); |
1037 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); | 1039 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); |
1038 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); | 1040 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); |
1039 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); | 1041 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); |
1040 | TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08); | 1042 | TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08); |
1041 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0); | 1043 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0); |
1042 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0); | 1044 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0); |
1043 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); | 1045 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); |
1044 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); | 1046 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); |
1045 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); | 1047 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); |
1046 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); | 1048 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); |
1047 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); | 1049 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); |
1048 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); | 1050 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); |
1049 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); | 1051 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); |
1050 | 1052 | ||
1051 | static u8 twl_get_smps_offset(void) | 1053 | static u8 twl_get_smps_offset(void) |
1052 | { | 1054 | { |
1053 | u8 value; | 1055 | u8 value; |
1054 | 1056 | ||
1055 | twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, | 1057 | twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, |
1056 | TWL6030_SMPS_OFFSET); | 1058 | TWL6030_SMPS_OFFSET); |
1057 | return value; | 1059 | return value; |
1058 | } | 1060 | } |
1059 | 1061 | ||
1060 | static u8 twl_get_smps_mult(void) | 1062 | static u8 twl_get_smps_mult(void) |
1061 | { | 1063 | { |
1062 | u8 value; | 1064 | u8 value; |
1063 | 1065 | ||
1064 | twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, | 1066 | twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, |
1065 | TWL6030_SMPS_MULT); | 1067 | TWL6030_SMPS_MULT); |
1066 | return value; | 1068 | return value; |
1067 | } | 1069 | } |
1068 | 1070 | ||
1069 | #define TWL_OF_MATCH(comp, family, label) \ | 1071 | #define TWL_OF_MATCH(comp, family, label) \ |
1070 | { \ | 1072 | { \ |
1071 | .compatible = comp, \ | 1073 | .compatible = comp, \ |
1072 | .data = &family##_INFO_##label, \ | 1074 | .data = &family##_INFO_##label, \ |
1073 | } | 1075 | } |
1074 | 1076 | ||
1075 | #define TWL4030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL4030, label) | 1077 | #define TWL4030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL4030, label) |
1076 | #define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label) | 1078 | #define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label) |
1077 | #define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label) | 1079 | #define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label) |
1078 | #define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label) | 1080 | #define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label) |
1079 | #define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label) | 1081 | #define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label) |
1080 | 1082 | ||
1081 | static const struct of_device_id twl_of_match[] __devinitconst = { | 1083 | static const struct of_device_id twl_of_match[] __devinitconst = { |
1082 | TWL4030_OF_MATCH("ti,twl4030-vaux1", VAUX1), | 1084 | TWL4030_OF_MATCH("ti,twl4030-vaux1", VAUX1), |
1083 | TWL4030_OF_MATCH("ti,twl4030-vaux2", VAUX2_4030), | 1085 | TWL4030_OF_MATCH("ti,twl4030-vaux2", VAUX2_4030), |
1084 | TWL4030_OF_MATCH("ti,twl5030-vaux2", VAUX2), | 1086 | TWL4030_OF_MATCH("ti,twl5030-vaux2", VAUX2), |
1085 | TWL4030_OF_MATCH("ti,twl4030-vaux3", VAUX3), | 1087 | TWL4030_OF_MATCH("ti,twl4030-vaux3", VAUX3), |
1086 | TWL4030_OF_MATCH("ti,twl4030-vaux4", VAUX4), | 1088 | TWL4030_OF_MATCH("ti,twl4030-vaux4", VAUX4), |
1087 | TWL4030_OF_MATCH("ti,twl4030-vmmc1", VMMC1), | 1089 | TWL4030_OF_MATCH("ti,twl4030-vmmc1", VMMC1), |
1088 | TWL4030_OF_MATCH("ti,twl4030-vmmc2", VMMC2), | 1090 | TWL4030_OF_MATCH("ti,twl4030-vmmc2", VMMC2), |
1089 | TWL4030_OF_MATCH("ti,twl4030-vpll1", VPLL1), | 1091 | TWL4030_OF_MATCH("ti,twl4030-vpll1", VPLL1), |
1090 | TWL4030_OF_MATCH("ti,twl4030-vpll2", VPLL2), | 1092 | TWL4030_OF_MATCH("ti,twl4030-vpll2", VPLL2), |
1091 | TWL4030_OF_MATCH("ti,twl4030-vsim", VSIM), | 1093 | TWL4030_OF_MATCH("ti,twl4030-vsim", VSIM), |
1092 | TWL4030_OF_MATCH("ti,twl4030-vdac", VDAC), | 1094 | TWL4030_OF_MATCH("ti,twl4030-vdac", VDAC), |
1093 | TWL4030_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | 1095 | TWL4030_OF_MATCH("ti,twl4030-vintana2", VINTANA2), |
1094 | TWL4030_OF_MATCH("ti,twl4030-vio", VIO), | 1096 | TWL4030_OF_MATCH("ti,twl4030-vio", VIO), |
1095 | TWL4030_OF_MATCH("ti,twl4030-vdd1", VDD1), | 1097 | TWL4030_OF_MATCH("ti,twl4030-vdd1", VDD1), |
1096 | TWL4030_OF_MATCH("ti,twl4030-vdd2", VDD2), | 1098 | TWL4030_OF_MATCH("ti,twl4030-vdd2", VDD2), |
1097 | TWL6030_OF_MATCH("ti,twl6030-vdd1", VDD1), | 1099 | TWL6030_OF_MATCH("ti,twl6030-vdd1", VDD1), |
1098 | TWL6030_OF_MATCH("ti,twl6030-vdd2", VDD2), | 1100 | TWL6030_OF_MATCH("ti,twl6030-vdd2", VDD2), |
1099 | TWL6030_OF_MATCH("ti,twl6030-vdd3", VDD3), | 1101 | TWL6030_OF_MATCH("ti,twl6030-vdd3", VDD3), |
1100 | TWL6030_OF_MATCH("ti,twl6030-vaux1", VAUX1_6030), | 1102 | TWL6030_OF_MATCH("ti,twl6030-vaux1", VAUX1_6030), |
1101 | TWL6030_OF_MATCH("ti,twl6030-vaux2", VAUX2_6030), | 1103 | TWL6030_OF_MATCH("ti,twl6030-vaux2", VAUX2_6030), |
1102 | TWL6030_OF_MATCH("ti,twl6030-vaux3", VAUX3_6030), | 1104 | TWL6030_OF_MATCH("ti,twl6030-vaux3", VAUX3_6030), |
1103 | TWL6030_OF_MATCH("ti,twl6030-vmmc", VMMC), | 1105 | TWL6030_OF_MATCH("ti,twl6030-vmmc", VMMC), |
1104 | TWL6030_OF_MATCH("ti,twl6030-vpp", VPP), | 1106 | TWL6030_OF_MATCH("ti,twl6030-vpp", VPP), |
1105 | TWL6030_OF_MATCH("ti,twl6030-vusim", VUSIM), | 1107 | TWL6030_OF_MATCH("ti,twl6030-vusim", VUSIM), |
1106 | TWL6025_OF_MATCH("ti,twl6025-ldo2", LDO2), | 1108 | TWL6025_OF_MATCH("ti,twl6025-ldo2", LDO2), |
1107 | TWL6025_OF_MATCH("ti,twl6025-ldo4", LDO4), | 1109 | TWL6025_OF_MATCH("ti,twl6025-ldo4", LDO4), |
1108 | TWL6025_OF_MATCH("ti,twl6025-ldo3", LDO3), | 1110 | TWL6025_OF_MATCH("ti,twl6025-ldo3", LDO3), |
1109 | TWL6025_OF_MATCH("ti,twl6025-ldo5", LDO5), | 1111 | TWL6025_OF_MATCH("ti,twl6025-ldo5", LDO5), |
1110 | TWL6025_OF_MATCH("ti,twl6025-ldo1", LDO1), | 1112 | TWL6025_OF_MATCH("ti,twl6025-ldo1", LDO1), |
1111 | TWL6025_OF_MATCH("ti,twl6025-ldo7", LDO7), | 1113 | TWL6025_OF_MATCH("ti,twl6025-ldo7", LDO7), |
1112 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), | 1114 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), |
1113 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), | 1115 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), |
1114 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), | 1116 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), |
1115 | TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1), | 1117 | TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1), |
1116 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), | 1118 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), |
1117 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), | 1119 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), |
1118 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), | 1120 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), |
1119 | TWLFIXED_OF_MATCH("ti,twl4030-vusb3v1", VUSB3V1), | 1121 | TWLFIXED_OF_MATCH("ti,twl4030-vusb3v1", VUSB3V1), |
1120 | TWLFIXED_OF_MATCH("ti,twl6030-vana", VANA), | 1122 | TWLFIXED_OF_MATCH("ti,twl6030-vana", VANA), |
1121 | TWLFIXED_OF_MATCH("ti,twl6030-vcxio", VCXIO), | 1123 | TWLFIXED_OF_MATCH("ti,twl6030-vcxio", VCXIO), |
1122 | TWLFIXED_OF_MATCH("ti,twl6030-vdac", VDAC), | 1124 | TWLFIXED_OF_MATCH("ti,twl6030-vdac", VDAC), |
1123 | TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB), | 1125 | TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB), |
1124 | TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8), | 1126 | TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8), |
1125 | TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1), | 1127 | TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1), |
1126 | TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3), | 1128 | TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3), |
1127 | TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4), | 1129 | TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4), |
1128 | TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO), | 1130 | TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO), |
1129 | {}, | 1131 | {}, |
1130 | }; | 1132 | }; |
1131 | MODULE_DEVICE_TABLE(of, twl_of_match); | 1133 | MODULE_DEVICE_TABLE(of, twl_of_match); |
1132 | 1134 | ||
1133 | static int __devinit twlreg_probe(struct platform_device *pdev) | 1135 | static int __devinit twlreg_probe(struct platform_device *pdev) |
1134 | { | 1136 | { |
1135 | int i, id; | 1137 | int i, id; |
1136 | struct twlreg_info *info; | 1138 | struct twlreg_info *info; |
1137 | struct regulator_init_data *initdata; | 1139 | struct regulator_init_data *initdata; |
1138 | struct regulation_constraints *c; | 1140 | struct regulation_constraints *c; |
1139 | struct regulator_dev *rdev; | 1141 | struct regulator_dev *rdev; |
1140 | struct twl_regulator_driver_data *drvdata; | 1142 | struct twl_regulator_driver_data *drvdata; |
1141 | const struct of_device_id *match; | 1143 | const struct of_device_id *match; |
1142 | struct regulator_config config = { }; | 1144 | struct regulator_config config = { }; |
1143 | 1145 | ||
1144 | match = of_match_device(twl_of_match, &pdev->dev); | 1146 | match = of_match_device(twl_of_match, &pdev->dev); |
1145 | if (match) { | 1147 | if (match) { |
1146 | info = match->data; | 1148 | info = match->data; |
1147 | id = info->desc.id; | 1149 | id = info->desc.id; |
1148 | initdata = of_get_regulator_init_data(&pdev->dev, | 1150 | initdata = of_get_regulator_init_data(&pdev->dev, |
1149 | pdev->dev.of_node); | 1151 | pdev->dev.of_node); |
1150 | drvdata = NULL; | 1152 | drvdata = NULL; |
1151 | } else { | 1153 | } else { |
1152 | id = pdev->id; | 1154 | id = pdev->id; |
1153 | initdata = pdev->dev.platform_data; | 1155 | initdata = pdev->dev.platform_data; |
1154 | for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { | 1156 | for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { |
1155 | info = twl_of_match[i].data; | 1157 | info = twl_of_match[i].data; |
1156 | if (info && info->desc.id == id) | 1158 | if (info && info->desc.id == id) |
1157 | break; | 1159 | break; |
1158 | } | 1160 | } |
1159 | if (i == ARRAY_SIZE(twl_of_match)) | 1161 | if (i == ARRAY_SIZE(twl_of_match)) |
1160 | return -ENODEV; | 1162 | return -ENODEV; |
1161 | 1163 | ||
1162 | drvdata = initdata->driver_data; | 1164 | drvdata = initdata->driver_data; |
1163 | if (!drvdata) | 1165 | if (!drvdata) |
1164 | return -EINVAL; | 1166 | return -EINVAL; |
1165 | } | 1167 | } |
1166 | 1168 | ||
1167 | if (!info) | 1169 | if (!info) |
1168 | return -ENODEV; | 1170 | return -ENODEV; |
1169 | 1171 | ||
1170 | if (!initdata) | 1172 | if (!initdata) |
1171 | return -EINVAL; | 1173 | return -EINVAL; |
1172 | 1174 | ||
1173 | if (drvdata) { | 1175 | if (drvdata) { |
1174 | /* copy the driver data into regulator data */ | 1176 | /* copy the driver data into regulator data */ |
1175 | info->features = drvdata->features; | 1177 | info->features = drvdata->features; |
1176 | info->data = drvdata->data; | 1178 | info->data = drvdata->data; |
1177 | info->set_voltage = drvdata->set_voltage; | 1179 | info->set_voltage = drvdata->set_voltage; |
1178 | info->get_voltage = drvdata->get_voltage; | 1180 | info->get_voltage = drvdata->get_voltage; |
1179 | } | 1181 | } |
1180 | 1182 | ||
1181 | /* Constrain board-specific capabilities according to what | 1183 | /* Constrain board-specific capabilities according to what |
1182 | * this driver and the chip itself can actually do. | 1184 | * this driver and the chip itself can actually do. |
1183 | */ | 1185 | */ |
1184 | c = &initdata->constraints; | 1186 | c = &initdata->constraints; |
1185 | c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; | 1187 | c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; |
1186 | c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | 1188 | c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE |
1187 | | REGULATOR_CHANGE_MODE | 1189 | | REGULATOR_CHANGE_MODE |
1188 | | REGULATOR_CHANGE_STATUS; | 1190 | | REGULATOR_CHANGE_STATUS; |
1189 | switch (id) { | 1191 | switch (id) { |
1190 | case TWL4030_REG_VIO: | 1192 | case TWL4030_REG_VIO: |
1191 | case TWL4030_REG_VDD1: | 1193 | case TWL4030_REG_VDD1: |
1192 | case TWL4030_REG_VDD2: | 1194 | case TWL4030_REG_VDD2: |
1193 | case TWL4030_REG_VPLL1: | 1195 | case TWL4030_REG_VPLL1: |
1194 | case TWL4030_REG_VINTANA1: | 1196 | case TWL4030_REG_VINTANA1: |
1195 | case TWL4030_REG_VINTANA2: | 1197 | case TWL4030_REG_VINTANA2: |
1196 | case TWL4030_REG_VINTDIG: | 1198 | case TWL4030_REG_VINTDIG: |
1197 | c->always_on = true; | 1199 | c->always_on = true; |
1198 | break; | 1200 | break; |
1199 | default: | 1201 | default: |
1200 | break; | 1202 | break; |
1201 | } | 1203 | } |
1202 | 1204 | ||
1203 | switch (id) { | 1205 | switch (id) { |
1204 | case TWL6025_REG_SMPS3: | 1206 | case TWL6025_REG_SMPS3: |
1205 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) | 1207 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) |
1206 | info->flags |= SMPS_EXTENDED_EN; | 1208 | info->flags |= SMPS_EXTENDED_EN; |
1207 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3) | 1209 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3) |
1208 | info->flags |= SMPS_OFFSET_EN; | 1210 | info->flags |= SMPS_OFFSET_EN; |
1209 | break; | 1211 | break; |
1210 | case TWL6025_REG_SMPS4: | 1212 | case TWL6025_REG_SMPS4: |
1211 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4) | 1213 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4) |
1212 | info->flags |= SMPS_EXTENDED_EN; | 1214 | info->flags |= SMPS_EXTENDED_EN; |
1213 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4) | 1215 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4) |
1214 | info->flags |= SMPS_OFFSET_EN; | 1216 | info->flags |= SMPS_OFFSET_EN; |
1215 | break; | 1217 | break; |
1216 | case TWL6025_REG_VIO: | 1218 | case TWL6025_REG_VIO: |
1217 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO) | 1219 | if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO) |
1218 | info->flags |= SMPS_EXTENDED_EN; | 1220 | info->flags |= SMPS_EXTENDED_EN; |
1219 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO) | 1221 | if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO) |
1220 | info->flags |= SMPS_OFFSET_EN; | 1222 | info->flags |= SMPS_OFFSET_EN; |
1221 | break; | 1223 | break; |
1222 | } | 1224 | } |
1223 | 1225 | ||
1224 | config.dev = &pdev->dev; | 1226 | config.dev = &pdev->dev; |
1225 | config.init_data = initdata; | 1227 | config.init_data = initdata; |
1226 | config.driver_data = info; | 1228 | config.driver_data = info; |
1227 | config.of_node = pdev->dev.of_node; | 1229 | config.of_node = pdev->dev.of_node; |
1228 | 1230 | ||
1229 | rdev = regulator_register(&info->desc, &config); | 1231 | rdev = regulator_register(&info->desc, &config); |
1230 | if (IS_ERR(rdev)) { | 1232 | if (IS_ERR(rdev)) { |
1231 | dev_err(&pdev->dev, "can't register %s, %ld\n", | 1233 | dev_err(&pdev->dev, "can't register %s, %ld\n", |
1232 | info->desc.name, PTR_ERR(rdev)); | 1234 | info->desc.name, PTR_ERR(rdev)); |
1233 | return PTR_ERR(rdev); | 1235 | return PTR_ERR(rdev); |
1234 | } | 1236 | } |
1235 | platform_set_drvdata(pdev, rdev); | 1237 | platform_set_drvdata(pdev, rdev); |
1236 | 1238 | ||
1237 | if (twl_class_is_4030()) | 1239 | if (twl_class_is_4030()) |
1238 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, | 1240 | twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, |
1239 | info->remap); | 1241 | info->remap); |
1240 | 1242 | ||
1241 | /* NOTE: many regulators support short-circuit IRQs (presentable | 1243 | /* NOTE: many regulators support short-circuit IRQs (presentable |
1242 | * as REGULATOR_OVER_CURRENT notifications?) configured via: | 1244 | * as REGULATOR_OVER_CURRENT notifications?) configured via: |
1243 | * - SC_CONFIG | 1245 | * - SC_CONFIG |
1244 | * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4) | 1246 | * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4) |
1245 | * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2) | 1247 | * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2) |
1246 | * - IT_CONFIG | 1248 | * - IT_CONFIG |
1247 | */ | 1249 | */ |
1248 | 1250 | ||
1249 | return 0; | 1251 | return 0; |
1250 | } | 1252 | } |
1251 | 1253 | ||
1252 | static int __devexit twlreg_remove(struct platform_device *pdev) | 1254 | static int __devexit twlreg_remove(struct platform_device *pdev) |
1253 | { | 1255 | { |
1254 | regulator_unregister(platform_get_drvdata(pdev)); | 1256 | regulator_unregister(platform_get_drvdata(pdev)); |
1255 | return 0; | 1257 | return 0; |
1256 | } | 1258 | } |
1257 | 1259 | ||
1258 | MODULE_ALIAS("platform:twl_reg"); | 1260 | MODULE_ALIAS("platform:twl_reg"); |
1259 | 1261 | ||
1260 | static struct platform_driver twlreg_driver = { | 1262 | static struct platform_driver twlreg_driver = { |
1261 | .probe = twlreg_probe, | 1263 | .probe = twlreg_probe, |
1262 | .remove = __devexit_p(twlreg_remove), | 1264 | .remove = __devexit_p(twlreg_remove), |
1263 | /* NOTE: short name, to work around driver model truncation of | 1265 | /* NOTE: short name, to work around driver model truncation of |
1264 | * "twl_regulator.12" (and friends) to "twl_regulator.1". | 1266 | * "twl_regulator.12" (and friends) to "twl_regulator.1". |
1265 | */ | 1267 | */ |
1266 | .driver = { | 1268 | .driver = { |
1267 | .name = "twl_reg", | 1269 | .name = "twl_reg", |
1268 | .owner = THIS_MODULE, | 1270 | .owner = THIS_MODULE, |
1269 | .of_match_table = of_match_ptr(twl_of_match), | 1271 | .of_match_table = of_match_ptr(twl_of_match), |
1270 | }, | 1272 | }, |
1271 | }; | 1273 | }; |
1272 | 1274 | ||
1273 | static int __init twlreg_init(void) | 1275 | static int __init twlreg_init(void) |
1274 | { | 1276 | { |
1275 | return platform_driver_register(&twlreg_driver); | 1277 | return platform_driver_register(&twlreg_driver); |
1276 | } | 1278 | } |
1277 | subsys_initcall(twlreg_init); | 1279 | subsys_initcall(twlreg_init); |
1278 | 1280 | ||
1279 | static void __exit twlreg_exit(void) | 1281 | static void __exit twlreg_exit(void) |
1280 | { | 1282 | { |
1281 | platform_driver_unregister(&twlreg_driver); | 1283 | platform_driver_unregister(&twlreg_driver); |
1282 | } | 1284 | } |
1283 | module_exit(twlreg_exit) | 1285 | module_exit(twlreg_exit) |
1284 | 1286 | ||
1285 | MODULE_DESCRIPTION("TWL regulator driver"); | 1287 | MODULE_DESCRIPTION("TWL regulator driver"); |