Battery SFI table structure is modified to align with the new SFI table. And sfi_table_populate function got modified to read/map the structure from FW instead of hard coding the in the driver.
msic_batt_temp_charging function got modified and cleaned to support the new SFI table. A new function is added to lookup the temperature range. Modified init_batt_props function to align with the new SFI table. Also a new macro is added in the sfi.h file to support battery SFI table. Signed-off-by: Ramakrishna Pallala <ramakrishna.pall...@intel.com> --- drivers/power/intel_mdf_battery.c | 196 +++++++++++++++---------------------- include/linux/sfi.h | 1 + 2 files changed, 80 insertions(+), 117 deletions(-) diff --git a/drivers/power/intel_mdf_battery.c b/drivers/power/intel_mdf_battery.c index 641007d..cd4ccde 100644 --- a/drivers/power/intel_mdf_battery.c +++ b/drivers/power/intel_mdf_battery.c @@ -39,6 +39,7 @@ #include <linux/io.h> #include <linux/sched.h> #include <linux/pm_runtime.h> +#include <linux/sfi.h> #include <asm/intel_scu_ipc.h> #include <linux/usb/penwell_otg.h> @@ -247,6 +248,11 @@ #define BATT_STRING_MAX 8 #define HYSTR_SAMPLE_MAX 4 +#define BATTID_STR_LEN 8 +#define MANFCT_STR_LEN 2 +#define MODEL_STR_LEN 4 +#define SFI_TEMP_NR_RNG 4 + #define DISCHRG_CURVE_MAX_SAMPLES 17 #define DISCHRG_CURVE_MAX_COLOMNS 2 @@ -329,50 +335,30 @@ static int const therm_curve_data[THERM_CURVE_MAX_SAMPLES] * SFI table entries Structures *********************************************************************/ -/* Battery Identifier */ -struct battery_id { - unsigned char manufac[3]; - unsigned char model[5]; - unsigned char sub_ver[3]; -}; - /* Parameters defining the range */ -struct temperature_monitoring_range { - unsigned char range_number; - char temp_low_lim; - char temp_up_lim; - short int full_chrg_cur; +struct temp_mon_table { + short int temp_up_lim; + short int rbatt; short int full_chrg_vol; - short int maint_chrg_cur; + short int full_chrg_cur; short int maint_chrg_vol_ll; short int maint_chrg_vol_ul; -}; + short int maint_chrg_cur; +} __packed; /* SFI table entries structure. This code * will be modified or removed when the * Firmware supports SFI entries for Battery */ struct msic_batt_sfi_prop { - unsigned char sign[5]; - unsigned int length; - unsigned char revision; - unsigned char checksum; - unsigned char oem_id[7]; - unsigned char oem_tid[9]; - struct battery_id batt_id; + char batt_id[BATTID_STR_LEN]; unsigned short int voltage_max; unsigned int capacity; - unsigned char battery_type; - char safe_temp_low_lim; - char safe_temp_up_lim; - unsigned short int safe_vol_low_lim; - unsigned short int safe_vol_up_lim; - unsigned short int chrg_cur_lim; - char chrg_term_lim; - unsigned short int term_cur; - char temp_mon_ranges; - struct temperature_monitoring_range temp_mon_range[4]; -}; + short int battery_type; + short int temp_mon_ranges; + struct temp_mon_table temp_mon_range[SFI_TEMP_NR_RNG]; + short int temp_least_ll; +} __packed; static struct msic_batt_sfi_prop *sfi_table; @@ -1710,6 +1696,27 @@ static void calculate_charge_cycles(struct msic_power_module_info *mbi, chr_prev = chr_now; } +static unsigned int sfi_temp_range_lookup(int adc_temp) +{ + int i, up_lim, low_lim; + + for (i = 0; i < sfi_table->temp_mon_ranges; i++) { + /* find teh low temperature limit */ + if (i == (sfi_table->temp_mon_ranges - 1)) + low_lim = sfi_table->temp_least_ll; + else + low_lim = sfi_table->temp_mon_range[i+1].temp_up_lim; + up_lim = sfi_table->temp_mon_range[i].temp_up_lim; + + if (adc_temp <= up_lim && adc_temp > low_lim) { + dev_dbg(msic_dev, "Temp Range %d\n", i); + break; + } + } + + return i; +} + /** * msic_batt_temp_charging - manages the charging based on temperature * @charge_param: charging parameter @@ -1727,7 +1734,7 @@ static void msic_batt_temp_charging(struct work_struct *work) struct charge_params charge_param; struct msic_power_module_info *mbi = container_of(work, struct msic_power_module_info, connect_handler.work); - struct temperature_monitoring_range *temp_mon = NULL; + struct temp_mon_table *temp_mon = NULL; memset(&charge_param, 0x0, sizeof(struct charge_params)); charge_param.vinilmt = mbi->ch_params.vinilmt; @@ -1750,27 +1757,8 @@ static void msic_batt_temp_charging(struct work_struct *work) /* mdf_read_adc_regs returns in milli Centigrade */ adc_temp = ret / 1000; - for (i = 0; i < sfi_table->temp_mon_ranges; i++) { - if ((adc_temp >= sfi_table->temp_mon_range[i].temp_low_lim) && - (adc_temp < sfi_table->temp_mon_range[i].temp_up_lim)) { - - cv = sfi_table->temp_mon_range[i].full_chrg_vol; - cc = sfi_table->temp_mon_range[i].full_chrg_cur; - cvref = cv; - - /* D7,D6 bits of CHRCNTL will set the VINILMT */ - if (charge_param.vinilmt > 950) - vinlimit = 0xC0; /* VINILMT set to No Limit */ - else if (charge_param.vinilmt > 500) - vinlimit = 0x80; /* VINILMT set to 950mA */ - else if (charge_param.vinilmt > 100) - vinlimit = 0x40; /* VINILMT set to 500mA */ - else - vinlimit = 0x00; /* VINILMT set to 100mA */ - - break; - } - } + /* find teh temperature range */ + i = sfi_temp_range_lookup(adc_temp); if (i >= sfi_table->temp_mon_ranges) { dev_warn(msic_dev, "TEMP RANGE NOT EXIST\n"); @@ -1783,6 +1771,22 @@ static void msic_batt_temp_charging(struct work_struct *work) goto lbl_sched_work; } + /* Set charger parameters */ + cv = sfi_table->temp_mon_range[i].full_chrg_vol; + cc = sfi_table->temp_mon_range[i].full_chrg_cur; + cvref = cv; + + /* D7,D6 bits of CHRCNTL will set the VINILMT */ + if (charge_param.vinilmt > 950) + vinlimit = 0xC0; /* VINILMT set to No Limit */ + else if (charge_param.vinilmt > 500) + vinlimit = 0x80; /* VINILMT set to 950mA */ + else if (charge_param.vinilmt > 100) + vinlimit = 0x40; /* VINILMT set to 500mA */ + else + vinlimit = 0x00; /* VINILMT set to 100mA */ + + /* * Check for Charge full condition and set the battery * properties accordingly. Also check for charging mode @@ -2309,70 +2313,29 @@ static void ipc_ocv_to_chrg_update(struct msic_power_module_info *mbi) * SFI table has entries for the temperature limits * which is populated in a local structure */ -static void sfi_table_populate(struct msic_batt_sfi_prop *sfi_table) +static int __init sfi_table_populate(struct sfi_table_header *table) { + struct sfi_table_simple *sb; + struct msic_batt_sfi_prop *pentry; + int totentrs = 0, totlen = 0; + int i; - /* This is temporary code, will be removed - * or modified as soon as the firmware supports - * SFI entries for MSIC battery. - */ - memcpy(sfi_table->sign, "BATT", sizeof("BATT")); - sfi_table->length = 183; - sfi_table->revision = 1; - sfi_table->checksum = 15; - memcpy(sfi_table->oem_id, "INTEL", sizeof("INTEL")); - memcpy(sfi_table->oem_tid, "OEMTID", sizeof("OEMTID")); - memcpy(sfi_table->batt_id.manufac, "NK", sizeof("NK")); - memcpy(sfi_table->batt_id.model, "BP4L", sizeof("BP4L")); - memcpy(sfi_table->batt_id.sub_ver, "00", sizeof("00")); - sfi_table->voltage_max = 4200; - sfi_table->capacity = 1500; - sfi_table->battery_type = 2; /* POWER_SUPPLY_TECHNOLOGY_LION */ - sfi_table->safe_temp_low_lim = 0; - sfi_table->safe_temp_up_lim = 60; - sfi_table->safe_vol_low_lim = 3700; - sfi_table->safe_vol_up_lim = 4200; - sfi_table->chrg_cur_lim = 1000; - sfi_table->chrg_term_lim = 1; - sfi_table->term_cur = 50; - sfi_table->temp_mon_ranges = 4; - - sfi_table->temp_mon_range[0].range_number = 0; - sfi_table->temp_mon_range[0].temp_low_lim = 45; - sfi_table->temp_mon_range[0].temp_up_lim = 60; - sfi_table->temp_mon_range[0].full_chrg_cur = 950; - sfi_table->temp_mon_range[0].full_chrg_vol = 4100; - sfi_table->temp_mon_range[0].maint_chrg_cur = 950; - sfi_table->temp_mon_range[0].maint_chrg_vol_ll = 4000; - sfi_table->temp_mon_range[0].maint_chrg_vol_ul = 4050; - sfi_table->temp_mon_range[1].range_number = 1; - sfi_table->temp_mon_range[1].temp_low_lim = 10; - sfi_table->temp_mon_range[1].temp_up_lim = 45; - sfi_table->temp_mon_range[1].full_chrg_cur = 950; - sfi_table->temp_mon_range[1].full_chrg_vol = 4200; - sfi_table->temp_mon_range[1].maint_chrg_cur = 950; - sfi_table->temp_mon_range[1].maint_chrg_vol_ll = 4100; - sfi_table->temp_mon_range[1].maint_chrg_vol_ul = 4150; - sfi_table->temp_mon_range[2].range_number = 2; - sfi_table->temp_mon_range[2].temp_low_lim = 0; - sfi_table->temp_mon_range[2].temp_up_lim = 10; - sfi_table->temp_mon_range[2].full_chrg_cur = 950; - sfi_table->temp_mon_range[2].full_chrg_vol = 4100; - sfi_table->temp_mon_range[2].maint_chrg_cur = 950; - sfi_table->temp_mon_range[2].maint_chrg_vol_ll = 4000; - sfi_table->temp_mon_range[2].maint_chrg_vol_ul = 4050; - sfi_table->temp_mon_range[3].range_number = 3; - sfi_table->temp_mon_range[3].temp_low_lim = -10; - sfi_table->temp_mon_range[3].temp_up_lim = 0; - sfi_table->temp_mon_range[3].full_chrg_cur = 950; - sfi_table->temp_mon_range[3].full_chrg_vol = 3900; - sfi_table->temp_mon_range[3].maint_chrg_cur = 950; - sfi_table->temp_mon_range[3].maint_chrg_vol_ll = 3950; - sfi_table->temp_mon_range[3].maint_chrg_vol_ul = 3950; + sb = (struct sfi_table_simple *)table; + if (!sb) { + printk(KERN_WARNING "SFI: Unable to map BATT signature\n"); + return -ENODEV; + } + + totentrs = SFI_GET_NUM_ENTRIES(sb, struct msic_batt_sfi_prop); + pentry = (struct msic_batt_sfi_prop *) sb->pentry; + totlen = totentrs * sizeof(*pentry); + memcpy(sfi_table, pentry, totlen); /* Temporary fixes untill FW support is available */ sram_intr_addr = 0xFFFF7FC3; sram_ocv_addr = 0xFFFF3008; + + return 0; } /** @@ -2413,10 +2376,9 @@ static void init_batt_props(struct msic_power_module_info *mbi) mbi->batt_props.energy_full = (mbi->batt_props.vol_max_des * mbi->batt_props.charge_full_des) / 1000; - memcpy(mbi->batt_props.vender, sfi_table->batt_id.manufac, - sizeof(sfi_table->batt_id.manufac)); - memcpy(mbi->batt_props.model, sfi_table->batt_id.model, - sizeof(sfi_table->batt_id.model)); + memcpy(mbi->batt_props.vender, sfi_table->batt_id, MANFCT_STR_LEN); + memcpy(mbi->batt_props.model, sfi_table->batt_id + MANFCT_STR_LEN, + MODEL_STR_LEN); /* read specific to determine the status */ retval = intel_scu_ipc_ioread8(MSIC_BATT_CHR_SPWRSRCINT_ADDR, &data); @@ -2542,7 +2504,7 @@ static int msic_battery_probe(struct platform_device *pdev) mutex_init(&mbi->ipc_rw_lock); /* Populate data from SFI Table */ - sfi_table_populate(sfi_table); + sfi_table_parse(SFI_SIG_OEM0, NULL, NULL, sfi_table_populate); /* Initialize battery and charger Properties*/ init_batt_props(mbi); diff --git a/include/linux/sfi.h b/include/linux/sfi.h index eb7d598..b4ee568 100644 --- a/include/linux/sfi.h +++ b/include/linux/sfi.h @@ -75,6 +75,7 @@ #define SFI_SIG_GPEM "GPEM" #define SFI_SIG_DEVS "DEVS" #define SFI_SIG_GPIO "GPIO" +#define SFI_SIG_OEM0 "OEM0" #define SFI_SIGNATURE_SIZE 4 #define SFI_OEM_ID_SIZE 6 -- 1.7.2.3
0002-SFI-table-integration.patch
Description: 0002-SFI-table-integration.patch
_______________________________________________ MeeGo-kernel mailing list MeeGo-kernel@lists.meego.com http://lists.meego.com/listinfo/meego-kernel