aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/Kconfig14
-rw-r--r--drivers/power/Makefile2
-rw-r--r--drivers/power/max17042_fuelgauge_px.c348
-rw-r--r--drivers/power/max17042_fuelgauge_u1.c15
-rw-r--r--drivers/power/max8922_charger_s2plus.c320
-rw-r--r--drivers/power/power_supply_sysfs.c3
-rw-r--r--drivers/power/sec_battery_px.c206
-rw-r--r--drivers/power/sec_battery_u1.c93
-rw-r--r--[-rwxr-xr-x]drivers/power/smb347_charger.c0
9 files changed, 583 insertions, 418 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 9474894..5715075 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -241,12 +241,6 @@ config BATTERY_SAMSUNG
help
Say Y to enable support for batteries with samsung chip.
-config BATTERY_SAMSUNG_S2PLUS
- tristate "Fake battery driver for samsung s2plus boards"
- depends on PLAT_SAMSUNG
- help
- Say Y to enable support for batteries with s2plus board.
-
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
@@ -282,14 +276,6 @@ config CHARGER_MAX8922_U1
Say Y here to enable support for the battery charger in the Maxim
MAX8922 Charger IC.
-config CHARGER_MAX8922_S2PLUS
- tristate "MAX8922 battery charger support for Samsung Galaxy S2 ICS upgrade"
- depends on PLAT_SAMSUNG
- default n
- help
- Say Y here to enable support for the battery charger in the Maxim
- MAX8922 Charger IC.
-
config BATTERY_MAX17042_FUELGAUGE_U1
tristate "Maxim MAX17042/8997/8966 Fuel Gauge for Samsung Galaxy S2 ICS upgrade"
depends on I2C
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 9be94fd..b33da76 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -37,11 +37,9 @@ obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_BATTERY_SAMSUNG) += samsung_fake_battery.o
-obj-$(CONFIG_BATTERY_SAMSUNG_S2PLUS) += samsung_fake_battery.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8997_U1) += max8997_charger_u1.o
obj-$(CONFIG_CHARGER_MAX8922_U1) += max8922_charger_u1.o
-obj-$(CONFIG_CHARGER_MAX8922_S2PLUS) += max8922_charger_s2plus.o
obj-$(CONFIG_CHARGER_MAX8997_PX) += max8997_charger_px.o
ifeq ($(CONFIG_TARGET_LOCALE_KOR),y)
obj-$(CONFIG_BATTERY_SEC_U1) += sec_battery_u1_kor.o
diff --git a/drivers/power/max17042_fuelgauge_px.c b/drivers/power/max17042_fuelgauge_px.c
index 6244f2b..b8f02cb 100644
--- a/drivers/power/max17042_fuelgauge_px.c
+++ b/drivers/power/max17042_fuelgauge_px.c
@@ -28,6 +28,9 @@
#include <linux/workqueue.h>
#include <linux/rtc.h>
#include <mach/gpio.h>
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+#include <linux/power_supply.h>
+#endif /* CONFIG_TARGET_LOCALE_KOR */
#include <linux/power/sec_battery_px.h>
#include <linux/power/max17042_fuelgauge_px.h>
@@ -136,11 +139,11 @@ void fg_write_and_verify_register(u8 addr, u16 w_data)
}
}
-static void fg_test_print(void)
+static void fg_debug_print(void)
{
struct i2c_client *client = fg_i2c_client;
u8 data[2];
- u32 average_vcell;
+ u32 avg_v;
u16 w_data;
u32 temp;
u32 temp2;
@@ -154,19 +157,19 @@ static void fg_test_print(void)
w_data = (data[1]<<8) | data[0];
temp = (w_data & 0xFFF) * 78125;
- average_vcell = temp / 1000000;
+ avg_v = temp / 1000000;
temp = ((w_data & 0xF000) >> 4) * 78125;
temp2 = temp / 1000000;
- average_vcell += (temp2 << 4);
+ avg_v += (temp2 << 4);
fullcap = fg_read_register(FULLCAP_REG);
remcap = fg_read_register(REMCAP_REP_REG);
mixcap = fg_read_register(REMCAP_MIX_REG);
avcap = fg_read_register(REMCAP_AV_REG);
- pr_info("avg_vcell(%d), fullcap(%d), remcap(%d), mixcap(%d), avcap(%d)\n",
- average_vcell, fullcap/2, remcap/2, mixcap/2, avcap/2);
+ pr_info("avg_v(%d), fullcap(%d), remcap(%d), mixcap(%d), avcap(%d)\n",
+ avg_v, (fullcap / 2), (remcap / 2), (mixcap / 2), (avcap / 2));
msleep(20);
}
@@ -221,8 +224,8 @@ static int fg_read_vcell(void)
vcell += (temp2 << 4);
if (!(chip->info.pr_cnt % PRINT_COUNT))
- pr_info("%s: VCELL(%d), data(0x%04x)\n",
- __func__, vcell, (data[1]<<8) | data[0]);
+ pr_info("%s: vcell(%d, 0x%04x)\n", __func__,
+ vcell, (data[1]<<8) | data[0]);
return vcell;
}
@@ -339,44 +342,49 @@ static int fg_read_temp(void)
temper = 20000;
if (!(chip->info.pr_cnt % PRINT_COUNT))
- pr_info("%s: TEMPERATURE(%d), data(0x%04x)\n", __func__,
+ pr_info("%s: temper(%d, 0x%04x)\n", __func__,
temper, (data[1]<<8) | data[0]);
return temper;
}
-static int fg_read_soc(void)
+static int fg_read_vfsoc(void)
{
struct i2c_client *client = fg_i2c_client;
- struct max17042_chip *chip = i2c_get_clientdata(client);
u8 data[2];
- u32 soc = 0;
- if (fg_i2c_read(client, SOCREP_REG, data, 2) < 0) {
- pr_err("%s: Failed to read SOCREP\n", __func__);
+ if (fg_i2c_read(client, VFSOC_REG, data, 2) < 0) {
+ pr_err("%s: Failed to read VFSOC\n", __func__);
return -1;
}
- soc = data[1];
-
- if (!(chip->info.pr_cnt % PRINT_COUNT))
- pr_info("%s: SOC(%d), data(0x%04x)\n", __func__,
- soc, (data[1]<<8) | data[0]);
-
- return soc;
+ return (int)data[1];
}
-static int fg_read_vfsoc(void)
+static int fg_read_soc(void)
{
struct i2c_client *client = fg_i2c_client;
+ struct max17042_chip *chip = i2c_get_clientdata(client);
u8 data[2];
+ u32 soc = 0;
+ u32 soc_lsb = 0;
+ int psoc = 0;
- if (fg_i2c_read(client, VFSOC_REG, data, 2) < 0) {
- pr_err("%s: Failed to read VFSOC\n", __func__);
+ if (fg_i2c_read(client, SOCREP_REG, data, 2) < 0) {
+ pr_err("%s: Failed to read SOCREP\n", __func__);
return -1;
}
- return (int)data[1];
+ soc_lsb = (data[0] * 100) / 256;
+ psoc = (data[1] * 100) + soc_lsb;
+ soc = psoc / 99;
+ chip->info.psoc = psoc;
+
+ if (!(chip->info.pr_cnt % PRINT_COUNT))
+ pr_info("%s: soc(%d), psoc(%d), vfsoc(%d)\n", __func__,
+ soc, psoc, fg_read_vfsoc());
+
+ return soc;
}
static int fg_read_current(void)
@@ -421,10 +429,11 @@ static int fg_read_current(void)
avg_current *= -1;
if (!(chip->info.pr_cnt++ % PRINT_COUNT)) {
- fg_test_print();
- pr_info("%s: CURRENT(%dmA), AVG_CURRENT(%dmA)\n", __func__,
+ pr_info("%s: curr(%d), avg_curr(%dmA)\n", __func__,
i_current, avg_current);
chip->info.pr_cnt = 1;
+
+ fg_debug_print();
/* Read max17042's all registers every 5 minute. */
fg_periodic_read();
}
@@ -590,8 +599,9 @@ void fg_low_batt_compensation(u32 level)
void fg_periodic_read(void)
{
+ u8 reg;
int i;
- u16 data[0x10];
+ int data[0x10];
struct timespec ts;
struct rtc_time tm;
@@ -599,21 +609,21 @@ void fg_periodic_read(void)
rtc_time_to_tm(ts.tv_sec, &tm);
pr_info("[MAX17042] %d/%d/%d %02d:%02d,",
- tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900, tm.tm_hour,
- tm.tm_min);
+ tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900,
+ tm.tm_hour, tm.tm_min);
for (i = 0; i < 16; i++) {
- fg_read_16register(i, data);
+ for (reg = 0; reg < 0x10; reg++)
+ data[reg] = fg_read_register(reg + i * 0x10);
- pr_info("%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
+ pr_info("%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,\n"
+ "%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
data[0x00], data[0x01], data[0x02], data[0x03],
- data[0x04], data[0x05], data[0x06], data[0x07]);
- pr_info("%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
+ data[0x04], data[0x05], data[0x06], data[0x07],
data[0x08], data[0x09], data[0x0a], data[0x0b],
data[0x0c], data[0x0d], data[0x0e], data[0x0f]);
if (i == 4)
i = 13;
-
msleep(20);
}
pr_info("\n");
@@ -1048,6 +1058,8 @@ static void display_low_batt_comp_cnt(void)
sprintf(type_str, "SDI");
else if (fg_get_battery_type() == ATL_BATTERY_TYPE)
sprintf(type_str, "ATL");
+ else if (fg_get_battery_type() == BYD_BATTERY_TYPE)
+ sprintf(type_str, "BYD");
else
sprintf(type_str, "Unknown");
@@ -1109,7 +1121,7 @@ void prevent_early_late_poweroff(int vcell, int *fg_soc)
return;
avg_vcell = fg_read_avg_vcell();
- pr_info("%s: soc=%d%%(0x%04x), vcell=%d avg_vcell=%d\n",
+ pr_info("%s: soc(%d%%(0x%04x)), v(%d), avg_v(%d)\n",
__func__, repsoc, repsoc_data, vcell, avg_vcell);
if (vcell > POWER_OFF_VOLTAGE_HIGH_MARGIN) {
@@ -1118,8 +1130,8 @@ void prevent_early_late_poweroff(int vcell, int *fg_soc)
fg_write_register(REMCAP_REP_REG, (u16)(read_val * 13 / 1000));
msleep(200);
*fg_soc = fg_read_soc();
- pr_info("%s: new soc=%d, vcell=%d, avg_vcell=%d\n",
- __func__, *fg_soc, vcell, avg_vcell);
+ pr_info("%s: 1.3%% case: new soc(%d), v(%d), avg_v(%d)\n",
+ __func__, *fg_soc, vcell, avg_vcell);
} else if ((vcell < POWER_OFF_VOLTAGE_NOW_LOW_MARGIN) &&
(avg_vcell < POWER_OFF_VOLTAGE_AVG_LOW_MARGIN)) {
read_val = fg_read_register(FULLCAP_REG);
@@ -1127,8 +1139,8 @@ void prevent_early_late_poweroff(int vcell, int *fg_soc)
fg_write_register(REMCAP_REP_REG, (u16)(read_val * 9 / 1000));
msleep(200);
*fg_soc = fg_read_soc();
- pr_info("%s: new soc=%d, vcell=%d, avg_vcell=%d\n",
- __func__, *fg_soc, vcell, avg_vcell);
+ pr_info("%s: 0%% case: new soc(%d), v(%d), avg_v(%d)\n",
+ __func__, *fg_soc, vcell, avg_vcell);
}
}
@@ -1263,10 +1275,87 @@ static int get_low_batt_threshold(int range, int level, int nCurrent)
break;
}
}
+#if defined(CONFIG_MACH_P4NOTE)
+ else if (fg_get_battery_type() == BYD_BATTERY_TYPE) {
+ switch (range) {
+ case 5:
+ if (level == 1)
+ ret = BYD_Range5_1_Offset + \
+ ((nCurrent * BYD_Range5_1_Slope) / 1000);
+ else if (level == 3)
+ ret = BYD_Range5_3_Offset + \
+ ((nCurrent * BYD_Range5_3_Slope) / 1000);
+ break;
+ case 4:
+ if (level == 1)
+ ret = BYD_Range4_1_Offset + \
+ ((nCurrent * BYD_Range4_1_Slope) / 1000);
+ else if (level == 3)
+ ret = BYD_Range4_3_Offset + \
+ ((nCurrent * BYD_Range4_3_Slope) / 1000);
+ break;
+
+ case 3:
+ if (level == 1)
+ ret = BYD_Range3_1_Offset + \
+ ((nCurrent * BYD_Range3_1_Slope) / 1000);
+ else if (level == 3)
+ ret = BYD_Range3_3_Offset + \
+ ((nCurrent * BYD_Range3_3_Slope) / 1000);
+ break;
+
+ case 2:
+ if (level == 1)
+ ret = BYD_Range2_1_Offset + \
+ ((nCurrent * BYD_Range2_1_Slope) / 1000);
+ else if (level == 3)
+ ret = BYD_Range2_3_Offset + \
+ ((nCurrent * BYD_Range2_3_Slope) / 1000);
+ break;
+ case 1:
+ if (level == 1)
+ ret = BYD_Range1_1_Offset + \
+ ((nCurrent * BYD_Range1_1_Slope) / 1000);
+ else if (level == 3)
+ ret = BYD_Range1_3_Offset + \
+ ((nCurrent * BYD_Range1_3_Slope) / 1000);
+ break;
+
+ default:
+ break;
+ }
+ }
+#endif
return ret;
}
+void fg_reset_fullcap_in_fullcharge(void)
+{
+ u32 fullCap = fg_read_register(FULLCAP_REG);
+ u32 remCapRep = fg_read_register(REMCAP_REP_REG);
+ if (!fullCap || !remCapRep) {
+ pr_err("%s: Possible i2c failure !!!\n", __func__);
+ return;
+ }
+
+ pr_info("%s: FullCap(%d), RemCapRep(%d)\n",
+ __func__,
+ fullCap,
+ remCapRep);
+
+ if (remCapRep < fullCap) {
+ /* Usually we need a delay of 100ms here for the
+ * RemCapRep to adjust to the new FullCap but
+ * here this call is being made in an interrupt where
+ * we already follow this call with a delay
+ * of 300ms, hence avoided.
+ */
+ fg_write_register(FULLCAP_REG, remCapRep);
+ }
+ return;
+}
+
int low_batt_compensation(int fg_soc, int fg_vcell, int fg_current)
{
struct i2c_client *client = fg_i2c_client;
@@ -1411,6 +1500,9 @@ static void fg_set_battery_type(void)
else if ((data == chip->pdata->atl_vfcapacity) || \
(data == chip->pdata->atl_vfcapacity-1))
chip->info.battery_type = ATL_BATTERY_TYPE;
+ else if ((data == chip->pdata->byd_vfcapacity) || \
+ (data == chip->pdata->byd_vfcapacity-1))
+ chip->info.battery_type = BYD_BATTERY_TYPE;
else {
pr_info("%s: Unknown battery is set to SDI type.\n", __func__);
chip->info.battery_type = SDI_BATTERY_TYPE;
@@ -1420,6 +1512,8 @@ static void fg_set_battery_type(void)
sprintf(type_str, "SDI");
else if (chip->info.battery_type == ATL_BATTERY_TYPE)
sprintf(type_str, "ATL");
+ else if (chip->info.battery_type == BYD_BATTERY_TYPE)
+ sprintf(type_str, "BYD");
else
sprintf(type_str, "Unknown");
@@ -1431,7 +1525,10 @@ static void fg_set_battery_type(void)
chip->info.capacity = chip->pdata->atl_capacity;
chip->info.vfcapacity = chip->pdata->atl_vfcapacity;
break;
-
+ case BYD_BATTERY_TYPE:
+ chip->info.capacity = chip->pdata->byd_capacity;
+ chip->info.vfcapacity = chip->pdata->byd_vfcapacity;
+ break;
case SDI_BATTERY_TYPE:
default:
chip->info.capacity = chip->pdata->sdi_capacity;
@@ -1447,6 +1544,9 @@ static void fg_set_battery_type(void)
else if (chip->info.battery_type == ATL_BATTERY_TYPE)
chip->info.check_start_vol = \
chip->pdata->atl_low_bat_comp_start_vol;
+ else if (chip->info.battery_type == BYD_BATTERY_TYPE)
+ chip->info.check_start_vol = \
+ chip->pdata->byd_low_bat_comp_start_vol;
}
}
@@ -1537,10 +1637,159 @@ static int fg_i2c_remove(struct i2c_client *client)
return 0;
}
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+static int max17042_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = 1;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = get_fuelgauge_value(FG_VOLTAGE);
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = get_fuelgauge_value(FG_LEVEL);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property max17042_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+};
+
+static ssize_t max17042_show_property(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t max17042_store_property(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+#define SEC_MAX17042_ATTR(_name) \
+{ \
+ .attr = { .name = #_name, .mode = S_IRUGO | (S_IWUSR | S_IWGRP) }, \
+ .show = max17042_show_property, \
+ .store = max17042_store_property, \
+}
+
+static struct device_attribute sec_max17042_attrs[] = {
+ SEC_MAX17042_ATTR(fg_vfsoc),
+ SEC_MAX17042_ATTR(fg_vfocv),
+ SEC_MAX17042_ATTR(fg_filtercfg),
+ SEC_MAX17042_ATTR(fg_cgain),
+};
+
+enum {
+ MAX17042_VFSOC = 0,
+ MAX17042_VFOCV,
+ MAX17042_FILTERCFG,
+ MAX17042_CGAIN,
+};
+
+static ssize_t max17042_show_property(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct power_supply *psy = dev_get_drvdata(dev);
+ struct max17042_chip *chip = container_of(psy,
+ struct max17042_chip,
+ battery);
+ int i = 0;
+ const ptrdiff_t off = attr - sec_max17042_attrs;
+ int val;
+
+ switch (off) {
+ case MAX17042_VFSOC:
+ val = fg_read_register(VFSOC_REG);
+ val = val >> 8; /* % */
+ if (val >= 0)
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ else
+ i = -EINVAL;
+ break;
+ case MAX17042_VFOCV:
+ val = fg_read_register(VFOCV_REG);
+ val = ((val >> 3) * 625) / 1000; /* mV */
+ if (val >= 0)
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ else
+ i = -EINVAL;
+ break;
+ case MAX17042_FILTERCFG:
+ val = fg_read_register(FILTERCFG_REG);
+ if (val >= 0)
+ i += scnprintf(buf + i, PAGE_SIZE - i, "0x%x\n", val);
+ else
+ i = -EINVAL;
+ break;
+ case MAX17042_CGAIN:
+ val = fg_read_register(CGAIN_REG);
+ if (val >= 0)
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "0x%x, PSOC: %d\n", val, chip->info.psoc);
+ else
+ i = -EINVAL;
+ break;
+ default:
+ i = -EINVAL;
+ break;
+ }
+
+ return i;
+}
+
+static ssize_t max17042_store_property(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ const ptrdiff_t off = attr - sec_max17042_attrs;
+
+ switch (off) {
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int max17042_create_attrs(struct device *dev)
+{
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(sec_max17042_attrs); i++) {
+ rc = device_create_file(dev, &sec_max17042_attrs[i]);
+ if (rc)
+ goto max17042_attrs_failed;
+ }
+ goto succeed;
+
+max17042_attrs_failed:
+ while (i--)
+ device_remove_file(dev, &sec_max17042_attrs[i]);
+succeed:
+ return rc;
+}
+#endif /* CONFIG_TARGET_LOCALE_KOR */
+
static int
fg_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct max17042_chip *chip;
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ int ret = 0;
+#endif /* CONFIG_TARGET_LOCALE_KOR */
if (!client->dev.platform_data) {
pr_err("%s: No platform data\n", __func__);
@@ -1585,6 +1834,23 @@ fg_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
fg_alert_init();
fg_read_model_data();
fg_periodic_read();
+
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ chip->battery.name = "fuelgauge";
+ chip->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+ chip->battery.get_property = max17042_get_property;
+ chip->battery.properties = max17042_battery_props;
+ chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props);
+ ret = power_supply_register(&client->dev, &chip->battery);
+ if (ret) {
+ pr_err("%s : failed to regist fuel_gauge(ret = %d)\n",
+ __func__, ret);
+ kfree(chip);
+ return ret;
+ }
+
+ max17042_create_attrs(chip->battery.dev);
+#endif /* CONFIG_TARGET_LOCALE_KOR */
return 0;
}
diff --git a/drivers/power/max17042_fuelgauge_u1.c b/drivers/power/max17042_fuelgauge_u1.c
index 1434c72..39b931c 100644
--- a/drivers/power/max17042_fuelgauge_u1.c
+++ b/drivers/power/max17042_fuelgauge_u1.c
@@ -337,9 +337,10 @@ static void max17042_get_soc(struct i2c_client *client)
if (chip->is_enable) {
if (max17042_read_reg(client, MAX17042_REG_SOC_VF, data) < 0)
return;
+#ifndef PRODUCT_SHIP
dev_info(&chip->client->dev, "%s : soc(%02x%02x)\n",
__func__, data[1], data[0]);
-
+#endif
soc = (data[1] * 100) + (data[0] * 100 / 256);
chip->raw_soc = min(soc / 100, 100);
@@ -398,7 +399,7 @@ static void max17042_get_soc(struct i2c_client *client)
/*raw 1.6% ~ 97.6% */
soc = (soc > 100) ? ((soc - 60) * 100 / 9700) : 0;
/*raw 1.5% ~ 95% */
- /*soc = (soc < 150) ? 0 : ((soc - 150) * 100 / 9350) + 1; */
+ /*soc = (soc < 150) ? 0 : ((soc - 150) * 100 / 9350) + 1; */
}
#else
/* adjusted soc by adding 0.45 */
@@ -412,8 +413,10 @@ static void max17042_get_soc(struct i2c_client *client)
chip->soc = soc;
+#ifndef PRODUCT_SHIP
dev_info(&client->dev, "%s : use raw (%d), soc (%d)\n",
__func__, chip->raw_soc, soc);
+#endif
}
static void max17042_get_temperature(struct i2c_client *client)
@@ -423,7 +426,8 @@ static void max17042_get_temperature(struct i2c_client *client)
s32 temper = 0;
if (chip->is_enable) {
- if (max17042_read_reg(client, MAX17042_REG_TEMPERATURE, data) < 0)
+ if (max17042_read_reg(client,
+ MAX17042_REG_TEMPERATURE, data) < 0)
return;
/* data[] store 2's compliment format number */
@@ -513,7 +517,7 @@ static void max17042_work(struct work_struct *work)
dev_info(&chip->client->dev,
"fuel alert already activated (raw:%d)\n",
chip->raw_soc);
- } else if (chip->raw_soc == chip->fuel_alert_soc) {
+ } else if (chip->raw_soc >= chip->fuel_alert_soc) {
if (chip->is_fuel_alerted) {
wake_unlock(&chip->fuel_alert_wake_lock);
chip->is_fuel_alerted = false;
@@ -629,7 +633,8 @@ static ssize_t sec_fg_store(struct device *dev,
union power_supply_propval value;
if (!psy) {
- pr_err("%s: fail to get battery ps\n", __func__);
+ pr_err("%s: fail to get battery ps\n",
+ __func__);
return -ENODEV;
}
diff --git a/drivers/power/max8922_charger_s2plus.c b/drivers/power/max8922_charger_s2plus.c
deleted file mode 100644
index 86b8af7..0000000
--- a/drivers/power/max8922_charger_s2plus.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * max8922-charger.c
- * MAXIM 8922 charger interface driver
- *
- * Copyright (C) 2011 Samsung Electronics
- *
- * <ms925.kim@samsung.com>
- *
- * Copyright (C) 2012 Samsung Electronics
- * Jaecheol kim <jc22.kim@samsung.com>
- *
- * modify S2PLUS usb charger based on max8922_charger_u1.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/power_supply.h>
-#include <linux/power/max8922_charger_u1.h>
-#include <linux/battery/samsung_battery.h>
-
-struct max8922_info {
- struct device *dev;
- struct power_supply psy_bat;
- struct max8922_platform_data *pdata;
- bool is_usb_cable;
- int irq_chg_ing;
-};
-
-static enum power_supply_property max8922_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_ONLINE,
-};
-
-static inline int max8922_is_charging(struct max8922_info *info)
-{
- int ta_nconnected = gpio_get_value(info->pdata->gpio_ta_nconnected);
- int chg_ing = gpio_get_value(info->pdata->gpio_chg_ing);
-
- dev_info(info->dev, "%s: charging state = 0x%x\n", __func__,
- (ta_nconnected << 1) | chg_ing);
-
- /*return (ta_nconnected == 0 && chg_ing == 0); */
- return (ta_nconnected << 1) | chg_ing;
-}
-
-static int max8922_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct max8922_info *info =
- container_of(psy, struct max8922_info, psy_bat);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- switch (max8922_is_charging(info)) {
- case 0:
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- break;
- case 1:
- val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
- break;
- default:
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- break;
- }
- break;
- case POWER_SUPPLY_PROP_ONLINE:
- /* battery is always online */
- val->intval = 1;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int max8922_enable_charging(struct max8922_info *info, bool enable)
-{
- int gpio_chg_en = info->pdata->gpio_chg_en;
- unsigned long flags;
-
- dev_info(info->dev, "%s: %s charging,%s\n", __func__,
- enable ? "enable" : "disable",
- info->is_usb_cable ? "USB" : "TA");
-
- if (enable) {
- if (info->is_usb_cable) {
- /* Charging by USB cable */
- gpio_direction_output(gpio_chg_en, GPIO_LEVEL_HIGH);
- } else {
- /* Charging by TA cable */
- gpio_direction_output(gpio_chg_en, GPIO_LEVEL_HIGH);
- mdelay(5);
-
- local_irq_save(flags);
- gpio_direction_output(gpio_chg_en, GPIO_LEVEL_LOW);
- udelay(300);
- gpio_direction_output(gpio_chg_en, GPIO_LEVEL_HIGH);
- local_irq_restore(flags);
- }
- } else
- gpio_direction_output(gpio_chg_en, GPIO_LEVEL_LOW);
-
- msleep(300);
- return max8922_is_charging(info);
-}
-
-static int max8922_set_property(struct power_supply *psy,
- enum power_supply_property psp,
- const union power_supply_propval *val)
-{
- struct max8922_info *info =
- container_of(psy, struct max8922_info, psy_bat);
- bool enable;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_CURRENT_NOW: /* Set charging current */
- info->is_usb_cable = (val->intval <= CHARGER_USB_CURRENT);
- break;
- case POWER_SUPPLY_PROP_STATUS: /* Enable/Disable charging */
- enable = (val->intval == POWER_SUPPLY_STATUS_CHARGING);
- max8922_enable_charging(info, enable);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static irqreturn_t max8922_chg_ing_irq(int irq, void *data)
-{
- struct max8922_info *info = data;
- int ret = 0;
-
- dev_info(info->dev, "chg_ing IRQ occurred!\n");
-
- if (gpio_get_value(info->pdata->gpio_ta_nconnected))
- return IRQ_HANDLED;
-
- if (info->pdata->topoff_cb)
- ret = info->pdata->topoff_cb();
-
- if (ret) {
- dev_err(info->dev, "%s: error from topoff_cb(%d)\n", __func__,
- ret);
- return IRQ_HANDLED;
- }
-
- return IRQ_HANDLED;
-}
-
-static __devinit int max8922_probe(struct platform_device *pdev)
-{
- struct max8922_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct max8922_info *info;
- int ret;
-
- dev_info(&pdev->dev, "%s : MAX8922 Charger Driver Loading\n", __func__);
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, info);
-
- info->dev = &pdev->dev;
- info->pdata = pdata;
-
- info->psy_bat.name = "max8922-charger",
- info->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY,
- info->psy_bat.properties = max8922_battery_props,
- info->psy_bat.num_properties = ARRAY_SIZE(max8922_battery_props),
- info->psy_bat.get_property = max8922_get_property,
- info->psy_bat.set_property = max8922_set_property,
- ret = power_supply_register(&pdev->dev, &info->psy_bat);
- if (ret) {
- dev_err(info->dev, "Failed to register psy_bat\n");
- goto err_kfree;
- }
-
- if (pdata->cfg_gpio) {
- ret = pdata->cfg_gpio();
- if (ret) {
- dev_err(info->dev, "failed to configure GPIO\n");
- goto err_kfree;
- }
- }
-
- if (gpio_is_valid(pdata->gpio_chg_en)) {
- if (!pdata->gpio_chg_en) {
- dev_err(info->dev, "gpio_chg_en defined as 0\n");
- WARN_ON(!pdata->gpio_chg_en);
- ret = -EIO;
- goto err_kfree;
- }
- gpio_request(pdata->gpio_chg_en, "MAX8922 CHG_EN");
- }
-
- if (gpio_is_valid(pdata->gpio_chg_ing)) {
- if (!pdata->gpio_chg_ing) {
- dev_err(info->dev, "gpio_chg_ing defined as 0\n");
- WARN_ON(!pdata->gpio_chg_ing);
- ret = -EIO;
- goto err_kfree;
- }
- gpio_request(pdata->gpio_chg_ing, "MAX8922 CHG_ING");
- }
-
- if (gpio_is_valid(pdata->gpio_ta_nconnected)) {
- if (!pdata->gpio_ta_nconnected) {
- dev_err(info->dev, "gpio_ta_nconnected defined as 0\n");
- WARN_ON(!pdata->gpio_ta_nconnected);
- ret = -EIO;
- goto err_kfree;
- }
- gpio_request(pdata->gpio_ta_nconnected,
- "MAX8922 TA_nCONNECTED");
- }
-#if 0
- info->irq_chg_ing = gpio_to_irq(pdata->gpio_chg_ing);
-
- ret = request_threaded_irq(info->irq_chg_ing, NULL,
- max8922_chg_ing_irq,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT,
- "chg_ing", info);
- if (ret)
- dev_err(&pdev->dev, "%s: fail to request chg_ing IRQ:"
- " %d: %d\n", __func__, info->irq_chg_ing, ret);
-#endif
-
- return 0;
-err_kfree:
- power_supply_unregister(&info->psy_bat);
- platform_set_drvdata(pdev, NULL);
- kfree(info);
- return ret;
-}
-
-static int __devexit max8922_remove(struct platform_device *pdev)
-{
- struct max8922_info *info = platform_get_drvdata(pdev);
-
- power_supply_unregister(&info->psy_bat);
-
- gpio_free(info->pdata->gpio_chg_en);
- gpio_free(info->pdata->gpio_chg_ing);
- gpio_free(info->pdata->gpio_ta_nconnected);
-
- kfree(info);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int max8922_suspend(struct device *dev)
-{
- struct max8922_info *info = dev_get_drvdata(dev);
-
- if (info && info->irq_chg_ing)
- disable_irq(info->irq_chg_ing);
-
- return 0;
-}
-
-static int max8922_resume(struct device *dev)
-{
- struct max8922_info *info = dev_get_drvdata(dev);
-
- if (info && info->irq_chg_ing)
- enable_irq(info->irq_chg_ing);
-
- return 0;
-}
-#else
-#define max8922_charger_suspend NULL
-#define max8922_charger_resume NULL
-#endif
-
-static const struct dev_pm_ops max8922_pm_ops = {
- .suspend = max8922_suspend,
- .resume = max8922_resume,
-};
-
-static struct platform_driver max8922_driver = {
- .driver = {
- .name = "max8922-charger",
- .owner = THIS_MODULE,
- .pm = &max8922_pm_ops,
- },
- .probe = max8922_probe,
- .remove = __devexit_p(max8922_remove),
-};
-
-static int __init max8922_init(void)
-{
- return platform_driver_register(&max8922_driver);
-}
-
-static void __exit max8922_exit(void)
-{
- platform_driver_register(&max8922_driver);
-}
-
-module_init(max8922_init);
-module_exit(max8922_exit);
-
-MODULE_DESCRIPTION("MAXIM 8922 charger control driver");
-MODULE_AUTHOR("<ms925.kim@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 605514a..009e905 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -158,6 +158,9 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(energy_now),
POWER_SUPPLY_ATTR(energy_avg),
POWER_SUPPLY_ATTR(capacity),
+#ifdef CONFIG_SLP
+ POWER_SUPPLY_ATTR(capacity_raw),
+#endif
POWER_SUPPLY_ATTR(capacity_level),
POWER_SUPPLY_ATTR(temp),
POWER_SUPPLY_ATTR(temp_ambient),
diff --git a/drivers/power/sec_battery_px.c b/drivers/power/sec_battery_px.c
index 0b5d8d4..4787c9d 100644
--- a/drivers/power/sec_battery_px.c
+++ b/drivers/power/sec_battery_px.c
@@ -33,13 +33,18 @@
#include <linux/power/sec_battery_px.h>
#include <linux/power/max17042_fuelgauge_px.h>
#include <linux/mfd/max8997.h>
-
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+#include <linux/proc_fs.h>
+#endif /* CONFIG_TARGET_LOCALE_KOR */
#include <plat/adc.h>
#include <mach/usb_switch.h>
#define FAST_POLL 40 /* 40 sec */
#define SLOW_POLL (30*60) /* 30 min */
+/* cut off voltage */
+#define MAX_CUT_OFF_VOL 3500
+
/* SIOP */
#define CHARGING_CURRENT_HIGH_LOW_STANDARD 450
#define CHARGING_CURRENT_USB 500
@@ -67,11 +72,16 @@ static char *supply_list[] = {
"battery",
};
+/* Get LP charging mode state */
+unsigned int lpcharge;
+
static enum power_supply_property sec_battery_properties[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
POWER_SUPPLY_PROP_CAPACITY,
};
@@ -95,6 +105,11 @@ struct battery_info {
u32 batt_improper_ta; /* 1: improper ta */
u32 abstimer_is_active; /* 0 : Not active 1: Active */
u32 siop_activated; /* 0 : Not active 1: Active */
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ u32 batt_vfsoc;
+ u32 batt_soc;
+#endif /* CONFIG_TARGET_LOCALE_KOR */
+ u32 batt_current_avg;
};
struct battery_data {
@@ -123,6 +138,9 @@ struct battery_data {
#ifdef __TEST_DEVICE_DRIVER__
struct wake_lock wake_lock_for_dev;
#endif /* __TEST_DEVICE_DRIVER__ */
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ struct proc_dir_entry *entry;
+#endif /* CONFIG_TARGET_LOCALE_KOR */
enum charger_type current_cable_status;
enum charger_type previous_cable_status;
int present;
@@ -146,6 +164,7 @@ struct battery_data {
/* 0:Default, 1:Only charger, 2:Only PMIC */
int cable_detect_source;
int pmic_cable_state;
+ int dock_type;
bool is_low_batt_alarm;
};
@@ -174,6 +193,7 @@ static int bat_temp_force_state;
static bool check_UV_charging_case(void);
static void sec_bat_status_update(struct power_supply *bat_ps);
+static void fullcharge_discharge_comp(struct battery_data *battery);
static int get_cached_charging_status(struct battery_data *battery)
{
@@ -226,7 +246,7 @@ static int check_ta_conn(struct battery_data *battery)
#ifdef CONFIG_SAMSUNG_LPM_MODE
static void lpm_mode_check(struct battery_data *battery)
{
- battery->charging_mode_booting = \
+ battery->charging_mode_booting = lpcharge =
battery->pdata->check_lp_charging_boot();
pr_info("%s : charging_mode_booting(%d)\n", __func__,
battery->charging_mode_booting);
@@ -292,7 +312,7 @@ enum charger_type sec_get_dedicted_charger_type(struct battery_data *battery)
mutex_lock(&battery->work_lock);
/* ADC check margin (300~500ms) */
- msleep(150);
+ msleep(300);
usb_switch_lock();
usb_switch_set_path(USB_PATH_ADCCHECK);
@@ -318,10 +338,13 @@ enum charger_type sec_get_dedicted_charger_type(struct battery_data *battery)
battery->pdata->charger.accessory_line);
pr_info("%s: accessory line(%d)\n", __func__, accessory_line);
- if (accessory_line == 0) /* HDMI dock cable connected*/
+ if (battery->dock_type == DOCK_DESK) {
+ pr_info("%s: deskdock(%d) charging\n",
+ __func__, battery->dock_type);
result = CHARGER_DOCK;
- else
+ } else {
result = CHARGER_AC;
+ }
#else
result = CHARGER_AC; /* TA connected. */
#endif
@@ -369,6 +392,9 @@ static void sec_TA_work_handler(struct work_struct *work)
/* Prevent unstable VBUS signal from PC */
ta_state = check_ta_conn(battery);
if (ta_state == 0) {
+ /* Check for immediate discharge after fullcharge */
+ fullcharge_discharge_comp(battery);
+
msleep(TA_DISCONNECT_RECHECK_TIME);
if (ta_state != check_ta_conn(battery)) {
pr_info("%s: unstable ta_state(%d), ignore it.\n",
@@ -456,6 +482,29 @@ static int is_over_abs_time(struct battery_data *battery)
return 0;
}
+/* fullcharge_discharge_comp: During the small window between
+ * Full Charge and Recharge if the cable is connected , we always show
+ * 100% SOC to the UI , evven though in background its discharging.
+ * If the user pulls out the TA in between this small window he should
+ * see a sudden drop from 100% to a disacharged state of 95% - 98%.
+ * We fake the SOC on Fulll cap and let FG manage the differences on
+ * long run.
+ * Also during the start of recharging phase if the TA is disconnected SOC
+ * can sudden;y drop down to a lower value. In that case also the user
+ * expects to see a 100% so we update Full Cap again.
+*/
+static void fullcharge_discharge_comp(struct battery_data *battery)
+{
+ int fg_vcell = get_fuelgauge_value(FG_VOLTAGE);
+
+ if (battery->info.batt_is_full) {
+ pr_info("%s: Resetting FULLCAP !!\n", __func__);
+ fg_reset_fullcap_in_fullcharge();
+ }
+
+ return;
+}
+
static int sec_get_bat_level(struct power_supply *bat_ps)
{
struct battery_data *battery = container_of(bat_ps,
@@ -476,6 +525,9 @@ static int sec_get_bat_level(struct power_supply *bat_ps)
}
fg_soc = get_fuelgauge_value(FG_LEVEL);
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ battery->info.batt_soc = fg_soc;
+#endif /* CONFIG_TARGET_LOCALE_KOR */
if (fg_soc < 0) {
pr_info("Can't read soc!!!");
fg_soc = battery->info.level;
@@ -523,6 +575,10 @@ static int sec_get_bat_level(struct power_supply *bat_ps)
battery->info.batt_current = fg_current;
avg_current = get_fuelgauge_value(FG_CURRENT_AVG);
fg_vfsoc = get_fuelgauge_value(FG_VF_SOC);
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ battery->info.batt_vfsoc = fg_vfsoc;
+#endif /* CONFIG_TARGET_LOCALE_KOR */
+ battery->info.batt_current_avg = avg_current;
/* P4-Creative does not set full flag by force */
#if !defined(CONFIG_MACH_P4NOTE)
@@ -992,8 +1048,7 @@ static int sec_bat_get_charging_status(struct battery_data *battery)
case CHARGER_AC:
case CHARGER_MISC:
case CHARGER_DOCK:
- if (battery->info.batt_is_full ||
- battery->info.level == 100)
+ if (battery->info.batt_is_full)
return POWER_SUPPLY_STATUS_FULL;
else if (battery->info.batt_improper_ta)
return POWER_SUPPLY_STATUS_DISCHARGING;
@@ -1015,6 +1070,15 @@ static int sec_bat_set_property(struct power_supply *ps,
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
+#if defined(CONFIG_MACH_P4NOTE)
+ battery->dock_type = val->intval;
+ pr_info("dock type(%d)\n", battery->dock_type);
+ /* if need current update state, set */
+ if (battery->dock_type == DOCK_DESK) {
+ sec_get_cable_status(battery);
+ sec_cable_changed(battery);
+ }
+#else
battery->pmic_cable_state = val->intval;
pr_info("PMIC cable state: %d\n", battery->pmic_cable_state);
if (battery->cable_detect_source == 2) {
@@ -1024,6 +1088,7 @@ static int sec_bat_set_property(struct power_supply *ps,
sec_cable_changed(battery);
}
battery->cable_detect_source = 0;
+#endif
break;
default:
return -EINVAL;
@@ -1052,8 +1117,25 @@ static int sec_bat_get_property(struct power_supply *bat_ps,
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = battery->info.batt_current;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
+ val->intval = battery->info.batt_current_avg;
+ break;
case POWER_SUPPLY_PROP_CAPACITY:
+#if defined(CONFIG_MACH_P4NOTE)
+ if ((battery->info.level == 0) &&
+ (battery->info.batt_vol > MAX_CUT_OFF_VOL)) {
+ pr_info("%s: mismatch power off soc(%d) and vol(%d)\n",
+ __func__, battery->info.level, battery->info.batt_vol);
+ val->intval = battery->info.level = 1;
+ } else {
+ val->intval = battery->info.level;
+ }
+#else
val->intval = battery->info.level;
+#endif
pr_info("level = %d\n", val->intval);
break;
case POWER_SUPPLY_PROP_TEMP:
@@ -1143,6 +1225,13 @@ static struct device_attribute sec_battery_attrs[] = {
#endif
SEC_BATTERY_ATTR(jig_on),
SEC_BATTERY_ATTR(fg_capacity),
+ SEC_BATTERY_ATTR(update),
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ SEC_BATTERY_ATTR(batt_sysrev),
+ SEC_BATTERY_ATTR(batt_temp_adc_spec),
+ SEC_BATTERY_ATTR(batt_current_adc),
+ SEC_BATTERY_ATTR(batt_current_avg),
+#endif /* CONFIG_TARGET_LOCALE_KOR */
};
enum {
@@ -1167,6 +1256,13 @@ enum {
#endif
JIG_ON,
FG_CAPACITY,
+ UPDATE,
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ BATT_SYSTEM_REVISION,
+ BATT_TEMP_ADC_SPEC,
+ BATT_CURRENT_ADC,
+ BATT_CURRENT_AVG,
+#endif /* CONFIG_TARGET_LOCALE_KOR */
};
static int sec_bat_create_attrs(struct device *dev)
@@ -1268,6 +1364,28 @@ static ssize_t sec_bat_show_property(struct device *dev,
get_fuelgauge_capacity(CAPACITY_TYPE_AV),
get_fuelgauge_capacity(CAPACITY_TYPE_REP));
break;
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ case BATT_SYSTEM_REVISION:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ system_rev);
+ break;
+ case BATT_TEMP_ADC_SPEC:
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "(HIGH: %d / %d,\tLOW: %d / %d)\n",
+ debug_batterydata->pdata->temp_high_threshold / 100,
+ debug_batterydata->pdata->temp_high_recovery / 100,
+ debug_batterydata->pdata->temp_low_threshold / 100,
+ debug_batterydata->pdata->temp_low_recovery / 100);
+ break;
+ case BATT_CURRENT_ADC:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ get_fuelgauge_value(FG_CURRENT));
+ break;
+ case BATT_CURRENT_AVG:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
+ get_fuelgauge_value(FG_CURRENT_AVG));
+ break;
+#endif /* CONFIG_TARGET_LOCALE_KOR */
default:
i = -EINVAL;
}
@@ -1334,6 +1452,12 @@ static ssize_t sec_bat_store(struct device *dev,
}
pr_info("%s: SIOP_ACTIVATED :%d\n", __func__, x);
break;
+ case UPDATE:
+ pr_info("%s: battery update\n", __func__);
+ wake_lock(&debug_batterydata->work_wake_lock);
+ schedule_work(&debug_batterydata->battery_work);
+ ret = count;
+ break;
#ifdef CONFIG_SAMSUNG_LPM_MODE
case BATT_LP_CHARGING:
if (sscanf(buf, "%d\n", &x) == 1) {
@@ -1503,8 +1627,6 @@ static int sec_cable_status_update(struct battery_data *battery, int status)
wake_lock(&battery->work_wake_lock);
schedule_work(&battery->battery_work);
- pr_debug("call power_supply_changed ");
-
return ret;
}
@@ -1543,10 +1665,12 @@ static void sec_bat_status_update(struct power_supply *bat_ps)
power_supply_changed(bat_ps);
pr_debug("call power_supply_changed");
- pr_info("BAT : soc(%d), vcell(%dmV), curr(%dmA), temp(%d.%d), chg(%d)",
+ pr_info("BAT : soc(%d), vcell(%dmV), curr(%dmA), "
+ "avg curr(%dmA), temp(%d.%d), chg(%d)",
battery->info.level,
battery->info.batt_vol,
battery->info.batt_current,
+ battery->info.batt_current_avg,
battery->info.batt_temp/10,
battery->info.batt_temp%10,
battery->info.charging_enabled);
@@ -1723,17 +1847,15 @@ void fuelgauge_recovery_handler(struct work_struct *work)
if (battery->info.level > 0) {
pr_err("%s: Reduce the Reported SOC by 1 unit, wait for 30s\n",
- __func__);
+ __func__);
if (!battery->info.charging_enabled)
wake_lock_timeout(&battery->vbus_wake_lock, HZ);
current_soc = get_fuelgauge_value(FG_LEVEL);
if (current_soc) {
pr_info("%s: Returning to Normal discharge path.\n",
__func__);
- pr_info(" Actual SOC(%d) non-zero.\n",
- current_soc);
+ pr_info(" Actual SOC(%d) non-zero.\n", current_soc);
battery->is_low_batt_alarm = false;
- return;
} else {
battery->info.level--;
pr_err("%s: New Reduced Reported SOC (%d).\n",
@@ -1745,12 +1867,22 @@ void fuelgauge_recovery_handler(struct work_struct *work)
}
} else {
if (!get_charger_status(battery)) {
- pr_err("Set battery level as 0, power off.\n");
+ pr_err("%s: 0%% wo/ charging, will be power off\n",
+ __func__);
battery->info.level = 0;
wake_lock_timeout(&battery->vbus_wake_lock, HZ);
power_supply_changed(&battery->psy_battery);
+ } else {
+ pr_info("%s: 0%% w/ charging, exit low bat alarm\n",
+ __func__);
+ /* finish low battery alarm state */
+ battery->is_low_batt_alarm = false;
}
}
+
+ pr_info("%s: low batt alarm(%d)\n", __func__,
+ battery->is_low_batt_alarm);
+ return;
}
#define STABLE_LOW_BATTERY_DIFF 3
@@ -1759,6 +1891,7 @@ int _low_battery_alarm_(struct battery_data *battery)
{
int overcurrent_limit_in_soc;
int current_soc = get_fuelgauge_value(FG_LEVEL);
+ pr_info("%s\n", __func__);
if (battery->info.level <= STABLE_LOW_BATTERY_DIFF)
overcurrent_limit_in_soc = STABLE_LOW_BATTERY_DIFF_LOWBATT;
@@ -1881,6 +2014,39 @@ static void fullcharging_work_handler(struct work_struct *work)
enable_irq(battery->charging_irq);
}
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+static int sec_bat_read_proc(char *buf, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct battery_data *battery = data;
+ struct timespec cur_time;
+ ktime_t ktime;
+ int len = 0;
+
+ ktime = alarm_get_elapsed_realtime();
+ cur_time = ktime_to_timespec(ktime);
+
+ len = sprintf(buf,
+ "%lu\t%u\t%u\t%u\t%u\t%u\t%u\t%d\t%d\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t0x%04x\t0x%04x\n",
+ cur_time.tv_sec,
+ battery->info.batt_vol, battery->info.level,
+ battery->info.batt_soc, battery->info.batt_vfsoc,
+ max17042_chip_data->info.psoc,
+ battery->info.batt_temp,
+ battery->info.batt_current, battery->info.batt_current_avg,
+ battery->info.charging_source, battery->info.batt_improper_ta,
+ battery->info.charging_enabled, battery->info.charging_current,
+ sec_bat_get_charging_status(battery), battery->info.batt_health,
+ battery->info.batt_is_full, battery->info.batt_is_recharging,
+ battery->info.abstimer_is_active, battery->info.siop_activated,
+ get_fuelgauge_capacity(CAPACITY_TYPE_FULL),
+ get_fuelgauge_capacity(CAPACITY_TYPE_REP)
+ );
+
+ return len;
+}
+#endif /* CONFIG_TARGET_LOCALE_KOR */
+
static int __devinit sec_bat_probe(struct platform_device *pdev)
{
struct sec_battery_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -2063,6 +2229,16 @@ static int __devinit sec_bat_probe(struct platform_device *pdev)
lpm_mode_check(battery);
#endif
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+ battery->entry = create_proc_entry("batt_info_proc", S_IRUGO, NULL);
+ if (!battery->entry) {
+ pr_err("%s : failed to create proc_entry!\n", __func__);
+ } else {
+ battery->entry->read_proc = sec_bat_read_proc;
+ battery->entry->data = battery;
+ }
+#endif /* CONFIG_TARGET_LOCALE_KOR */
+
return 0;
err_charger_irq:
diff --git a/drivers/power/sec_battery_u1.c b/drivers/power/sec_battery_u1.c
index a442251..3dcd150 100644
--- a/drivers/power/sec_battery_u1.c
+++ b/drivers/power/sec_battery_u1.c
@@ -39,8 +39,13 @@
#if defined(CONFIG_TARGET_LOCALE_NAATT)
#define VF_CHECK_INTERVAL (5 * 1000)
+#if defined(CONFIG_MACH_U1_NA_SPR) || defined(CONFIG_MACH_U1_NA_USCC)
+#define MAX_VF 1500
+#define MIN_VF 1350
+#else
#define MAX_VF 1800
#define MIN_VF 1100
+#endif
#define VF_COUNT 1
#elif defined(CONFIG_MACH_Q1_BD)
#define VF_CHECK_INTERVAL (5 * 1000)
@@ -126,6 +131,17 @@
#define LOW_BLOCK_TEMP_ADC_LPM 521
#define HIGH_RECOVER_TEMP_ADC_LPM 714
#define LOW_RECOVER_TEMP_ADC_LPM 522
+#elif defined(CONFIG_MACH_U1_NA_USCC)
+#define EVENT_BLOCK_TEMP_ADC 770
+#define HIGH_BLOCK_TEMP_ADC 770
+#define LOW_BLOCK_TEMP_ADC 502
+#define HIGH_RECOVER_TEMP_ADC 699
+#define LOW_RECOVER_TEMP_ADC 516
+
+#define HIGH_BLOCK_TEMP_ADC_LPM 710
+#define LOW_BLOCK_TEMP_ADC_LPM 506
+#define HIGH_RECOVER_TEMP_ADC_LPM 702
+#define LOW_RECOVER_TEMP_ADC_LPM 512
#else
#define EVENT_BLOCK_TEMP_ADC 777
#define HIGH_BLOCK_TEMP_ADC 729
@@ -367,6 +383,10 @@ static enum power_supply_property sec_battery_props[] = {
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CAPACITY,
+#ifdef CONFIG_SLP
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+#endif
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_CURRENT_AVG,
};
@@ -492,6 +512,20 @@ static int sec_bat_get_property(struct power_supply *ps,
if (val->intval == -1)
return -EINVAL;
break;
+#ifdef CONFIG_SLP
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ if (info->charging_status == POWER_SUPPLY_STATUS_FULL)
+ val->intval = true;
+ else
+ val->intval = false;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ if (info->charging_status == POWER_SUPPLY_STATUS_CHARGING)
+ val->intval = true;
+ else
+ val->intval = false;
+ break;
+#endif
case POWER_SUPPLY_PROP_CAPACITY:
#ifdef CONFIG_TARGET_LOCALE_NA
if (info->charging_status != POWER_SUPPLY_STATUS_FULL
@@ -513,7 +547,7 @@ static int sec_bat_get_property(struct power_supply *ps,
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
- val->intval = -1;
+ val->intval = 1;
break;
default:
return -EINVAL;
@@ -783,12 +817,16 @@ static int is_event_end_timer_running(struct sec_bat_info *info)
if (time_after(passed_time, (unsigned long)EVENT_OVER_TIME)) {
info->event_end_time = 0xFFFFFFFF;
+ #ifndef PRODUCT_SHIP
dev_info(info->dev, "%s: Event timer is over 10 min\n",
__func__);
+ #endif
return false;
} else {
+ #ifndef PRODUCT_SHIP
dev_info(info->dev, "%s: Event timer is running(%u s)\n",
__func__, jiffies_to_msecs(passed_time) / 1000);
+ #endif
return true;
}
@@ -816,13 +854,17 @@ static int is_event_end_timer_running(struct sec_bat_info *info)
if (time_after(passed_time, (unsigned long)BAT_USE_TIMER_EXPIRE)) {
info->event_expired_time = 0xFFFFFFFF;
+ #ifndef PRODUCT_SHIP
dev_info(info->dev, "[SPR_NA] %s: Event timer is over 10 min\n",
__func__);
+ #endif
return false;
} else {
+#ifndef PRODUCT_SHIP
dev_info(info->dev,
"[SPR_NA] %s: Event timer is running(%u s)\n",
__func__, jiffies_to_msecs(passed_time) / 1000);
+#endif
return true;
}
@@ -932,9 +974,11 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
} else {
if ((info->batt_event_status)
|| (is_event_end_timer_running(info))) {
+#ifndef PRODUCT_SHIP
dev_info(info->dev,
- "[NA_SPR] Changed Put off Current",
+ "%s: [NA_SPR] Changed Put off Current",
__func__);
+#endif
if (temp_radc >= EVENT_BLOCK_TEMP_ADC) {
if (health !=
POWER_SUPPLY_HEALTH_OVERHEAT
@@ -943,7 +987,7 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
if (info->batt_temp_high_cnt <
TEMP_BLOCK_COUNT)
info->
- batt_temp_high_cnt++;
+ batt_temp_high_cnt++;
dev_info(info->dev,
"%s: high count = %d\n",
__func__,
@@ -962,7 +1006,7 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
batt_temp_recover_cnt <
TEMP_BLOCK_COUNT)
info->
- batt_temp_recover_cnt++;
+ batt_temp_recover_cnt++;
dev_info(info->dev,
"%s: recovery count = %d\n",
__func__,
@@ -995,7 +1039,7 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
if (info->batt_temp_high_cnt <
TEMP_BLOCK_COUNT)
info->
- batt_temp_high_cnt++;
+ batt_temp_high_cnt++;
dev_info(info->dev,
"%s: high count = %d\n",
__func__,
@@ -1015,7 +1059,7 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
batt_temp_recover_cnt <
TEMP_BLOCK_COUNT)
info->
- batt_temp_recover_cnt++;
+ batt_temp_recover_cnt++;
dev_info(info->dev,
"%s: recovery count = %d\n",
__func__,
@@ -1073,9 +1117,9 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
__func__, ret);
}
}
-
+#ifndef PRODUCT_SHIP
dev_info(info->dev, "%s: temp=%d, adc=%d\n", __func__, temp, temp_adc);
-
+#endif
return temp;
}
@@ -1263,8 +1307,9 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
__func__, ret);
}
}
-
+#ifndef PRODUCT_SHIP
dev_info(info->dev, "%s: temp=%d, adc=%d\n", __func__, temp, temp_adc);
+#endif
return temp;
}
@@ -1350,9 +1395,9 @@ static int sec_bat_check_temper(struct sec_bat_info *info)
__func__, ret);
}
}
-
+#ifndef PRODUCT_SHIP
dev_info(info->dev, "%s: temp=%d, adc=%d\n", __func__, temp, temp_adc);
-
+#endif
return temp;
}
#endif
@@ -1729,9 +1774,10 @@ static bool sec_bat_charging_time_management(struct sec_bat_info *info)
dev_info(info->dev, "%s: Undefine Battery Status\n", __func__);
return false;
}
-
+#ifndef PRODUCT_SHIP
dev_info(info->dev, "Time past : %u secs\n",
jiffies_to_msecs(info->charging_passed_time) / 1000);
+#endif
return false;
}
@@ -1953,9 +1999,9 @@ static bool sec_bat_check_ing_level_trigger(struct sec_bat_info *info)
charging_int_full_count >=
FULL_CHG_COND_COUNT) {
info->
- charging_int_full_count
+ charging_int_full_count
= 0;
- sec_bat_handle_charger_topoff
+ sec_bat_handle_charger_topoff
(info);
return true;
}
@@ -1963,7 +2009,7 @@ static bool sec_bat_check_ing_level_trigger(struct sec_bat_info *info)
"%s : full interrupt cnt = %d\n",
__func__,
info->
- charging_int_full_count);
+ charging_int_full_count);
} else {
info->charging_int_full_count =
0;
@@ -2042,9 +2088,9 @@ static bool sec_bat_check_ing_level_trigger(struct sec_bat_info *info)
charging_int_full_count >=
FULL_CHG_COND_COUNT) {
info->
- charging_int_full_count
+ charging_int_full_count
= 0;
- sec_bat_handle_charger_topoff
+ sec_bat_handle_charger_topoff
(info);
return true;
}
@@ -2052,13 +2098,14 @@ static bool sec_bat_check_ing_level_trigger(struct sec_bat_info *info)
"%s : full interrupt cnt = %d\n",
__func__,
info->
- charging_int_full_count);
+ charging_int_full_count);
} else {
info->charging_int_full_count =
0;
/*reactivate charging in */
/*next monitor work */
- /*for abnormal full-charged status */
+ /*for abnormal
+ full-charged status */
info->charging_next_time =
info->charging_passed_time +
HZ;
@@ -2230,12 +2277,14 @@ static void sec_bat_monitor_work(struct work_struct *work)
info->batt_temp / 10, info->charging_status, info->batt_health,
info->batt_vf_adc);
#else
+#ifndef PRODUCT_SHIP
dev_info(info->dev,
"soc(%d), vfocv(%d), vcell(%d), temp(%d), charging(%d), health(%d), chg_adc(%d)\n",
info->batt_soc, info->batt_vfocv, info->batt_vcell / 1000,
info->batt_temp / 10, info->charging_status,
info->batt_health, info->batt_current_adc);
#endif
+#endif
power_supply_changed(&info->psy_bat);
@@ -2449,10 +2498,10 @@ static void sec_bat_check_event_status(struct sec_bat_info *info, int mode,
if (info->batt_event_status & offset)
info->batt_event_status &= ~offset;
}
-
+#ifndef PRODUCT_SHIP
printk(KERN_DEBUG "[%s] current batt_event_status = 0x%x\n", __func__,
info->batt_event_status);
-
+#endif
if ((info->batt_event_status == 0) && (is_event_running == 1))
info->event_expired_time = jiffies;
@@ -2463,6 +2512,7 @@ int sec_bat_use_wimax(int onoff)
{
struct sec_bat_info *info = pchg;
sec_bat_check_event_status(info, onoff, USE_WIMAX);
+ return 0;
}
EXPORT_SYMBOL(sec_bat_use_wimax);
#endif
@@ -2916,6 +2966,7 @@ static ssize_t sec_bat_store(struct device *dev,
case BATT_CAMERA:
/* TODO */
if (sscanf(buf, "%d\n", &x) == 1) {
+ info->use_camera = x;
dev_info(info->dev, "[NA_SPR]%s: CAMERA(%d)\n",
__func__, x);
ret = count;
diff --git a/drivers/power/smb347_charger.c b/drivers/power/smb347_charger.c
index a339776..a339776 100755..100644
--- a/drivers/power/smb347_charger.c
+++ b/drivers/power/smb347_charger.c