power: pm8921-bms: use battery data based on battery id
Currently the battery data is passed via the board file. Instead
read the battery id and choose the appropriate battery data to use.
CRs-Fixed: 304376
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 863f1ff..f00ba8d 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -3606,7 +3606,6 @@
.i_test = 2500,
.v_failure = 3000,
.calib_delay_ms = 600000,
- .batt_data = &palladium_1500_data,
};
#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
diff --git a/arch/arm/mach-msm/board-msm8960.h b/arch/arm/mach-msm/board-msm8960.h
index 7a939af..1cfcfdd 100644
--- a/arch/arm/mach-msm/board-msm8960.h
+++ b/arch/arm/mach-msm/board-msm8960.h
@@ -41,6 +41,4 @@
extern struct rpm_regulator_platform_data msm_rpm_regulator_pdata __devinitdata;
-extern struct pm8921_bms_battery_data palladium_1500_data;
-
#endif
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index de1c698..20b7760 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -463,6 +463,7 @@
pdata->bms_pdata->bms_cdata.vbat_channel = CHANNEL_VBAT;
pdata->bms_pdata->bms_cdata.ref625mv_channel = CHANNEL_625MV;
pdata->bms_pdata->bms_cdata.ref1p25v_channel = CHANNEL_125V;
+ pdata->bms_pdata->bms_cdata.batt_id_channel = CHANNEL_BATT_ID;
bms_cell.platform_data = pdata->bms_pdata;
bms_cell.pdata_size = sizeof(struct pm8921_bms_platform_data);
ret = mfd_add_devices(pmic->dev, 0, &bms_cell, 1, NULL,
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 3a34a6a..b27d73f 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -84,6 +84,7 @@
unsigned int vbat_channel;
unsigned int ref625mv_channel;
unsigned int ref1p25v_channel;
+ unsigned int batt_id_channel;
unsigned int pmic_bms_irq[PM_BMS_MAX_INTS];
DECLARE_BITMAP(enabled_irqs, PM_BMS_MAX_INTS);
};
@@ -1102,6 +1103,53 @@
pr_debug("ocv = %d last_ocv_uv = %d\n", ocv, last_ocv_uv);
}
+static int64_t read_battery_id(struct pm8921_bms_chip *chip)
+{
+ int rc;
+ struct pm8921_adc_chan_result result;
+
+ rc = pm8921_adc_read(chip->batt_id_channel, &result);
+ if (rc) {
+ pr_err("error reading batt id channel = %d, rc = %d\n",
+ chip->vbat_channel, rc);
+ return rc;
+ }
+ pr_debug("batt_id phy = %lld meas = 0x%llx\n", result.physical,
+ result.measurement);
+ return result.physical;
+}
+
+#define PALLADIUM_ID_MIN 2500
+#define PALLADIUM_ID_MAX 4000
+static int set_battery_data(struct pm8921_bms_chip *chip)
+{
+ int64_t battery_id;
+
+ 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)) {
+ 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 {
+ pr_warn("invalid battery id, palladium 1500 assumed\n");
+ 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;
+ }
+}
+
enum {
CALC_RBATT,
CALC_FCC,
@@ -1366,17 +1414,17 @@
chip->i_test = pdata->i_test;
chip->v_failure = pdata->v_failure;
chip->calib_delay_ms = pdata->calib_delay_ms;
- chip->fcc = pdata->batt_data->fcc;
-
- chip->fcc_temp_lut = pdata->batt_data->fcc_temp_lut;
- chip->fcc_sf_lut = pdata->batt_data->fcc_sf_lut;
- chip->pc_temp_ocv_lut = pdata->batt_data->pc_temp_ocv_lut;
- chip->pc_sf_lut = pdata->batt_data->pc_sf_lut;
+ rc = set_battery_data(chip);
+ if (rc) {
+ pr_err("%s bad battery data %d\n", __func__, rc);
+ return rc;
+ }
chip->batt_temp_channel = pdata->bms_cdata.batt_temp_channel;
chip->vbat_channel = pdata->bms_cdata.vbat_channel;
chip->ref625mv_channel = pdata->bms_cdata.ref625mv_channel;
chip->ref1p25v_channel = pdata->bms_cdata.ref1p25v_channel;
+ chip->batt_id_channel = pdata->bms_cdata.batt_id_channel;
chip->revision = pm8xxx_get_revision(chip->dev->parent);
INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index a8793e6..ac86b15 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -92,6 +92,7 @@
unsigned int vbat_channel;
unsigned int ref625mv_channel;
unsigned int ref1p25v_channel;
+ unsigned int batt_id_channel;
};
/**
@@ -101,7 +102,6 @@
* calculated or the peak system current (mA)
* @v_failure: the voltage at which the battery is considered empty(mV)
* @calib_delay_ms: how often should the adc calculate gain and offset
- * @batt_data: the battery profile data for the one used in the board
*/
struct pm8921_bms_platform_data {
struct pm8xxx_bms_core_data bms_cdata;
@@ -109,10 +109,10 @@
unsigned int i_test;
unsigned int v_failure;
unsigned int calib_delay_ms;
- struct pm8921_bms_battery_data *batt_data;
};
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
+extern struct pm8921_bms_battery_data palladium_1500_data;
/**
* pm8921_bms_get_vsense_avg - return the voltage across the sense
* resitor in microvolts