diff options
Diffstat (limited to 'drivers/battery/max17047_fuelgauge.c')
-rw-r--r-- | drivers/battery/max17047_fuelgauge.c | 102 |
1 files changed, 47 insertions, 55 deletions
diff --git a/drivers/battery/max17047_fuelgauge.c b/drivers/battery/max17047_fuelgauge.c index fc01547..ca87c15 100644 --- a/drivers/battery/max17047_fuelgauge.c +++ b/drivers/battery/max17047_fuelgauge.c @@ -100,6 +100,11 @@ struct max17047_fuelgauge_data { /* adjust full soc */ int full_soc; +#ifdef USE_TRIM_ERROR_DETECTION + /* trim error state */ + bool trim_err; +#endif + #ifdef CONFIG_DEBUG_FS struct dentry *fg_debugfs_dir; #endif @@ -260,55 +265,32 @@ static int max17047_get_rawsoc(struct i2c_client *client) static int max17047_get_soc(struct i2c_client *client) { struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client); - int rawsoc, soc; + int rawsoc, soc, fullsoc, empty; pr_debug("%s\n", __func__); rawsoc = max17047_get_rawsoc(fg_data->client); -#if defined(CONFIG_MACH_C1_KOR_SKT) || \ - defined(CONFIG_MACH_C1_KOR_KT) || \ - defined(CONFIG_MACH_C1_KOR_LGT) - if (fg_data->full_soc <= 0) - fg_data->full_soc = FULL_SOC_DEFAULT; - - soc = fg_data->soc = - ((rawsoc < 0) ? 0 : (min((rawsoc * 100 / - fg_data->full_soc), 100))); -#elif defined(CONFIG_MACH_M0_KOR_SKT) || \ - defined(CONFIG_MACH_M0_KOR_KT) - if (fg_data->full_soc <= 0) - fg_data->full_soc = FULL_SOC_DEFAULT; - - soc = fg_data->soc = - ((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 / - (fg_data->full_soc - 29)), 100))); -#elif defined(CONFIG_MACH_T0_KOR_SKT) || \ - defined(CONFIG_MACH_T0_KOR_KT) || \ - defined(CONFIG_MACH_T0_KOR_LGT) - if (fg_data->full_soc <= 0) - fg_data->full_soc = FULL_SOC_DEFAULT; +#if defined(CONFIG_MACH_C1) + empty = 0; +#else /* M0, T0,,, */ + empty = 29; +#endif - soc = fg_data->soc = - ((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 / - (fg_data->full_soc - 29)), 100))); -#elif defined(CONFIG_MACH_M0_CTC) if (fg_data->full_soc <= 0) fg_data->full_soc = FULL_SOC_DEFAULT; + fullsoc = fg_data->full_soc - empty; + rawsoc -= empty; - soc = fg_data->soc = - ((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 / - (fg_data->full_soc - 29)), 100))); -#else - /* M0 */ - if (fg_data->full_soc <= 0) - fg_data->full_soc = FULL_SOC_DEFAULT; +/* adjust fullsoc value for fast termination */ +#if defined(USE_2STEP_TERM) && !defined(CONFIG_TARGET_LOCALE_KOR) + fullsoc *= 99; + fullsoc /= 100; +#endif soc = fg_data->soc = - ((rawsoc < 29) ? 0 : (min(((rawsoc - 29) * 100 / - (fg_data->full_soc - 29)), 100))); -#endif + ((rawsoc < empty) ? 0 : (min((rawsoc * 100 / fullsoc), 100))); - pr_debug("%s: SOC(%d, %d)\n", __func__, soc, rawsoc); + pr_info("%s: SOC(%d, %d / %d)\n", __func__, soc, rawsoc, fullsoc); return soc; } @@ -371,8 +353,8 @@ static void max17047_adjust_fullsoc(struct i2c_client *client) } if (prev_full_soc != fg_data->full_soc) - pr_info("%s : full_soc = %d, keep_soc = %d\n", __func__, - fg_data->full_soc, keep_soc); + pr_info("%s : p_full_soc(%d), full_soc(%d), keep_soc(%d)\n", + __func__, prev_full_soc, fg_data->full_soc, keep_soc); } /* SOC% alert, disabled(0xFF00) */ @@ -503,7 +485,6 @@ static void max17047_update_work(struct work_struct *work) if (!battery_psy || !battery_psy->set_property) { pr_err("%s: fail to get battery power supply\n", __func__); - mutex_unlock(&fg_data->irq_lock); return; } @@ -554,8 +535,9 @@ static enum power_supply_property max17047_fuelgauge_props[] = { /* Temp: Init max17047 sample has trim value error. For detecting that. */ #define TRIM_ERROR_DETECT_VOLTAGE1 2500000 #define TRIM_ERROR_DETECT_VOLTAGE2 3600000 -static int max17047_detect_trim_error(struct max17047_fuelgauge_data *fg_data) +static bool max17047_detect_trim_error(struct max17047_fuelgauge_data *fg_data) { + bool ret = false; int vcell, soc; vcell = max17047_get_vcell(fg_data->client); @@ -563,12 +545,12 @@ static int max17047_detect_trim_error(struct max17047_fuelgauge_data *fg_data) if (((vcell < TRIM_ERROR_DETECT_VOLTAGE1) || (vcell == TRIM_ERROR_DETECT_VOLTAGE2)) && (soc == 0)) { - pr_debug("%s: (maybe)It's a trim error version. " + pr_err("%s: (maybe)It's a trim error version. " "VCELL(%d), SOC(%d)\n", __func__, vcell, soc); - return 1; + ret = true; } - return 0; + return ret; } #endif @@ -581,7 +563,7 @@ static int max17047_get_property(struct power_supply *psy, fuelgauge); #ifdef USE_TRIM_ERROR_DETECTION - if (max17047_detect_trim_error(fg_data)) { + if (fg_data->trim_err == true) { switch (psp) { case POWER_SUPPLY_PROP_VOLTAGE_NOW: case POWER_SUPPLY_PROP_VOLTAGE_AVG: @@ -674,7 +656,6 @@ static irqreturn_t max17047_fuelgauge_isr(int irq, void *data) { struct max17047_fuelgauge_data *fg_data = data; struct i2c_client *client = fg_data->client; - union power_supply_propval value; u8 i2c_data[2]; pr_info("%s: irq(%d)\n", __func__, irq); mutex_lock(&fg_data->irq_lock); @@ -683,6 +664,7 @@ static irqreturn_t max17047_fuelgauge_isr(int irq, void *data) pr_info("%s: MAX17047_REG_STATUS(0x%02x%02x)\n", __func__, i2c_data[1], i2c_data[0]); + cancel_delayed_work(&fg_data->update_work); wake_lock(&fg_data->update_wake_lock); schedule_delayed_work(&fg_data->update_work, msecs_to_jiffies(1000)); @@ -842,10 +824,15 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct max17047_fuelgauge_data *fg_data; - int ret; - u8 i2c_data[2]; + struct max17047_platform_data *pdata = client->dev.platform_data; + int ret = -ENODEV; int rawsoc, firstsoc; - pr_info("%s: max17047 Fuel gauge Driver Loading\n", __func__); + pr_info("%s: fuelgauge init\n", __func__); + + if (!pdata) { + pr_err("%s: no platform data\n", __func__); + return -ENODEV; + } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; @@ -855,7 +842,7 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, return -ENOMEM; fg_data->client = client; - fg_data->pdata = client->dev.platform_data; + fg_data->pdata = pdata; i2c_set_clientdata(client, fg_data); @@ -864,6 +851,11 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, wake_lock_init(&fg_data->update_wake_lock, WAKE_LOCK_SUSPEND, "fuel-update"); +#ifdef USE_TRIM_ERROR_DETECTION + /* trim error detect */ + fg_data->trim_err = max17047_detect_trim_error(fg_data); +#endif + /* Initialize full_soc, set this before fisrt SOC reading */ fg_data->full_soc = FULL_SOC_DEFAULT; /* first full_soc update */ @@ -899,6 +891,9 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, /* Initialize fuelgauge alert */ max17047_alert_init(fg_data); + INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work, + max17047_update_work); + /* Request IRQ */ fg_data->irq = gpio_to_irq(fg_data->pdata->irq_gpio); ret = gpio_request(fg_data->pdata->irq_gpio, "fuelgauge-irq"); @@ -926,8 +921,6 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, goto err_enable_irq; } - INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work, - max17047_update_work); #ifdef DEBUG_FUELGAUGE_POLLING INIT_DELAYED_WORK_DEFERRABLE(&fg_data->polling_work, max17047_polling_work); @@ -936,8 +929,7 @@ static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, max17047_test_read(fg_data); #endif - max17047_i2c_read(client, MAX17047_REG_VERSION, i2c_data); - pr_info("max17047 fuelgauge(rev.%d%d) initialized.\n", i2c_data[0], i2c_data[1]); + pr_info("%s: probe complete\n", __func__); #if defined(CONFIG_TARGET_LOCALE_KOR) #ifdef CONFIG_DEBUG_FS |