diff options
Diffstat (limited to 'drivers/regulator/tps65023-regulator.c')
-rw-r--r-- | drivers/regulator/tps65023-regulator.c | 201 |
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 */ |
94 | static const u16 VCORE_VSEL_table[] = { | 90 | static 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 | |||
101 | static const unsigned int DCDC_FIXED_3300000_VSEL_table[] = { | ||
102 | 3300000, | ||
103 | }; | ||
104 | |||
105 | static 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 */ |
106 | static const u16 TPS65020_LDO1_VSEL_table[] = { | 110 | static 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 | ||
111 | static const u16 TPS65020_LDO2_VSEL_table[] = { | 115 | static 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 */ |
118 | static const u16 TPS65023_LDO1_VSEL_table[] = { | 122 | static 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 | ||
123 | static const u16 TPS65023_LDO2_VSEL_table[] = { | 127 | static 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 */ |
129 | struct tps_info { | 133 | struct 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 | ||
153 | static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) | 154 | static 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 | ||
172 | static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, | 173 | static 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 | ||
196 | static 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 | |||
214 | static 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 | |||
225 | static 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 | |||
243 | static 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 */ |
259 | static struct regulator_ops tps65023_dcdc_ops = { | 198 | static 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 | ||
278 | static struct regmap_config tps65023_regmap_config = { | 217 | static 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) | |||
384 | static const struct tps_info tps65020_regs[] = { | 332 | static 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[] = { | |||
421 | static const struct tps_info tps65021_regs[] = { | 360 | static 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[] = { | |||
457 | static const struct tps_info tps65023_regs[] = { | 388 | static 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 | }, |