Merge tag 'v3.5-rc6' into irqdomain/next
[deliverable/linux.git] / drivers / regulator / tps65023-regulator.c
CommitLineData
30e6599d
AA
1/*
2 * tps65023-regulator.c
3 *
4 * Supports TPS65023 Regulator
5 *
6 * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation version 2.
11 *
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
13 * whether express or implied; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/err.h>
22#include <linux/platform_device.h>
23#include <linux/regulator/driver.h>
24#include <linux/regulator/machine.h>
25#include <linux/i2c.h>
5a0e3ad6 26#include <linux/slab.h>
90923351 27#include <linux/regmap.h>
30e6599d
AA
28
29/* Register definitions */
30#define TPS65023_REG_VERSION 0
31#define TPS65023_REG_PGOODZ 1
32#define TPS65023_REG_MASK 2
33#define TPS65023_REG_REG_CTRL 3
34#define TPS65023_REG_CON_CTRL 4
35#define TPS65023_REG_CON_CTRL2 5
36#define TPS65023_REG_DEF_CORE 6
37#define TPS65023_REG_DEFSLEW 7
38#define TPS65023_REG_LDO_CTRL 8
39
40/* PGOODZ bitfields */
41#define TPS65023_PGOODZ_PWRFAILZ BIT(7)
42#define TPS65023_PGOODZ_LOWBATTZ BIT(6)
43#define TPS65023_PGOODZ_VDCDC1 BIT(5)
44#define TPS65023_PGOODZ_VDCDC2 BIT(4)
45#define TPS65023_PGOODZ_VDCDC3 BIT(3)
46#define TPS65023_PGOODZ_LDO2 BIT(2)
47#define TPS65023_PGOODZ_LDO1 BIT(1)
48
49/* MASK bitfields */
50#define TPS65023_MASK_PWRFAILZ BIT(7)
51#define TPS65023_MASK_LOWBATTZ BIT(6)
52#define TPS65023_MASK_VDCDC1 BIT(5)
53#define TPS65023_MASK_VDCDC2 BIT(4)
54#define TPS65023_MASK_VDCDC3 BIT(3)
55#define TPS65023_MASK_LDO2 BIT(2)
56#define TPS65023_MASK_LDO1 BIT(1)
57
58/* REG_CTRL bitfields */
59#define TPS65023_REG_CTRL_VDCDC1_EN BIT(5)
60#define TPS65023_REG_CTRL_VDCDC2_EN BIT(4)
61#define TPS65023_REG_CTRL_VDCDC3_EN BIT(3)
62#define TPS65023_REG_CTRL_LDO2_EN BIT(2)
63#define TPS65023_REG_CTRL_LDO1_EN BIT(1)
64
f068ad8c
MF
65/* REG_CTRL2 bitfields */
66#define TPS65023_REG_CTRL2_GO BIT(7)
67#define TPS65023_REG_CTRL2_CORE_ADJ BIT(6)
68#define TPS65023_REG_CTRL2_DCDC2 BIT(2)
69#define TPS65023_REG_CTRL2_DCDC1 BIT(1)
70#define TPS65023_REG_CTRL2_DCDC3 BIT(0)
71
30e6599d
AA
72/* LDO_CTRL bitfields */
73#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4)
6b57c015 74#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x07 << ((ldo_id)*4))
30e6599d
AA
75
76/* Number of step-down converters available */
77#define TPS65023_NUM_DCDC 3
78/* Number of LDO voltage regulators available */
79#define TPS65023_NUM_LDO 2
80/* Number of total regulators available */
81#define TPS65023_NUM_REGULATOR (TPS65023_NUM_DCDC + TPS65023_NUM_LDO)
82
83/* DCDCs */
84#define TPS65023_DCDC_1 0
85#define TPS65023_DCDC_2 1
86#define TPS65023_DCDC_3 2
87/* LDOs */
88#define TPS65023_LDO_1 3
89#define TPS65023_LDO_2 4
90
91#define TPS65023_MAX_REG_ID TPS65023_LDO_2
92
93/* Supported voltage values for regulators */
1c3ede05 94static const u16 VCORE_VSEL_table[] = {
30e6599d
AA
95 800, 825, 850, 875,
96 900, 925, 950, 975,
97 1000, 1025, 1050, 1075,
98 1100, 1125, 1150, 1175,
99 1200, 1225, 1250, 1275,
100 1300, 1325, 1350, 1375,
101 1400, 1425, 1450, 1475,
102 1500, 1525, 1550, 1600,
103};
104
437afd2a
MF
105/* Supported voltage values for LDO regulators for tps65020 */
106static const u16 TPS65020_LDO1_VSEL_table[] = {
107 1000, 1050, 1100, 1300,
108 1800, 2500, 3000, 3300,
109};
1c3ede05 110
437afd2a
MF
111static const u16 TPS65020_LDO2_VSEL_table[] = {
112 1000, 1050, 1100, 1300,
113 1800, 2500, 3000, 3300,
114};
1c3ede05
MF
115
116/* Supported voltage values for LDO regulators
117 * for tps65021 and tps65023 */
118static const u16 TPS65023_LDO1_VSEL_table[] = {
30e6599d
AA
119 1000, 1100, 1300, 1800,
120 2200, 2600, 2800, 3150,
121};
122
1c3ede05 123static const u16 TPS65023_LDO2_VSEL_table[] = {
30e6599d
AA
124 1050, 1200, 1300, 1800,
125 2500, 2800, 3000, 3300,
126};
127
30e6599d
AA
128/* Regulator specific details */
129struct tps_info {
130 const char *name;
131 unsigned min_uV;
132 unsigned max_uV;
133 bool fixed;
134 u8 table_len;
135 const u16 *table;
136};
137
138/* PMIC details */
139struct tps_pmic {
140 struct regulator_desc desc[TPS65023_NUM_REGULATOR];
30e6599d
AA
141 struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
142 const struct tps_info *info[TPS65023_NUM_REGULATOR];
90923351 143 struct regmap *regmap;
1c3ede05
MF
144 u8 core_regulator;
145};
146
147/* Struct passed as driver data */
148struct tps_driver_data {
149 const struct tps_info *info;
150 u8 core_regulator;
30e6599d
AA
151};
152
30e6599d
AA
153static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
154{
155 struct tps_pmic *tps = rdev_get_drvdata(dev);
43530b69 156 int ret;
30e6599d
AA
157 int data, dcdc = rdev_get_id(dev);
158
159 if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
160 return -EINVAL;
161
1c3ede05 162 if (dcdc == tps->core_regulator) {
43530b69
JC
163 ret = regmap_read(tps->regmap, TPS65023_REG_DEF_CORE, &data);
164 if (ret != 0)
165 return ret;
30e6599d
AA
166 data &= (tps->info[dcdc]->table_len - 1);
167 return tps->info[dcdc]->table[data] * 1000;
168 } else
169 return tps->info[dcdc]->min_uV;
170}
171
7061873f
AL
172static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
173 unsigned selector)
30e6599d
AA
174{
175 struct tps_pmic *tps = rdev_get_drvdata(dev);
176 int dcdc = rdev_get_id(dev);
cc17ef3f 177 int ret;
30e6599d 178
1c3ede05 179 if (dcdc != tps->core_regulator)
30e6599d 180 return -EINVAL;
30e6599d 181
7061873f
AL
182 ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, selector);
183 if (ret)
184 goto out;
cc17ef3f
MF
185
186 /* Tell the chip that we have changed the value in DEFCORE
187 * and its time to update the core voltage
188 */
7061873f
AL
189 ret = regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
190 TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
cc17ef3f 191
7061873f 192out:
cc17ef3f 193 return ret;
30e6599d
AA
194}
195
196static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
197{
198 struct tps_pmic *tps = rdev_get_drvdata(dev);
199 int data, ldo = rdev_get_id(dev);
43530b69 200 int ret;
30e6599d
AA
201
202 if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
203 return -EINVAL;
204
43530b69
JC
205 ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
206 if (ret != 0)
207 return ret;
30e6599d
AA
208
209 data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1));
210 data &= (tps->info[ldo]->table_len - 1);
211 return tps->info[ldo]->table[data] * 1000;
212}
213
7061873f
AL
214static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev,
215 unsigned selector)
30e6599d
AA
216{
217 struct tps_pmic *tps = rdev_get_drvdata(dev);
7061873f 218 int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1;
30e6599d 219
7061873f
AL
220 return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL,
221 TPS65023_LDO_CTRL_LDOx_MASK(ldo_index),
222 selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index));
30e6599d
AA
223}
224
225static int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
226 unsigned selector)
227{
228 struct tps_pmic *tps = rdev_get_drvdata(dev);
229 int dcdc = rdev_get_id(dev);
230
231 if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
232 return -EINVAL;
233
1c3ede05 234 if (dcdc == tps->core_regulator) {
30e6599d
AA
235 if (selector >= tps->info[dcdc]->table_len)
236 return -EINVAL;
237 else
238 return tps->info[dcdc]->table[selector] * 1000;
239 } else
240 return tps->info[dcdc]->min_uV;
241}
242
243static int tps65023_ldo_list_voltage(struct regulator_dev *dev,
244 unsigned selector)
245{
246 struct tps_pmic *tps = rdev_get_drvdata(dev);
247 int ldo = rdev_get_id(dev);
248
249 if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
250 return -EINVAL;
251
252 if (selector >= tps->info[ldo]->table_len)
253 return -EINVAL;
254 else
255 return tps->info[ldo]->table[selector] * 1000;
256}
257
258/* Operations permitted on VDCDCx */
259static struct regulator_ops tps65023_dcdc_ops = {
ee7b1914
AL
260 .is_enabled = regulator_is_enabled_regmap,
261 .enable = regulator_enable_regmap,
262 .disable = regulator_disable_regmap,
30e6599d 263 .get_voltage = tps65023_dcdc_get_voltage,
7061873f 264 .set_voltage_sel = tps65023_dcdc_set_voltage_sel,
30e6599d
AA
265 .list_voltage = tps65023_dcdc_list_voltage,
266};
267
268/* Operations permitted on LDOx */
269static struct regulator_ops tps65023_ldo_ops = {
ee7b1914
AL
270 .is_enabled = regulator_is_enabled_regmap,
271 .enable = regulator_enable_regmap,
272 .disable = regulator_disable_regmap,
30e6599d 273 .get_voltage = tps65023_ldo_get_voltage,
7061873f 274 .set_voltage_sel = tps65023_ldo_set_voltage_sel,
30e6599d
AA
275 .list_voltage = tps65023_ldo_list_voltage,
276};
277
90923351
MB
278static struct regmap_config tps65023_regmap_config = {
279 .reg_bits = 8,
280 .val_bits = 8,
281};
282
54d13ab1
DT
283static int __devinit tps_65023_probe(struct i2c_client *client,
284 const struct i2c_device_id *id)
30e6599d 285{
1c3ede05
MF
286 const struct tps_driver_data *drv_data = (void *)id->driver_data;
287 const struct tps_info *info = drv_data->info;
c172708d 288 struct regulator_config config = { };
30e6599d
AA
289 struct regulator_init_data *init_data;
290 struct regulator_dev *rdev;
291 struct tps_pmic *tps;
292 int i;
54d13ab1 293 int error;
30e6599d
AA
294
295 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
296 return -EIO;
297
298 /**
299 * init_data points to array of regulator_init structures
300 * coming from the board-evm file.
301 */
302 init_data = client->dev.platform_data;
30e6599d
AA
303 if (!init_data)
304 return -EIO;
305
19a8da21 306 tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
30e6599d
AA
307 if (!tps)
308 return -ENOMEM;
309
19a8da21 310 tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config);
90923351
MB
311 if (IS_ERR(tps->regmap)) {
312 error = PTR_ERR(tps->regmap);
313 dev_err(&client->dev, "Failed to allocate register map: %d\n",
314 error);
19a8da21 315 return error;
90923351 316 }
30e6599d
AA
317
318 /* common for all regulators */
1c3ede05 319 tps->core_regulator = drv_data->core_regulator;
30e6599d
AA
320
321 for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) {
322 /* Store regulator specific information */
323 tps->info[i] = info;
324
325 tps->desc[i].name = info->name;
77fa44d0 326 tps->desc[i].id = i;
1c3ede05 327 tps->desc[i].n_voltages = info->table_len;
30e6599d
AA
328 tps->desc[i].ops = (i > TPS65023_DCDC_3 ?
329 &tps65023_ldo_ops : &tps65023_dcdc_ops);
330 tps->desc[i].type = REGULATOR_VOLTAGE;
331 tps->desc[i].owner = THIS_MODULE;
332
ee7b1914
AL
333 tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL;
334 if (i == TPS65023_LDO_1)
335 tps->desc[i].enable_mask = 1 << 1;
336 else if (i == TPS65023_LDO_2)
337 tps->desc[i].enable_mask = 1 << 2;
338 else /* DCDCx */
339 tps->desc[i].enable_mask =
340 1 << (TPS65023_NUM_REGULATOR - i);
341
c172708d
MB
342 config.dev = &client->dev;
343 config.init_data = init_data;
344 config.driver_data = tps;
ee7b1914 345 config.regmap = tps->regmap;
c172708d 346
30e6599d 347 /* Register the regulators */
c172708d 348 rdev = regulator_register(&tps->desc[i], &config);
30e6599d
AA
349 if (IS_ERR(rdev)) {
350 dev_err(&client->dev, "failed to register %s\n",
351 id->name);
54d13ab1
DT
352 error = PTR_ERR(rdev);
353 goto fail;
30e6599d
AA
354 }
355
356 /* Save regulator for cleanup */
357 tps->rdev[i] = rdev;
358 }
359
360 i2c_set_clientdata(client, tps);
361
fc999b83 362 /* Enable setting output voltage by I2C */
43530b69
JC
363 regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
364 TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
fc999b83 365
30e6599d 366 return 0;
54d13ab1
DT
367
368 fail:
369 while (--i >= 0)
370 regulator_unregister(tps->rdev[i]);
54d13ab1 371 return error;
30e6599d
AA
372}
373
30e6599d
AA
374static int __devexit tps_65023_remove(struct i2c_client *client)
375{
376 struct tps_pmic *tps = i2c_get_clientdata(client);
377 int i;
378
379 for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
380 regulator_unregister(tps->rdev[i]);
30e6599d
AA
381 return 0;
382}
383
437afd2a
MF
384static const struct tps_info tps65020_regs[] = {
385 {
386 .name = "VDCDC1",
387 .min_uV = 3300000,
388 .max_uV = 3300000,
389 .fixed = 1,
390 },
391 {
392 .name = "VDCDC2",
393 .min_uV = 1800000,
394 .max_uV = 1800000,
395 .fixed = 1,
396 },
397 {
398 .name = "VDCDC3",
399 .min_uV = 800000,
400 .max_uV = 1600000,
401 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
402 .table = VCORE_VSEL_table,
403 },
404
405 {
406 .name = "LDO1",
407 .min_uV = 1000000,
408 .max_uV = 3150000,
409 .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table),
410 .table = TPS65020_LDO1_VSEL_table,
411 },
412 {
413 .name = "LDO2",
414 .min_uV = 1050000,
415 .max_uV = 3300000,
416 .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table),
417 .table = TPS65020_LDO2_VSEL_table,
418 },
419};
420
1c3ede05
MF
421static const struct tps_info tps65021_regs[] = {
422 {
423 .name = "VDCDC1",
424 .min_uV = 3300000,
425 .max_uV = 3300000,
426 .fixed = 1,
427 },
428 {
429 .name = "VDCDC2",
430 .min_uV = 1800000,
431 .max_uV = 1800000,
432 .fixed = 1,
433 },
434 {
435 .name = "VDCDC3",
436 .min_uV = 800000,
437 .max_uV = 1600000,
438 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
439 .table = VCORE_VSEL_table,
440 },
441 {
442 .name = "LDO1",
443 .min_uV = 1000000,
444 .max_uV = 3150000,
445 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
446 .table = TPS65023_LDO1_VSEL_table,
447 },
448 {
449 .name = "LDO2",
450 .min_uV = 1050000,
451 .max_uV = 3300000,
452 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
453 .table = TPS65023_LDO2_VSEL_table,
454 },
455};
456
30e6599d
AA
457static const struct tps_info tps65023_regs[] = {
458 {
459 .name = "VDCDC1",
460 .min_uV = 800000,
461 .max_uV = 1600000,
1c3ede05
MF
462 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
463 .table = VCORE_VSEL_table,
30e6599d
AA
464 },
465 {
466 .name = "VDCDC2",
467 .min_uV = 3300000,
468 .max_uV = 3300000,
469 .fixed = 1,
470 },
471 {
472 .name = "VDCDC3",
473 .min_uV = 1800000,
474 .max_uV = 1800000,
475 .fixed = 1,
476 },
477 {
478 .name = "LDO1",
479 .min_uV = 1000000,
480 .max_uV = 3150000,
1c3ede05
MF
481 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
482 .table = TPS65023_LDO1_VSEL_table,
30e6599d
AA
483 },
484 {
485 .name = "LDO2",
486 .min_uV = 1050000,
487 .max_uV = 3300000,
1c3ede05
MF
488 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
489 .table = TPS65023_LDO2_VSEL_table,
30e6599d
AA
490 },
491};
492
437afd2a
MF
493static struct tps_driver_data tps65020_drv_data = {
494 .info = tps65020_regs,
495 .core_regulator = TPS65023_DCDC_3,
496};
497
1c3ede05 498static struct tps_driver_data tps65021_drv_data = {
7061873f
AL
499 .info = tps65021_regs,
500 .core_regulator = TPS65023_DCDC_3,
1c3ede05
MF
501};
502
503static struct tps_driver_data tps65023_drv_data = {
7061873f
AL
504 .info = tps65023_regs,
505 .core_regulator = TPS65023_DCDC_1,
1c3ede05
MF
506};
507
9e108d33
LG
508static const struct i2c_device_id tps_65023_id[] = {
509 {.name = "tps65023",
1c3ede05 510 .driver_data = (unsigned long) &tps65023_drv_data},
1880a2fc 511 {.name = "tps65021",
1c3ede05 512 .driver_data = (unsigned long) &tps65021_drv_data,},
437afd2a
MF
513 {.name = "tps65020",
514 .driver_data = (unsigned long) &tps65020_drv_data},
9e108d33 515 { },
30e6599d
AA
516};
517
518MODULE_DEVICE_TABLE(i2c, tps_65023_id);
519
520static struct i2c_driver tps_65023_i2c_driver = {
521 .driver = {
522 .name = "tps65023",
523 .owner = THIS_MODULE,
524 },
525 .probe = tps_65023_probe,
526 .remove = __devexit_p(tps_65023_remove),
9e108d33 527 .id_table = tps_65023_id,
30e6599d
AA
528};
529
30e6599d
AA
530static int __init tps_65023_init(void)
531{
532 return i2c_add_driver(&tps_65023_i2c_driver);
533}
534subsys_initcall(tps_65023_init);
535
30e6599d
AA
536static void __exit tps_65023_cleanup(void)
537{
538 i2c_del_driver(&tps_65023_i2c_driver);
539}
540module_exit(tps_65023_cleanup);
541
542MODULE_AUTHOR("Texas Instruments");
543MODULE_DESCRIPTION("TPS65023 voltage regulator driver");
9e108d33 544MODULE_LICENSE("GPL v2");
This page took 0.204923 seconds and 5 git commands to generate.