aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@gmail.com>2012-03-12 03:57:50 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-03-14 10:13:17 -0400
commitf2933d333118bff82e4b46fff605e31f799df5ce (patch)
tree1f868e5e6e40477a4c118201ffcdb667d57b689e
parent0a41685fd58f8a4fe097449063764420ebb7ed93 (diff)
regulator: Refactor tps6507x to use one tps6507x_pmic_ops for all LDOs and DCDCs
All the callback functions implementation for DCDCx and LDOx are very similar, I think it is ok to use one tps6507x_pmic_ops for all LDOs and DCDCs. This refactor removes a couple of duplicated code. Signed-off-by: Axel Lin <axel.lin@gmail.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--drivers/regulator/tps6507x-regulator.c268
1 files changed, 67 insertions, 201 deletions
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index 0b63ef71a5fe..e140a152f5f8 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -238,16 +238,16 @@ static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val)
238 return err; 238 return err;
239} 239}
240 240
241static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev) 241static int tps6507x_pmic_is_enabled(struct regulator_dev *dev)
242{ 242{
243 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 243 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
244 int data, dcdc = rdev_get_id(dev); 244 int data, rid = rdev_get_id(dev);
245 u8 shift; 245 u8 shift;
246 246
247 if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 247 if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
248 return -EINVAL; 248 return -EINVAL;
249 249
250 shift = TPS6507X_MAX_REG_ID - dcdc; 250 shift = TPS6507X_MAX_REG_ID - rid;
251 data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); 251 data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
252 252
253 if (data < 0) 253 if (data < 0)
@@ -256,99 +256,65 @@ static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev)
256 return (data & 1<<shift) ? 1 : 0; 256 return (data & 1<<shift) ? 1 : 0;
257} 257}
258 258
259static int tps6507x_pmic_ldo_is_enabled(struct regulator_dev *dev) 259static int tps6507x_pmic_enable(struct regulator_dev *dev)
260{ 260{
261 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 261 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
262 int data, ldo = rdev_get_id(dev); 262 int rid = rdev_get_id(dev);
263 u8 shift; 263 u8 shift;
264 264
265 if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 265 if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
266 return -EINVAL; 266 return -EINVAL;
267 267
268 shift = TPS6507X_MAX_REG_ID - ldo; 268 shift = TPS6507X_MAX_REG_ID - rid;
269 data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1);
270
271 if (data < 0)
272 return data;
273 else
274 return (data & 1<<shift) ? 1 : 0;
275}
276
277static int tps6507x_pmic_dcdc_enable(struct regulator_dev *dev)
278{
279 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
280 int dcdc = rdev_get_id(dev);
281 u8 shift;
282
283 if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3)
284 return -EINVAL;
285
286 shift = TPS6507X_MAX_REG_ID - dcdc;
287 return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
288}
289
290static int tps6507x_pmic_dcdc_disable(struct regulator_dev *dev)
291{
292 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
293 int dcdc = rdev_get_id(dev);
294 u8 shift;
295
296 if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3)
297 return -EINVAL;
298
299 shift = TPS6507X_MAX_REG_ID - dcdc;
300 return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
301 1 << shift);
302}
303
304static int tps6507x_pmic_ldo_enable(struct regulator_dev *dev)
305{
306 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
307 int ldo = rdev_get_id(dev);
308 u8 shift;
309
310 if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
311 return -EINVAL;
312
313 shift = TPS6507X_MAX_REG_ID - ldo;
314 return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); 269 return tps6507x_pmic_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift);
315} 270}
316 271
317static int tps6507x_pmic_ldo_disable(struct regulator_dev *dev) 272static int tps6507x_pmic_disable(struct regulator_dev *dev)
318{ 273{
319 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 274 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
320 int ldo = rdev_get_id(dev); 275 int rid = rdev_get_id(dev);
321 u8 shift; 276 u8 shift;
322 277
323 if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 278 if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
324 return -EINVAL; 279 return -EINVAL;
325 280
326 shift = TPS6507X_MAX_REG_ID - ldo; 281 shift = TPS6507X_MAX_REG_ID - rid;
327 return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 282 return tps6507x_pmic_clear_bits(tps, TPS6507X_REG_CON_CTRL1,
328 1 << shift); 283 1 << shift);
329} 284}
330 285
331static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev) 286static int tps6507x_pmic_get_voltage(struct regulator_dev *dev)
332{ 287{
333 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 288 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
334 int data, dcdc = rdev_get_id(dev); 289 int data, rid = rdev_get_id(dev);
335 u8 reg; 290 u8 reg, mask;
336 291
337 switch (dcdc) { 292 switch (rid) {
338 case TPS6507X_DCDC_1: 293 case TPS6507X_DCDC_1:
339 reg = TPS6507X_REG_DEFDCDC1; 294 reg = TPS6507X_REG_DEFDCDC1;
295 mask = TPS6507X_DEFDCDCX_DCDC_MASK;
340 break; 296 break;
341 case TPS6507X_DCDC_2: 297 case TPS6507X_DCDC_2:
342 if (tps->info[dcdc]->defdcdc_default) 298 if (tps->info[rid]->defdcdc_default)
343 reg = TPS6507X_REG_DEFDCDC2_HIGH; 299 reg = TPS6507X_REG_DEFDCDC2_HIGH;
344 else 300 else
345 reg = TPS6507X_REG_DEFDCDC2_LOW; 301 reg = TPS6507X_REG_DEFDCDC2_LOW;
302 mask = TPS6507X_DEFDCDCX_DCDC_MASK;
346 break; 303 break;
347 case TPS6507X_DCDC_3: 304 case TPS6507X_DCDC_3:
348 if (tps->info[dcdc]->defdcdc_default) 305 if (tps->info[rid]->defdcdc_default)
349 reg = TPS6507X_REG_DEFDCDC3_HIGH; 306 reg = TPS6507X_REG_DEFDCDC3_HIGH;
350 else 307 else
351 reg = TPS6507X_REG_DEFDCDC3_LOW; 308 reg = TPS6507X_REG_DEFDCDC3_LOW;
309 mask = TPS6507X_DEFDCDCX_DCDC_MASK;
310 break;
311 case TPS6507X_LDO_1:
312 reg = TPS6507X_REG_LDO_CTRL1;
313 mask = TPS6507X_REG_LDO_CTRL1_LDO1_MASK;
314 break;
315 case TPS6507X_LDO_2:
316 reg = TPS6507X_REG_DEFLDO2;
317 mask = TPS6507X_REG_DEFLDO2_LDO2_MASK;
352 break; 318 break;
353 default: 319 default:
354 return -EINVAL; 320 return -EINVAL;
@@ -358,47 +324,56 @@ static int tps6507x_pmic_dcdc_get_voltage(struct regulator_dev *dev)
358 if (data < 0) 324 if (data < 0)
359 return data; 325 return data;
360 326
361 data &= TPS6507X_DEFDCDCX_DCDC_MASK; 327 data &= mask;
362 return tps->info[dcdc]->table[data] * 1000; 328 return tps->info[rid]->table[data] * 1000;
363} 329}
364 330
365static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, 331static int tps6507x_pmic_set_voltage(struct regulator_dev *dev,
366 int min_uV, int max_uV, 332 int min_uV, int max_uV,
367 unsigned *selector) 333 unsigned *selector)
368{ 334{
369 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 335 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
370 int data, vsel, dcdc = rdev_get_id(dev); 336 int data, vsel, rid = rdev_get_id(dev);
371 u8 reg; 337 u8 reg, mask;
372 338
373 switch (dcdc) { 339 switch (rid) {
374 case TPS6507X_DCDC_1: 340 case TPS6507X_DCDC_1:
375 reg = TPS6507X_REG_DEFDCDC1; 341 reg = TPS6507X_REG_DEFDCDC1;
342 mask = TPS6507X_DEFDCDCX_DCDC_MASK;
376 break; 343 break;
377 case TPS6507X_DCDC_2: 344 case TPS6507X_DCDC_2:
378 if (tps->info[dcdc]->defdcdc_default) 345 if (tps->info[rid]->defdcdc_default)
379 reg = TPS6507X_REG_DEFDCDC2_HIGH; 346 reg = TPS6507X_REG_DEFDCDC2_HIGH;
380 else 347 else
381 reg = TPS6507X_REG_DEFDCDC2_LOW; 348 reg = TPS6507X_REG_DEFDCDC2_LOW;
349 mask = TPS6507X_DEFDCDCX_DCDC_MASK;
382 break; 350 break;
383 case TPS6507X_DCDC_3: 351 case TPS6507X_DCDC_3:
384 if (tps->info[dcdc]->defdcdc_default) 352 if (tps->info[rid]->defdcdc_default)
385 reg = TPS6507X_REG_DEFDCDC3_HIGH; 353 reg = TPS6507X_REG_DEFDCDC3_HIGH;
386 else 354 else
387 reg = TPS6507X_REG_DEFDCDC3_LOW; 355 reg = TPS6507X_REG_DEFDCDC3_LOW;
356 mask = TPS6507X_DEFDCDCX_DCDC_MASK;
357 break;
358 case TPS6507X_LDO_1:
359 reg = TPS6507X_REG_LDO_CTRL1;
360 mask = TPS6507X_REG_LDO_CTRL1_LDO1_MASK;
361 break;
362 case TPS6507X_LDO_2:
363 reg = TPS6507X_REG_DEFLDO2;
364 mask = TPS6507X_REG_DEFLDO2_LDO2_MASK;
388 break; 365 break;
389 default: 366 default:
390 return -EINVAL; 367 return -EINVAL;
391 } 368 }
392 369
393 if (min_uV < tps->info[dcdc]->min_uV 370 if (min_uV < tps->info[rid]->min_uV || min_uV > tps->info[rid]->max_uV)
394 || min_uV > tps->info[dcdc]->max_uV)
395 return -EINVAL; 371 return -EINVAL;
396 if (max_uV < tps->info[dcdc]->min_uV 372 if (max_uV < tps->info[rid]->min_uV || max_uV > tps->info[rid]->max_uV)
397 || max_uV > tps->info[dcdc]->max_uV)
398 return -EINVAL; 373 return -EINVAL;
399 374
400 for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { 375 for (vsel = 0; vsel < tps->info[rid]->table_len; vsel++) {
401 int mV = tps->info[dcdc]->table[vsel]; 376 int mV = tps->info[rid]->table[vsel];
402 int uV = mV * 1000; 377 int uV = mV * 1000;
403 378
404 /* Break at the first in-range value */ 379 /* Break at the first in-range value */
@@ -407,78 +382,7 @@ static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev,
407 } 382 }
408 383
409 /* write to the register in case we found a match */ 384 /* write to the register in case we found a match */
410 if (vsel == tps->info[dcdc]->table_len) 385 if (vsel == tps->info[rid]->table_len)
411 return -EINVAL;
412
413 *selector = vsel;
414
415 data = tps6507x_pmic_reg_read(tps, reg);
416 if (data < 0)
417 return data;
418
419 data &= ~TPS6507X_DEFDCDCX_DCDC_MASK;
420 data |= vsel;
421
422 return tps6507x_pmic_reg_write(tps, reg, data);
423}
424
425static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev)
426{
427 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
428 int data, ldo = rdev_get_id(dev);
429 u8 reg, mask;
430
431 if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
432 return -EINVAL;
433 else {
434 reg = (ldo == TPS6507X_LDO_1 ?
435 TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2);
436 mask = (ldo == TPS6507X_LDO_1 ?
437 TPS6507X_REG_LDO_CTRL1_LDO1_MASK :
438 TPS6507X_REG_DEFLDO2_LDO2_MASK);
439 }
440
441 data = tps6507x_pmic_reg_read(tps, reg);
442 if (data < 0)
443 return data;
444
445 data &= mask;
446 return tps->info[ldo]->table[data] * 1000;
447}
448
449static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev,
450 int min_uV, int max_uV,
451 unsigned *selector)
452{
453 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
454 int data, vsel, ldo = rdev_get_id(dev);
455 u8 reg, mask;
456
457 if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2)
458 return -EINVAL;
459 else {
460 reg = (ldo == TPS6507X_LDO_1 ?
461 TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2);
462 mask = (ldo == TPS6507X_LDO_1 ?
463 TPS6507X_REG_LDO_CTRL1_LDO1_MASK :
464 TPS6507X_REG_DEFLDO2_LDO2_MASK);
465 }
466
467 if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV)
468 return -EINVAL;
469 if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV)
470 return -EINVAL;
471
472 for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) {
473 int mV = tps->info[ldo]->table[vsel];
474 int uV = mV * 1000;
475
476 /* Break at the first in-range value */
477 if (min_uV <= uV && uV <= max_uV)
478 break;
479 }
480
481 if (vsel == tps->info[ldo]->table_len)
482 return -EINVAL; 386 return -EINVAL;
483 387
484 *selector = vsel; 388 *selector = vsel;
@@ -493,58 +397,31 @@ static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev,
493 return tps6507x_pmic_reg_write(tps, reg, data); 397 return tps6507x_pmic_reg_write(tps, reg, data);
494} 398}
495 399
496static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev, 400static int tps6507x_pmic_list_voltage(struct regulator_dev *dev,
497 unsigned selector) 401 unsigned selector)
498{ 402{
499 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 403 struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
500 int dcdc = rdev_get_id(dev); 404 int rid = rdev_get_id(dev);
501 405
502 if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) 406 if (rid < TPS6507X_DCDC_1 || rid > TPS6507X_LDO_2)
503 return -EINVAL; 407 return -EINVAL;
504 408
505 if (selector >= tps->info[dcdc]->table_len) 409 if (selector >= tps->info[rid]->table_len)
506 return -EINVAL; 410 return -EINVAL;
507 else 411 else
508 return tps->info[dcdc]->table[selector] * 1000; 412 return tps->info[rid]->table[selector] * 1000;
509} 413}
510 414
511static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev, 415static struct regulator_ops tps6507x_pmic_ops = {
512 unsigned selector) 416 .is_enabled = tps6507x_pmic_is_enabled,
513{ 417 .enable = tps6507x_pmic_enable,
514 struct tps6507x_pmic *tps = rdev_get_drvdata(dev); 418 .disable = tps6507x_pmic_disable,
515 int ldo = rdev_get_id(dev); 419 .get_voltage = tps6507x_pmic_get_voltage,
516 420 .set_voltage = tps6507x_pmic_set_voltage,
517 if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) 421 .list_voltage = tps6507x_pmic_list_voltage,
518 return -EINVAL;
519
520 if (selector >= tps->info[ldo]->table_len)
521 return -EINVAL;
522 else
523 return tps->info[ldo]->table[selector] * 1000;
524}
525
526/* Operations permitted on VDCDCx */
527static struct regulator_ops tps6507x_pmic_dcdc_ops = {
528 .is_enabled = tps6507x_pmic_dcdc_is_enabled,
529 .enable = tps6507x_pmic_dcdc_enable,
530 .disable = tps6507x_pmic_dcdc_disable,
531 .get_voltage = tps6507x_pmic_dcdc_get_voltage,
532 .set_voltage = tps6507x_pmic_dcdc_set_voltage,
533 .list_voltage = tps6507x_pmic_dcdc_list_voltage,
534}; 422};
535 423
536/* Operations permitted on LDOx */ 424static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
537static struct regulator_ops tps6507x_pmic_ldo_ops = {
538 .is_enabled = tps6507x_pmic_ldo_is_enabled,
539 .enable = tps6507x_pmic_ldo_enable,
540 .disable = tps6507x_pmic_ldo_disable,
541 .get_voltage = tps6507x_pmic_ldo_get_voltage,
542 .set_voltage = tps6507x_pmic_ldo_set_voltage,
543 .list_voltage = tps6507x_pmic_ldo_list_voltage,
544};
545
546static __devinit
547int tps6507x_pmic_probe(struct platform_device *pdev)
548{ 425{
549 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); 426 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
550 struct tps_info *info = &tps6507x_pmic_regs[0]; 427 struct tps_info *info = &tps6507x_pmic_regs[0];
@@ -593,8 +470,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
593 tps->desc[i].name = info->name; 470 tps->desc[i].name = info->name;
594 tps->desc[i].id = i; 471 tps->desc[i].id = i;
595 tps->desc[i].n_voltages = info->table_len; 472 tps->desc[i].n_voltages = info->table_len;
596 tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? 473 tps->desc[i].ops = &tps6507x_pmic_ops;
597 &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
598 tps->desc[i].type = REGULATOR_VOLTAGE; 474 tps->desc[i].type = REGULATOR_VOLTAGE;
599 tps->desc[i].owner = THIS_MODULE; 475 tps->desc[i].owner = THIS_MODULE;
600 476
@@ -648,22 +524,12 @@ static struct platform_driver tps6507x_pmic_driver = {
648 .remove = __devexit_p(tps6507x_pmic_remove), 524 .remove = __devexit_p(tps6507x_pmic_remove),
649}; 525};
650 526
651/**
652 * tps6507x_pmic_init
653 *
654 * Module init function
655 */
656static int __init tps6507x_pmic_init(void) 527static int __init tps6507x_pmic_init(void)
657{ 528{
658 return platform_driver_register(&tps6507x_pmic_driver); 529 return platform_driver_register(&tps6507x_pmic_driver);
659} 530}
660subsys_initcall(tps6507x_pmic_init); 531subsys_initcall(tps6507x_pmic_init);
661 532
662/**
663 * tps6507x_pmic_cleanup
664 *
665 * Module exit function
666 */
667static void __exit tps6507x_pmic_cleanup(void) 533static void __exit tps6507x_pmic_cleanup(void)
668{ 534{
669 platform_driver_unregister(&tps6507x_pmic_driver); 535 platform_driver_unregister(&tps6507x_pmic_driver);