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



Attachment: 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

Reply via email to