aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/battery/max17047_fuelgauge.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/battery/max17047_fuelgauge.c')
-rw-r--r--drivers/battery/max17047_fuelgauge.c102
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