aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/tps65023-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/tps65023-regulator.c')
-rw-r--r--drivers/regulator/tps65023-regulator.c201
1 files changed, 62 insertions, 139 deletions
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 8f1be8586c72..6998d579d07b 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -69,10 +69,6 @@
69#define TPS65023_REG_CTRL2_DCDC1 BIT(1) 69#define TPS65023_REG_CTRL2_DCDC1 BIT(1)
70#define TPS65023_REG_CTRL2_DCDC3 BIT(0) 70#define TPS65023_REG_CTRL2_DCDC3 BIT(0)
71 71
72/* LDO_CTRL bitfields */
73#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4)
74#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x07 << ((ldo_id)*4))
75
76/* Number of step-down converters available */ 72/* Number of step-down converters available */
77#define TPS65023_NUM_DCDC 3 73#define TPS65023_NUM_DCDC 3
78/* Number of LDO voltage regulators available */ 74/* Number of LDO voltage regulators available */
@@ -91,48 +87,53 @@
91#define TPS65023_MAX_REG_ID TPS65023_LDO_2 87#define TPS65023_MAX_REG_ID TPS65023_LDO_2
92 88
93/* Supported voltage values for regulators */ 89/* Supported voltage values for regulators */
94static const u16 VCORE_VSEL_table[] = { 90static const unsigned int VCORE_VSEL_table[] = {
95 800, 825, 850, 875, 91 800000, 825000, 850000, 875000,
96 900, 925, 950, 975, 92 900000, 925000, 950000, 975000,
97 1000, 1025, 1050, 1075, 93 1000000, 1025000, 1050000, 1075000,
98 1100, 1125, 1150, 1175, 94 1100000, 1125000, 1150000, 1175000,
99 1200, 1225, 1250, 1275, 95 1200000, 1225000, 1250000, 1275000,
100 1300, 1325, 1350, 1375, 96 1300000, 1325000, 1350000, 1375000,
101 1400, 1425, 1450, 1475, 97 1400000, 1425000, 1450000, 1475000,
102 1500, 1525, 1550, 1600, 98 1500000, 1525000, 1550000, 1600000,
99};
100
101static const unsigned int DCDC_FIXED_3300000_VSEL_table[] = {
102 3300000,
103};
104
105static const unsigned int DCDC_FIXED_1800000_VSEL_table[] = {
106 1800000,
103}; 107};
104 108
105/* Supported voltage values for LDO regulators for tps65020 */ 109/* Supported voltage values for LDO regulators for tps65020 */
106static const u16 TPS65020_LDO1_VSEL_table[] = { 110static const unsigned int TPS65020_LDO1_VSEL_table[] = {
107 1000, 1050, 1100, 1300, 111 1000000, 1050000, 1100000, 1300000,
108 1800, 2500, 3000, 3300, 112 1800000, 2500000, 3000000, 3300000,
109}; 113};
110 114
111static const u16 TPS65020_LDO2_VSEL_table[] = { 115static const unsigned int TPS65020_LDO2_VSEL_table[] = {
112 1000, 1050, 1100, 1300, 116 1000000, 1050000, 1100000, 1300000,
113 1800, 2500, 3000, 3300, 117 1800000, 2500000, 3000000, 3300000,
114}; 118};
115 119
116/* Supported voltage values for LDO regulators 120/* Supported voltage values for LDO regulators
117 * for tps65021 and tps65023 */ 121 * for tps65021 and tps65023 */
118static const u16 TPS65023_LDO1_VSEL_table[] = { 122static const unsigned int TPS65023_LDO1_VSEL_table[] = {
119 1000, 1100, 1300, 1800, 123 1000000, 1100000, 1300000, 1800000,
120 2200, 2600, 2800, 3150, 124 2200000, 2600000, 2800000, 3150000,
121}; 125};
122 126
123static const u16 TPS65023_LDO2_VSEL_table[] = { 127static const unsigned int TPS65023_LDO2_VSEL_table[] = {
124 1050, 1200, 1300, 1800, 128 1050000, 1200000, 1300000, 1800000,
125 2500, 2800, 3000, 3300, 129 2500000, 2800000, 3000000, 3300000,
126}; 130};
127 131
128/* Regulator specific details */ 132/* Regulator specific details */
129struct tps_info { 133struct tps_info {
130 const char *name; 134 const char *name;
131 unsigned min_uV;
132 unsigned max_uV;
133 bool fixed;
134 u8 table_len; 135 u8 table_len;
135 const u16 *table; 136 const unsigned int *table;
136}; 137};
137 138
138/* PMIC details */ 139/* PMIC details */
@@ -150,7 +151,7 @@ struct tps_driver_data {
150 u8 core_regulator; 151 u8 core_regulator;
151}; 152};
152 153
153static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) 154static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev)
154{ 155{
155 struct tps_pmic *tps = rdev_get_drvdata(dev); 156 struct tps_pmic *tps = rdev_get_drvdata(dev);
156 int ret; 157 int ret;
@@ -164,9 +165,9 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
164 if (ret != 0) 165 if (ret != 0)
165 return ret; 166 return ret;
166 data &= (tps->info[dcdc]->table_len - 1); 167 data &= (tps->info[dcdc]->table_len - 1);
167 return tps->info[dcdc]->table[data] * 1000; 168 return data;
168 } else 169 } else
169 return tps->info[dcdc]->min_uV; 170 return 0;
170} 171}
171 172
172static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, 173static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
@@ -193,76 +194,14 @@ out:
193 return ret; 194 return ret;
194} 195}
195 196
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);
200 int ret;
201
202 if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
203 return -EINVAL;
204
205 ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
206 if (ret != 0)
207 return ret;
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
214static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev,
215 unsigned selector)
216{
217 struct tps_pmic *tps = rdev_get_drvdata(dev);
218 int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1;
219
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));
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
234 if (dcdc == tps->core_regulator) {
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 */ 197/* Operations permitted on VDCDCx */
259static struct regulator_ops tps65023_dcdc_ops = { 198static struct regulator_ops tps65023_dcdc_ops = {
260 .is_enabled = regulator_is_enabled_regmap, 199 .is_enabled = regulator_is_enabled_regmap,
261 .enable = regulator_enable_regmap, 200 .enable = regulator_enable_regmap,
262 .disable = regulator_disable_regmap, 201 .disable = regulator_disable_regmap,
263 .get_voltage = tps65023_dcdc_get_voltage, 202 .get_voltage_sel = tps65023_dcdc_get_voltage_sel,
264 .set_voltage_sel = tps65023_dcdc_set_voltage_sel, 203 .set_voltage_sel = tps65023_dcdc_set_voltage_sel,
265 .list_voltage = tps65023_dcdc_list_voltage, 204 .list_voltage = regulator_list_voltage_table,
266}; 205};
267 206
268/* Operations permitted on LDOx */ 207/* Operations permitted on LDOx */
@@ -270,9 +209,9 @@ static struct regulator_ops tps65023_ldo_ops = {
270 .is_enabled = regulator_is_enabled_regmap, 209 .is_enabled = regulator_is_enabled_regmap,
271 .enable = regulator_enable_regmap, 210 .enable = regulator_enable_regmap,
272 .disable = regulator_disable_regmap, 211 .disable = regulator_disable_regmap,
273 .get_voltage = tps65023_ldo_get_voltage, 212 .get_voltage_sel = regulator_get_voltage_sel_regmap,
274 .set_voltage_sel = tps65023_ldo_set_voltage_sel, 213 .set_voltage_sel = regulator_set_voltage_sel_regmap,
275 .list_voltage = tps65023_ldo_list_voltage, 214 .list_voltage = regulator_list_voltage_table,
276}; 215};
277 216
278static struct regmap_config tps65023_regmap_config = { 217static struct regmap_config tps65023_regmap_config = {
@@ -325,19 +264,28 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
325 tps->desc[i].name = info->name; 264 tps->desc[i].name = info->name;
326 tps->desc[i].id = i; 265 tps->desc[i].id = i;
327 tps->desc[i].n_voltages = info->table_len; 266 tps->desc[i].n_voltages = info->table_len;
267 tps->desc[i].volt_table = info->table;
328 tps->desc[i].ops = (i > TPS65023_DCDC_3 ? 268 tps->desc[i].ops = (i > TPS65023_DCDC_3 ?
329 &tps65023_ldo_ops : &tps65023_dcdc_ops); 269 &tps65023_ldo_ops : &tps65023_dcdc_ops);
330 tps->desc[i].type = REGULATOR_VOLTAGE; 270 tps->desc[i].type = REGULATOR_VOLTAGE;
331 tps->desc[i].owner = THIS_MODULE; 271 tps->desc[i].owner = THIS_MODULE;
332 272
333 tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL; 273 tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL;
334 if (i == TPS65023_LDO_1) 274 switch (i) {
275 case TPS65023_LDO_1:
276 tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL;
277 tps->desc[i].vsel_mask = 0x07;
335 tps->desc[i].enable_mask = 1 << 1; 278 tps->desc[i].enable_mask = 1 << 1;
336 else if (i == TPS65023_LDO_2) 279 break;
280 case TPS65023_LDO_2:
281 tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL;
282 tps->desc[i].vsel_mask = 0x70;
337 tps->desc[i].enable_mask = 1 << 2; 283 tps->desc[i].enable_mask = 1 << 2;
338 else /* DCDCx */ 284 break;
285 default: /* DCDCx */
339 tps->desc[i].enable_mask = 286 tps->desc[i].enable_mask =
340 1 << (TPS65023_NUM_REGULATOR - i); 287 1 << (TPS65023_NUM_REGULATOR - i);
288 }
341 289
342 config.dev = &client->dev; 290 config.dev = &client->dev;
343 config.init_data = init_data; 291 config.init_data = init_data;
@@ -384,35 +332,26 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
384static const struct tps_info tps65020_regs[] = { 332static const struct tps_info tps65020_regs[] = {
385 { 333 {
386 .name = "VDCDC1", 334 .name = "VDCDC1",
387 .min_uV = 3300000, 335 .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table),
388 .max_uV = 3300000, 336 .table = DCDC_FIXED_3300000_VSEL_table,
389 .fixed = 1,
390 }, 337 },
391 { 338 {
392 .name = "VDCDC2", 339 .name = "VDCDC2",
393 .min_uV = 1800000, 340 .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table),
394 .max_uV = 1800000, 341 .table = DCDC_FIXED_1800000_VSEL_table,
395 .fixed = 1,
396 }, 342 },
397 { 343 {
398 .name = "VDCDC3", 344 .name = "VDCDC3",
399 .min_uV = 800000,
400 .max_uV = 1600000,
401 .table_len = ARRAY_SIZE(VCORE_VSEL_table), 345 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
402 .table = VCORE_VSEL_table, 346 .table = VCORE_VSEL_table,
403 }, 347 },
404
405 { 348 {
406 .name = "LDO1", 349 .name = "LDO1",
407 .min_uV = 1000000,
408 .max_uV = 3150000,
409 .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table), 350 .table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table),
410 .table = TPS65020_LDO1_VSEL_table, 351 .table = TPS65020_LDO1_VSEL_table,
411 }, 352 },
412 { 353 {
413 .name = "LDO2", 354 .name = "LDO2",
414 .min_uV = 1050000,
415 .max_uV = 3300000,
416 .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table), 355 .table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table),
417 .table = TPS65020_LDO2_VSEL_table, 356 .table = TPS65020_LDO2_VSEL_table,
418 }, 357 },
@@ -421,34 +360,26 @@ static const struct tps_info tps65020_regs[] = {
421static const struct tps_info tps65021_regs[] = { 360static const struct tps_info tps65021_regs[] = {
422 { 361 {
423 .name = "VDCDC1", 362 .name = "VDCDC1",
424 .min_uV = 3300000, 363 .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table),
425 .max_uV = 3300000, 364 .table = DCDC_FIXED_3300000_VSEL_table,
426 .fixed = 1,
427 }, 365 },
428 { 366 {
429 .name = "VDCDC2", 367 .name = "VDCDC2",
430 .min_uV = 1800000, 368 .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table),
431 .max_uV = 1800000, 369 .table = DCDC_FIXED_1800000_VSEL_table,
432 .fixed = 1,
433 }, 370 },
434 { 371 {
435 .name = "VDCDC3", 372 .name = "VDCDC3",
436 .min_uV = 800000,
437 .max_uV = 1600000,
438 .table_len = ARRAY_SIZE(VCORE_VSEL_table), 373 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
439 .table = VCORE_VSEL_table, 374 .table = VCORE_VSEL_table,
440 }, 375 },
441 { 376 {
442 .name = "LDO1", 377 .name = "LDO1",
443 .min_uV = 1000000,
444 .max_uV = 3150000,
445 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), 378 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
446 .table = TPS65023_LDO1_VSEL_table, 379 .table = TPS65023_LDO1_VSEL_table,
447 }, 380 },
448 { 381 {
449 .name = "LDO2", 382 .name = "LDO2",
450 .min_uV = 1050000,
451 .max_uV = 3300000,
452 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), 383 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
453 .table = TPS65023_LDO2_VSEL_table, 384 .table = TPS65023_LDO2_VSEL_table,
454 }, 385 },
@@ -457,34 +388,26 @@ static const struct tps_info tps65021_regs[] = {
457static const struct tps_info tps65023_regs[] = { 388static const struct tps_info tps65023_regs[] = {
458 { 389 {
459 .name = "VDCDC1", 390 .name = "VDCDC1",
460 .min_uV = 800000,
461 .max_uV = 1600000,
462 .table_len = ARRAY_SIZE(VCORE_VSEL_table), 391 .table_len = ARRAY_SIZE(VCORE_VSEL_table),
463 .table = VCORE_VSEL_table, 392 .table = VCORE_VSEL_table,
464 }, 393 },
465 { 394 {
466 .name = "VDCDC2", 395 .name = "VDCDC2",
467 .min_uV = 3300000, 396 .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table),
468 .max_uV = 3300000, 397 .table = DCDC_FIXED_3300000_VSEL_table,
469 .fixed = 1,
470 }, 398 },
471 { 399 {
472 .name = "VDCDC3", 400 .name = "VDCDC3",
473 .min_uV = 1800000, 401 .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table),
474 .max_uV = 1800000, 402 .table = DCDC_FIXED_1800000_VSEL_table,
475 .fixed = 1,
476 }, 403 },
477 { 404 {
478 .name = "LDO1", 405 .name = "LDO1",
479 .min_uV = 1000000,
480 .max_uV = 3150000,
481 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), 406 .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
482 .table = TPS65023_LDO1_VSEL_table, 407 .table = TPS65023_LDO1_VSEL_table,
483 }, 408 },
484 { 409 {
485 .name = "LDO2", 410 .name = "LDO2",
486 .min_uV = 1050000,
487 .max_uV = 3300000,
488 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), 411 .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
489 .table = TPS65023_LDO2_VSEL_table, 412 .table = TPS65023_LDO2_VSEL_table,
490 }, 413 },