msm: 8960/8064: robust battery detection

To ensure proper battery id dectection on LiQUID and MTP
use machine_is_msm8960/8064_mtp/cdp to determine which
calibration data to use for battery. If platform is
unknown fall back on regular battery id detection.

Change-Id: I2f5629572d1e5fcac0a2feb114947b91a96f3bf0
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 364df81..bd5f703 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -356,6 +356,7 @@
 
 static struct pm8921_bms_platform_data
 apq8064_pm8921_bms_pdata __devinitdata = {
+	.battery_type	= BATT_UNKNOWN,
 	.r_sense		= 10,
 	.i_test			= 2500,
 	.v_failure		= 3000,
@@ -428,5 +429,9 @@
 	if (machine_is_apq8064_rumi3()) {
 		apq8064_pm8921_irq_pdata.devirq = 0;
 		apq8064_pm8821_irq_pdata.devirq = 0;
+	} else if (machine_is_apq8064_mtp()) {
+		apq8064_pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
+	} else if (machine_is_apq8064_liquid()) {
+		apq8064_pm8921_bms_pdata.battery_type = BATT_DESAY;
 	}
 }
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 3f9f976..e19cde0 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -273,6 +273,7 @@
 };
 
 static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
+	.battery_type	= BATT_UNKNOWN,
 	.r_sense		= 10,
 	.i_test			= 2500,
 	.v_failure		= 3000,
@@ -310,4 +311,8 @@
 				&msm8930_ssbi_pm8038_pdata;
 	pm8038_platform_data.num_regulators
 		= msm8930_pm8038_regulator_pdata_len;
+	if (machine_is_apq8064_mtp())
+		pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
+	else if (machine_is_apq8064_liquid())
+		pm8921_bms_pdata.battery_type = BATT_DESAY;
 }
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 5f8f90b..e3646ed 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -439,6 +439,7 @@
 };
 
 static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
+	.battery_type	= BATT_UNKNOWN,
 	.r_sense		= 10,
 	.i_test			= 2500,
 	.v_failure		= 3000,
@@ -601,5 +602,8 @@
 	if (machine_is_msm8960_liquid()) {
 		pm8921_platform_data.keypad_pdata = &keypad_data_liquid;
 		pm8921_platform_data.leds_pdata = &pm8xxx_leds_pdata_liquid;
+		pm8921_platform_data.bms_pdata->battery_type = BATT_DESAY;
+	} else if (machine_is_msm8960_mtp()) {
+		pm8921_platform_data.bms_pdata->battery_type = BATT_PALLADIUM;
 	}
 }
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index e159366..709583a 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -103,7 +103,7 @@
 	unsigned int		charging_began;
 	unsigned int		start_percent;
 	unsigned int		end_percent;
-
+	enum battery_type	batt_type;
 	uint16_t		ocv_reading_at_100;
 	int			cc_reading_at_100;
 	int			max_voltage_uv;
@@ -1576,29 +1576,41 @@
 {
 	int64_t battery_id;
 
-	battery_id = read_battery_id(chip);
+	if (chip->batt_type == BATT_DESAY)
+		goto desay;
+	else if (chip->batt_type == BATT_PALLADIUM)
+		goto palladium;
 
+	battery_id = read_battery_id(chip);
 	if (battery_id < 0) {
 		pr_err("cannot read battery id err = %lld\n", battery_id);
 		return battery_id;
 	}
 
 	if (is_between(PALLADIUM_ID_MIN, PALLADIUM_ID_MAX, battery_id)) {
+		goto palladium;
+	} else if (is_between(DESAY_5200_ID_MIN, DESAY_5200_ID_MAX,
+				battery_id)) {
+		goto desay;
+	} else {
+		goto unknown;
+	}
+
+palladium:
 		chip->fcc = palladium_1500_data.fcc;
 		chip->fcc_temp_lut = palladium_1500_data.fcc_temp_lut;
 		chip->fcc_sf_lut = palladium_1500_data.fcc_sf_lut;
 		chip->pc_temp_ocv_lut = palladium_1500_data.pc_temp_ocv_lut;
 		chip->pc_sf_lut = palladium_1500_data.pc_sf_lut;
 		return 0;
-	} else if (is_between(DESAY_5200_ID_MIN, DESAY_5200_ID_MAX,
-				battery_id)) {
+desay:
 		chip->fcc = desay_5200_data.fcc;
 		chip->fcc_temp_lut = desay_5200_data.fcc_temp_lut;
 		chip->fcc_sf_lut = desay_5200_data.fcc_sf_lut;
 		chip->pc_temp_ocv_lut = desay_5200_data.pc_temp_ocv_lut;
 		chip->pc_sf_lut = desay_5200_data.pc_sf_lut;
 		return 0;
-	} else {
+unknown:
 		pr_warn("invalid battery id, palladium 1500 assumed batt_id %llx\n",
 				battery_id);
 		chip->fcc = palladium_1500_data.fcc;
@@ -1607,7 +1619,6 @@
 		chip->pc_temp_ocv_lut = palladium_1500_data.pc_temp_ocv_lut;
 		chip->pc_sf_lut = palladium_1500_data.pc_sf_lut;
 		return 0;
-	}
 }
 
 enum {
@@ -1878,6 +1889,7 @@
 	chip->v_failure = pdata->v_failure;
 	chip->calib_delay_ms = pdata->calib_delay_ms;
 	chip->max_voltage_uv = pdata->max_voltage_uv;
+	chip->batt_type = pdata->battery_type;
 	chip->start_percent = -EINVAL;
 	chip->end_percent = -EINVAL;
 	rc = set_battery_data(chip);
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 44141e5..e2d4d93 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -95,8 +95,15 @@
 	unsigned int	batt_id_channel;
 };
 
+enum battery_type {
+	BATT_UNKNOWN = 0,
+	BATT_PALLADIUM,
+	BATT_DESAY,
+};
+
 /**
  * struct pm8921_bms_platform_data -
+ * @batt_type:		allows to force chose battery calibration data
  * @r_sense:		sense resistor value in (mOhms)
  * @i_test:		current at which the unusable charger cutoff is to be
  *			calculated or the peak system current (mA)
@@ -105,6 +112,7 @@
  */
 struct pm8921_bms_platform_data {
 	struct pm8xxx_bms_core_data	bms_cdata;
+	enum battery_type		battery_type;
 	unsigned int			r_sense;
 	unsigned int			i_test;
 	unsigned int			v_failure;