aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/ab8500-gpadc.c
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2013-02-11 05:38:00 -0500
committerLee Jones <lee.jones@linaro.org>2013-03-06 23:28:21 -0500
commite4bffe8d8ad9856143b6e941a17870aee37413d7 (patch)
tree591f0b3e5c7c08c14ef1483b810cd2eaa4ccdee4 /drivers/mfd/ab8500-gpadc.c
parent75932094601b404fc9ef28f7b6c0aa83dd619af0 (diff)
mfd: ab8500-gpadc: Add support for the AB8540
This patch enables the GPADC to work on AB8540 based platforms. Signed-off-by: Lee Jones <lee.jones@linaro.org> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/ab8500-gpadc.c')
-rw-r--r--drivers/mfd/ab8500-gpadc.c316
1 files changed, 276 insertions, 40 deletions
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index fc8da4496e84..c985b90577f6 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -37,6 +37,13 @@
37#define AB8500_GPADC_AUTODATAL_REG 0x07 37#define AB8500_GPADC_AUTODATAL_REG 0x07
38#define AB8500_GPADC_AUTODATAH_REG 0x08 38#define AB8500_GPADC_AUTODATAH_REG 0x08
39#define AB8500_GPADC_MUX_CTRL_REG 0x09 39#define AB8500_GPADC_MUX_CTRL_REG 0x09
40#define AB8540_GPADC_MANDATA2L_REG 0x09
41#define AB8540_GPADC_MANDATA2H_REG 0x0A
42#define AB8540_GPADC_APEAAX_REG 0x10
43#define AB8540_GPADC_APEAAT_REG 0x11
44#define AB8540_GPADC_APEAAM_REG 0x12
45#define AB8540_GPADC_APEAAH_REG 0x13
46#define AB8540_GPADC_APEAAL_REG 0x14
40 47
41/* 48/*
42 * OTP register offsets 49 * OTP register offsets
@@ -49,6 +56,10 @@
49#define AB8500_GPADC_CAL_5 0x13 56#define AB8500_GPADC_CAL_5 0x13
50#define AB8500_GPADC_CAL_6 0x14 57#define AB8500_GPADC_CAL_6 0x14
51#define AB8500_GPADC_CAL_7 0x15 58#define AB8500_GPADC_CAL_7 0x15
59/* New calibration for 8540 */
60#define AB8540_GPADC_OTP4_REG_7 0x38
61#define AB8540_GPADC_OTP4_REG_6 0x39
62#define AB8540_GPADC_OTP4_REG_5 0x3A
52 63
53/* gpadc constants */ 64/* gpadc constants */
54#define EN_VINTCORE12 0x04 65#define EN_VINTCORE12 0x04
@@ -67,6 +78,7 @@
67#define GPADC_BUSY 0x01 78#define GPADC_BUSY 0x01
68#define EN_FALLING 0x10 79#define EN_FALLING 0x10
69#define EN_TRIG_EDGE 0x02 80#define EN_TRIG_EDGE 0x02
81#define EN_VBIAS_XTAL_TEMP 0x02
70 82
71/* GPADC constants from AB8500 spec, UM0836 */ 83/* GPADC constants from AB8500 spec, UM0836 */
72#define ADC_RESOLUTION 1024 84#define ADC_RESOLUTION 1024
@@ -85,8 +97,21 @@
85#define ADC_CH_BKBAT_MIN 0 97#define ADC_CH_BKBAT_MIN 0
86#define ADC_CH_BKBAT_MAX 3200 98#define ADC_CH_BKBAT_MAX 3200
87 99
100/* GPADC constants from AB8540 spec */
101#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat*/
102#define ADC_CH_IBAT_MAX 6000
103#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
104#define ADC_CH_IBAT_MAX_V 60
105#define IBAT_VDROP_L (-56) /* mV */
106#define IBAT_VDROP_H 56
107
88/* This is used to not lose precision when dividing to get gain and offset */ 108/* This is used to not lose precision when dividing to get gain and offset */
89#define CALIB_SCALE 1000 109#define CALIB_SCALE 1000
110/*
111 * Number of bits shift used to not lose precision
112 * when dividing to get ibat gain.
113 */
114#define CALIB_SHIFT_IBAT 20
90 115
91/* Time in ms before disabling regulator */ 116/* Time in ms before disabling regulator */
92#define GPADC_AUDOSUSPEND_DELAY 1 117#define GPADC_AUDOSUSPEND_DELAY 1
@@ -97,6 +122,7 @@ enum cal_channels {
97 ADC_INPUT_VMAIN = 0, 122 ADC_INPUT_VMAIN = 0,
98 ADC_INPUT_BTEMP, 123 ADC_INPUT_BTEMP,
99 ADC_INPUT_VBAT, 124 ADC_INPUT_VBAT,
125 ADC_INPUT_IBAT,
100 NBR_CAL_INPUTS, 126 NBR_CAL_INPUTS,
101}; 127};
102 128
@@ -107,8 +133,8 @@ enum cal_channels {
107 * @offset: Offset of the ADC channel 133 * @offset: Offset of the ADC channel
108 */ 134 */
109struct adc_cal_data { 135struct adc_cal_data {
110 u64 gain; 136 s64 gain;
111 u64 offset; 137 s64 offset;
112}; 138};
113 139
114/** 140/**
@@ -180,6 +206,7 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
180 gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE; 206 gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE;
181 break; 207 break;
182 208
209 case XTAL_TEMP:
183 case BAT_CTRL: 210 case BAT_CTRL:
184 case BTEMP_BALL: 211 case BTEMP_BALL:
185 case ACC_DETECT1: 212 case ACC_DETECT1:
@@ -198,6 +225,7 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
198 break; 225 break;
199 226
200 case MAIN_BAT_V: 227 case MAIN_BAT_V:
228 case VBAT_TRUE_MEAS:
201 /* For some reason we don't have calibrated data */ 229 /* For some reason we don't have calibrated data */
202 if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) { 230 if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) {
203 res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX - 231 res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX -
@@ -241,6 +269,20 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
241 ADC_RESOLUTION; 269 ADC_RESOLUTION;
242 break; 270 break;
243 271
272 case IBAT_VIRTUAL_CHANNEL:
273 /* For some reason we don't have calibrated data */
274 if (!gpadc->cal_data[ADC_INPUT_IBAT].gain) {
275 res = ADC_CH_IBAT_MIN + (ADC_CH_IBAT_MAX -
276 ADC_CH_IBAT_MIN) * ad_value /
277 ADC_RESOLUTION;
278 break;
279 }
280 /* Here we can use the calibrated data */
281 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_IBAT].gain +
282 gpadc->cal_data[ADC_INPUT_IBAT].offset)
283 >> CALIB_SHIFT_IBAT;
284 break;
285
244 default: 286 default:
245 dev_err(gpadc->dev, 287 dev_err(gpadc->dev,
246 "unknown channel, not possible to convert\n"); 288 "unknown channel, not possible to convert\n");
@@ -304,9 +346,19 @@ EXPORT_SYMBOL(ab8500_gpadc_convert);
304int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, 346int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
305 u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) 347 u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type)
306{ 348{
349 int raw_data;
350 raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
351 avg_sample, trig_edge, trig_timer, conv_type, NULL);
352 return raw_data;
353}
354
355int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
356 u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type,
357 int *ibat)
358{
307 int ret; 359 int ret;
308 int looplimit = 0; 360 int looplimit = 0;
309 u8 val, low_data, high_data; 361 u8 val, low_data, high_data, low_data2, high_data2;
310 362
311 if (!gpadc) 363 if (!gpadc)
312 return -ENODEV; 364 return -ENODEV;
@@ -359,7 +411,6 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
359 default: 411 default:
360 val = channel | AVG_16; 412 val = channel | AVG_16;
361 break; 413 break;
362
363 } 414 }
364 415
365 if (conv_type == ADC_HW) 416 if (conv_type == ADC_HW)
@@ -383,8 +434,8 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
383 ret = abx500_mask_and_set_register_interruptible(gpadc->dev, 434 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
384 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, 435 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
385 EN_FALLING, EN_FALLING); 436 EN_FALLING, EN_FALLING);
386
387 } 437 }
438
388 switch (channel) { 439 switch (channel) {
389 case MAIN_CHARGER_C: 440 case MAIN_CHARGER_C:
390 case USB_CHARGER_C: 441 case USB_CHARGER_C:
@@ -401,6 +452,55 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
401 EN_BUF | EN_ICHAR, 452 EN_BUF | EN_ICHAR,
402 EN_BUF | EN_ICHAR); 453 EN_BUF | EN_ICHAR);
403 break; 454 break;
455
456 case XTAL_TEMP:
457 if (conv_type == ADC_HW)
458 ret = abx500_mask_and_set_register_interruptible(
459 gpadc->dev,
460 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
461 EN_BUF | EN_TRIG_EDGE,
462 EN_BUF | EN_TRIG_EDGE);
463 else
464 ret = abx500_mask_and_set_register_interruptible(
465 gpadc->dev,
466 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
467 EN_BUF ,
468 EN_BUF);
469 break;
470
471 case VBAT_TRUE_MEAS:
472 if (conv_type == ADC_HW)
473 ret = abx500_mask_and_set_register_interruptible(
474 gpadc->dev,
475 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
476 EN_BUF | EN_TRIG_EDGE,
477 EN_BUF | EN_TRIG_EDGE);
478 else
479 ret = abx500_mask_and_set_register_interruptible(
480 gpadc->dev,
481 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
482 EN_BUF ,
483 EN_BUF);
484 break;
485
486 case BAT_CTRL_AND_IBAT:
487 case VBAT_MEAS_AND_IBAT:
488 case VBAT_TRUE_MEAS_AND_IBAT:
489 case BAT_TEMP_AND_IBAT:
490 if (conv_type == ADC_HW)
491 ret = abx500_mask_and_set_register_interruptible(
492 gpadc->dev,
493 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
494 EN_TRIG_EDGE,
495 EN_TRIG_EDGE);
496 else
497 ret = abx500_mask_and_set_register_interruptible(
498 gpadc->dev,
499 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
500 EN_BUF,
501 0);
502 break;
503
404 case BTEMP_BALL: 504 case BTEMP_BALL:
405 if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { 505 if (!is_ab8500_2p0_or_earlier(gpadc->parent)) {
406 if (conv_type == ADC_HW) 506 if (conv_type == ADC_HW)
@@ -471,21 +571,19 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
471 /* wait for completion of conversion */ 571 /* wait for completion of conversion */
472 if (conv_type == ADC_HW) { 572 if (conv_type == ADC_HW) {
473 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 573 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete,
474 2*HZ)) { 574 2 * HZ)) {
475 dev_err(gpadc->dev, 575 dev_err(gpadc->dev,
476 "timeout didn't receive" 576 "timeout didn't receive hw GPADC conv interrupt\n");
477 " hw GPADC conv interrupt\n"); 577 ret = -EINVAL;
478 ret = -EINVAL; 578 goto out;
479 goto out;
480 } 579 }
481 } else { 580 } else {
482 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 581 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete,
483 msecs_to_jiffies(CONVERSION_TIME))) { 582 msecs_to_jiffies(CONVERSION_TIME))) {
484 dev_err(gpadc->dev, 583 dev_err(gpadc->dev,
485 "timeout didn't receive" 584 "timeout didn't receive sw GPADC conv interrupt\n");
486 " sw GPADC conv interrupt\n"); 585 ret = -EINVAL;
487 ret = -EINVAL; 586 goto out;
488 goto out;
489 } 587 }
490 } 588 }
491 589
@@ -523,6 +621,46 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
523 goto out; 621 goto out;
524 } 622 }
525 } 623 }
624 /* Check if double convertion is required */
625 if ((channel == BAT_CTRL_AND_IBAT) ||
626 (channel == VBAT_MEAS_AND_IBAT) ||
627 (channel == VBAT_TRUE_MEAS_AND_IBAT) ||
628 (channel == BAT_TEMP_AND_IBAT)) {
629
630 if (conv_type == ADC_HW) {
631 /* not supported */
632 ret = -ENOTSUPP;
633 dev_err(gpadc->dev,
634 "gpadc_conversion: only SW double conversion supported\n");
635 goto out;
636 } else {
637 /* Read the converted RAW data 2 */
638 ret = abx500_get_register_interruptible(gpadc->dev,
639 AB8500_GPADC, AB8540_GPADC_MANDATA2L_REG,
640 &low_data2);
641 if (ret < 0) {
642 dev_err(gpadc->dev,
643 "gpadc_conversion: read sw low data 2 failed\n");
644 goto out;
645 }
646
647 ret = abx500_get_register_interruptible(gpadc->dev,
648 AB8500_GPADC, AB8540_GPADC_MANDATA2H_REG,
649 &high_data2);
650 if (ret < 0) {
651 dev_err(gpadc->dev,
652 "gpadc_conversion: read sw high data 2 failed\n");
653 goto out;
654 }
655 if (ibat != NULL) {
656 *ibat = (high_data2 << 8) | low_data2;
657 } else {
658 dev_warn(gpadc->dev,
659 "gpadc_conversion: ibat not stored\n");
660 }
661
662 }
663 }
526 664
527 /* Disable GPADC */ 665 /* Disable GPADC */
528 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, 666 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
@@ -586,15 +724,27 @@ static int otp_cal_regs[] = {
586 AB8500_GPADC_CAL_7, 724 AB8500_GPADC_CAL_7,
587}; 725};
588 726
727static int otp4_cal_regs[] = {
728 AB8540_GPADC_OTP4_REG_7,
729 AB8540_GPADC_OTP4_REG_6,
730 AB8540_GPADC_OTP4_REG_5,
731};
732
589static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) 733static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
590{ 734{
591 int i; 735 int i;
592 int ret[ARRAY_SIZE(otp_cal_regs)]; 736 int ret[ARRAY_SIZE(otp_cal_regs)];
593 u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)]; 737 u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)];
594 738 int ret_otp4[ARRAY_SIZE(otp4_cal_regs)];
739 u8 gpadc_otp4[ARRAY_SIZE(otp4_cal_regs)];
595 int vmain_high, vmain_low; 740 int vmain_high, vmain_low;
596 int btemp_high, btemp_low; 741 int btemp_high, btemp_low;
597 int vbat_high, vbat_low; 742 int vbat_high, vbat_low;
743 int ibat_high, ibat_low;
744 s64 V_gain, V_offset, V2A_gain, V2A_offset;
745 struct ab8500 *ab8500;
746
747 ab8500 = gpadc->parent;
598 748
599 /* First we read all OTP registers and store the error code */ 749 /* First we read all OTP registers and store the error code */
600 for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) { 750 for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) {
@@ -614,7 +764,7 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
614 * bt_h/l = btemp_high/low 764 * bt_h/l = btemp_high/low
615 * vb_h/l = vbat_high/low 765 * vb_h/l = vbat_high/low
616 * 766 *
617 * Data bits: 767 * Data bits 8500/9540:
618 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 768 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
619 * |.......|.......|.......|.......|.......|.......|.......|....... 769 * |.......|.......|.......|.......|.......|.......|.......|.......
620 * | | vm_h9 | vm_h8 770 * | | vm_h9 | vm_h8
@@ -632,6 +782,35 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
632 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | 782 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
633 * |.......|.......|.......|.......|.......|.......|.......|....... 783 * |.......|.......|.......|.......|.......|.......|.......|.......
634 * 784 *
785 * Data bits 8540:
786 * OTP2
787 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
788 * |.......|.......|.......|.......|.......|.......|.......|.......
789 * |
790 * |.......|.......|.......|.......|.......|.......|.......|.......
791 * | vm_h9 | vm_h8 | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
792 * |.......|.......|.......|.......|.......|.......|.......|.......
793 * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
794 * |.......|.......|.......|.......|.......|.......|.......|.......
795 * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
796 * |.......|.......|.......|.......|.......|.......|.......|.......
797 * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
798 * |.......|.......|.......|.......|.......|.......|.......|.......
799 * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
800 * |.......|.......|.......|.......|.......|.......|.......|.......
801 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
802 * |.......|.......|.......|.......|.......|.......|.......|.......
803 *
804 * Data bits 8540:
805 * OTP4
806 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
807 * |.......|.......|.......|.......|.......|.......|.......|.......
808 * | | ib_h9 | ib_h8 | ib_h7
809 * |.......|.......|.......|.......|.......|.......|.......|.......
810 * | ib_h6 | ib_h5 | ib_h4 | ib_h3 | ib_h2 | ib_h1 | ib_h0 | ib_l5
811 * |.......|.......|.......|.......|.......|.......|.......|.......
812 * | ib_l4 | ib_l3 | ib_l2 | ib_l1 | ib_l0 |
813 *
635 * 814 *
636 * Ideal output ADC codes corresponding to injected input voltages 815 * Ideal output ADC codes corresponding to injected input voltages
637 * during manufacturing is: 816 * during manufacturing is:
@@ -644,38 +823,96 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
644 * vbat_low: Vin = 2380mV / ADC ideal code = 33 823 * vbat_low: Vin = 2380mV / ADC ideal code = 33
645 */ 824 */
646 825
647 /* Calculate gain and offset for VMAIN if all reads succeeded */ 826 if (is_ab8540(ab8500)) {
648 if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) { 827 /* Calculate gain and offset for VMAIN if all reads succeeded*/
649 vmain_high = (((gpadc_cal[0] & 0x03) << 8) | 828 if (!(ret[1] < 0 || ret[2] < 0)) {
650 ((gpadc_cal[1] & 0x3F) << 2) | 829 vmain_high = (((gpadc_cal[1] & 0xFF) << 2) |
651 ((gpadc_cal[2] & 0xC0) >> 6)); 830 ((gpadc_cal[2] & 0xC0) >> 6));
831 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
832 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
833 (19500 - 315) / (vmain_high - vmain_low);
834 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE *
835 19500 - (CALIB_SCALE * (19500 - 315) /
836 (vmain_high - vmain_low)) * vmain_high;
837 } else {
838 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
839 }
652 840
653 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); 841 /* Read IBAT calibration Data */
842 for (i = 0; i < ARRAY_SIZE(otp4_cal_regs); i++) {
843 ret_otp4[i] = abx500_get_register_interruptible(
844 gpadc->dev, AB8500_OTP_EMUL,
845 otp4_cal_regs[i], &gpadc_otp4[i]);
846 if (ret_otp4[i] < 0)
847 dev_err(gpadc->dev,
848 "%s: read otp4 reg 0x%02x failed\n",
849 __func__, otp4_cal_regs[i]);
850 }
654 851
655 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * 852 /* Calculate gain and offset for IBAT if all reads succeeded */
656 (19500 - 315) / (vmain_high - vmain_low); 853 if (!(ret_otp4[0] < 0 || ret_otp4[1] < 0 || ret_otp4[2] < 0)) {
854 ibat_high = (((gpadc_otp4[0] & 0x07) << 7) |
855 ((gpadc_otp4[1] & 0xFE) >> 1));
856 ibat_low = (((gpadc_otp4[1] & 0x01) << 5) |
857 ((gpadc_otp4[2] & 0xF8) >> 3));
858
859 V_gain = ((IBAT_VDROP_H - IBAT_VDROP_L)
860 << CALIB_SHIFT_IBAT) / (ibat_high - ibat_low);
861
862 V_offset = (IBAT_VDROP_H << CALIB_SHIFT_IBAT) -
863 (((IBAT_VDROP_H - IBAT_VDROP_L) <<
864 CALIB_SHIFT_IBAT) / (ibat_high - ibat_low))
865 * ibat_high;
866 /*
867 * Result obtained is in mV (at a scale factor),
868 * we need to calculate gain and offset to get mA
869 */
870 V2A_gain = (ADC_CH_IBAT_MAX - ADC_CH_IBAT_MIN)/
871 (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V);
872 V2A_offset = ((ADC_CH_IBAT_MAX_V * ADC_CH_IBAT_MIN -
873 ADC_CH_IBAT_MAX * ADC_CH_IBAT_MIN_V)
874 << CALIB_SHIFT_IBAT)
875 / (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V);
876
877 gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
878 gpadc->cal_data[ADC_INPUT_IBAT].offset = V_offset *
879 V2A_gain + V2A_offset;
880 } else {
881 gpadc->cal_data[ADC_INPUT_IBAT].gain = 0;
882 }
657 883
658 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 - 884 dev_dbg(gpadc->dev, "IBAT gain %llu offset %llu\n",
659 (CALIB_SCALE * (19500 - 315) / 885 gpadc->cal_data[ADC_INPUT_IBAT].gain,
660 (vmain_high - vmain_low)) * vmain_high; 886 gpadc->cal_data[ADC_INPUT_IBAT].offset);
661 } else { 887 } else {
662 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; 888 /* Calculate gain and offset for VMAIN if all reads succeeded */
889 if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) {
890 vmain_high = (((gpadc_cal[0] & 0x03) << 8) |
891 ((gpadc_cal[1] & 0x3F) << 2) |
892 ((gpadc_cal[2] & 0xC0) >> 6));
893 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
894
895 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
896 (19500 - 315) / (vmain_high - vmain_low);
897
898 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE *
899 19500 - (CALIB_SCALE * (19500 - 315) /
900 (vmain_high - vmain_low)) * vmain_high;
901 } else {
902 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
903 }
663 } 904 }
664
665 /* Calculate gain and offset for BTEMP if all reads succeeded */ 905 /* Calculate gain and offset for BTEMP if all reads succeeded */
666 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { 906 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) {
667 btemp_high = (((gpadc_cal[2] & 0x01) << 9) | 907 btemp_high = (((gpadc_cal[2] & 0x01) << 9) |
668 (gpadc_cal[3] << 1) | 908 (gpadc_cal[3] << 1) | ((gpadc_cal[4] & 0x80) >> 7));
669 ((gpadc_cal[4] & 0x80) >> 7));
670
671 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); 909 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2);
672 910
673 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 911 gpadc->cal_data[ADC_INPUT_BTEMP].gain =
674 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); 912 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low);
675
676 gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 - 913 gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 -
677 (CALIB_SCALE * (1300 - 21) / 914 (CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low))
678 (btemp_high - btemp_low)) * btemp_high; 915 * btemp_high;
679 } else { 916 } else {
680 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0; 917 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0;
681 } 918 }
@@ -687,7 +924,6 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
687 924
688 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * 925 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE *
689 (4700 - 2380) / (vbat_high - vbat_low); 926 (4700 - 2380) / (vbat_high - vbat_low);
690
691 gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 - 927 gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 -
692 (CALIB_SCALE * (4700 - 2380) / 928 (CALIB_SCALE * (4700 - 2380) /
693 (vbat_high - vbat_low)) * vbat_high; 929 (vbat_high - vbat_low)) * vbat_high;