aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2013-02-11 05:49:41 -0500
committerLee Jones <lee.jones@linaro.org>2013-03-06 23:28:35 -0500
commit7c8f023616f89c3796331cece68b7efdc5a0b1ca (patch)
tree4c165cfb443660beb1f9e333ee22e17bddd34d51 /drivers/mfd
parentbc6b4132bcae4b8e59766ba2dae8f377009b26d0 (diff)
mfd: ab8500-gpadc: Optimise GPADC driver
Optimise GPADC driver: * for code readability and maintenance by grouping similar cheking * for performance by grouping several writing to control register Signed-off-by: Alexandre Bourdiol <alexandre.bourdiol@stericsson.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/ab8500-gpadc.c212
1 files changed, 55 insertions, 157 deletions
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index e3535c74d5fe..af1db2a45e86 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -360,7 +360,12 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
360{ 360{
361 int ret; 361 int ret;
362 int looplimit = 0; 362 int looplimit = 0;
363 unsigned long completion_timeout;
363 u8 val, low_data, high_data, low_data2, high_data2; 364 u8 val, low_data, high_data, low_data2, high_data2;
365 u8 val_reg1 = 0;
366 unsigned int delay_min = 0;
367 unsigned int delay_max = 0;
368 u8 data_low_addr, data_high_addr;
364 369
365 if (!gpadc) 370 if (!gpadc)
366 return -ENODEV; 371 return -ENODEV;
@@ -392,12 +397,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
392 } 397 }
393 398
394 /* Enable GPADC */ 399 /* Enable GPADC */
395 ret = abx500_mask_and_set_register_interruptible(gpadc->dev, 400 val_reg1 |= EN_GPADC;
396 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC);
397 if (ret < 0) {
398 dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
399 goto out;
400 }
401 401
402 /* Select the channel source and set average samples */ 402 /* Select the channel source and set average samples */
403 switch (avg_sample) { 403 switch (avg_sample) {
@@ -415,9 +415,13 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
415 break; 415 break;
416 } 416 }
417 417
418 if (conv_type == ADC_HW) 418 if (conv_type == ADC_HW) {
419 ret = abx500_set_register_interruptible(gpadc->dev, 419 ret = abx500_set_register_interruptible(gpadc->dev,
420 AB8500_GPADC, AB8500_GPADC_CTRL3_REG, val); 420 AB8500_GPADC, AB8500_GPADC_CTRL3_REG, val);
421 val_reg1 |= EN_TRIG_EDGE;
422 if (trig_edge)
423 val_reg1 |= EN_FALLING;
424 }
421 else 425 else
422 ret = abx500_set_register_interruptible(gpadc->dev, 426 ret = abx500_set_register_interruptible(gpadc->dev,
423 AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val); 427 AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val);
@@ -432,123 +436,42 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
432 * charging current sense if it needed, ABB 3.0 needs some special 436 * charging current sense if it needed, ABB 3.0 needs some special
433 * treatment too. 437 * treatment too.
434 */ 438 */
435 if ((conv_type == ADC_HW) && (trig_edge)) {
436 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
437 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
438 EN_FALLING, EN_FALLING);
439 }
440
441 switch (channel) { 439 switch (channel) {
442 case MAIN_CHARGER_C: 440 case MAIN_CHARGER_C:
443 case USB_CHARGER_C: 441 case USB_CHARGER_C:
444 if (conv_type == ADC_HW) 442 val_reg1 |= EN_BUF | EN_ICHAR;
445 ret = abx500_mask_and_set_register_interruptible(
446 gpadc->dev,
447 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
448 EN_BUF | EN_ICHAR | EN_TRIG_EDGE,
449 EN_BUF | EN_ICHAR | EN_TRIG_EDGE);
450 else
451 ret = abx500_mask_and_set_register_interruptible(
452 gpadc->dev,
453 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
454 EN_BUF | EN_ICHAR,
455 EN_BUF | EN_ICHAR);
456 break;
457
458 case XTAL_TEMP:
459 if (conv_type == ADC_HW)
460 ret = abx500_mask_and_set_register_interruptible(
461 gpadc->dev,
462 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
463 EN_BUF | EN_TRIG_EDGE,
464 EN_BUF | EN_TRIG_EDGE);
465 else
466 ret = abx500_mask_and_set_register_interruptible(
467 gpadc->dev,
468 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
469 EN_BUF ,
470 EN_BUF);
471 break;
472
473 case VBAT_TRUE_MEAS:
474 if (conv_type == ADC_HW)
475 ret = abx500_mask_and_set_register_interruptible(
476 gpadc->dev,
477 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
478 EN_BUF | EN_TRIG_EDGE,
479 EN_BUF | EN_TRIG_EDGE);
480 else
481 ret = abx500_mask_and_set_register_interruptible(
482 gpadc->dev,
483 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
484 EN_BUF ,
485 EN_BUF);
486 break;
487
488 case BAT_CTRL_AND_IBAT:
489 case VBAT_MEAS_AND_IBAT:
490 case VBAT_TRUE_MEAS_AND_IBAT:
491 case BAT_TEMP_AND_IBAT:
492 if (conv_type == ADC_HW)
493 ret = abx500_mask_and_set_register_interruptible(
494 gpadc->dev,
495 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
496 EN_TRIG_EDGE,
497 EN_TRIG_EDGE);
498 else
499 ret = abx500_mask_and_set_register_interruptible(
500 gpadc->dev,
501 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
502 EN_BUF,
503 0);
504 break; 443 break;
505
506 case BTEMP_BALL: 444 case BTEMP_BALL:
507 if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { 445 if (!is_ab8500_2p0_or_earlier(gpadc->parent)) {
508 if (conv_type == ADC_HW) 446 val_reg1 |= EN_BUF | BTEMP_PULL_UP;
509 /* Turn on btemp pull-up on ABB 3.0 */ 447 /*
510 ret = abx500_mask_and_set_register_interruptible 448 * Delay might be needed for ABB8500 cut 3.0, if not,
511 (gpadc->dev, 449 * remove when hardware will be availible
512 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, 450 */
513 EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE, 451 delay_min = 1000; /* Delay in micro seconds */
514 EN_BUF | BTEMP_PULL_UP | EN_TRIG_EDGE); 452 delay_max = 10000; /* large range to optimise sleep mode */
515 else
516 ret = abx500_mask_and_set_register_interruptible
517 (gpadc->dev,
518 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
519 EN_BUF | BTEMP_PULL_UP,
520 EN_BUF | BTEMP_PULL_UP);
521
522 /*
523 * Delay might be needed for ABB8500 cut 3.0, if not, remove
524 * when hardware will be available
525 */
526 usleep_range(1000, 1000);
527 break; 453 break;
528 } 454 }
529 /* Intentional fallthrough */ 455 /* Intentional fallthrough */
530 default: 456 default:
531 if (conv_type == ADC_HW) 457 val_reg1 |= EN_BUF;
532 ret = abx500_mask_and_set_register_interruptible(
533 gpadc->dev,
534 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
535 EN_BUF | EN_TRIG_EDGE,
536 EN_BUF | EN_TRIG_EDGE);
537 else
538 ret = abx500_mask_and_set_register_interruptible(
539 gpadc->dev,
540 AB8500_GPADC,
541 AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
542 break; 458 break;
543 } 459 }
460
461 /* Write configuration to register */
462 ret = abx500_set_register_interruptible(gpadc->dev,
463 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, val_reg1);
544 if (ret < 0) { 464 if (ret < 0) {
545 dev_err(gpadc->dev, 465 dev_err(gpadc->dev,
546 "gpadc_conversion: select falling edge failed\n"); 466 "gpadc_conversion: set Control register failed\n");
547 goto out; 467 goto out;
548 } 468 }
549 469
550 /* Set trigger delay timer */ 470 if (delay_min != 0)
471 usleep_range(delay_min, delay_max);
472
551 if (conv_type == ADC_HW) { 473 if (conv_type == ADC_HW) {
474 /* Set trigger delay timer */
552 ret = abx500_set_register_interruptible(gpadc->dev, 475 ret = abx500_set_register_interruptible(gpadc->dev,
553 AB8500_GPADC, AB8500_GPADC_AUTO_TIMER_REG, trig_timer); 476 AB8500_GPADC, AB8500_GPADC_AUTO_TIMER_REG, trig_timer);
554 if (ret < 0) { 477 if (ret < 0) {
@@ -556,10 +479,11 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
556 "gpadc_conversion: trig timer failed\n"); 479 "gpadc_conversion: trig timer failed\n");
557 goto out; 480 goto out;
558 } 481 }
559 } 482 completion_timeout = 2 * HZ;
560 483 data_low_addr = AB8500_GPADC_AUTODATAL_REG;
561 /* Start SW conversion */ 484 data_high_addr = AB8500_GPADC_AUTODATAH_REG;
562 if (conv_type == ADC_SW) { 485 } else {
486 /* Start SW conversion */
563 ret = abx500_mask_and_set_register_interruptible(gpadc->dev, 487 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
564 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, 488 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
565 ADC_SW_CONV, ADC_SW_CONV); 489 ADC_SW_CONV, ADC_SW_CONV);
@@ -568,61 +492,35 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
568 "gpadc_conversion: start s/w conv failed\n"); 492 "gpadc_conversion: start s/w conv failed\n");
569 goto out; 493 goto out;
570 } 494 }
495 completion_timeout = msecs_to_jiffies(CONVERSION_TIME);
496 data_low_addr = AB8500_GPADC_MANDATAL_REG;
497 data_high_addr = AB8500_GPADC_MANDATAH_REG;
571 } 498 }
572 499
573 /* wait for completion of conversion */ 500 /* wait for completion of conversion */
574 if (conv_type == ADC_HW) { 501 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete,
575 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 502 completion_timeout)) {
576 2 * HZ)) { 503 dev_err(gpadc->dev,
577 dev_err(gpadc->dev, 504 "timeout didn't receive GPADC conv interrupt\n");
578 "timeout didn't receive hw GPADC conv interrupt\n"); 505 ret = -EINVAL;
579 ret = -EINVAL; 506 goto out;
580 goto out;
581 }
582 } else {
583 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete,
584 msecs_to_jiffies(CONVERSION_TIME))) {
585 dev_err(gpadc->dev,
586 "timeout didn't receive sw GPADC conv interrupt\n");
587 ret = -EINVAL;
588 goto out;
589 }
590 } 507 }
591 508
592 /* Read the converted RAW data */ 509 /* Read the converted RAW data */
593 if (conv_type == ADC_HW) { 510 ret = abx500_get_register_interruptible(gpadc->dev,
594 ret = abx500_get_register_interruptible(gpadc->dev, 511 AB8500_GPADC, data_low_addr, &low_data);
595 AB8500_GPADC, AB8500_GPADC_AUTODATAL_REG, &low_data); 512 if (ret < 0) {
596 if (ret < 0) { 513 dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n");
597 dev_err(gpadc->dev, 514 goto out;
598 "gpadc_conversion: read hw low data failed\n"); 515 }
599 goto out;
600 }
601
602 ret = abx500_get_register_interruptible(gpadc->dev,
603 AB8500_GPADC, AB8500_GPADC_AUTODATAH_REG, &high_data);
604 if (ret < 0) {
605 dev_err(gpadc->dev,
606 "gpadc_conversion: read hw high data failed\n");
607 goto out;
608 }
609 } else {
610 ret = abx500_get_register_interruptible(gpadc->dev,
611 AB8500_GPADC, AB8500_GPADC_MANDATAL_REG, &low_data);
612 if (ret < 0) {
613 dev_err(gpadc->dev,
614 "gpadc_conversion: read sw low data failed\n");
615 goto out;
616 }
617 516
618 ret = abx500_get_register_interruptible(gpadc->dev, 517 ret = abx500_get_register_interruptible(gpadc->dev,
619 AB8500_GPADC, AB8500_GPADC_MANDATAH_REG, &high_data); 518 AB8500_GPADC, data_high_addr, &high_data);
620 if (ret < 0) { 519 if (ret < 0) {
621 dev_err(gpadc->dev, 520 dev_err(gpadc->dev, "gpadc_conversion: read high data failed\n");
622 "gpadc_conversion: read sw high data failed\n"); 521 goto out;
623 goto out;
624 }
625 } 522 }
523
626 /* Check if double convertion is required */ 524 /* Check if double convertion is required */
627 if ((channel == BAT_CTRL_AND_IBAT) || 525 if ((channel == BAT_CTRL_AND_IBAT) ||
628 (channel == VBAT_MEAS_AND_IBAT) || 526 (channel == VBAT_MEAS_AND_IBAT) ||