hwmon: pm8xxx-adc-scale: Change scaling function

Modify the scaling function routines for Battery temperature
and all channels whose units return milli-volts for voltage.

The Charger driver requires the Units of Voltage and temperature
in uV and 0.1 DegC according to the framework where all voltages,
currents, chargers, energies, time and temperature are in uV, uA,
uAh, uWh, seconds and tenths of degree Celsius unless otherwise
stated. In accordance with the above expected units, the scaling
functions are modified for all voltage channels and the Batt Therm.

This change fixes the XO Therm temperature scaling routine,
PA Therm and Batt id to use the ratiometric calibration.
XO Therm and PA therm units are returned as milli-degree and
degree Centigrade respectively.

Accordingly, update the clients of xoadc to handle this change in
units.

CRs-Fixed: 315797
Change-Id: I6fa3b808062563fef3b0e70cc694e3132421f735
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/hwmon/pm8xxx-adc-scale.c b/drivers/hwmon/pm8xxx-adc-scale.c
index 7b27f72..fb2f1d5 100644
--- a/drivers/hwmon/pm8xxx-adc-scale.c
+++ b/drivers/hwmon/pm8xxx-adc-scale.c
@@ -17,230 +17,222 @@
 #include <linux/mfd/pm8xxx/pm8xxx-adc.h>
 #define KELVINMIL_DEGMIL	273160
 
-static const struct pm8xxx_adc_map_pt adcmap_batttherm[] = {
-	{41001,	-30},
-	{40017,	-20},
-	{38721,	-10},
-	{37186,	  0},
-	{35554,	 10},
-	{33980,	 20},
-	{33253,	 25},
-	{32580,	 30},
-	{31412,	 40},
-	{30481,	 50},
-	{29759,	 60},
-	{29209,	 70},
-	{28794,	 80}
-};
-
+/* Units for temperature below (on x axis) is in 0.1DegC as
+   required by the battery driver. Note the resolution used
+   here to compute the table was done for DegC to milli-volts.
+   In consideration to limit the size of the table for the given
+   temperature range below, the result is linearly interpolated
+   and provided to the battery driver in the units desired for
+   their framework which is 0.1DegC. True resolution of 0.1DegC
+   will result in the below table size to increase by 10 times */
 static const struct pm8xxx_adc_map_pt adcmap_btm_threshold[] = {
-	{-30,	1642},
-	{-20,	1544},
-	{-10,	1414},
+	{-300,	1642},
+	{-200,	1544},
+	{-100,	1414},
 	{0,	1260},
-	{1,	1244},
-	{2,	1228},
-	{3,	1212},
-	{4,	1195},
-	{5,	1179},
-	{6,	1162},
-	{7,	1146},
-	{8,	1129},
-	{9,	1113},
-	{10,	1097},
-	{11,	1080},
-	{12,	1064},
-	{13,	1048},
-	{14,	1032},
-	{15,	1016},
-	{16,	1000},
-	{17,	985},
-	{18,	969},
-	{19,	954},
-	{20,	939},
-	{21,	924},
-	{22,	909},
-	{23,	894},
-	{24,	880},
-	{25,	866},
-	{26,	852},
-	{27,	838},
-	{28,	824},
-	{29,	811},
-	{30,	798},
-	{31,	785},
-	{32,	773},
-	{33,	760},
-	{34,	748},
-	{35,	736},
-	{36,	725},
-	{37,	713},
-	{38,	702},
-	{39,	691},
-	{40,	681},
-	{41,	670},
-	{42,	660},
-	{43,	650},
-	{44,	640},
-	{45,	631},
-	{46,	622},
-	{47,	613},
-	{48,	604},
-	{49,	595},
-	{50,	587},
-	{51,	579},
-	{52,	571},
-	{53,	563},
-	{54,	556},
-	{55,	548},
-	{56,	541},
-	{57,	534},
-	{58,	527},
-	{59,	521},
-	{60,	514},
-	{61,	508},
-	{62,	502},
-	{63,	496},
-	{64,	490},
-	{65,	485},
-	{66,	281},
-	{67,	274},
-	{68,	267},
-	{69,	260},
-	{70,	254},
-	{71,	247},
-	{72,	241},
-	{73,	235},
-	{74,	229},
-	{75,	224},
-	{76,	218},
-	{77,	213},
-	{78,	208},
-	{79,	203}
+	{10,	1244},
+	{20,	1228},
+	{30,	1212},
+	{40,	1195},
+	{50,	1179},
+	{60,	1162},
+	{70,	1146},
+	{80,	1129},
+	{90,	1113},
+	{100,	1097},
+	{110,	1080},
+	{120,	1064},
+	{130,	1048},
+	{140,	1032},
+	{150,	1016},
+	{160,	1000},
+	{170,	985},
+	{180,	969},
+	{190,	954},
+	{200,	939},
+	{210,	924},
+	{220,	909},
+	{230,	894},
+	{240,	880},
+	{250,	866},
+	{260,	852},
+	{270,	838},
+	{280,	824},
+	{290,	811},
+	{300,	798},
+	{310,	785},
+	{320,	773},
+	{330,	760},
+	{340,	748},
+	{350,	736},
+	{360,	725},
+	{370,	713},
+	{380,	702},
+	{390,	691},
+	{400,	681},
+	{410,	670},
+	{420,	660},
+	{430,	650},
+	{440,	640},
+	{450,	631},
+	{460,	622},
+	{470,	613},
+	{480,	604},
+	{490,	595},
+	{500,	587},
+	{510,	579},
+	{520,	571},
+	{530,	563},
+	{540,	556},
+	{550,	548},
+	{560,	541},
+	{570,	534},
+	{580,	527},
+	{590,	521},
+	{600,	514},
+	{610,	508},
+	{620,	502},
+	{630,	496},
+	{640,	490},
+	{650,	485},
+	{660,	281},
+	{670,	274},
+	{680,	267},
+	{690,	260},
+	{700,	254},
+	{710,	247},
+	{720,	241},
+	{730,	235},
+	{740,	229},
+	{750,	224},
+	{760,	218},
+	{770,	213},
+	{780,	208},
+	{790,	203}
 };
 
 static const struct pm8xxx_adc_map_pt adcmap_pa_therm[] = {
-	{41350,	-30},
-	{41282,	-29},
-	{41211,	-28},
-	{41137,	-27},
-	{41060,	-26},
-	{40980,	-25},
-	{40897,	-24},
-	{40811,	-23},
-	{40721,	-22},
-	{40629,	-21},
-	{40533,	-20},
-	{40434,	-19},
-	{40331,	-18},
-	{40226,	-17},
-	{40116,	-16},
-	{40004,	-15},
-	{39888,	-14},
-	{39769,	-13},
-	{39647,	-12},
-	{39521,	-11},
-	{39392,	-10},
-	{39260,	-9},
-	{39124,	-8},
-	{38986,	-7},
-	{38845,	-6},
-	{38700,	-5},
-	{38553,	-4},
-	{38403,	-3},
-	{38250,	-2},
-	{38094,	-1},
-	{37936,	0},
-	{37776,	1},
-	{37613,	2},
-	{37448,	3},
-	{37281,	4},
-	{37112,	5},
-	{36942,	6},
-	{36770,	7},
-	{36596,	8},
-	{36421,	9},
-	{36245,	10},
-	{36068,	11},
-	{35890,	12},
-	{35712,	13},
-	{35532,	14},
-	{35353,	15},
-	{35173,	16},
-	{34993,	17},
-	{34813,	18},
-	{34634,	19},
-	{34455,	20},
-	{34276,	21},
-	{34098,	22},
-	{33921,	23},
-	{33745,	24},
-	{33569,	25},
-	{33395,	26},
-	{33223,	27},
-	{33051,	28},
-	{32881,	29},
-	{32713,	30},
-	{32547,	31},
-	{32382,	32},
-	{32219,	33},
-	{32058,	34},
-	{31899,	35},
-	{31743,	36},
-	{31588,	37},
-	{31436,	38},
-	{31285,	39},
-	{31138,	40},
-	{30992,	41},
-	{30849,	42},
-	{30708,	43},
-	{30570,	44},
-	{30434,	45},
-	{30300,	46},
-	{30169,	47},
-	{30041,	48},
-	{29915,	49},
-	{29791,	50},
-	{29670,	51},
-	{29551,	52},
-	{29435,	53},
-	{29321,	54},
-	{29210,	55},
-	{29101,	56},
-	{28994,	57},
-	{28890,	58},
-	{28788,	59},
-	{28688,	60},
-	{28590,	61},
-	{28495,	62},
-	{28402,	63},
-	{28311,	64},
-	{28222,	65},
-	{28136,	66},
-	{28051,	67},
-	{27968,	68},
-	{27888,	69},
-	{27809,	70},
-	{27732,	71},
-	{27658,	72},
-	{27584,	73},
-	{27513,	74},
-	{27444,	75},
-	{27376,	76},
-	{27310,	77},
-	{27245,	78},
-	{27183,	79},
-	{27121,	80},
-	{27062,	81},
-	{27004,	82},
-	{26947,	83},
-	{26892,	84},
-	{26838,	85},
-	{26785,	86},
-	{26734,	87},
-	{26684,	88},
-	{26636,	89},
-	{26588,	90}
+	{1677,	-30},
+	{1671,	-29},
+	{1663,	-28},
+	{1656,	-27},
+	{1648,	-26},
+	{1640,	-25},
+	{1632,	-24},
+	{1623,	-23},
+	{1615,	-22},
+	{1605,	-21},
+	{1596,	-20},
+	{1586,	-19},
+	{1576,	-18},
+	{1565,	-17},
+	{1554,	-16},
+	{1543,	-15},
+	{1531,	-14},
+	{1519,	-13},
+	{1507,	-12},
+	{1494,	-11},
+	{1482,	-10},
+	{1468,	-9},
+	{1455,	-8},
+	{1441,	-7},
+	{1427,	-6},
+	{1412,	-5},
+	{1398,	-4},
+	{1383,	-3},
+	{1367,	-2},
+	{1352,	-1},
+	{1336,	0},
+	{1320,	1},
+	{1304,	2},
+	{1287,	3},
+	{1271,	4},
+	{1254,	5},
+	{1237,	6},
+	{1219,	7},
+	{1202,	8},
+	{1185,	9},
+	{1167,	10},
+	{1149,	11},
+	{1131,	12},
+	{1114,	13},
+	{1096,	14},
+	{1078,	15},
+	{1060,	16},
+	{1042,	17},
+	{1024,	18},
+	{1006,	19},
+	{988,	20},
+	{970,	21},
+	{952,	22},
+	{934,	23},
+	{917,	24},
+	{899,	25},
+	{882,	26},
+	{865,	27},
+	{848,	28},
+	{831,	29},
+	{814,	30},
+	{797,	31},
+	{781,	32},
+	{764,	33},
+	{748,	34},
+	{732,	35},
+	{717,	36},
+	{701,	37},
+	{686,	38},
+	{671,	39},
+	{656,	40},
+	{642,	41},
+	{627,	42},
+	{613,	43},
+	{599,	44},
+	{586,	45},
+	{572,	46},
+	{559,	47},
+	{546,	48},
+	{534,	49},
+	{522,	50},
+	{509,	51},
+	{498,	52},
+	{486,	53},
+	{475,	54},
+	{463,	55},
+	{452,	56},
+	{442,	57},
+	{431,	58},
+	{421,	59},
+	{411,	60},
+	{401,	61},
+	{392,	62},
+	{383,	63},
+	{374,	64},
+	{365,	65},
+	{356,	66},
+	{348,	67},
+	{339,	68},
+	{331,	69},
+	{323,	70},
+	{316,	71},
+	{308,	72},
+	{301,	73},
+	{294,	74},
+	{287,	75},
+	{280,	76},
+	{273,	77},
+	{267,	78},
+	{261,	79},
+	{255,	80},
+	{249,	81},
+	{243,	82},
+	{237,	83},
+	{232,	84},
+	{226,	85},
+	{221,	86},
+	{216,	87},
+	{211,	88},
+	{206,	89},
+	{201,	90}
 };
 
 static const struct pm8xxx_adc_map_pt adcmap_ntcg_104ef_104fb[] = {
@@ -458,42 +450,91 @@
 	return 0;
 }
 
+static int32_t pm8xxx_adc_map_batt_therm(const struct pm8xxx_adc_map_pt *pts,
+		uint32_t tablesize, int32_t input, int64_t *output)
+{
+	bool descending = 1;
+	uint32_t i = 0;
+
+	if ((pts == NULL) || (output == NULL))
+		return -EINVAL;
+
+	/* Check if table is descending or ascending */
+	if (tablesize > 1) {
+		if (pts[0].y < pts[1].y)
+			descending = 0;
+	}
+
+	while (i < tablesize) {
+		if ((descending == 1) && (pts[i].y < input)) {
+			/* table entry is less than measured
+				value and table is descending, stop */
+			break;
+		} else if ((descending == 0) && (pts[i].y > input)) {
+			/* table entry is greater than measured
+				value and table is ascending, stop */
+			break;
+		} else {
+			i++;
+		}
+	}
+
+	if (i == 0) {
+		*output = pts[0].x;
+	} else if (i == tablesize) {
+		*output = pts[tablesize-1].x;
+	} else {
+		/* result is between search_index and search_index-1 */
+		/* interpolate linearly */
+		*output = (((int32_t) ((pts[i].x - pts[i-1].x)*
+			(input - pts[i-1].y))/
+			(pts[i].y - pts[i-1].y))+
+			pts[i-1].x);
+	}
+
+	return 0;
+}
+
 int32_t pm8xxx_adc_scale_default(int32_t adc_code,
 		const struct pm8xxx_adc_properties *adc_properties,
 		const struct pm8xxx_adc_chan_properties *chan_properties,
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
-	bool negative_rawfromoffset = 0;
-	int32_t rawfromoffset = 0;
+	bool negative_rawfromoffset = 0, negative_offset = 0;
+	int64_t scale_voltage = 0;
 
 	if (!chan_properties || !chan_properties->offset_gain_numerator ||
 		!chan_properties->offset_gain_denominator || !adc_properties
 		|| !adc_chan_result)
 		return -EINVAL;
 
-	rawfromoffset = adc_code -
-			chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].offset;
+	scale_voltage = (adc_code -
+		chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd)
+		* chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
+	if (scale_voltage < 0) {
+		negative_offset = 1;
+		scale_voltage = -scale_voltage;
+	}
+	do_div(scale_voltage,
+		chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy);
+	if (negative_offset)
+		scale_voltage = -scale_voltage;
+	scale_voltage += chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
 
-	adc_chan_result->adc_code = adc_code;
-	if (rawfromoffset < 0) {
+	if (scale_voltage < 0) {
 		if (adc_properties->bipolar) {
-			rawfromoffset = -rawfromoffset;
+			scale_voltage = -scale_voltage;
 			negative_rawfromoffset = 1;
 		} else {
-			rawfromoffset = 0;
+			scale_voltage = 0;
 		}
 	}
 
-	if (rawfromoffset >= 1 << adc_properties->bitresolution)
-		rawfromoffset = (1 << adc_properties->bitresolution) - 1;
-
-	adc_chan_result->measurement = (int64_t)rawfromoffset *
-		chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx *
+	adc_chan_result->measurement = scale_voltage *
 				chan_properties->offset_gain_denominator;
 
 	/* do_div only perform positive integer division! */
 	do_div(adc_chan_result->measurement,
-		chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy *
 				chan_properties->offset_gain_numerator);
 
 	if (negative_rawfromoffset)
@@ -503,25 +544,52 @@
 	 * adc_properties.adc_reference. For generic channel processing,
 	 * channel measurement is a scale/ratio relative to the adc
 	 * reference input */
-	adc_chan_result->physical = (int32_t) adc_chan_result->measurement;
+	adc_chan_result->physical = adc_chan_result->measurement;
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_default);
 
+static int64_t pm8xxx_adc_scale_ratiometric_calib(int32_t adc_code,
+		const struct pm8xxx_adc_properties *adc_properties,
+		const struct pm8xxx_adc_chan_properties *chan_properties)
+{
+	int64_t adc_voltage = 0;
+	bool negative_offset = 0;
+
+	if (!chan_properties || !chan_properties->offset_gain_numerator ||
+		!chan_properties->offset_gain_denominator || !adc_properties)
+		return -EINVAL;
+
+	adc_voltage = (adc_code -
+		chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd)
+		* adc_properties->adc_vdd_reference;
+	if (adc_voltage < 0) {
+		negative_offset = 1;
+		adc_voltage = -adc_voltage;
+	}
+	do_div(adc_voltage,
+		chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy);
+	if (negative_offset)
+		adc_voltage = -adc_voltage;
+
+	return adc_voltage;
+}
+
 int32_t pm8xxx_adc_scale_batt_therm(int32_t adc_code,
 		const struct pm8xxx_adc_properties *adc_properties,
 		const struct pm8xxx_adc_chan_properties *chan_properties,
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
-	/* Note: adc_chan_result->measurement is in the unit of
-		adc_properties.adc_reference */
-	adc_chan_result->measurement = adc_code;
-	/* convert mV ---> degC using the table */
-	return pm8xxx_adc_map_linear(
-			adcmap_batttherm,
-			ARRAY_SIZE(adcmap_batttherm),
-			adc_code,
+	int64_t bat_voltage = 0;
+
+	bat_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
+			adc_properties, chan_properties);
+
+	return pm8xxx_adc_map_batt_therm(
+			adcmap_btm_threshold,
+			ARRAY_SIZE(adcmap_btm_threshold),
+			bat_voltage,
 			&adc_chan_result->physical);
 }
 EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_batt_therm);
@@ -531,54 +599,74 @@
 		const struct pm8xxx_adc_chan_properties *chan_properties,
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
-	/* Note: adc_chan_result->measurement is in the unit of
-		adc_properties.adc_reference */
-	adc_chan_result->measurement = adc_code;
-	/* convert mV ---> degC using the table */
+	int64_t pa_voltage = 0;
+
+	pa_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
+			adc_properties, chan_properties);
+
 	return pm8xxx_adc_map_linear(
 			adcmap_pa_therm,
 			ARRAY_SIZE(adcmap_pa_therm),
-			adc_code,
+			pa_voltage,
 			&adc_chan_result->physical);
 }
 EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_pa_therm);
 
+int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
+		const struct pm8xxx_adc_properties *adc_properties,
+		const struct pm8xxx_adc_chan_properties *chan_properties,
+		struct pm8xxx_adc_chan_result *adc_chan_result)
+{
+	int64_t batt_id_voltage = 0;
+
+	batt_id_voltage = pm8xxx_adc_scale_ratiometric_calib(adc_code,
+			adc_properties, chan_properties);
+	adc_chan_result->physical = batt_id_voltage;
+	adc_chan_result->physical = adc_chan_result->measurement;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pm8xxx_adc_scale_batt_id);
+
 int32_t pm8xxx_adc_scale_pmic_therm(int32_t adc_code,
 		const struct pm8xxx_adc_properties *adc_properties,
 		const struct pm8xxx_adc_chan_properties *chan_properties,
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
-	int32_t rawfromoffset;
+	int64_t pmic_voltage = 0;
+	bool negative_offset = 0;
 
 	if (!chan_properties || !chan_properties->offset_gain_numerator ||
 		!chan_properties->offset_gain_denominator || !adc_properties
 		|| !adc_chan_result)
 		return -EINVAL;
 
-	adc_chan_result->adc_code = adc_code;
-	rawfromoffset = adc_code -
-			chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].offset;
-	if (rawfromoffset > 0) {
-		if (rawfromoffset >= 1 << adc_properties->bitresolution)
-			rawfromoffset = (1 << adc_properties->bitresolution)
-									- 1;
+	pmic_voltage = (adc_code -
+		chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd)
+		* chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
+	if (pmic_voltage < 0) {
+		negative_offset = 1;
+		pmic_voltage = -pmic_voltage;
+	}
+	do_div(pmic_voltage,
+		chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy);
+	if (negative_offset)
+		pmic_voltage = -pmic_voltage;
+	pmic_voltage += chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx;
+
+	if (pmic_voltage > 0) {
 		/* 2mV/K */
-		adc_chan_result->measurement = (int64_t)rawfromoffset*
-			chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dx *
-			chan_properties->offset_gain_denominator * 1000;
+		adc_chan_result->measurement = pmic_voltage*
+			chan_properties->offset_gain_denominator;
 
 		do_div(adc_chan_result->measurement,
-			chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].dy *
-			chan_properties->offset_gain_numerator*2);
+			chan_properties->offset_gain_numerator * 2);
 	} else {
 		adc_chan_result->measurement = 0;
 	}
-	/* Note: adc_chan_result->measurement is in the unit of
-		adc_properties.adc_reference */
-	adc_chan_result->physical = (int32_t)adc_chan_result->measurement;
 	/* Change to .001 deg C */
-	adc_chan_result->physical -= KELVINMIL_DEGMIL;
-	adc_chan_result->measurement <<= 1;
+	adc_chan_result->measurement -= KELVINMIL_DEGMIL;
+	adc_chan_result->physical = (int32_t)adc_chan_result->measurement;
 
 	return 0;
 }
@@ -592,14 +680,19 @@
 		const struct pm8xxx_adc_chan_properties *chan_properties,
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
-	int32_t rt_r25;
-	int32_t offset = chan_properties->adc_graph[ADC_CALIB_ABSOLUTE].offset;
+	int64_t xo_thm = 0;
 
-	rt_r25 = adc_code - offset;
+	if (!chan_properties || !chan_properties->offset_gain_numerator ||
+		!chan_properties->offset_gain_denominator || !adc_properties
+		|| !adc_chan_result)
+		return -EINVAL;
 
+	xo_thm = pm8xxx_adc_scale_ratiometric_calib(adc_code,
+			adc_properties, chan_properties);
+	xo_thm <<= 4;
 	pm8xxx_adc_map_linear(adcmap_ntcg_104ef_104fb,
 		ARRAY_SIZE(adcmap_ntcg_104ef_104fb),
-		rt_r25, &adc_chan_result->physical);
+		xo_thm, &adc_chan_result->physical);
 
 	return 0;
 }
@@ -614,7 +707,7 @@
 	rc = pm8xxx_adc_map_linear(
 		adcmap_btm_threshold,
 		ARRAY_SIZE(adcmap_btm_threshold),
-		btm_param->low_thr_temp,
+		(btm_param->low_thr_temp),
 		&btm_param->low_thr_voltage);
 	if (rc)
 		return rc;
@@ -628,7 +721,7 @@
 	rc = pm8xxx_adc_map_linear(
 		adcmap_btm_threshold,
 		ARRAY_SIZE(adcmap_btm_threshold),
-		btm_param->high_thr_temp,
+		(btm_param->high_thr_temp),
 		&btm_param->high_thr_voltage);
 	if (rc)
 		return rc;
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 72246e5..c33598f 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -502,7 +502,7 @@
 {
 	struct pm8xxx_adc *adc_pmic = pmic_adc;
 	struct pm8xxx_adc_amux_properties conv;
-	int rc, offset_adc, slope_adc, calib_read_1, calib_read_2;
+	int rc, calib_read_1, calib_read_2;
 	u8 data_arb_usrp_cntrl1 = 0;
 
 	conv.amux_channel = CHANNEL_125V;
@@ -565,18 +565,14 @@
 	}
 	pm8xxx_adc_calib_first_adc = false;
 
-	slope_adc = (((calib_read_1 - calib_read_2) << PM8XXX_ADC_MUL)/
-					PM8XXX_CHANNEL_ADC_625_MV);
-	offset_adc = calib_read_2 -
-			((slope_adc * PM8XXX_CHANNEL_ADC_625_MV) >>
-							PM8XXX_ADC_MUL);
-
-	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].offset
-								= offset_adc;
 	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].dy =
 					(calib_read_1 - calib_read_2);
 	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].dx
-						= PM8XXX_CHANNEL_ADC_625_MV;
+						= PM8XXX_CHANNEL_ADC_625_UV;
+	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].adc_vref =
+					calib_read_1;
+	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_ABSOLUTE].adc_gnd =
+					calib_read_2;
 	rc = pm8xxx_adc_arb_cntrl(0, CHANNEL_NONE);
 	if (rc < 0) {
 		pr_err("%s: Configuring ADC Arbiter disable"
@@ -644,14 +640,6 @@
 	}
 	pm8xxx_adc_calib_first_adc = false;
 
-	slope_adc = (((calib_read_1 - calib_read_2) << PM8XXX_ADC_MUL)/
-				adc_pmic->adc_prop->adc_vdd_reference);
-	offset_adc = calib_read_2 -
-			((slope_adc * adc_pmic->adc_prop->adc_vdd_reference)
-							>> PM8XXX_ADC_MUL);
-
-	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].offset
-								= offset_adc;
 	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dy =
 					(calib_read_1 - calib_read_2);
 	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dx =
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 74562bc..df2d556 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -552,11 +552,15 @@
 
 static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp)
 {
+	/* batt_temp is in tenths of degC - convert it to degC for lookups */
+	batt_temp = batt_temp/10;
 	return interpolate_single_lut(chip->fcc_temp_lut, batt_temp);
 }
 
 static int interpolate_fcc_adjusted(struct pm8921_bms_chip *chip, int batt_temp)
 {
+	/* batt_temp is in tenths of degC - convert it to degC for lookups */
+	batt_temp = batt_temp/10;
 	return interpolate_single_lut(chip->adjusted_fcc_temp_lut, batt_temp);
 }
 
@@ -672,6 +676,9 @@
 	int rows = chip->pc_temp_ocv_lut->rows;
 	int cols = chip->pc_temp_ocv_lut->cols;
 
+	/* batt_temp is in tenths of degC - convert it to degC for lookups */
+	batt_temp = batt_temp/10;
+
 	if (batt_temp < chip->pc_temp_ocv_lut->temp[0]) {
 		pr_debug("batt_temp %d < known temp range for pc\n", batt_temp);
 		batt_temp = chip->pc_temp_ocv_lut->temp[0];
@@ -854,13 +861,12 @@
 	pr_debug("mvolts phy = %lld meas = 0x%llx", result.physical,
 						result.measurement);
 	*uvolts = (int)result.physical;
-	*uvolts = *uvolts * 1000;
 	return 0;
 }
 
 static int adc_based_ocv(struct pm8921_bms_chip *chip, int *ocv)
 {
-	int vbatt, rbatt, ibatt, rc;
+	int vbatt, rbatt, ibatt_ua, rc;
 	struct pm8921_soc_params raw;
 
 	rc = get_battery_uvolts(chip, &vbatt);
@@ -869,7 +875,7 @@
 		return rc;
 	}
 
-	rc =  pm8921_bms_get_battery_current(&ibatt);
+	rc =  pm8921_bms_get_battery_current(&ibatt_ua);
 	if (rc) {
 		pr_err("failed to read batt current rc = %d\n", rc);
 		return rc;
@@ -880,7 +886,7 @@
 	rbatt = calculate_rbatt(the_chip, &raw);
 	if (rbatt < 0)
 		rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
-	*ocv = vbatt + ibatt * rbatt;
+	*ocv = vbatt + (ibatt_ua * rbatt)/1000;
 	return 0;
 }
 
@@ -1138,7 +1144,7 @@
 		return;
 	}
 	voltage = calib_hkadc_convert_microvolt(result.adc_code);
-	pr_debug("result 0.625V = 0x%x, voltage = %duV adc_mead = %lld\n",
+	pr_debug("result 0.625V = 0x%x, voltage = %duV adc_meas = %lld\n",
 				result.adc_code, voltage, result.measurement);
 	/* check for valid range */
 	if (voltage > XOADC_MAX_0P625V)
@@ -1186,7 +1192,7 @@
 }
 EXPORT_SYMBOL(pm8921_bms_get_vsense_avg);
 
-int pm8921_bms_get_battery_current(int *result)
+int pm8921_bms_get_battery_current(int *result_ua)
 {
 	unsigned long flags;
 	int vsense;
@@ -1207,7 +1213,7 @@
 	spin_unlock_irqrestore(&the_chip->bms_output_lock, flags);
 	pr_debug("vsense=%d\n", vsense);
 	/* cast for signed division */
-	*result = vsense / (int)the_chip->r_sense;
+	*result_ua = vsense * 1000 / (int)the_chip->r_sense;
 
 	return 0;
 }
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 47a5d47..ef97389 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -192,16 +192,16 @@
 /**
  * struct pm8921_chg_chip -device information
  * @dev:			device pointer to access the parent
- * @is_usb_path_used:		indicates whether USB charging is used at all
- * @is_usb_path_used:		indicates whether DC charging is used at all
  * @usb_present:		present status of usb
  * @dc_present:			present status of dc
  * @usb_charger_current:	usb current to charge the battery with used when
  *				the usb path is enabled or charging is resumed
  * @safety_time:		max time for which charging will happen
  * @update_time:		how frequently the userland needs to be updated
- * @max_voltage:		the max volts the batt should be charged up to
- * @min_voltage:		the min battery voltage before turning the FETon
+ * @max_voltage_mv:		the max volts the batt should be charged up to
+ * @min_voltage_mv:		the min battery voltage before turning the FETon
+ * @cool_temp_dc:		the cool temp threshold in deciCelcius
+ * @warm_temp_dc:		the warm temp threshold in deciCelcius
  * @resume_voltage_delta:	the voltage delta from vdd max at which the
  *				battery should resume charging
  * @term_current:		The charging based term current
@@ -217,10 +217,10 @@
 	unsigned int			safety_time;
 	unsigned int			ttrkl_time;
 	unsigned int			update_time;
-	unsigned int			max_voltage;
-	unsigned int			min_voltage;
-	unsigned int			cool_temp;
-	unsigned int			warm_temp;
+	unsigned int			max_voltage_mv;
+	unsigned int			min_voltage_mv;
+	unsigned int			cool_temp_dc;
+	unsigned int			warm_temp_dc;
 	unsigned int			temp_check_period;
 	unsigned int			cool_bat_chg_current;
 	unsigned int			warm_bat_chg_current;
@@ -923,7 +923,7 @@
 	POWER_SUPPLY_PROP_ENERGY_FULL,
 };
 
-static int get_prop_battery_mvolts(struct pm8921_chg_chip *chip)
+static int get_prop_battery_uvolts(struct pm8921_chg_chip *chip)
 {
 	int rc;
 	struct pm8xxx_adc_chan_result result;
@@ -941,16 +941,17 @@
 
 static unsigned int voltage_based_capacity(struct pm8921_chg_chip *chip)
 {
-	unsigned int current_voltage = get_prop_battery_mvolts(chip);
-	unsigned int low_voltage = chip->min_voltage;
-	unsigned int high_voltage = chip->max_voltage;
+	unsigned int current_voltage_uv = get_prop_battery_uvolts(chip);
+	unsigned int current_voltage_mv = current_voltage_uv / 1000;
+	unsigned int low_voltage = chip->min_voltage_mv;
+	unsigned int high_voltage = chip->max_voltage_mv;
 
-	if (current_voltage <= low_voltage)
+	if (current_voltage_mv <= low_voltage)
 		return 0;
-	else if (current_voltage >= high_voltage)
+	else if (current_voltage_mv >= high_voltage)
 		return 100;
 	else
-		return (current_voltage - low_voltage) * 100
+		return (current_voltage_mv - low_voltage) * 100
 		    / (high_voltage - low_voltage);
 }
 
@@ -969,18 +970,18 @@
 
 static int get_prop_batt_current(struct pm8921_chg_chip *chip)
 {
-	int result_ma, rc;
+	int result_ua, rc;
 
-	rc = pm8921_bms_get_battery_current(&result_ma);
+	rc = pm8921_bms_get_battery_current(&result_ua);
 	if (rc == -ENXIO) {
-		rc = pm8xxx_ccadc_get_battery_current(&result_ma);
+		rc = pm8xxx_ccadc_get_battery_current(&result_ua);
 	}
 
 	if (rc) {
 		pr_err("unable to get batt current rc = %d\n", rc);
 		return rc;
 	} else {
-		return result_ma;
+		return result_ua;
 	}
 }
 
@@ -1105,13 +1106,13 @@
 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
-		val->intval = chip->max_voltage;
+		val->intval = chip->max_voltage_mv * 1000;
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
-		val->intval = chip->min_voltage;
+		val->intval = chip->min_voltage_mv * 1000;
 		break;
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		val->intval = get_prop_battery_mvolts(chip);
+		val->intval = get_prop_battery_uvolts(chip);
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
 		val->intval = get_prop_batt_capacity(chip);
@@ -1123,7 +1124,7 @@
 		val->intval = get_prop_batt_temp(chip);
 		break;
 	case POWER_SUPPLY_PROP_ENERGY_FULL:
-		val->intval = get_prop_batt_fcc(chip);
+		val->intval = get_prop_batt_fcc(chip) * 1000;
 		break;
 	default:
 		return -EINVAL;
@@ -1844,8 +1845,8 @@
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct pm8921_chg_chip *chip = container_of(dwork,
 				struct pm8921_chg_chip, eoc_work);
-	int vbat_meas, vbat_programmed;
-	int ichg_meas, iterm_programmed;
+	int vbat_meas_uv, vbat_meas_mv, vbat_programmed;
+	int ichg_meas_ma, iterm_programmed;
 	int regulation_loop, fast_chg, vcp;
 	int rc;
 	static int count;
@@ -1873,18 +1874,19 @@
 			goto reset_and_reschedule;
 
 		/* reset count if battery voltage is less than vddmax */
-		vbat_meas = get_prop_battery_mvolts(chip);
-		if (vbat_meas < 0)
+		vbat_meas_uv = get_prop_battery_uvolts(chip);
+		if (vbat_meas_uv < 0)
 			goto reset_and_reschedule;
+		vbat_meas_mv = vbat_meas_uv / 1000;
 
 		rc = pm_chg_vddmax_get(chip, &vbat_programmed);
 		if (rc) {
 			pr_err("couldnt read vddmax rc = %d\n", rc);
 			goto reset_and_reschedule;
 		}
-		pr_debug("vddmax = %d vbat_meas=%d\n",
-			 vbat_programmed, vbat_meas);
-		if (vbat_meas < vbat_programmed - VBAT_TOLERANCE_MV)
+		pr_debug("vddmax = %d vbat_meas_mv=%d\n",
+			 vbat_programmed, vbat_meas_mv);
+		if (vbat_meas_mv < vbat_programmed - VBAT_TOLERANCE_MV)
 			goto reset_and_reschedule;
 	} /* !is_ext_charging */
 
@@ -1895,17 +1897,17 @@
 		goto reset_and_reschedule;
 	}
 
-	ichg_meas = get_prop_batt_current(chip);
-	pr_debug("iterm_programmed = %d ichg_meas=%d\n",
-				iterm_programmed, ichg_meas);
+	ichg_meas_ma = (get_prop_batt_current(chip)) / 1000;
+	pr_debug("iterm_programmed = %d ichg_meas_ma=%d\n",
+				iterm_programmed, ichg_meas_ma);
 	/*
-	 * ichg_meas < 0 means battery is drawing current
-	 * ichg_meas > 0 means battery is providing current
+	 * ichg_meas_ma < 0 means battery is drawing current
+	 * ichg_meas_ma > 0 means battery is providing current
 	 */
-	if (ichg_meas > 0)
+	if (ichg_meas_ma > 0)
 		goto reset_and_reschedule;
 
-	if (ichg_meas * -1 > iterm_programmed)
+	if (ichg_meas_ma * -1 > iterm_programmed)
 		goto reset_and_reschedule;
 
 	if (!is_ext_charging(chip)) {
@@ -1989,18 +1991,19 @@
 	the_chip->is_bat_cool = enter;
 	if (enter) {
 		btm_config.low_thr_temp =
-			the_chip->cool_temp + TEMP_HYSTERISIS_DEGC;
+			the_chip->cool_temp_dc + TEMP_HYSTERISIS_DEGC;
 		set_appropriate_battery_current(the_chip);
 		pm_chg_vddmax_set(the_chip, the_chip->cool_bat_voltage);
 		pm_chg_vbatdet_set(the_chip,
 			the_chip->cool_bat_voltage
 			- the_chip->resume_voltage_delta);
 	} else {
-		btm_config.low_thr_temp = the_chip->cool_temp;
+		btm_config.low_thr_temp = the_chip->cool_temp_dc;
 		set_appropriate_battery_current(the_chip);
-		pm_chg_vddmax_set(the_chip, the_chip->max_voltage);
+		pm_chg_vddmax_set(the_chip, the_chip->max_voltage_mv);
 		pm_chg_vbatdet_set(the_chip,
-			the_chip->max_voltage - the_chip->resume_voltage_delta);
+			the_chip->max_voltage_mv
+			- the_chip->resume_voltage_delta);
 	}
 	schedule_work(&btm_config_work);
 }
@@ -2013,18 +2016,19 @@
 	the_chip->is_bat_warm = enter;
 	if (enter) {
 		btm_config.high_thr_temp =
-			the_chip->warm_temp - TEMP_HYSTERISIS_DEGC;
+			the_chip->warm_temp_dc - TEMP_HYSTERISIS_DEGC;
 		set_appropriate_battery_current(the_chip);
 		pm_chg_vddmax_set(the_chip, the_chip->warm_bat_voltage);
 		pm_chg_vbatdet_set(the_chip,
 			the_chip->warm_bat_voltage
 			- the_chip->resume_voltage_delta);
 	} else {
-		btm_config.high_thr_temp = the_chip->warm_temp;
+		btm_config.high_thr_temp = the_chip->warm_temp_dc;
 		set_appropriate_battery_current(the_chip);
-		pm_chg_vddmax_set(the_chip, the_chip->max_voltage);
+		pm_chg_vddmax_set(the_chip, the_chip->max_voltage_mv);
 		pm_chg_vbatdet_set(the_chip,
-			the_chip->max_voltage - the_chip->resume_voltage_delta);
+			the_chip->max_voltage_mv
+			- the_chip->resume_voltage_delta);
 	}
 	schedule_work(&btm_config_work);
 }
@@ -2035,8 +2039,8 @@
 
 	btm_config.btm_warm_fn = battery_warm;
 	btm_config.btm_cool_fn = battery_cool;
-	btm_config.low_thr_temp = chip->cool_temp;
-	btm_config.high_thr_temp = chip->warm_temp;
+	btm_config.low_thr_temp = chip->cool_temp_dc;
+	btm_config.high_thr_temp = chip->warm_temp_dc;
 	btm_config.interval = chip->temp_check_period;
 	rc = pm8xxx_adc_btm_configure(&btm_config);
 	if (rc)
@@ -2315,24 +2319,25 @@
 		return rc;
 	}
 
-	rc = pm_chg_vddsafe_set(chip, chip->max_voltage);
+	rc = pm_chg_vddsafe_set(chip, chip->max_voltage_mv);
 	if (rc) {
 		pr_err("Failed to set safe voltage to %d rc=%d\n",
-						chip->max_voltage, rc);
+						chip->max_voltage_mv, rc);
 		return rc;
 	}
 	rc = pm_chg_vbatdet_set(chip,
-				chip->max_voltage - chip->resume_voltage_delta);
+				chip->max_voltage_mv
+				- chip->resume_voltage_delta);
 	if (rc) {
 		pr_err("Failed to set vbatdet comprator voltage to %d rc=%d\n",
-			chip->max_voltage - chip->resume_voltage_delta, rc);
+			chip->max_voltage_mv - chip->resume_voltage_delta, rc);
 		return rc;
 	}
 
-	rc = pm_chg_vddmax_set(chip, chip->max_voltage);
+	rc = pm_chg_vddmax_set(chip, chip->max_voltage_mv);
 	if (rc) {
 		pr_err("Failed to set max voltage to %d rc=%d\n",
-						chip->max_voltage, rc);
+						chip->max_voltage_mv, rc);
 		return rc;
 	}
 	rc = pm_chg_ibatsafe_set(chip, SAFE_CURRENT_MA);
@@ -2677,7 +2682,7 @@
 	int rc;
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
-	if (!(chip->cool_temp == 0 && chip->warm_temp == 0)
+	if (!(chip->cool_temp_dc == 0 && chip->warm_temp_dc == 0)
 		&& !(chip->keep_btm_on_suspend)) {
 		rc = pm8xxx_adc_btm_configure(&btm_config);
 		if (rc)
@@ -2695,7 +2700,7 @@
 	int rc;
 	struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
 
-	if (!(chip->cool_temp == 0 && chip->warm_temp == 0)
+	if (!(chip->cool_temp_dc == 0 && chip->warm_temp_dc == 0)
 		&& !(chip->keep_btm_on_suspend)) {
 		rc = pm8xxx_adc_btm_end();
 		if (rc)
@@ -2726,8 +2731,8 @@
 	chip->safety_time = pdata->safety_time;
 	chip->ttrkl_time = pdata->ttrkl_time;
 	chip->update_time = pdata->update_time;
-	chip->max_voltage = pdata->max_voltage;
-	chip->min_voltage = pdata->min_voltage;
+	chip->max_voltage_mv = pdata->max_voltage;
+	chip->min_voltage_mv = pdata->min_voltage;
 	chip->resume_voltage_delta = pdata->resume_voltage_delta;
 	chip->term_current = pdata->term_current;
 	chip->vbat_channel = pdata->charger_cdata.vbat_channel;
@@ -2735,8 +2740,8 @@
 	chip->batt_id_channel = pdata->charger_cdata.batt_id_channel;
 	chip->batt_id_min = pdata->batt_id_min;
 	chip->batt_id_max = pdata->batt_id_max;
-	chip->cool_temp = pdata->cool_temp;
-	chip->warm_temp = pdata->warm_temp;
+	chip->cool_temp_dc = pdata->cool_temp * 10;
+	chip->warm_temp_dc = pdata->warm_temp * 10;
 	chip->temp_check_period = pdata->temp_check_period;
 	chip->max_bat_chg_current = pdata->max_bat_chg_current;
 	chip->cool_bat_chg_current = pdata->cool_bat_chg_current;
@@ -2819,10 +2824,10 @@
 	enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
 	enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
 	/*
-	 * if both the cool_temp and warm_temp are zero the device doesnt
+	 * if both the cool_temp_dc and warm_temp_dc are zero the device doesnt
 	 * care for jeita compliance
 	 */
-	if (!(chip->cool_temp == 0 && chip->warm_temp == 0)) {
+	if (!(chip->cool_temp_dc == 0 && chip->warm_temp_dc == 0)) {
 		rc = configure_btm(chip);
 		if (rc) {
 			pr_err("couldn't register with btm rc=%d\n", rc);
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index e40677b..aeaedad 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -546,7 +546,7 @@
 	return 0;
 }
 
-int pm8xxx_ccadc_get_battery_current(int *bat_current)
+int pm8xxx_ccadc_get_battery_current(int *bat_current_ua)
 {
 	int voltage_uv, rc;
 
@@ -556,13 +556,13 @@
 		return rc;
 	}
 
-	*bat_current = voltage_uv/the_chip->r_sense;
+	*bat_current_ua = voltage_uv * 1000/the_chip->r_sense;
 	/*
 	 * ccadc reads +ve current when the battery is charging
 	 * We need to return -ve if the battery is charging
 	 */
-	*bat_current = -1 * (*bat_current);
-	pr_debug("bat current = %d ma\n", *bat_current);
+	*bat_current_ua = -1 * (*bat_current_ua);
+	pr_debug("bat current = %d ma\n", *bat_current_ua);
 	return 0;
 }
 EXPORT_SYMBOL(pm8xxx_ccadc_get_battery_current);
diff --git a/include/linux/mfd/pm8xxx/ccadc.h b/include/linux/mfd/pm8xxx/ccadc.h
index 6f6cb39..23d0fb0 100644
--- a/include/linux/mfd/pm8xxx/ccadc.h
+++ b/include/linux/mfd/pm8xxx/ccadc.h
@@ -73,7 +73,7 @@
 
 /**
  * pm8xxx_ccadc_get_battery_current - return the battery current based on vsense
- *				resitor in milliamperes
+ *				resitor in microamperes
  * @result:	The pointer where the voltage will be updated. A -ve
  *		result means that the current is flowing in
  *		the battery - during battery charging
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 630e90a..82db9a4 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -130,7 +130,7 @@
 
 /**
  * pm8921_bms_get_battery_current - return the battery current based on vsense
- *				resitor in milliamperes
+ *				resitor in microamperes
  * @result:	The pointer where the voltage will be updated. A -ve
  *		result means that the current is flowing in
  *		the battery - during battery charging
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index ba4b29c..a572ae3 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -97,7 +97,7 @@
 
 #define PM8XXX_ADC_PMIC_0	0x0
 
-#define PM8XXX_CHANNEL_ADC_625_MV	625
+#define PM8XXX_CHANNEL_ADC_625_UV	625000
 #define PM8XXX_CHANNEL_MPP_SCALE1_IDX	20
 #define PM8XXX_CHANNEL_MPP_SCALE3_IDX	40
 
@@ -218,7 +218,6 @@
 
 /**
  * struct pm8xxx_adc_linear_graph - Represent ADC characteristics
- * @offset: Offset with respect to the actual curve
  * @dy: Numerator slope to calculate the gain
  * @dx: Denominator slope to calculate the gain
  * @adc_vref: A/D word of the voltage reference used for the channel
@@ -228,11 +227,10 @@
  * to calibrate the device.
  */
 struct pm8xxx_adc_linear_graph {
-	int32_t offset;
-	int32_t dy;
-	int32_t dx;
-	int32_t adc_vref;
-	int32_t adc_gnd;
+	int64_t dy;
+	int64_t dx;
+	int64_t adc_vref;
+	int64_t adc_gnd;
 };
 
 /**
@@ -292,6 +290,10 @@
  *		 here is a number relative to a reference of a given ADC
  * @physical: The data meaningful for each individual channel whether it is
  *	      voltage, current, temperature, etc.
+ *	      All voltage units are represented in micro - volts.
+ *	      -Battery temperature units are represented as 0.1 DegC
+ *	      -PA Therm temperature units are represented as DegC
+ *	      -PMIC Die temperature units are represented as 0.001 DegC
  */
 struct pm8xxx_adc_chan_result {
 	uint32_t	chan;
@@ -379,6 +381,21 @@
 			const struct pm8xxx_adc_properties *adc_prop,
 			const struct pm8xxx_adc_chan_properties *chan_prop,
 			struct pm8xxx_adc_chan_result *chan_rslt);
+/**
+ * pm8xxx_adc_scale_batt_id() - Scales the pre-calibrated digital output
+ *		of an ADC to the ADC reference and compensates for the
+ *		gain and offset.
+ * @adc_code:	pre-calibrated digital ouput of the ADC.
+ * @adc_prop:	adc properties of the pm8xxx adc such as bit resolution,
+ *		reference voltage.
+ * @chan_prop:	individual channel properties to compensate the i/p scaling,
+ *		slope and offset.
+ * @chan_rslt:	physical result to be stored.
+ */
+int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
+			const struct pm8xxx_adc_properties *adc_prop,
+			const struct pm8xxx_adc_chan_properties *chan_prop,
+			struct pm8xxx_adc_chan_result *chan_rslt);
 #else
 static inline int32_t pm8xxx_adc_scale_default(int32_t adc_code,
 			const struct pm8xxx_adc_properties *adc_prop,
@@ -405,6 +422,11 @@
 			const struct pm8xxx_adc_chan_properties *chan_prop,
 			struct pm8xxx_adc_chan_result *chan_rslt)
 { return -ENXIO; }
+static inline int32_t pm8xxx_adc_scale_batt_id(int32_t adc_code,
+			const struct pm8xxx_adc_properties *adc_prop,
+			const struct pm8xxx_adc_chan_properties *chan_prop,
+			struct pm8xxx_adc_chan_result *chan_rslt)
+{ return -ENXIO; }
 #endif
 
 /**