diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-11-11 10:12:01 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-11-13 01:57:39 -0500 |
commit | 1a0bb679bcee5233dc5134e4f5fbf97d8caf8bbb (patch) | |
tree | 34366dbc9feb6bdc73a33149f537a8987bdf56ff /drivers/regulator/tps80031-regulator.c | |
parent | 77b67063bb6bce6d475e910d3b886a606d0d91f7 (diff) |
regulator: tps80031: add regulator driver for tps80031
Add regulator driver for Texas Instrument TPS80031/TPS80032 device.
TPS80031/ TPS80032 Fully Integrated Power Management with Power
Path and Battery Charger. It has 5 configurable step-down
converters, 11 general purpose LDOs, VBUS generator and digital
output to control regulators.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/tps80031-regulator.c')
-rw-r--r-- | drivers/regulator/tps80031-regulator.c | 789 |
1 files changed, 789 insertions, 0 deletions
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c new file mode 100644 index 000000000000..04844780b56c --- /dev/null +++ b/drivers/regulator/tps80031-regulator.c | |||
@@ -0,0 +1,789 @@ | |||
1 | /* | ||
2 | * tps80031-regulator.c -- TI TPS80031 regulator driver. | ||
3 | * | ||
4 | * Regulator driver for TITPS80031/TPS80032 Fully Integrated Power | ||
5 | * Management with Power Path and Battery Charger. | ||
6 | * | ||
7 | * Copyright (c) 2012, NVIDIA Corporation. | ||
8 | * | ||
9 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation version 2. | ||
14 | * | ||
15 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
16 | * whether express or implied; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
23 | * 02111-1307, USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/delay.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/mfd/tps80031.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/regulator/driver.h> | ||
34 | #include <linux/regulator/machine.h> | ||
35 | #include <linux/slab.h> | ||
36 | |||
37 | /* Flags for DCDC Voltage reading */ | ||
38 | #define DCDC_OFFSET_EN BIT(0) | ||
39 | #define DCDC_EXTENDED_EN BIT(1) | ||
40 | #define TRACK_MODE_ENABLE BIT(2) | ||
41 | |||
42 | #define SMPS_MULTOFFSET_VIO BIT(1) | ||
43 | #define SMPS_MULTOFFSET_SMPS1 BIT(3) | ||
44 | #define SMPS_MULTOFFSET_SMPS2 BIT(4) | ||
45 | #define SMPS_MULTOFFSET_SMPS3 BIT(6) | ||
46 | #define SMPS_MULTOFFSET_SMPS4 BIT(0) | ||
47 | |||
48 | #define SMPS_CMD_MASK 0xC0 | ||
49 | #define SMPS_VSEL_MASK 0x3F | ||
50 | #define LDO_VSEL_MASK 0x1F | ||
51 | #define LDO_TRACK_VSEL_MASK 0x3F | ||
52 | |||
53 | #define MISC2_LDOUSB_IN_VSYS BIT(4) | ||
54 | #define MISC2_LDOUSB_IN_PMID BIT(3) | ||
55 | #define MISC2_LDOUSB_IN_MASK 0x18 | ||
56 | |||
57 | #define MISC2_LDO3_SEL_VIB_VAL BIT(0) | ||
58 | #define MISC2_LDO3_SEL_VIB_MASK 0x1 | ||
59 | |||
60 | #define BOOST_HW_PWR_EN BIT(5) | ||
61 | #define BOOST_HW_PWR_EN_MASK BIT(5) | ||
62 | |||
63 | #define OPA_MODE_EN BIT(6) | ||
64 | #define OPA_MODE_EN_MASK BIT(6) | ||
65 | |||
66 | #define USB_VBUS_CTRL_SET 0x04 | ||
67 | #define USB_VBUS_CTRL_CLR 0x05 | ||
68 | #define VBUS_DISCHRG 0x20 | ||
69 | |||
70 | struct tps80031_regulator_info { | ||
71 | /* Regulator register address.*/ | ||
72 | u8 trans_reg; | ||
73 | u8 state_reg; | ||
74 | u8 force_reg; | ||
75 | u8 volt_reg; | ||
76 | u8 volt_id; | ||
77 | |||
78 | /*Power request bits */ | ||
79 | int preq_bit; | ||
80 | |||
81 | /* used by regulator core */ | ||
82 | struct regulator_desc desc; | ||
83 | |||
84 | }; | ||
85 | |||
86 | struct tps80031_regulator { | ||
87 | struct device *dev; | ||
88 | struct regulator_dev *rdev; | ||
89 | struct tps80031_regulator_info *rinfo; | ||
90 | |||
91 | u8 device_flags; | ||
92 | unsigned int config_flags; | ||
93 | unsigned int ext_ctrl_flag; | ||
94 | }; | ||
95 | |||
96 | static inline struct device *to_tps80031_dev(struct regulator_dev *rdev) | ||
97 | { | ||
98 | return rdev_get_dev(rdev)->parent->parent; | ||
99 | } | ||
100 | |||
101 | static int tps80031_reg_is_enabled(struct regulator_dev *rdev) | ||
102 | { | ||
103 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
104 | struct device *parent = to_tps80031_dev(rdev); | ||
105 | u8 reg_val; | ||
106 | int ret; | ||
107 | |||
108 | if (ri->ext_ctrl_flag & EXT_PWR_REQ) | ||
109 | return true; | ||
110 | |||
111 | ret = tps80031_read(parent, SLAVE_ID1, ri->rinfo->state_reg, ®_val); | ||
112 | if (ret < 0) { | ||
113 | dev_err(&rdev->dev, "Reg 0x%02x read failed, err = %d\n", | ||
114 | ri->rinfo->state_reg, ret); | ||
115 | return ret; | ||
116 | } | ||
117 | return ((reg_val & STATE_MASK) == STATE_ON); | ||
118 | } | ||
119 | |||
120 | static int tps80031_reg_enable(struct regulator_dev *rdev) | ||
121 | { | ||
122 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
123 | struct device *parent = to_tps80031_dev(rdev); | ||
124 | int ret; | ||
125 | |||
126 | if (ri->ext_ctrl_flag & EXT_PWR_REQ) | ||
127 | return 0; | ||
128 | |||
129 | ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg, | ||
130 | STATE_ON, STATE_MASK); | ||
131 | if (ret < 0) { | ||
132 | dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n", | ||
133 | ri->rinfo->state_reg, ret); | ||
134 | return ret; | ||
135 | } | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | static int tps80031_reg_disable(struct regulator_dev *rdev) | ||
140 | { | ||
141 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
142 | struct device *parent = to_tps80031_dev(rdev); | ||
143 | int ret; | ||
144 | |||
145 | if (ri->ext_ctrl_flag & EXT_PWR_REQ) | ||
146 | return 0; | ||
147 | |||
148 | ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg, | ||
149 | STATE_OFF, STATE_MASK); | ||
150 | if (ret < 0) | ||
151 | dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n", | ||
152 | ri->rinfo->state_reg, ret); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | /* DCDC voltages for the selector of 58 to 63 */ | ||
157 | static int tps80031_dcdc_voltages[4][5] = { | ||
158 | { 1350, 1500, 1800, 1900, 2100}, | ||
159 | { 1350, 1500, 1800, 1900, 2100}, | ||
160 | { 2084, 2315, 2778, 2932, 3241}, | ||
161 | { 4167, 2315, 2778, 2932, 3241}, | ||
162 | }; | ||
163 | |||
164 | static int tps80031_dcdc_list_voltage(struct regulator_dev *rdev, unsigned sel) | ||
165 | { | ||
166 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
167 | int volt_index = ri->device_flags & 0x3; | ||
168 | |||
169 | if (sel == 0) | ||
170 | return 0; | ||
171 | else if (sel < 58) | ||
172 | return regulator_list_voltage_linear(rdev, sel - 1); | ||
173 | else | ||
174 | return tps80031_dcdc_voltages[volt_index][sel - 58] * 1000; | ||
175 | } | ||
176 | |||
177 | static int tps80031_dcdc_set_voltage_sel(struct regulator_dev *rdev, | ||
178 | unsigned vsel) | ||
179 | { | ||
180 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
181 | struct device *parent = to_tps80031_dev(rdev); | ||
182 | int ret; | ||
183 | u8 reg_val; | ||
184 | |||
185 | if (ri->rinfo->force_reg) { | ||
186 | ret = tps80031_read(parent, ri->rinfo->volt_id, | ||
187 | ri->rinfo->force_reg, ®_val); | ||
188 | if (ret < 0) { | ||
189 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
190 | ri->rinfo->force_reg, ret); | ||
191 | return ret; | ||
192 | } | ||
193 | if (!(reg_val & SMPS_CMD_MASK)) { | ||
194 | ret = tps80031_update(parent, ri->rinfo->volt_id, | ||
195 | ri->rinfo->force_reg, vsel, SMPS_VSEL_MASK); | ||
196 | if (ret < 0) | ||
197 | dev_err(ri->dev, | ||
198 | "reg 0x%02x update failed, e = %d\n", | ||
199 | ri->rinfo->force_reg, ret); | ||
200 | return ret; | ||
201 | } | ||
202 | } | ||
203 | ret = tps80031_update(parent, ri->rinfo->volt_id, | ||
204 | ri->rinfo->volt_reg, vsel, SMPS_VSEL_MASK); | ||
205 | if (ret < 0) | ||
206 | dev_err(ri->dev, "reg 0x%02x update failed, e = %d\n", | ||
207 | ri->rinfo->volt_reg, ret); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static int tps80031_dcdc_get_voltage_sel(struct regulator_dev *rdev) | ||
212 | { | ||
213 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
214 | struct device *parent = to_tps80031_dev(rdev); | ||
215 | uint8_t vsel = 0; | ||
216 | int ret; | ||
217 | |||
218 | if (ri->rinfo->force_reg) { | ||
219 | ret = tps80031_read(parent, ri->rinfo->volt_id, | ||
220 | ri->rinfo->force_reg, &vsel); | ||
221 | if (ret < 0) { | ||
222 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
223 | ri->rinfo->force_reg, ret); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | if (!(vsel & SMPS_CMD_MASK)) | ||
228 | return vsel & SMPS_VSEL_MASK; | ||
229 | } | ||
230 | ret = tps80031_read(parent, ri->rinfo->volt_id, | ||
231 | ri->rinfo->volt_reg, &vsel); | ||
232 | if (ret < 0) { | ||
233 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
234 | ri->rinfo->volt_reg, ret); | ||
235 | return ret; | ||
236 | } | ||
237 | return vsel & SMPS_VSEL_MASK; | ||
238 | } | ||
239 | |||
240 | static int tps80031_ldo_set_voltage_sel(struct regulator_dev *rdev, | ||
241 | unsigned sel) | ||
242 | { | ||
243 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
244 | struct device *parent = to_tps80031_dev(rdev); | ||
245 | int ret; | ||
246 | |||
247 | /* Check for valid setting for TPS80031 or TPS80032-ES1.0 */ | ||
248 | if ((ri->rinfo->desc.id == TPS80031_REGULATOR_LDO2) && | ||
249 | (ri->device_flags & TRACK_MODE_ENABLE)) { | ||
250 | unsigned nvsel = (sel) & 0x1F; | ||
251 | if (((tps80031_get_chip_info(parent) == TPS80031) || | ||
252 | ((tps80031_get_chip_info(parent) == TPS80032) && | ||
253 | (tps80031_get_pmu_version(parent) == 0x0))) && | ||
254 | ((nvsel == 0x0) || (nvsel >= 0x19 && nvsel <= 0x1F))) { | ||
255 | dev_err(ri->dev, | ||
256 | "Invalid sel %d in track mode LDO2\n", | ||
257 | nvsel); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | ret = tps80031_write(parent, ri->rinfo->volt_id, | ||
263 | ri->rinfo->volt_reg, sel); | ||
264 | if (ret < 0) | ||
265 | dev_err(ri->dev, "Error in writing reg 0x%02x, e = %d\n", | ||
266 | ri->rinfo->volt_reg, ret); | ||
267 | return ret; | ||
268 | } | ||
269 | |||
270 | static int tps80031_ldo_get_voltage_sel(struct regulator_dev *rdev) | ||
271 | { | ||
272 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
273 | struct device *parent = to_tps80031_dev(rdev); | ||
274 | uint8_t vsel; | ||
275 | int ret; | ||
276 | |||
277 | ret = tps80031_read(parent, ri->rinfo->volt_id, | ||
278 | ri->rinfo->volt_reg, &vsel); | ||
279 | if (ret < 0) { | ||
280 | dev_err(ri->dev, "Error in writing the Voltage register\n"); | ||
281 | return ret; | ||
282 | } | ||
283 | return vsel & rdev->desc->vsel_mask; | ||
284 | } | ||
285 | |||
286 | static int tps80031_ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) | ||
287 | { | ||
288 | if (sel == 0) | ||
289 | return 0; | ||
290 | else | ||
291 | return regulator_list_voltage_linear(rdev, sel - 1); | ||
292 | } | ||
293 | |||
294 | static int tps80031_vbus_is_enabled(struct regulator_dev *rdev) | ||
295 | { | ||
296 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
297 | struct device *parent = to_tps80031_dev(rdev); | ||
298 | int ret = -EIO; | ||
299 | uint8_t ctrl1 = 0; | ||
300 | uint8_t ctrl3 = 0; | ||
301 | |||
302 | ret = tps80031_read(parent, SLAVE_ID2, | ||
303 | TPS80031_CHARGERUSB_CTRL1, &ctrl1); | ||
304 | if (ret < 0) { | ||
305 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
306 | TPS80031_CHARGERUSB_CTRL1, ret); | ||
307 | return ret; | ||
308 | } | ||
309 | ret = tps80031_read(parent, SLAVE_ID2, | ||
310 | TPS80031_CHARGERUSB_CTRL3, &ctrl3); | ||
311 | if (ret < 0) { | ||
312 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
313 | TPS80031_CHARGERUSB_CTRL1, ret); | ||
314 | return ret; | ||
315 | } | ||
316 | if ((ctrl1 & OPA_MODE_EN) && (ctrl3 & BOOST_HW_PWR_EN)) | ||
317 | return 1; | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | static int tps80031_vbus_enable(struct regulator_dev *rdev) | ||
322 | { | ||
323 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
324 | struct device *parent = to_tps80031_dev(rdev); | ||
325 | int ret; | ||
326 | |||
327 | ret = tps80031_set_bits(parent, SLAVE_ID2, | ||
328 | TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN); | ||
329 | if (ret < 0) { | ||
330 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
331 | TPS80031_CHARGERUSB_CTRL1, ret); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | ret = tps80031_set_bits(parent, SLAVE_ID2, | ||
336 | TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN); | ||
337 | if (ret < 0) { | ||
338 | dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n", | ||
339 | TPS80031_CHARGERUSB_CTRL3, ret); | ||
340 | return ret; | ||
341 | } | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | static int tps80031_vbus_disable(struct regulator_dev *rdev) | ||
346 | { | ||
347 | struct tps80031_regulator *ri = rdev_get_drvdata(rdev); | ||
348 | struct device *parent = to_tps80031_dev(rdev); | ||
349 | int ret = 0; | ||
350 | |||
351 | if (ri->config_flags & VBUS_DISCHRG_EN_PDN) { | ||
352 | ret = tps80031_write(parent, SLAVE_ID2, | ||
353 | USB_VBUS_CTRL_SET, VBUS_DISCHRG); | ||
354 | if (ret < 0) { | ||
355 | dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n", | ||
356 | USB_VBUS_CTRL_SET, ret); | ||
357 | return ret; | ||
358 | } | ||
359 | } | ||
360 | |||
361 | ret = tps80031_clr_bits(parent, SLAVE_ID2, | ||
362 | TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN); | ||
363 | if (ret < 0) { | ||
364 | dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n", | ||
365 | TPS80031_CHARGERUSB_CTRL1, ret); | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | ret = tps80031_clr_bits(parent, SLAVE_ID2, | ||
370 | TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN); | ||
371 | if (ret < 0) { | ||
372 | dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n", | ||
373 | TPS80031_CHARGERUSB_CTRL3, ret); | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | mdelay(DIV_ROUND_UP(ri->rinfo->desc.enable_time, 1000)); | ||
378 | if (ri->config_flags & VBUS_DISCHRG_EN_PDN) { | ||
379 | ret = tps80031_write(parent, SLAVE_ID2, | ||
380 | USB_VBUS_CTRL_CLR, VBUS_DISCHRG); | ||
381 | if (ret < 0) { | ||
382 | dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n", | ||
383 | USB_VBUS_CTRL_CLR, ret); | ||
384 | return ret; | ||
385 | } | ||
386 | } | ||
387 | return ret; | ||
388 | } | ||
389 | |||
390 | static struct regulator_ops tps80031_dcdc_ops = { | ||
391 | .list_voltage = tps80031_dcdc_list_voltage, | ||
392 | .set_voltage_sel = tps80031_dcdc_set_voltage_sel, | ||
393 | .get_voltage_sel = tps80031_dcdc_get_voltage_sel, | ||
394 | .enable = tps80031_reg_enable, | ||
395 | .disable = tps80031_reg_disable, | ||
396 | .is_enabled = tps80031_reg_is_enabled, | ||
397 | }; | ||
398 | |||
399 | static struct regulator_ops tps80031_ldo_ops = { | ||
400 | .list_voltage = tps80031_ldo_list_voltage, | ||
401 | .set_voltage_sel = tps80031_ldo_set_voltage_sel, | ||
402 | .get_voltage_sel = tps80031_ldo_get_voltage_sel, | ||
403 | .enable = tps80031_reg_enable, | ||
404 | .disable = tps80031_reg_disable, | ||
405 | .is_enabled = tps80031_reg_is_enabled, | ||
406 | }; | ||
407 | |||
408 | static struct regulator_ops tps80031_vbus_sw_ops = { | ||
409 | .enable = tps80031_vbus_enable, | ||
410 | .disable = tps80031_vbus_disable, | ||
411 | .is_enabled = tps80031_vbus_is_enabled, | ||
412 | }; | ||
413 | |||
414 | static struct regulator_ops tps80031_vbus_hw_ops = { | ||
415 | }; | ||
416 | |||
417 | static struct regulator_ops tps80031_ext_reg_ops = { | ||
418 | .enable = tps80031_reg_enable, | ||
419 | .disable = tps80031_reg_disable, | ||
420 | .is_enabled = tps80031_reg_is_enabled, | ||
421 | }; | ||
422 | |||
423 | /* Non-exiting default definition for some register */ | ||
424 | #define TPS80031_SMPS3_CFG_FORCE 0 | ||
425 | #define TPS80031_SMPS4_CFG_FORCE 0 | ||
426 | |||
427 | #define TPS80031_VBUS_CFG_TRANS 0 | ||
428 | #define TPS80031_VBUS_CFG_STATE 0 | ||
429 | |||
430 | #define TPS80031_REG_SMPS(_id, _volt_id, _pbit) \ | ||
431 | { \ | ||
432 | .trans_reg = TPS80031_##_id##_CFG_TRANS, \ | ||
433 | .state_reg = TPS80031_##_id##_CFG_STATE, \ | ||
434 | .force_reg = TPS80031_##_id##_CFG_FORCE, \ | ||
435 | .volt_reg = TPS80031_##_id##_CFG_VOLTAGE, \ | ||
436 | .volt_id = SLAVE_##_volt_id, \ | ||
437 | .preq_bit = _pbit, \ | ||
438 | .desc = { \ | ||
439 | .name = "tps80031_"#_id, \ | ||
440 | .id = TPS80031_REGULATOR_##_id, \ | ||
441 | .n_voltages = 63, \ | ||
442 | .ops = &tps80031_dcdc_ops, \ | ||
443 | .type = REGULATOR_VOLTAGE, \ | ||
444 | .owner = THIS_MODULE, \ | ||
445 | .enable_time = 500, \ | ||
446 | }, \ | ||
447 | } | ||
448 | |||
449 | #define TPS80031_REG_LDO(_id, _preq_bit) \ | ||
450 | { \ | ||
451 | .trans_reg = TPS80031_##_id##_CFG_TRANS, \ | ||
452 | .state_reg = TPS80031_##_id##_CFG_STATE, \ | ||
453 | .volt_reg = TPS80031_##_id##_CFG_VOLTAGE, \ | ||
454 | .volt_id = SLAVE_ID1, \ | ||
455 | .preq_bit = _preq_bit, \ | ||
456 | .desc = { \ | ||
457 | .owner = THIS_MODULE, \ | ||
458 | .name = "tps80031_"#_id, \ | ||
459 | .id = TPS80031_REGULATOR_##_id, \ | ||
460 | .ops = &tps80031_ldo_ops, \ | ||
461 | .type = REGULATOR_VOLTAGE, \ | ||
462 | .min_uV = 1000000, \ | ||
463 | .uV_step = 100000, \ | ||
464 | .n_voltages = 25, \ | ||
465 | .vsel_mask = LDO_VSEL_MASK, \ | ||
466 | .enable_time = 500, \ | ||
467 | }, \ | ||
468 | } | ||
469 | |||
470 | #define TPS80031_REG_FIXED(_id, max_mV, _ops, _delay, _pbit) \ | ||
471 | { \ | ||
472 | .trans_reg = TPS80031_##_id##_CFG_TRANS, \ | ||
473 | .state_reg = TPS80031_##_id##_CFG_STATE, \ | ||
474 | .volt_id = SLAVE_ID1, \ | ||
475 | .preq_bit = _pbit, \ | ||
476 | .desc = { \ | ||
477 | .name = "tps80031_"#_id, \ | ||
478 | .id = TPS80031_REGULATOR_##_id, \ | ||
479 | .n_voltages = 2, \ | ||
480 | .ops = &_ops, \ | ||
481 | .type = REGULATOR_VOLTAGE, \ | ||
482 | .owner = THIS_MODULE, \ | ||
483 | .enable_time = _delay, \ | ||
484 | }, \ | ||
485 | } | ||
486 | |||
487 | static struct tps80031_regulator_info tps80031_rinfo[TPS80031_REGULATOR_MAX] = { | ||
488 | TPS80031_REG_SMPS(VIO, ID0, 4), | ||
489 | TPS80031_REG_SMPS(SMPS1, ID0, 0), | ||
490 | TPS80031_REG_SMPS(SMPS2, ID0, 1), | ||
491 | TPS80031_REG_SMPS(SMPS3, ID1, 2), | ||
492 | TPS80031_REG_SMPS(SMPS4, ID1, 3), | ||
493 | TPS80031_REG_LDO(VANA, -1), | ||
494 | TPS80031_REG_LDO(LDO1, 8), | ||
495 | TPS80031_REG_LDO(LDO2, 9), | ||
496 | TPS80031_REG_LDO(LDO3, 10), | ||
497 | TPS80031_REG_LDO(LDO4, 11), | ||
498 | TPS80031_REG_LDO(LDO5, 12), | ||
499 | TPS80031_REG_LDO(LDO6, 13), | ||
500 | TPS80031_REG_LDO(LDO7, 14), | ||
501 | TPS80031_REG_LDO(LDOLN, 15), | ||
502 | TPS80031_REG_LDO(LDOUSB, 5), | ||
503 | TPS80031_REG_FIXED(VBUS, 5000, tps80031_vbus_hw_ops, 100000, -1), | ||
504 | TPS80031_REG_FIXED(REGEN1, 3300, tps80031_ext_reg_ops, 0, 16), | ||
505 | TPS80031_REG_FIXED(REGEN2, 3300, tps80031_ext_reg_ops, 0, 17), | ||
506 | TPS80031_REG_FIXED(SYSEN, 3300, tps80031_ext_reg_ops, 0, 18), | ||
507 | }; | ||
508 | |||
509 | static int tps80031_power_req_config(struct device *parent, | ||
510 | struct tps80031_regulator *ri, | ||
511 | struct tps80031_regulator_platform_data *tps80031_pdata) | ||
512 | { | ||
513 | int ret = 0; | ||
514 | |||
515 | if (ri->rinfo->preq_bit < 0) | ||
516 | goto skip_pwr_req_config; | ||
517 | |||
518 | ret = tps80031_ext_power_req_config(parent, ri->ext_ctrl_flag, | ||
519 | ri->rinfo->preq_bit, ri->rinfo->state_reg, | ||
520 | ri->rinfo->trans_reg); | ||
521 | if (ret < 0) { | ||
522 | dev_err(ri->dev, "ext powerreq config failed, err = %d\n", ret); | ||
523 | return ret; | ||
524 | } | ||
525 | |||
526 | skip_pwr_req_config: | ||
527 | if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP) { | ||
528 | ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg, | ||
529 | TRANS_SLEEP_ON, TRANS_SLEEP_MASK); | ||
530 | if (ret < 0) { | ||
531 | dev_err(ri->dev, "Reg 0x%02x update failed, e %d\n", | ||
532 | ri->rinfo->trans_reg, ret); | ||
533 | return ret; | ||
534 | } | ||
535 | } | ||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | static int tps80031_regulator_config(struct device *parent, | ||
540 | struct tps80031_regulator *ri, | ||
541 | struct tps80031_regulator_platform_data *tps80031_pdata) | ||
542 | { | ||
543 | int ret = 0; | ||
544 | |||
545 | switch (ri->rinfo->desc.id) { | ||
546 | case TPS80031_REGULATOR_LDOUSB: | ||
547 | if (ri->config_flags & | ||
548 | (USBLDO_INPUT_VSYS | USBLDO_INPUT_PMID)) { | ||
549 | unsigned val = 0; | ||
550 | if (ri->config_flags & USBLDO_INPUT_VSYS) | ||
551 | val = MISC2_LDOUSB_IN_VSYS; | ||
552 | else | ||
553 | val = MISC2_LDOUSB_IN_PMID; | ||
554 | |||
555 | ret = tps80031_update(parent, SLAVE_ID1, | ||
556 | TPS80031_MISC2, val, MISC2_LDOUSB_IN_MASK); | ||
557 | if (ret < 0) { | ||
558 | dev_err(ri->dev, | ||
559 | "LDOUSB config failed, e= %d\n", ret); | ||
560 | return ret; | ||
561 | } | ||
562 | } | ||
563 | break; | ||
564 | |||
565 | case TPS80031_REGULATOR_LDO3: | ||
566 | if (ri->config_flags & LDO3_OUTPUT_VIB) { | ||
567 | ret = tps80031_update(parent, SLAVE_ID1, | ||
568 | TPS80031_MISC2, MISC2_LDO3_SEL_VIB_VAL, | ||
569 | MISC2_LDO3_SEL_VIB_MASK); | ||
570 | if (ret < 0) { | ||
571 | dev_err(ri->dev, | ||
572 | "LDO3 config failed, e = %d\n", ret); | ||
573 | return ret; | ||
574 | } | ||
575 | } | ||
576 | break; | ||
577 | |||
578 | case TPS80031_REGULATOR_VBUS: | ||
579 | /* Provide SW control Ops if VBUS is SW control */ | ||
580 | if (!(ri->config_flags & VBUS_SW_ONLY)) | ||
581 | ri->rinfo->desc.ops = &tps80031_vbus_sw_ops; | ||
582 | break; | ||
583 | default: | ||
584 | break; | ||
585 | } | ||
586 | |||
587 | /* Configure Active state to ON, SLEEP to OFF and OFF_state to OFF */ | ||
588 | ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg, | ||
589 | TRANS_ACTIVE_ON | TRANS_SLEEP_OFF | TRANS_OFF_OFF, | ||
590 | TRANS_ACTIVE_MASK | TRANS_SLEEP_MASK | TRANS_OFF_MASK); | ||
591 | if (ret < 0) { | ||
592 | dev_err(ri->dev, "trans reg update failed, e %d\n", ret); | ||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | static int check_smps_mode_mult(struct device *parent, | ||
600 | struct tps80031_regulator *ri) | ||
601 | { | ||
602 | int mult_offset; | ||
603 | int ret; | ||
604 | u8 smps_offset; | ||
605 | u8 smps_mult; | ||
606 | |||
607 | ret = tps80031_read(parent, SLAVE_ID1, | ||
608 | TPS80031_SMPS_OFFSET, &smps_offset); | ||
609 | if (ret < 0) { | ||
610 | dev_err(parent, "Error in reading smps offset register\n"); | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | ret = tps80031_read(parent, SLAVE_ID1, | ||
615 | TPS80031_SMPS_MULT, &smps_mult); | ||
616 | if (ret < 0) { | ||
617 | dev_err(parent, "Error in reading smps mult register\n"); | ||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | switch (ri->rinfo->desc.id) { | ||
622 | case TPS80031_REGULATOR_VIO: | ||
623 | mult_offset = SMPS_MULTOFFSET_VIO; | ||
624 | break; | ||
625 | case TPS80031_REGULATOR_SMPS1: | ||
626 | mult_offset = SMPS_MULTOFFSET_SMPS1; | ||
627 | break; | ||
628 | case TPS80031_REGULATOR_SMPS2: | ||
629 | mult_offset = SMPS_MULTOFFSET_SMPS2; | ||
630 | break; | ||
631 | case TPS80031_REGULATOR_SMPS3: | ||
632 | mult_offset = SMPS_MULTOFFSET_SMPS3; | ||
633 | break; | ||
634 | case TPS80031_REGULATOR_SMPS4: | ||
635 | mult_offset = SMPS_MULTOFFSET_SMPS4; | ||
636 | break; | ||
637 | case TPS80031_REGULATOR_LDO2: | ||
638 | ri->device_flags = smps_mult & BIT(5) ? TRACK_MODE_ENABLE : 0; | ||
639 | /* TRACK mode the ldo2 varies from 600mV to 1300mV */ | ||
640 | if (ri->device_flags & TRACK_MODE_ENABLE) { | ||
641 | ri->rinfo->desc.min_uV = 600000; | ||
642 | ri->rinfo->desc.uV_step = 12500; | ||
643 | ri->rinfo->desc.n_voltages = 57; | ||
644 | ri->rinfo->desc.vsel_mask = LDO_TRACK_VSEL_MASK; | ||
645 | } | ||
646 | return 0; | ||
647 | default: | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | ri->device_flags = (smps_offset & mult_offset) ? DCDC_OFFSET_EN : 0; | ||
652 | ri->device_flags |= (smps_mult & mult_offset) ? DCDC_EXTENDED_EN : 0; | ||
653 | switch (ri->device_flags) { | ||
654 | case 0: | ||
655 | ri->rinfo->desc.min_uV = 607700; | ||
656 | ri->rinfo->desc.uV_step = 12660; | ||
657 | break; | ||
658 | case DCDC_OFFSET_EN: | ||
659 | ri->rinfo->desc.min_uV = 700000; | ||
660 | ri->rinfo->desc.uV_step = 12500; | ||
661 | break; | ||
662 | case DCDC_EXTENDED_EN: | ||
663 | ri->rinfo->desc.min_uV = 1852000; | ||
664 | ri->rinfo->desc.uV_step = 38600; | ||
665 | break; | ||
666 | case DCDC_OFFSET_EN | DCDC_EXTENDED_EN: | ||
667 | ri->rinfo->desc.min_uV = 2161000; | ||
668 | ri->rinfo->desc.uV_step = 38600; | ||
669 | break; | ||
670 | } | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | static int __devinit tps80031_regulator_probe(struct platform_device *pdev) | ||
675 | { | ||
676 | struct tps80031_platform_data *pdata; | ||
677 | struct tps80031_regulator_platform_data *tps_pdata; | ||
678 | struct tps80031_regulator_info *rinfo; | ||
679 | struct tps80031_regulator *ri; | ||
680 | struct tps80031_regulator *pmic; | ||
681 | struct regulator_dev *rdev; | ||
682 | struct regulator_config config = { }; | ||
683 | int ret; | ||
684 | int num; | ||
685 | |||
686 | pdata = dev_get_platdata(pdev->dev.parent); | ||
687 | |||
688 | if (!pdata) { | ||
689 | dev_err(&pdev->dev, "No platform data\n"); | ||
690 | return -EINVAL; | ||
691 | } | ||
692 | |||
693 | pmic = devm_kzalloc(&pdev->dev, | ||
694 | TPS80031_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL); | ||
695 | if (!pmic) { | ||
696 | dev_err(&pdev->dev, "mem alloc for pmic failed\n"); | ||
697 | return -ENOMEM; | ||
698 | } | ||
699 | |||
700 | for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { | ||
701 | tps_pdata = pdata->regulator_pdata[num]; | ||
702 | rinfo = &tps80031_rinfo[num]; | ||
703 | ri = &pmic[num]; | ||
704 | ri->rinfo = rinfo; | ||
705 | ri->dev = &pdev->dev; | ||
706 | |||
707 | check_smps_mode_mult(pdev->dev.parent, ri); | ||
708 | config.dev = &pdev->dev; | ||
709 | config.init_data = NULL; | ||
710 | config.driver_data = ri; | ||
711 | if (tps_pdata) { | ||
712 | config.init_data = tps_pdata->reg_init_data; | ||
713 | ri->config_flags = tps_pdata->config_flags; | ||
714 | ri->ext_ctrl_flag = tps_pdata->ext_ctrl_flag; | ||
715 | ret = tps80031_regulator_config(pdev->dev.parent, | ||
716 | ri, tps_pdata); | ||
717 | if (ret < 0) { | ||
718 | dev_err(&pdev->dev, | ||
719 | "regulator config failed, e %d\n", ret); | ||
720 | goto fail; | ||
721 | } | ||
722 | |||
723 | ret = tps80031_power_req_config(pdev->dev.parent, | ||
724 | ri, tps_pdata); | ||
725 | if (ret < 0) { | ||
726 | dev_err(&pdev->dev, | ||
727 | "pwr_req config failed, err %d\n", ret); | ||
728 | goto fail; | ||
729 | } | ||
730 | } | ||
731 | rdev = regulator_register(&ri->rinfo->desc, &config); | ||
732 | if (IS_ERR_OR_NULL(rdev)) { | ||
733 | dev_err(&pdev->dev, | ||
734 | "register regulator failed %s\n", | ||
735 | ri->rinfo->desc.name); | ||
736 | ret = PTR_ERR(rdev); | ||
737 | goto fail; | ||
738 | } | ||
739 | ri->rdev = rdev; | ||
740 | } | ||
741 | |||
742 | platform_set_drvdata(pdev, pmic); | ||
743 | return 0; | ||
744 | fail: | ||
745 | while (--num >= 0) { | ||
746 | ri = &pmic[num]; | ||
747 | regulator_unregister(ri->rdev); | ||
748 | } | ||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | static int __devexit tps80031_regulator_remove(struct platform_device *pdev) | ||
753 | { | ||
754 | struct tps80031_regulator *pmic = platform_get_drvdata(pdev); | ||
755 | struct tps80031_regulator *ri = NULL; | ||
756 | int num; | ||
757 | |||
758 | for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) { | ||
759 | ri = &pmic[num]; | ||
760 | regulator_unregister(ri->rdev); | ||
761 | } | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static struct platform_driver tps80031_regulator_driver = { | ||
766 | .driver = { | ||
767 | .name = "tps80031-pmic", | ||
768 | .owner = THIS_MODULE, | ||
769 | }, | ||
770 | .probe = tps80031_regulator_probe, | ||
771 | .remove = __devexit_p(tps80031_regulator_remove), | ||
772 | }; | ||
773 | |||
774 | static int __init tps80031_regulator_init(void) | ||
775 | { | ||
776 | return platform_driver_register(&tps80031_regulator_driver); | ||
777 | } | ||
778 | subsys_initcall(tps80031_regulator_init); | ||
779 | |||
780 | static void __exit tps80031_regulator_exit(void) | ||
781 | { | ||
782 | platform_driver_unregister(&tps80031_regulator_driver); | ||
783 | } | ||
784 | module_exit(tps80031_regulator_exit); | ||
785 | |||
786 | MODULE_ALIAS("platform:tps80031-regulator"); | ||
787 | MODULE_DESCRIPTION("Regulator Driver for TI TPS80031 PMIC"); | ||
788 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
789 | MODULE_LICENSE("GPL v2"); | ||