dv10_battery: add support to init fuel gauge data
authorRamakrishna Pallala <ramakrishna.pallala@intel.com>
Mon, 2 Apr 2012 05:12:02 +0000 (10:42 +0530)
committerbuildbot <buildbot@intel.com>
Tue, 10 Apr 2012 11:56:22 +0000 (04:56 -0700)
BZ: 29048

This patch adds the support to initialize maxim fuel gauge
data for dv10 platforms and adds charger interface for battery
charging notifications.

Change-Id: I3d1a54bf5d901666b25ac9ff416a054c32cdb4e3
Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
Reviewed-on: http://android.intel.com:8080/42117
Reviewed-by: Tc, Jenny <jenny.tc@intel.com>
Reviewed-by: Hari, NeelamX <neelamx.hari@intel.com>
Reviewed-by: Jena, TapanX <tapanx.jena@intel.com>
Tested-by: Kallappa Manjanna, MadhukumarX <madhukumarx.kallappa.manjanna@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/platform/intel-mid/board-redridge.c
drivers/power/max17042_battery.c
drivers/power/smb347-charger.c
include/linux/power/max17042_battery.h
include/linux/power/smb347-charger.h

index f0a1e05..5813e20 100644 (file)
@@ -670,6 +670,53 @@ static bool msic_battery_check(void)
        return false;
 }
 
+static uint16_t cell_char_tbl[] = {
+       /* Data to be written from 0x80h */
+       0xABB0, 0xB2B0, 0xBB10, 0xBBB0, 0xBC10, 0xBC70, 0xBD00, 0xBD70,
+       0xBDC0, 0xBE10, 0xC010, 0xC130, 0xC4A0, 0xC9C0, 0xCD10, 0xD090,
+
+       /* Data to be written from 0x90h */
+       0x0620, 0x0420, 0x1900, 0x3600, 0x3DA0, 0x2CA0, 0x3C20, 0x3500,
+       0x3500, 0x0440, 0x1240, 0x0DF0, 0x08F0, 0x0870, 0x07F0, 0x07F0,
+
+       /* Data to be written from 0xA0h */
+       0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
+       0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
+};
+
+/* WA function until UMIP support is provided for FG data */
+static int init_max170xx_fg_config_data(const char *name, void *data, int len)
+{
+       struct max17042_config_data *fg_conf_data =
+                               (struct max17042_config_data *)data;
+
+       fg_conf_data->size = 0x9e;
+       fg_conf_data->table_type = MAX17042_TBL_TYPE_DV10;
+       fg_conf_data->cfg = 0x2210;
+       fg_conf_data->learn_cfg = 0x0006;
+       fg_conf_data->filter_cfg = 0x87A4;
+       fg_conf_data->relax_cfg = 0x506B;
+       memcpy(&fg_conf_data->cell_char_tbl, cell_char_tbl,
+                                       sizeof(cell_char_tbl));
+       fg_conf_data->rcomp0 = 0x0092;
+       fg_conf_data->tempCo = 0x081D;
+       fg_conf_data->etc = 0x0B19;
+       fg_conf_data->kempty0 = 0x0D83;
+       fg_conf_data->ichgt_term = 0x0300;
+       fg_conf_data->soc_empty = 0x0001;
+       fg_conf_data->cycles = 0x00A0;
+       fg_conf_data->full_cap = 0x3988;
+       fg_conf_data->design_cap = 0x3988;
+       fg_conf_data->full_capnom = 0x3988;
+       fg_conf_data->rsense = 1;
+
+       return 0;
+}
+
+static int save_max170xx_fg_config_data(const char *name, void *data, int len)
+{
+       return 0;
+}
 
 static void *max17042_platform_data(void *info)
 {
@@ -689,23 +736,13 @@ static void *max17042_platform_data(void *info)
 
        platform_data.is_init_done = 0;
        platform_data.reset_i2c_lines = max17042_i2c_reset_workaround;
+       platform_data.enable_current_sense = true;
+       platform_data.technology = POWER_SUPPLY_TECHNOLOGY_LION;
+       platform_data.restore_config_data = init_max170xx_fg_config_data;
+       platform_data.save_config_data = save_max170xx_fg_config_data;
 
-#ifdef CONFIG_BATTERY_INTEL_MDF
-       platform_data.current_sense_enabled =
-           intel_msic_is_current_sense_enabled;
-       platform_data.battery_present = intel_msic_check_battery_present;
-       platform_data.battery_health = intel_msic_check_battery_health;
-       platform_data.battery_status = intel_msic_check_battery_status;
-       platform_data.battery_pack_temp = intel_msic_get_battery_pack_temp;
-       platform_data.save_config_data = intel_msic_save_config_data;
-       platform_data.restore_config_data = intel_msic_restore_config_data;
-
-       platform_data.is_cap_shutdown_enabled =
-                                       intel_msic_is_capacity_shutdown_en;
-       platform_data.is_volt_shutdown_enabled = intel_msic_is_volt_shutdown_en;
-       platform_data.is_lowbatt_shutdown_enabled =
-                                       intel_msic_is_lowbatt_shutdown_en;
-       platform_data.get_vmin_threshold = intel_msic_get_vsys_min;
+#ifdef CONFIG_CHARGER_SMB347
+       platform_data.battery_status = smb347_get_charging_status;
 #endif
 
        return &platform_data;
@@ -735,7 +772,7 @@ static struct smb347_charger_platform_data smb347_pdata = {
        .charge_current_compensation    = 900000,
        .use_mains                      = true,
        .enable_control                 = SMB347_CHG_ENABLE_PIN_ACTIVE_LOW,
-       .otg_control                    = SMB347_OTG_CONTROL_SW_AUTO,
+       .otg_control                    = SMB347_OTG_CONTROL_DISABLED,
        .irq_gpio                       = SMB347_IRQ_GPIO,
 };
 
index cb70735..f4416c7 100644 (file)
@@ -229,9 +229,7 @@ enum max170xx_chip_type {MAX17042, MAX17050};
 /* No of times we should reset I2C lines */
 #define NR_I2C_RESET_CNT       8
 
-/* No of cell characterization words to be written to max17042 */
-#define CELL_CHAR_TBL_SAMPLES  48
-
+/* default fuel gauge cell data for debug purpose only */
 static uint16_t cell_char_tbl[] = {
        /* Data to be written from 0x80h */
        0xA250, 0xB720, 0xB800, 0xB880, 0xB920, 0xBA00, 0xBA60, 0xBBF0,
@@ -244,46 +242,6 @@ static uint16_t cell_char_tbl[] = {
        0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
 };
 
-struct max17042_config_data {
-       /*
-        * if config_init is 0, which means new
-        * configuration has been loaded in that case
-        * we need to perform complete init of chip
-        */
-       u16     size;
-       u16     checksum;
-       u8      table_type;
-       u8      config_init;
-
-       u16     rcomp0;
-       u16     tempCo;
-       u16     kempty0;
-       u16     full_cap;
-       u16     cycles;
-       u16     full_capnom;
-
-       /* config data specific to max17050 */
-       u16   qrtbl00;
-       u16   qrtbl10;
-       u16   qrtbl20;
-       u16   qrtbl30;
-       u16   full_soc_thr;
-       u16   vempty;
-
-       u16     soc_empty;
-       u16     ichgt_term;
-       u16     design_cap;
-       u16     etc;
-       u16     rsense;
-       u16     cfg;
-       u16     learn_cfg;
-       u16     filter_cfg;
-       u16     relax_cfg;
-
-
-       u16     cell_char_tbl[CELL_CHAR_TBL_SAMPLES];
-} __packed;
-
 struct max17042_chip {
        struct i2c_client *client;
        enum max170xx_chip_type chip_type;
@@ -1185,12 +1143,6 @@ static void reset_max17042(struct max17042_chip *chip)
        /* adjust Temperature gain and offset */
        max17042_write_reg(chip->client, MAX17042_TGAIN, NTC_47K_TGAIN);
        max17042_write_reg(chip->client, MAx17042_TOFF, NTC_47K_TOFF);
-
-       /* Init complete, Clear the POR bit */
-       val = max17042_read_reg(chip->client, MAX17042_STATUS);
-       max17042_write_reg(chip->client, MAX17042_STATUS,
-                                       val & (~STATUS_POR_BIT));
-
 }
 
 static void max17042_restore_conf_data(struct max17042_chip *chip)
@@ -1221,6 +1173,12 @@ static void max17042_restore_conf_data(struct max17042_chip *chip)
                                                (val & STATUS_POR_BIT)) {
                                dev_info(&chip->client->dev,
                                        "config data needs to be loaded\n");
+
+                               /* WA: reset if table tyoe is dv10 */
+                               if (fg_conf_data->table_type ==
+                                                       MAX17042_TBL_TYPE_DV10)
+                                       reset_max17042(chip);
+
                                retval = init_max17042_chip(chip);
                                if (retval < 0) {
                                        dev_err(&chip->client->dev,
@@ -1244,6 +1202,12 @@ static void max17042_restore_conf_data(struct max17042_chip *chip)
                        }
                        chip->pdata->is_init_done = 1;
 
+                       /* multiply with 1000 to align with
+                        * linux power supply sub system.
+                        */
+                       chip->charge_full_des =
+                                       (fg_conf_data->design_cap / 2) * 1000;
+
                        /* mark the dirty byte in non-volatile memory */
                        if (!fg_conf_data->config_init && retval >= 0) {
                                fg_conf_data->config_init = 0x1;
index 021d44b..ddb7dad 100644 (file)
@@ -177,6 +177,12 @@ struct smb347_charger {
        struct delayed_work     smb347_statmon_worker;
 };
 
+static struct smb347_charger *smb347_dev;
+static char *smb347_power_supplied_to[] = {
+                       "max17042_battery",
+                       "max17050_battery",
+};
+
 /* Fast charge current in uA */
 static const unsigned int fcc_tbl[] = {
        700000,
@@ -352,7 +358,7 @@ static void smb347_status_monitor(struct work_struct *work)
        if (ret < 0)
                dev_err(&smb->client->dev, "error in updating smb347 status\n");
 
-       power_supply_changed(&smb->battery);
+       power_supply_changed(&smb->mains);
        schedule_delayed_work(&smb->smb347_statmon_worker,
                                                STATUS_UPDATE_INTERVAL);
 }
@@ -1308,6 +1314,22 @@ static int smb347_usb_get_property(struct power_supply *psy,
        return -EINVAL;
 }
 
+int smb347_get_charging_status(void)
+{
+       if (!smb347_dev)
+               return -EINVAL;
+
+       if (!smb347_is_online(smb347_dev))
+               return POWER_SUPPLY_STATUS_DISCHARGING;
+
+       if (smb347_charging_status(smb347_dev))
+               return POWER_SUPPLY_STATUS_CHARGING;
+       else
+               return POWER_SUPPLY_STATUS_FULL;
+
+}
+EXPORT_SYMBOL_GPL(smb347_usb_get_property);
+
 static enum power_supply_property smb347_usb_properties[] = {
        POWER_SUPPLY_PROP_ONLINE,
 };
@@ -1492,8 +1514,6 @@ static const struct file_operations smb347_debugfs_fops = {
 static int smb347_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
-       printk(KERN_DEBUG "Inside smb347_probe\n");
-       static char *battery[] = { "msic_battery" };
        const struct smb347_charger_platform_data *pdata;
        struct device *dev = &client->dev;
        struct smb347_charger *smb;
@@ -1525,16 +1545,16 @@ static int smb347_probe(struct i2c_client *client,
        smb->mains.get_property = smb347_mains_get_property;
        smb->mains.properties = smb347_mains_properties;
        smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties);
-       smb->mains.supplied_to = battery;
-       smb->mains.num_supplicants = ARRAY_SIZE(battery);
+       smb->mains.supplied_to = smb347_power_supplied_to;
+       smb->mains.num_supplicants = ARRAY_SIZE(smb347_power_supplied_to);
 
        smb->usb.name = "smb347-usb";
        smb->usb.type = POWER_SUPPLY_TYPE_USB;
        smb->usb.get_property = smb347_usb_get_property;
        smb->usb.properties = smb347_usb_properties;
        smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties);
-       smb->usb.supplied_to = battery;
-       smb->usb.num_supplicants = ARRAY_SIZE(battery);
+       smb->usb.supplied_to = smb347_power_supplied_to;
+       smb->usb.num_supplicants = ARRAY_SIZE(smb347_power_supplied_to);
 
        smb->battery.name = "smb347-battery";
        smb->battery.type = POWER_SUPPLY_TYPE_BATTERY;
@@ -1579,6 +1599,8 @@ static int smb347_probe(struct i2c_client *client,
 
        /* Start the status monitoring worker */
        schedule_delayed_work(&smb->smb347_statmon_worker, 0);
+
+       smb347_dev = smb;
        return 0;
 }
 
index cbe45ee..38fab2c 100644 (file)
 #ifndef __MAX17042_BATTERY_H_
 #define __MAX17042_BATTERY_H_
 
+/* No of cell characterization words to be written to max17042 */
+#define CELL_CHAR_TBL_SAMPLES  48
+
+/* fuel gauge table type for DV10 platfrom */
+#define MAX17042_TBL_TYPE_DV10 0xff
+
+struct max17042_config_data {
+       /*
+        * if config_init is 0, which means new
+        * configuration has been loaded in that case
+        * we need to perform complete init of chip
+        */
+       u16     size;
+       u16     checksum;
+       u8      table_type;
+       u8      config_init;
+
+       u16     rcomp0;
+       u16     tempCo;
+       u16     kempty0;
+       u16     full_cap;
+       u16     cycles;
+       u16     full_capnom;
+
+       u16     qrtbl00;
+       u16     qrtbl10;
+       u16     qrtbl20;
+       u16     qrtbl30;
+       u16     full_soc_thr;
+       u16     vempty;
+
+       u16     soc_empty;
+       u16     ichgt_term;
+       u16     design_cap;
+       u16     etc;
+       u16     rsense;
+       u16     cfg;
+       u16     learn_cfg;
+       u16     filter_cfg;
+       u16     relax_cfg;
+
+
+       u16     cell_char_tbl[CELL_CHAR_TBL_SAMPLES];
+} __packed;
+
 struct max17042_platform_data {
        bool enable_current_sense;
        bool is_init_done;
@@ -38,7 +83,7 @@ struct max17042_platform_data {
        int (*battery_pack_temp)(int *);
        int (*save_config_data)(const char *name, void *data, int len);
        int (*restore_config_data)(const char *name, void *data, int len);
-       int (*reset_i2c_lines)(void);
+       void (*reset_i2c_lines)(void);
 
        bool (*is_cap_shutdown_enabled)(void);
        bool (*is_volt_shutdown_enabled)(void);
index 58721fa..70266fe 100644 (file)
@@ -142,4 +142,6 @@ struct smb347_charger_platform_data {
        enum smb347_otg_control otg_control;
 };
 
+int smb347_get_charging_status(void);
+
 #endif /* SMB347_CHARGER_H */