aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/battery/battery-factory.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/battery/battery-factory.c')
-rw-r--r--drivers/battery/battery-factory.c398
1 files changed, 398 insertions, 0 deletions
diff --git a/drivers/battery/battery-factory.c b/drivers/battery/battery-factory.c
new file mode 100644
index 0000000..d617a01
--- /dev/null
+++ b/drivers/battery/battery-factory.c
@@ -0,0 +1,398 @@
+/*
+ * battery-factory.c - factory mode for battery driver
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * SangYoung Son <hello.son@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "battery-factory.h"
+
+static ssize_t battery_show_property(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t battery_store_property(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+#define BATTERY_ATTR(_name) \
+{ \
+ .attr = { .name = #_name, \
+ .mode = S_IRUGO | S_IWUSR | S_IWGRP, \
+ }, \
+ .show = battery_show_property, \
+ .store = battery_store_property, \
+}
+
+static struct device_attribute battery_attrs[] = {
+ BATTERY_ATTR(batt_reset_soc),
+ BATTERY_ATTR(batt_read_raw_soc),
+ BATTERY_ATTR(batt_read_adj_soc),
+ BATTERY_ATTR(batt_type),
+ BATTERY_ATTR(batt_temp_adc),
+ BATTERY_ATTR(batt_temp_aver),
+ BATTERY_ATTR(batt_temp_adc_aver),
+ BATTERY_ATTR(batt_vol_aver),
+ BATTERY_ATTR(batt_vfocv),
+ BATTERY_ATTR(batt_lp_charging),
+ BATTERY_ATTR(batt_charging_source),
+ BATTERY_ATTR(test_mode),
+ BATTERY_ATTR(batt_error_test),
+ BATTERY_ATTR(siop_activated),
+ BATTERY_ATTR(wc_status),
+ BATTERY_ATTR(wpc_pin_state),
+
+ /* not use */
+ BATTERY_ATTR(batt_vol_adc),
+ BATTERY_ATTR(batt_vol_adc_cal),
+ BATTERY_ATTR(batt_vol_adc_aver),
+ BATTERY_ATTR(batt_temp_adc_cal),
+ BATTERY_ATTR(batt_vf_adc),
+ BATTERY_ATTR(auth_battery),
+
+#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
+ BATTERY_ATTR(batt_temp_adc_spec),
+ BATTERY_ATTR(batt_sysrev),
+#endif
+};
+
+enum {
+ BATT_RESET_SOC = 0,
+ BATT_READ_RAW_SOC,
+ BATT_READ_ADJ_SOC,
+ BATT_TYPE,
+ BATT_TEMP_ADC,
+ BATT_TEMP_AVER,
+ BATT_TEMP_ADC_AVER,
+ BATT_VOL_AVER,
+ BATT_VFOCV,
+ BATT_LP_CHARGING,
+ BATT_CHARGING_SOURCE,
+ TEST_MODE,
+ BATT_ERROR_TEST,
+ SIOP_ACTIVATED,
+ WC_STATUS,
+ WPC_PIN_STATE,
+
+ /* not use */
+ BATT_VOL_ADC,
+ BATT_VOL_ADC_CAL,
+ BATT_VOL_ADC_AVER,
+ BATT_TEMP_ADC_CAL,
+ BATT_VF_ADC,
+ AUTH_BATTERY,
+
+#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
+ BATT_TEMP_ADC_SPEC,
+ BATT_SYSREV,
+#endif
+};
+
+static ssize_t battery_show_property(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct battery_info *info = dev_get_drvdata(dev->parent);
+ int i;
+ int cnt, dat, d_max, d_min, d_total;
+ int val;
+ const ptrdiff_t off = attr - battery_attrs;
+ pr_debug("%s: %s\n", __func__, battery_attrs[off].attr.name);
+
+ i = 0;
+ val = 0;
+ switch (off) {
+ case BATT_READ_RAW_SOC:
+ battery_update_info(info);
+ val = info->battery_raw_soc;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_READ_ADJ_SOC:
+ battery_get_info(info, POWER_SUPPLY_PROP_CAPACITY);
+ val = info->battery_soc;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_TYPE:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "SDI_SDI\n");
+ break;
+ case BATT_TEMP_ADC:
+ battery_get_info(info, POWER_SUPPLY_PROP_TEMP);
+ val = info->battery_temper_adc;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_TEMP_AVER:
+ val = 0;
+ for (cnt = 0; cnt < CNT_TEMPER_AVG; cnt++) {
+ msleep(100);
+ battery_get_info(info, POWER_SUPPLY_PROP_TEMP);
+ val += info->battery_temper_adc;
+ info->battery_temper_adc_avg = val / (cnt + 1);
+ }
+#ifdef CONFIG_S3C_ADC
+ info->battery_temper_avg = info->pdata->covert_adc(
+ info->battery_temper_adc_avg,
+ info->pdata->temper_ch);
+#else
+ info->battery_temper_avg = info->battery_temper;
+#endif
+ val = info->battery_temper_avg;
+ pr_info("%s: temper avg(%d)\n", __func__, val);
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_TEMP_ADC_AVER:
+ val = info->battery_temper_adc_avg;
+ pr_info("%s: temper adc avg(%d)\n", __func__, val);
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_VOL_AVER: /* not use POWER_SUPPLY_PROP_VOLTAGE_AVG */
+ val = dat = d_max = d_min = d_total = 0;
+ for (cnt = 0; cnt < CNT_VOLTAGE_AVG; cnt++) {
+ msleep(200);
+ dat = battery_get_info(info,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW);
+
+ if (cnt != 0) {
+ d_max = max(dat, d_max);
+ d_min = min(dat, d_min);
+ } else
+ d_max = d_min = dat;
+
+ d_total += dat;
+ }
+ val = (d_total - d_max - d_min) / (CNT_VOLTAGE_AVG - 2);
+ pr_info("%s: voltage avg(%d)\n", __func__, val);
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_VFOCV:
+ battery_update_info(info);
+ val = info->battery_vfocv;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_LP_CHARGING:
+ val = info->lpm_state;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_CHARGING_SOURCE:
+ battery_get_info(info, POWER_SUPPLY_PROP_ONLINE);
+ val = info->cable_type;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case TEST_MODE:
+ val = info->battery_test_mode;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_ERROR_TEST:
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "(%d): 0: normal, 1: full charged, 2: freezed, 3: overheated, 4: ovp, 5: vf\n",
+ info->battery_error_test);
+ break;
+ case SIOP_ACTIVATED:
+ val = info->siop_state;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case WC_STATUS:
+ case WPC_PIN_STATE:
+#ifdef CONFIG_BATTERY_WPC_CHARGER
+ val = !gpio_get_value(GPIO_WPC_INT);
+#else
+ val = false;
+#endif
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_VOL_ADC:
+ case BATT_VOL_ADC_CAL:
+ case BATT_VOL_ADC_AVER:
+ case BATT_TEMP_ADC_CAL:
+ case BATT_VF_ADC:
+ case AUTH_BATTERY:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "N/A\n");
+ break;
+#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
+ case BATT_SYSREV:
+ val = system_rev;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
+ break;
+ case BATT_TEMP_ADC_SPEC:
+ i += scnprintf(buf + i, PAGE_SIZE - i,
+ "(HIGH: %d / %d, LOW: %d / %d)\n",
+ info->pdata->overheat_stop_temp,
+ info->pdata->overheat_recovery_temp,
+ info->pdata->freeze_stop_temp,
+ info->pdata->freeze_recovery_temp);
+ break;
+#endif
+ default:
+ i = -EINVAL;
+ }
+
+ return i;
+}
+
+static ssize_t battery_store_property(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct battery_info *info = dev_get_drvdata(dev->parent);
+ int x;
+ int ret;
+ const ptrdiff_t off = attr - battery_attrs;
+ pr_info("%s: %s\n", __func__, battery_attrs[off].attr.name);
+
+ x = 0;
+ ret = 0;
+ switch (off) {
+ case BATT_RESET_SOC:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ if (x == 1) {
+ pr_info("%s: Reset SOC.\n", __func__);
+ battery_control_info(info,
+ POWER_SUPPLY_PROP_CAPACITY,
+ 1);
+ } else
+ pr_info("%s: Not supported param.\n", __func__);
+ ret = count;
+ }
+ break;
+ case TEST_MODE:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ info->battery_test_mode = x;
+ pr_info("%s: battery test mode: %d\n", __func__,
+ info->battery_test_mode);
+ ret = count;
+ }
+ break;
+ case BATT_ERROR_TEST:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ info->battery_error_test = x;
+ pr_info("%s: battery error test: %d\n", __func__,
+ info->battery_error_test);
+ ret = count;
+ }
+ break;
+ case SIOP_ACTIVATED:
+ if (sscanf(buf, "%d\n", &x) == 1) {
+ info->siop_state = x;
+
+ if (info->siop_state == SIOP_ACTIVE)
+ info->siop_charge_current =
+ info->pdata->chg_curr_usb;
+
+ pr_info("%s: SIOP %s\n", __func__,
+ (info->siop_state ?
+ "activated" : "deactivated"));
+ ret = count;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ schedule_work(&info->monitor_work);
+
+ return ret;
+}
+
+void battery_create_attrs(struct device *dev)
+{
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(battery_attrs); i++) {
+ rc = device_create_file(dev, &battery_attrs[i]);
+ pr_debug("%s: battery attr.: %s\n", __func__,
+ battery_attrs[i].attr.name);
+ if (rc)
+ goto create_attrs_failed;
+ }
+ goto succeed;
+
+create_attrs_failed:
+ while (i--)
+ device_remove_file(dev, &battery_attrs[i]);
+succeed:
+ return;
+}
+
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+int battery_info_proc(char *buf, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct battery_info *info = data;
+ struct timespec cur_time;
+ ktime_t ktime;
+ int len = 0;
+ /* Guess we need no more than 100 bytes. */
+ int size = 100;
+
+ ktime = alarm_get_elapsed_realtime();
+ cur_time = ktime_to_timespec(ktime);
+
+ len = snprintf(buf, size,
+ "%lu\t%u\t%u\t%u\t%u\t%d\t%u\t%d\t%d\t%u\t"
+ "%u\t%u\t%u\t%u\t%u\t%u\t%d\t%u\t%u\n",
+ cur_time.tv_sec,
+ info->battery_raw_soc,
+ info->battery_soc,
+ info->battery_vcell / 1000,
+ info->battery_vfocv / 1000,
+ info->battery_full_soc,
+ info->battery_present,
+ info->battery_temper,
+ info->battery_temper_adc,
+ info->battery_health,
+ info->charge_real_state,
+ info->charge_virt_state,
+ info->cable_type,
+ info->charge_current,
+ info->full_charged_state,
+ info->recharge_phase,
+ info->abstimer_state,
+ info->monitor_interval,
+ info->charge_start_time);
+ return len;
+}
+#elif defined(CONFIG_MACH_M0_CTC)
+int battery_info_proc(char *buf, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ struct battery_info *info = data;
+ struct timespec cur_time;
+ ktime_t ktime;
+ int len = 0;
+ /* Guess we need no more than 100 bytes. */
+ int size = 100;
+
+ ktime = alarm_get_elapsed_realtime();
+ cur_time = ktime_to_timespec(ktime);
+
+ len = snprintf(buf, size,
+ "%lu\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%d\t%u\t%u\n",
+ cur_time.tv_sec,
+ info->battery_raw_soc,
+ info->battery_soc,
+ info->battery_vcell / 1000,
+ info->battery_vfocv / 1000,
+ info->battery_present,
+ info->battery_temper,
+ info->battery_temper_adc,
+ info->battery_health,
+ info->charge_real_state,
+ info->charge_virt_state,
+ info->cable_type,
+ info->charge_current,
+ info->full_charged_state,
+ info->recharge_phase,
+ info->abstimer_state,
+ info->monitor_interval,
+ info->charge_start_time);
+ return len;
+}
+#endif