power: qpnp-bms: read battery data

Read in battery data from the batterydata-lib API for future use.

Currently, the battery data isn't used for anything, and battery-id
reading is not yet supported.

Change-Id: Id2169e24c23c1e180bbf8c8c7f467f599df1640c
Signed-off-by: Xiaozhe Shi <xiaozhes@codeaurora.org>
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b9a16fa..8171fa7 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -281,6 +281,7 @@
 obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
 obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8930-regulator-pm8038.o board-8930-regulator-pm8917.o
 obj-$(CONFIG_PM8921_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
+obj-$(CONFIG_QPNP_BMS) += bms-batterydata.o bms-batterydata-desay.o batterydata-lib.o
 obj-$(CONFIG_MACH_APQ8064_CDP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_MTP) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_MACH_APQ8064_LIQUID) += board-8064-all.o board-8064-regulator.o
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 7b4d97e..7b974bb 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,7 +10,7 @@
  * GNU General Public License for more details.
  */
 
-#define pr_fmt(fmt)	"%s: " fmt, __func__
+#define pr_fmt(fmt)	"BMS: %s: " fmt, __func__
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -21,6 +21,7 @@
 #include <linux/of_device.h>
 #include <linux/power_supply.h>
 #include <linux/spmi.h>
+#include <linux/mfd/pm8xxx/batterydata-lib.h>
 
 /* Interrupt offsets */
 #define INT_RT_STS(base)		(base + 0x10)
@@ -100,6 +101,14 @@
 	int				adjust_soc_low_threshold;
 	int				adjust_soc_high_threshold;
 	int				chg_term;
+	enum battery_type		batt_type;
+	unsigned int			fcc;
+	struct single_row_lut		*fcc_temp_lut;
+	struct single_row_lut		*fcc_sf_lut;
+	struct pc_temp_ocv_lut		*pc_temp_ocv_lut;
+	struct sf_lut			*pc_sf_lut;
+	struct sf_lut			*rbatt_sf_lut;
+	int				default_rbatt_mohm;
 };
 
 static struct of_device_id qpnp_bms_match_table[] = {
@@ -210,6 +219,61 @@
 	return 0;
 }
 
+#define PALLADIUM_ID_MIN	0x7F40
+#define PALLADIUM_ID_MAX	0x7F5A
+#define DESAY_5200_ID_MIN	0x7F7F
+#define DESAY_5200_ID_MAX	0x802F
+static int64_t read_battery_id(struct qpnp_bms_chip *chip)
+{
+	return PALLADIUM_ID_MIN+1;
+}
+
+static int set_battery_data(struct qpnp_bms_chip *chip)
+{
+	int64_t battery_id;
+
+	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 {
+		pr_warn("invalid battid, palladium 1500 assumed batt_id %llx\n",
+				battery_id);
+		goto palladium;
+	}
+
+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;
+		chip->rbatt_sf_lut = palladium_1500_data.rbatt_sf_lut;
+		chip->default_rbatt_mohm
+				= palladium_1500_data.default_rbatt_mohm;
+		return 0;
+desay:
+		chip->fcc = desay_5200_data.fcc;
+		chip->fcc_temp_lut = desay_5200_data.fcc_temp_lut;
+		chip->pc_temp_ocv_lut = desay_5200_data.pc_temp_ocv_lut;
+		chip->pc_sf_lut = desay_5200_data.pc_sf_lut;
+		chip->rbatt_sf_lut = desay_5200_data.rbatt_sf_lut;
+		chip->default_rbatt_mohm = desay_5200_data.default_rbatt_mohm;
+		return 0;
+}
+
 #define SPMI_PROPERTY_READ(chip_prop, qpnp_spmi_property, retval, errlabel)\
 do {									\
 	retval = of_property_read_u32(spmi->dev.of_node,		\
@@ -260,6 +324,12 @@
 		goto error_read;
 	}
 
+	rc = set_battery_data(chip);
+	if (rc) {
+		pr_err("Bad battery data %d\n", rc);
+		goto error_read;
+	}
+
 	SPMI_PROPERTY_READ(r_sense_mohm, "r-sense-mohm", rc, error_read);
 	SPMI_PROPERTY_READ(v_cutoff, "v-cutoff-uv", rc, error_read);
 	SPMI_PROPERTY_READ(max_voltage, "max-voltage-uv", rc, error_read);
diff --git a/include/linux/mfd/pm8xxx/batterydata-lib.h b/include/linux/mfd/pm8xxx/batterydata-lib.h
index c55e47e..afa1843 100644
--- a/include/linux/mfd/pm8xxx/batterydata-lib.h
+++ b/include/linux/mfd/pm8xxx/batterydata-lib.h
@@ -102,7 +102,8 @@
 };
 
 #if defined(CONFIG_PM8921_BMS) || \
-	defined(CONFIG_PM8921_BMS_MODULE)
+	defined(CONFIG_PM8921_BMS_MODULE) || \
+	defined(CONFIG_QPNP_BMS)
 extern struct bms_battery_data  palladium_1500_data;
 extern struct bms_battery_data  desay_5200_data;