summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorTao Huang <huangtao@rock-chips.com>2018-11-02 15:31:20 +0800
committerTao Huang <huangtao@rock-chips.com>2018-11-02 15:31:20 +0800
commitcf0099827eb6e79f7a535507819440225c10e99e (patch)
tree05c881998b8a87c9946802e4581f7a4372d4e489 /drivers/power
parent955c9802a55cae649f47212f3cb0d4e829f3397d (diff)
drivers: remove unused rt5025 drivers
Change-Id: Iee99365df115f30399737705d3c6b773a0f2cb34 Signed-off-by: Tao Huang <huangtao@rock-chips.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/rt5025-battery.c1861
-rwxr-xr-xdrivers/power/rt5025-charger.c1224
-rwxr-xr-xdrivers/power/rt5025-power.c566
-rwxr-xr-xdrivers/power/rt5025-swjeita.c494
4 files changed, 0 insertions, 4145 deletions
diff --git a/drivers/power/rt5025-battery.c b/drivers/power/rt5025-battery.c
deleted file mode 100644
index 8403b1da02d1..000000000000
--- a/drivers/power/rt5025-battery.c
+++ /dev/null
@@ -1,1861 +0,0 @@
-/* drivers/power/rt5025-battery.c
- * I2C Driver for Richtek RT5025 PMIC
- * Multi function device - multi functional baseband PMIC Battery part
- *
- * Copyright (C) 2014 Richtek Technology Corp.
- * Author: Nick Hung <nick_hung@richtek.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 as
- * published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/power_supply.h>
-#include <linux/slab.h>
-#include <linux/wakelock.h>
-#include <linux/workqueue.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/alarmtimer.h>
-#include <linux/mfd/rt5025.h>
-#include <linux/power/rt5025-battery.h>
-
-
-#define VOLTAGE_ALERT 0
-#define TEMPERATURE_ALERT 0
-
-#define RT5025_CSV 0
-#define RT5025_B 1
-#define RT5025_TEST_WAKE_LOCK 0
-
-u8 irq_thres[LAST_TYPE];
-
-static unsigned char gauge_init_regval[] = {
- 0xFF, /*REG 0x53*/
- 0x00, /*REG 0x54*/
- 0x00, /*REG 0x55*/
- 0xFF, /*REG 0x56*/
- 0x00, /*REG 0x57*/
-};
-
-static u16 crctab16[256] = {
- 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
- 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
- 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
- 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
- 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
- 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
- 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
- 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
- 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
- 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
- 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
- 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
- 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
- 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
- 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
- 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
- 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
- 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
- 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
- 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
- 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
- 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
- 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
- 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
- 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
- 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
- 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
- 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
- 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
- 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
- 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
- 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78,
-};
-
-static int rt5025_battery_parameter_backup(struct rt5025_battery_info *);
-static void rt5025_get_external_temp(struct rt5025_battery_info *);
-static void rt5025_get_internal_temp(struct rt5025_battery_info *);
-static void rt5025_get_vcell(struct rt5025_battery_info *);
-static void rt5025_get_current(struct rt5025_battery_info *);
-static void rt5025_temp_comp(struct rt5025_battery_info *);
-
-/* 20140415 CY */
-static int rt5025_read_reg(struct i2c_client *client,
- u8 reg, u8 *data, u8 len)
-{
- return rt5025_reg_block_read(client, reg, len, data);
-}
-
-static int rt5025_write_reg(struct i2c_client *client,
- u8 reg, u8 *data, u8 len)
-{
- return rt5025_reg_block_write(client, reg, len, data);
-}
-
-static void rt5025_set_battery_led(struct rt5025_battery_info *bi, int status)
-{
- switch (status) {
- case POWER_SUPPLY_STATUS_CHARGING:
- break;
- case POWER_SUPPLY_STATUS_DISCHARGING:
- break;
- case POWER_SUPPLY_STATUS_FULL:
- break;
- default:
- break;
- }
-}
-
-static int rt5025_set_property(struct power_supply *psy,
- enum power_supply_property psp,
- const union power_supply_propval *val)
-{
- struct rt5025_battery_info *bi = dev_get_drvdata(psy->dev->parent);
- int rc = 0;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- if (val->intval == POWER_SUPPLY_STATUS_FULL) {
- bi->tp_flag = true;
- pr_info("%s: Battery is full \n", __func__);
- } else {
- mutex_lock(&bi->status_change_lock);
- bi->status = val->intval;
- if (bi->status == POWER_SUPPLY_STATUS_DISCHARGING)
- bi->tp_flag = false;
- rt5025_set_battery_led(bi, bi->status);
- mutex_unlock(&bi->status_change_lock);
- }
- wake_lock_timeout(&bi->status_wake_lock, 1.5*HZ);
- schedule_delayed_work(&bi->monitor_work, msecs_to_jiffies(100));
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- bi->batt_present = val->intval;
- break;
- default:
- rc = -EINVAL;
- break;
- }
- return rc;
-}
-
-static int rt5025_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct rt5025_battery_info *bi = dev_get_drvdata(psy->dev->parent);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = bi->status;
- /*val->intval = POWER_SUPPLY_STATUS_CHARGING;*/
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- val->intval = bi->health;
- /*If there's no battery, always show battery health to good.*/
- if (!bi->present || !bi->batt_present)
- val->intval = POWER_SUPPLY_HEALTH_GOOD;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- val->intval = bi->present;
- break;
- case POWER_SUPPLY_PROP_TEMP:
- if (val->intval == 23) {
- rt5025_get_external_temp(bi);
- val->intval = bi->ext_temp;
- } else {
- /*If there's no battery, always show battery temperature to 25'c.*/
- if (!bi->present || !bi->batt_present)
- val->intval = 250;
- else
- val->intval = bi->ext_temp;
- }
- break;
- case POWER_SUPPLY_PROP_TEMP_AMBIENT:
- rt5025_get_internal_temp(bi);
- val->intval = bi->int_temp;
- break;
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = bi->online;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- rt5025_get_vcell(bi);
- val->intval = bi->vcell * 1000; /*uv*/
- break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- rt5025_get_current(bi);
- val->intval = bi->curr * 1000; /*uA*/
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = bi->soc;
- if (val->intval > 100)
- val->intval = 100;
- /*If there's no battery, always show capacity to 50*/
- if (!bi->present || !bi->batt_present)
- val->intval = 50;
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static void rt5025_get_vcell(struct rt5025_battery_info *bi)
-{
- u8 data[2];
-
- if (rt5025_read_reg(bi->client, RT5025_REG_VBATSH, data, 2) < 0)
- pr_err("%s: Failed to read Voltage\n", __func__);
-
- if (bi->avg_flag)
- bi->vcell = ((data[0] << 8) + data[1]) * 61 / 100;
- else
- bi->vcell =
- (bi->vcell + ((data[0] << 8) + data[1]) * 61 / 100) / 2;
-#if RT5025_B
-
- /*b. Remove current offset compensation; 2013/12/17*/
- bi->curr_offset = 0;
- /*bi->curr_offset = (15444 * bi->vcell - 27444000) / 10000;*/
-
-#else
- if (37 * bi->vcell > 92000)
- bi->curr_offset = (37 * bi->vcell - 92000) / 1000;
- else
- bi->curr_offset = 0;
-#endif
-
-#if RT5025_CSV
- /* if (!bi->avg_flag)*/
- /* pr_info("%d,%d,", bi->vcell, bi->curr_offset);*/
-#else
- if (bi->avg_flag)
- RTINFO("vcell_pre: %d, offset: %d\n", bi->vcell, bi->curr_offset);
- else
- RTINFO("vcell_avg: %d, offset: %d\n", bi->vcell, bi->curr_offset);
-#endif
-}
-
-static void rt5025_get_current(struct rt5025_battery_info *bi)
-{
- u8 data[2];
- s32 temp;
- int sign = 0;
- u8 curr_region;
-
- if (rt5025_read_reg(bi->client, RT5025_REG_CURRH, data, 2) < 0)
- pr_err("%s: Failed to read CURRENT\n", __func__);
-
-#if RT5025_B
- temp = (data[0] << 8) | data[1];
- bi->curr_raw = ((temp & 0x7FFF) * 3125) / 10000;
-
- if (data[0] & (1 << 7)) {
- sign = 1;
- temp = (((temp & 0x7FFF) * 3125) / 10 + bi->curr_offset) / 1000;
- } else {
- if ((temp * 3125) / 10 > bi->curr_offset)
- temp = ((temp * 3125) / 10 - bi->curr_offset) / 1000;
- }
- if (temp < DEADBAND)
- temp = 0;
- if (sign) {
- temp *= -1;
- bi->curr_raw *= -1;
- }
-#else
- temp = (data[0] << 8) | data[1];
- if (data[0] & (1 << 7)) {
- sign = 1;
- temp = temp & 0x7FFF;
- if (temp > bi->curr_offset)
- temp = temp - bi->curr_offset;
- } else {
- temp = temp + bi->curr_offset;
- }
- temp = (temp * 37375) / 100000; /*Unit: 0.3125mA*/
- if (temp < DEADBAND)
- temp = 0;
- if (sign)
- temp *= -1;
-#endif
-
- if (bi->avg_flag)
- bi->curr = temp;
- else
- bi->curr = (bi->curr + temp) / 2;
-
- if (bi->curr > -500)
- curr_region = 0;
- else if (bi->curr <= -500 && bi->curr > -1500)
- curr_region = 1;
- else
- curr_region = 2;
-
- if (curr_region != bi->edv_region) {
- switch (curr_region) {
- case 0:
- bi->empty_edv = rt5025_battery_param2[4].x;
- break;
- case 1:
- bi->empty_edv = rt5025_battery_param2[4].x - 75;
- break;
- case 2:
- bi->empty_edv = rt5025_battery_param2[4].x - 100;
- break;
- }
- bi->edv_region = curr_region;
- }
- RTINFO("empty_voltage=%d\n", bi->empty_edv);
-
- if (bi->curr > 0) {
- bi->internal_status = POWER_SUPPLY_STATUS_CHARGING;
- bi->last_tp_flag = false;
- /*b. add fcc update flag; 2013/12/18*/
- bi->fcc_update_flag = true;
- } else {
- bi->internal_status = POWER_SUPPLY_STATUS_DISCHARGING;
- }
- RTINFO("current=%d, internal_status=%d\n", bi->curr, bi->internal_status);
-
-#if RT5025_CSV
- /*if (!bi->avg_flag)*/
- /*pr_info("%d,",bi->curr);*/
-#else
- if (bi->avg_flag)
- RTINFO("current_pre: %d\n", bi->curr);
- else
- RTINFO("current_avg: %d\n", bi->curr);
-#endif
-}
-
-static void rt5025_get_internal_temp(struct rt5025_battery_info *bi)
-{
- u8 data[2];
- s32 temp;
-
- if (rt5025_read_reg(bi->client, RT5025_REG_INTEMPH, data, 2) < 0)
- pr_err("%s: Failed to read internal TEMPERATURE\n", __func__);
-
- temp = ((data[0] & 0x1F) << 8) + data[1];
- temp *= 15625;
- temp /= 100000;
-
- temp = (data[0] & 0x20) ? -temp : temp;
- bi->int_temp = temp;
- RTINFO("internal temperature: %d\n", bi->int_temp);
-}
-
-static void rt5025_get_external_temp(struct rt5025_battery_info *bi)
-{
- u8 data[2];
- s32 temp;
-
- if (rt5025_read_reg(bi->client, RT5025_REG_AINH, data, 2) < 0)
- pr_err("%s: Failed to read TEMPERATURE\n", __func__);
- bi->ain_volt = (data[0] * 256 + data[1]) * 61 / 100;
- if (bi->ain_volt < 1150)
- bi->present = 1;
- else
- bi->present = 0;
-
- temp = (bi->ain_volt * (-91738) + 81521000) / 100000;
- bi->ext_temp = (int)temp;
- /*test bi->ext_temp = 250;*/
-
- if (bi->ext_temp >= HIGH_TEMP_THRES) {
- if (bi->health != POWER_SUPPLY_HEALTH_OVERHEAT)
- bi->temp_high_cnt++;
- } else if (bi->ext_temp <= HIGH_TEMP_RECOVER
- && bi->ext_temp >= LOW_TEMP_RECOVER) {
- if (bi->health == POWER_SUPPLY_HEALTH_OVERHEAT
- || bi->health == POWER_SUPPLY_HEALTH_COLD)
- bi->temp_recover_cnt++;
- } else if (bi->ext_temp <= LOW_TEMP_THRES) {
- if (bi->health != POWER_SUPPLY_HEALTH_COLD)
- bi->temp_low_cnt++;
- } else {
- bi->temp_high_cnt = 0;
- bi->temp_low_cnt = 0;
- bi->temp_recover_cnt = 0;
- }
-
- if (bi->temp_high_cnt >= TEMP_ABNORMAL_COUNT) {
- bi->health = POWER_SUPPLY_HEALTH_OVERHEAT;
- bi->temp_high_cnt = 0;
- } else if (bi->temp_low_cnt >= TEMP_ABNORMAL_COUNT) {
- bi->health = POWER_SUPPLY_HEALTH_COLD;
- bi->temp_low_cnt = 0;
- } else if (bi->temp_recover_cnt >= TEMP_ABNORMAL_COUNT) {
- bi->health = POWER_SUPPLY_HEALTH_GOOD;
- bi->temp_recover_cnt = 0;
- }
- RTINFO("external temperature: %d\n", bi->ext_temp);
-}
-
-static void rt5025_clear_cc(struct rt5025_battery_info *bi, operation_mode mode)
-{
- u8 data[2];
-
- if (rt5025_read_reg(bi->client, RT5025_REG_CHANNELH, data, 2) < 0)
- pr_err("%s: failed to read channel\n", __func__);
-
- if (mode == CHG)
- data[0] = data[0] | CHANNEL_H_BIT_CLRQCHG;
- else
- data[0] = data[0] | CHANNEL_H_BIT_CLRQDCHG;
-
- if (rt5025_write_reg(bi->client, RT5025_REG_CHANNELH, data, 2) < 0)
- pr_err("%s: failed to write channel\n", __func__);
-}
-
-static void rt5025_get_chg_cc(struct rt5025_battery_info *bi)
-{
- u8 data[4];
- u32 qh_old, ql_old, qh_new, ql_new;
- u32 cc_masec, offset = 0;
-
- if (rt5025_read_reg(bi->client, RT5025_REG_QCHGHH, data, 4) < 0)
- pr_err("%s: Failed to read QCHG\n", __func__);
-
- qh_old = (data[0]<<8) + data[1];
- ql_old = (data[2]<<8) + data[3];
- RTINFO("qh_old=%d, ql_old=%d\n", qh_old, ql_old);
-
- if (rt5025_read_reg(bi->client, RT5025_REG_QCHGHH, data, 4) < 0)
- pr_err("%s: Failed to read QCHG\n", __func__);
-
- qh_new = (data[0]<<8) + data[1];
- ql_new = (data[2]<<8) + data[3];
- RTINFO("qh_new=%d, ql_new=%d\n", qh_new, ql_new);
-
-#if RT5025_B
- if (qh_new > qh_old) {
- /*cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;*/
- cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
- } else if (qh_new == qh_old) {
- if (ql_new >= ql_old) {
- /*cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;*/
- cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
- } else {
- /*cc_masec = (((qh_old<<16) + ql_old) * 50134) / 10;*/
- cc_masec = qh_old*328558+(qh_old*1824+ql_old*50134)/10000;
- }
- }
-
- if (!bi->init_once)
- offset = bi->curr_offset * bi->time_interval;
- if (cc_masec > offset)
- cc_masec = cc_masec - (offset / 1000);
-#else
- if (qh_new > qh_old) {
- cc_masec = (((qh_new << 16) + ql_new) * 5996) / 1000;
- } else if (qh_new == qh_old) {
- if (ql_new >= ql_old)
- cc_masec = (((qh_new<<16) + ql_new) * 5996) / 1000;
- else
- cc_masec = (((qh_old<<16) + ql_old) * 5996) / 1000;
- }
-
- offset = (bi->curr_offset * bi->time_interval * 37375) / 100000;
-
- if (cc_masec != 0)
- cc_masec = cc_masec - offset;
-#endif
- if (cc_masec < (DEADBAND * bi->time_interval))
- cc_masec = 0;
-
-#if RT5025_CSV
-#else
- RTINFO("chg_cc_mAsec: %d\n", cc_masec);
-#endif
-
- /*if (!bi->init_once)*/
- bi->chg_cc = cc_masec;
- /*bi->chg_cc = (cc_masec + bi->chg_cc_unuse) / 3600;*/
- /*bi->chg_cc_unuse = (cc_masec + bi->chg_cc_unuse) % 3600;*/
- rt5025_clear_cc(bi, CHG);
-}
-
-static void rt5025_get_dchg_cc(struct rt5025_battery_info *bi)
-{
- u8 data[4];
- u32 qh_old, ql_old, qh_new, ql_new;
- u32 cc_masec, offset = 0;
-
- if (rt5025_read_reg(bi->client, RT5025_REG_QDCHGHH, data, 4) < 0)
- pr_err("%s: Failed to read QDCHG\n",
- __func__);
-
- qh_old = (data[0] << 8) + data[1];
- ql_old = (data[2] << 8) + data[3];
-
- if (rt5025_read_reg(bi->client, RT5025_REG_QDCHGHH, data, 4) < 0)
- pr_err("%s: Failed to read QDCHG\n",
- __func__);
-
- qh_new = (data[0] << 8) + data[1];
- ql_new = (data[2] << 8) + data[3];
-
-#if RT5025_B
- if (qh_new > qh_old) {
- /*cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;*/
- cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
- } else if (qh_new == qh_old) {
- if (ql_new >= ql_old) {
- /*cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;*/
- cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
- } else {
- /*cc_masec = (((qh_old<<16) + ql_old) * 50134) / 10;*/
- cc_masec = qh_old*328558+(qh_old*1824+ql_old*50134)/10000;
- }
- }
- if (!bi->init_once)
- offset = bi->curr_offset * bi->time_interval;
- if (cc_masec != 0)
- cc_masec = cc_masec + (offset / 1000);
-#else
- if (qh_new > qh_old) {
- cc_masec = (((qh_new<<16) + ql_new) * 5996) / 1000;
- } else if (qh_new == qh_old) {
- if (ql_new >= ql_old)
- cc_masec = (((qh_new<<16) + ql_new) * 5996) / 1000;
- else
- cc_masec = (((qh_old<<16) + ql_old) * 5996) / 1000;
- }
-
- offset = (bi->curr_offset * bi->time_interval * 37375) / 100000;
-
- if (cc_masec > offset)
- cc_masec = cc_masec - offset;
-#endif
- if (cc_masec < (DEADBAND * bi->time_interval))
- cc_masec = 0;
-
-#if RT5025_CSV
-#else
- RTINFO("dchg_cc_mAsec: %d\n", cc_masec);
-#endif
- bi->dchg_cc = cc_masec;
- /*b. add fcc update flag; 2013/12/18*/
- if ((bi->last_tp_flag) && (bi->fcc_update_flag))
- bi->cal_fcc += cc_masec;
- else
- bi->cal_fcc = 0;
-
- RTINFO("bi->cal_fcc=%d, bi->last_tp_flag=%d\n",
- bi->cal_fcc, bi->last_tp_flag);
- /*bi->dchg_cc = (cc_masec + bi->dchg_cc_unuse) / 3600;*/
- /*bi->dchg_cc_unuse = (cc_masec + bi->dchg_cc_unuse) % 3600;*/
- rt5025_clear_cc(bi, DCHG);
-
-}
-
-static void rt5025_cycle_count(struct rt5025_battery_info *bi)
-{
- bi->acc_dchg_cap += bi->dchg_cc;
- if (bi->acc_dchg_cap >= (bi->dc * 3600)) {
- bi->cycle_cnt++;
- bi->acc_dchg_cap -= (bi->dc * 3600);
- }
-}
-
-static void rt5025_get_irq_flag(struct rt5025_battery_info *bi, u8 flag)
-{
- bi->irq_flag = flag;
- /*RTINFO("IRQ_FLG 0x%x\n", bi->irq_flag);*/
-}
-
-static void rt5025_get_timer(struct rt5025_battery_info *bi)
-{
- u8 data[2];
-
- if (rt5025_read_reg(bi->client, RT5025_REG_TIMERH, data, 2) < 0)
- pr_err("%s: Failed to read Timer\n", __func__);
-
- bi->gauge_timer = (data[0] << 8) + data[1];
- if (!bi->device_suspend) {
- if (bi->gauge_timer > bi->pre_gauge_timer)
- bi->time_interval = bi->gauge_timer - bi->pre_gauge_timer;
- else
- bi->time_interval = 65536 - bi->pre_gauge_timer + bi->gauge_timer;
- }
-
- bi->pre_gauge_timer = bi->gauge_timer;
-#if RT5025_CSV
- /*pr_info("%d,%d,", bi->gauge_timer,bi->time_interval);*/
-#else
- RTINFO("timer %d , interval %d\n", bi->gauge_timer, bi->time_interval);
-#endif
-}
-
-static void rt5025_alert_setting(struct rt5025_battery_info *bi,
- alert_type type, bool enable)
-{
- u8 data[1];
-
- if (rt5025_read_reg(bi->client, RT5025_REG_IRQCTL, data, 1) < 0)
- pr_err("%s: Failed to read CONFIG\n", __func__);
-
- if (enable) {
- switch (type) {
- case MAXTEMP:
- data[0] |= IRQ_CTL_BIT_TMX;
- /*Enable max temperature alert*/
- bi->max_temp_irq = true;
- /*RTDBG("Enable min temperature alert");*/
- break;
- case MINTEMP:
- data[0] |= IRQ_CTL_BIT_TMN;
- /*Enable min temperature alert*/
- bi->min_temp_irq = true;
- /*RTDBG("Enable max temperature alert");*/
- break;
- case MAXVOLT:
- data[0] |= IRQ_CTL_BIT_VMX;
- /*Enable max voltage alert*/
- bi->max_volt_irq = true;
- /*RTDBG("Enable max voltage alert");*/
- break;
- case MINVOLT1:
- data[0] |= IRQ_CTL_BIT_VMN1;
- /*Enable min1 voltage alert*/
- bi->min_volt1_irq = true;
- /*RTDBG("Enable min1 voltage alert");*/
- break;
- case MINVOLT2:
- data[0] |= IRQ_CTL_BIT_VMN2;
- /*Enable min2 voltage alert*/
- bi->min_volt2_irq = true;
- /*RTDBG("Enable min2 voltage alert");*/
- break;
- default:
- break;
- }
- } else {
- switch (type) {
- case MAXTEMP:
- data[0] = data[0] & ~IRQ_CTL_BIT_TMX;
- /*Disable max temperature alert*/
- bi->max_temp_irq = false;
- /*RTDBG("Disable min temperature alert");*/
- break;
- case MINTEMP:
- data[0] = data[0] & ~IRQ_CTL_BIT_TMN;
- /*Disable min temperature alert*/
- bi->min_temp_irq = false;
- /*RTDBG("Disable max temperature alert");*/
- break;
- case MAXVOLT:
- data[0] = data[0] & ~IRQ_CTL_BIT_VMX;
- /*Disable max voltage alert*/
- bi->max_volt_irq = false;
- /*RTDBG("Disable max voltage alert");*/
- break;
- case MINVOLT1:
- data[0] = data[0] & ~IRQ_CTL_BIT_VMN1;
- /*Disable min1 voltage alert*/
- bi->min_volt1_irq = false;
- /*RTDBG("Disable min1 voltage alert");*/
- break;
- case MINVOLT2:
- data[0] = data[0] & ~IRQ_CTL_BIT_VMN2;
- /*Disable min2 voltage alert*/
- bi->min_volt2_irq = false;
- /*RTDBG("Disable min2 voltage alert");*/
- break;
- default:
- break;
- }
- }
- if (rt5025_write_reg(bi->client, RT5025_REG_IRQCTL, data, 1) < 0)
- pr_err("%s: failed to write IRQ control\n", __func__);
-}
-
-static void rt5025_alert_threshold_init(struct i2c_client *client)
-{
- u8 data[1];
-
- /* VALRT MAX threshold setting */
- data[0] = irq_thres[MAXVOLT];
- if (rt5025_write_reg(client, RT5025_REG_VALRTMAX, data, 1) < 0)
- pr_err("%s: failed to write VALRT MAX threshold\n",
- __func__);
- /* VALRT MIN1 threshold setting */
- data[0] = irq_thres[MINVOLT1];
- if (rt5025_write_reg(client, RT5025_REG_VALRTMIN1, data, 1) < 0)
- pr_err("%s: failed to write VALRT MIN1 threshold\n",
- __func__);
- /* VALRT MIN2 threshold setting */
- data[0] = irq_thres[MINVOLT2];
- if (rt5025_write_reg(client, RT5025_REG_VALRTMIN2, data, 1) < 0)
- pr_err("%s: failed to write VALRT MIN2 threshold\n",
- __func__);
-}
-
-static void rt5025_alert_init(struct rt5025_battery_info *bi)
-{
-
- /* Set RT5025 gauge alert configuration */
- rt5025_alert_threshold_init(bi->client);
- /* Enable gauge alert function */
- rt5025_alert_setting(bi, MINVOLT2, VOLTAGE_ALERT);
-}
-
-void rt5025_gauge_irq_handler(struct rt5025_battery_info *bi,
- unsigned int irq_flag)
-{
- rt5025_get_irq_flag(bi, irq_flag);
-
- if ((bi->irq_flag) & IRQ_FLG_BIT_TMX) {
- /*printk(KERN_INFO "[RT5025]: Min temperature IRQ received\n");*/
- rt5025_alert_setting(bi, MAXTEMP, false);
- bi->max_temp_irq = false;
- }
- if ((bi->irq_flag) & IRQ_FLG_BIT_TMN) {
- /*printk(KERN_INFO "[RT5025]: Max temperature IRQ received\n");*/
- rt5025_alert_setting(bi, MINTEMP, false);
- bi->min_temp_irq = false;
- }
- if ((bi->irq_flag) & IRQ_FLG_BIT_VMX) {
- /*printk(KERN_INFO "[RT5025]: Max voltage IRQ received\n");*/
- rt5025_alert_setting(bi, MAXVOLT, false);
- bi->max_volt_irq = false;
- }
- if ((bi->irq_flag) & IRQ_FLG_BIT_VMN1) {
- /*printk(KERN_INFO "[RT5025]: Min voltage1 IRQ received\n");*/
- rt5025_alert_setting(bi, MINVOLT1, false);
- bi->min_volt1_irq = false;
- }
- if ((bi->irq_flag) & IRQ_FLG_BIT_VMN2) {
- /*printk(KERN_INFO "[RT5025]: Min voltage2 IRQ received\n");*/
- rt5025_alert_setting(bi, MINVOLT2, false);
- bi->min_volt2_irq = false;
- bi->min_volt2_alert = true;
- wake_lock_timeout(&bi->low_battery_wake_lock,
- msecs_to_jiffies(LOW_BAT_WAKE_LOK_TIME *
- MSEC_PER_SEC));
- }
-}
-EXPORT_SYMBOL(rt5025_gauge_irq_handler);
-
-static void rt5025_convert_masec_to_permille(struct rt5025_battery_info *bi)
-{
- bi->permille = bi->rm / 3600 * 1000 / bi->fcc;
- RTINFO("permille=%d\n", bi->permille);
- /*return;*/
-}
-
-static void rt5025_convert_permille_to_masec(struct rt5025_battery_info *bi)
-{
- bi->rm = bi->permille * bi->fcc / 1000 * 3600;
- /*return;*/
-}
-
-static void rt5025_init_capacity(struct rt5025_battery_info *bi)
-{
- int i = 1;
- int size;
- int slope, const_term;
- int delta_y, delta_x;
-
- size = ARRAY_SIZE(rt5025_battery_param1);
- while ((bi->vcell < rt5025_battery_param1[i].x) &&
- (i < (size - 1))) {
- i++;
- }
-
- delta_x = rt5025_battery_param1[i-1].x - rt5025_battery_param1[i].x;
- delta_y = (rt5025_battery_param1[i-1].y - rt5025_battery_param1[i].y);
-
- slope = delta_y * 1000 / delta_x;
-
- const_term = (rt5025_battery_param1[i].y) - ((rt5025_battery_param1[i].x * slope) / 1000);
-
- if (bi->vcell >= rt5025_battery_param1[0].x)
- bi->permille = rt5025_battery_param1[0].y;
- else if (bi->vcell <= rt5025_battery_param1[size-1].x)
- bi->permille = rt5025_battery_param1[size-1].y;
- else
- bi->permille = (bi->vcell * slope) / 1000 + const_term;
- rt5025_convert_permille_to_masec(bi);
- bi->soc = bi->rm / 36 / bi->fcc_aging;
- bi->init_cap = false;
-
- rt5025_battery_parameter_backup(bi);
-
- RTINFO("voltage=%d, permille=%d, soc=%d, rm=%d\n",
- bi->vcell, bi->permille, bi->soc, bi->rm);
- /*return;*/
-}
-
-static void rt5025_smooth_soc(struct rt5025_battery_info *bi)
-{
- if ((bi->internal_status == POWER_SUPPLY_STATUS_CHARGING || bi->tp_flag) &&
- (bi->soc < 100)) {
- if (bi->last_suspend == true) {
- bi->soc = 100;
- bi->last_suspend = false;
- } else {
- bi->soc++;
- }
- bi->rm = bi->fcc * bi->soc * 36;
- rt5025_convert_masec_to_permille(bi);
-
- if (bi->soc == 100) {
- /*fcc update in soc smooth 100%.*/
- if (bi->cal_soc_offset != 0) {
- bi->fcc_aging -= bi->cal_soc_offset;
- if ((200 <= bi->ext_temp) && (bi->ext_temp <= 300)) {
- bi->fcc = bi->fcc_aging;
- bi->rm = bi->fcc * bi->soc * 36;
- } else {
- rt5025_temp_comp(bi);
- }
- bi->cal_soc_offset = 0;
- }
- wake_unlock(&bi->smooth100_wake_lock);
- bi->last_tp = true;
- bi->tp_flag = false;
- bi->pre_soc = bi->soc;
-
- /*c. Only EOC occurs and full discharge to update FCC; 2013/12/17*/
- bi->last_tp_flag = true;
- mutex_lock(&bi->status_change_lock);
- if (bi->status != POWER_SUPPLY_STATUS_DISCHARGING) {
- bi->status = POWER_SUPPLY_STATUS_FULL;
- rt5025_set_battery_led(bi, bi->status);
- }
- mutex_unlock(&bi->status_change_lock);
- }
- } else if ((bi->internal_status == POWER_SUPPLY_STATUS_DISCHARGING) &&
- (bi->soc > 0)) {
- if (bi->last_suspend == true) {
- bi->soc = 0;
- bi->last_suspend = false;
- } else {
- bi->soc--;
- }
- bi->rm = bi->fcc * bi->soc * 36;
- rt5025_convert_masec_to_permille(bi);
- if (bi->soc == 0)
- wake_unlock(&bi->smooth0_wake_lock);
- } else {
- bi->smooth_flag = false;
- bi->update_time = NORMAL_POLL;
- }
-}
-
-
-static void rt5025_soc_irreversible(struct rt5025_battery_info *bi)
-{
- if (!bi->init_once) {
- if (bi->internal_status == POWER_SUPPLY_STATUS_CHARGING) {
- if (bi->soc < bi->pre_soc)
- bi->soc = bi->pre_soc;
- } else if ((bi->internal_status == POWER_SUPPLY_STATUS_DISCHARGING) &&
- (bi->tp_flag == 0)) {
- if (bi->soc > bi->pre_soc)
- bi->soc = bi->pre_soc;
- }
- } else {
- bi->init_once = false;
- }
-
- if (bi->pre_soc != bi->soc)
- rt5025_battery_parameter_backup(bi);
-
- bi->pre_soc = bi->soc;
- RTINFO("pre_soc=%d, soc=%d, internal status=%d\n",
- bi->pre_soc, bi->soc, bi->internal_status);
-}
-
-static void rt5025_soc_lock(struct rt5025_battery_info *bi)
-{
- /*lock 99%*/
- u16 eoc_fcc_new = 0;
-
- RTINFO("internal status=%d, tp_flag=%d, soc=%d, soc99_lock_cnt=%d\n",
- bi->internal_status, bi->tp_flag, bi->soc,
- bi->soc99_lock_cnt);
- RTINFO("init_once=%d, rm=%d, soc=%d\n",
- bi->init_once, bi->rm, bi->soc);
-
- if (bi->soc >= 99) {
- if (bi->soc99_lock_cnt >= 3600) {
- bi->soc = 100;
- bi->permille = 1000;
- /*eoc fcc update function: when flag is true, update FCC.*/
- if (bi->cal_eoc_fcc != 0) {
- /*eoc fcc update function: fcc update limitation 3%*/
- eoc_fcc_new = bi->fcc_aging + bi->cal_eoc_fcc / 3600;
- if (eoc_fcc_new > ((bi->fcc_aging * 103) / 100))
- bi->fcc_aging = (bi->fcc_aging * 103) / 100;
- else
- bi->fcc_aging = eoc_fcc_new;
-
- if ((200 <= bi->ext_temp) && (bi->ext_temp <= 300)) {
- bi->fcc = bi->fcc_aging;
- bi->rm = bi->fcc * bi->permille * 36 / 10;
- } else {
- rt5025_temp_comp(bi);
- }
- bi->cal_eoc_fcc = 0;
- }
- wake_unlock(&bi->full_battery_wake_lock);
- bi->soc99_lock_cnt = 0;
- bi->last_tp = true;
- bi->tp_flag = false;
- bi->pre_soc = bi->soc;
- /*b. add fcc update flag; 2013/12/18*/
- bi->fcc_update_flag = false;
-
- /*a. When SOC = 100, report battery status is full; 2013/12/17
- bi->status = POWER_SUPPLY_STATUS_FULL;
- */
- } else if (bi->tp_flag) {
- RTINFO("before_eoc_fcc_new=%d\n", eoc_fcc_new);
- RTINFO("before_cal_eoc_fcc=%d\n", bi->cal_eoc_fcc);
- RTINFO("before_fcc_aging=%d\n", bi->fcc_aging);
- bi->soc = 100;
- bi->permille = 1000;
- if (bi->cal_eoc_fcc != 0) {
- /*fcc update in eoc occurs. */
- eoc_fcc_new = bi->fcc_aging + bi->cal_eoc_fcc/3600;
- if (eoc_fcc_new > ((bi->fcc_aging*103)/100))
- bi->fcc_aging = (bi->fcc_aging*103)/100;
- else
- bi->fcc_aging = eoc_fcc_new;
-
- RTINFO("after_eoc_fcc_new=%d\n", eoc_fcc_new);
- RTINFO("after_cal_eoc_fcc=%d\n", bi->cal_eoc_fcc);
- RTINFO("after_fcc_aging=%d\n", bi->fcc_aging);
- if ((200 <= bi->ext_temp) && (bi->ext_temp <= 300)) {
- bi->fcc = bi->fcc_aging;
- bi->rm = bi->fcc * bi->permille * 36 / 10;
- } else {
- rt5025_temp_comp(bi);
- }
- bi->cal_eoc_fcc = 0;
- } else if (bi->cal_soc_offset != 0) {
- bi->fcc_aging -= bi->cal_soc_offset;
- if ((200 <= bi->ext_temp) && (bi->ext_temp <= 300)) {
- bi->fcc = bi->fcc_aging;
- bi->rm = bi->fcc * bi->permille * 36 / 10;
- } else {
- rt5025_temp_comp(bi);
- }
- bi->cal_soc_offset = 0;
- }
-
- wake_unlock(&bi->full_battery_wake_lock);
- bi->soc99_lock_cnt = 0;
- bi->last_tp = true;
- bi->tp_flag = false;
- bi->pre_soc = bi->soc;
-
- /*c. Only EOC occurs and full discharge to update FCC; 2013/12/17*/
- bi->last_tp_flag = true;
-
- mutex_lock(&bi->status_change_lock);
- if (bi->status != POWER_SUPPLY_STATUS_DISCHARGING) {
- bi->status = POWER_SUPPLY_STATUS_FULL;
- rt5025_set_battery_led(bi, bi->status);
- }
- mutex_unlock(&bi->status_change_lock);
- } else if ((bi->internal_status == POWER_SUPPLY_STATUS_CHARGING) &&
- (bi->last_tp == false)) {
- bi->soc = 99;
- bi->pre_soc = 99;
- bi->soc99_lock_cnt += bi->time_interval;
- }
- } else if ((bi->soc < 99) && (bi->tp_flag)) {
- /*calculate soc offset */
- if (bi->cal_soc_offset == 0) {
- bi->cal_soc_offset = bi->fcc*3600 - bi->rm;
- if (bi->cal_soc_offset > (bi->fcc_aging*3/100))
- bi->cal_soc_offset = bi->fcc_aging*3/100;
- }
- wake_lock(&bi->smooth100_wake_lock);
- bi->update_time = SMOOTH_POLL;
- bi->smooth_flag = true;
- rt5025_smooth_soc(bi);
- } else {
- wake_unlock(&bi->smooth100_wake_lock);
- bi->tp_flag = false;
- bi->soc99_lock_cnt = 0;
- }
- /* a. When SOC = 100, report battery status is full; 2013/12/17
- /// a. judge charging status to check battery full condition; 2013/12/18*/
- if ((bi->soc == 100) &&
- (bi->internal_status == POWER_SUPPLY_STATUS_CHARGING)) {
- mutex_lock(&bi->status_change_lock);
- if (bi->status != POWER_SUPPLY_STATUS_DISCHARGING) {
- bi->status = POWER_SUPPLY_STATUS_FULL;
- rt5025_set_battery_led(bi, bi->status);
- }
- mutex_unlock(&bi->status_change_lock);
- }
-
- /*lock 1% */
- if ((bi->soc <= 1) &&
- (bi->internal_status == POWER_SUPPLY_STATUS_DISCHARGING)) {
- if (bi->edv_flag) {
- bi->soc = 0;
- } else {
- if (bi->rm <= 0) {
- bi->soc1_lock_cnt += bi->time_interval;
- if (bi->soc1_lock_cnt >= 600) {
- bi->soc = 0;
- bi->soc1_lock_cnt = 0;
- } else {
- bi->soc = 1;
- bi->pre_soc = 1;
- }
- } else {
- bi->soc = 1;
- bi->pre_soc = 1;
- bi->soc1_lock_cnt = 0;
- }
- }
- } else if ((bi->soc > 1) &&
- (bi->internal_status == POWER_SUPPLY_STATUS_DISCHARGING) &&
- (bi->edv_flag)) {
- wake_lock(&bi->smooth0_wake_lock);
- bi->update_time = SMOOTH_POLL;
- bi->smooth_flag = true;
- rt5025_smooth_soc(bi);
- } else {
- bi->edv_flag = false;
- wake_unlock(&bi->smooth0_wake_lock);
- }
- RTINFO("cal_soc_offset=%d\n", bi->cal_soc_offset);
-}
-
-static void rt5025_get_soc(struct rt5025_battery_info *bi)
-{
- if (bi->smooth_flag) {
- bi->smooth_flag = false;
- bi->update_time = NORMAL_POLL;
- }
- RTINFO("before rm=%d\n", bi->rm);
- if ((!bi->tp_flag) && (!bi->edv_flag)) {
- bi->rm = (bi->rm + bi->chg_cc) > bi->dchg_cc ?
- bi->rm + bi->chg_cc - bi->dchg_cc : 0;
- if (bi->rm > (bi->fcc * 3600))
- bi->rm = bi->fcc * 3600;
-
- /* accumulate coulomb counter when rm = fcc and enable flag = true.*/
- if (bi->rm == (bi->fcc * 3600))
- bi->cal_eoc_fcc += (bi->chg_cc - bi->dchg_cc);
- else
- bi->cal_eoc_fcc = 0;
-
- RTINFO("cal_eoc_fcc=%d\n", bi->cal_eoc_fcc);
- rt5025_convert_masec_to_permille(bi);
- /*a. When SOC = 100, report battery status is full; 2113/12/17*/
- bi->soc = DIV_ROUND_UP(bi->permille, 10);
- }
-#if RT5025_CSV
- bi->temp_soc = bi->soc;
- /*pr_info("%d", bi->soc);*/
-#else
- RTINFO("after rm=%d\n", bi->rm);
- RTINFO("temp_soc=%d\n", bi->soc);
-#endif
-#if RT5025_CSV
- RTINFO("soc=%d, permille=%d, rm=%d, fcc=%d, smooth_flag=%d\n",
- bi->soc, bi->permille, bi->rm,
- bi->fcc, bi->smooth_flag);
- /*pr_info("%d,%d,%d,%d,%d", bi->soc,bi->permille,bi->rm,bi->fcc,bi->smooth_flag);*/
-#else
- RTINFO("soc=%d, permille=%d, rm=%d, fcc=%d, smooth_flag=%d\n",
- bi->soc, bi->permille, bi->rm,
- bi->fcc, bi->smooth_flag);
-#endif
- /*return;*/
-}
-
-static void rt5025_soc_relearn_check(struct rt5025_battery_info *bi)
-{
-
- if (bi->tp_flag == true) {
- bi->rm = bi->fcc * 3600;
- rt5025_convert_masec_to_permille(bi);
- bi->update_time = NORMAL_POLL;
- }
-
- if (bi->vcell <= bi->empty_edv) {
- if (bi->edv_cnt < 2)
- bi->edv_cnt++;
- } else {
- bi->edv_cnt = 0;
- }
-
- if (bi->empty_edv < bi->vcell && bi->vcell <= bi->empty_edv + 300) {
- bi->update_time = EDV_POLL;
- bi->edv_detection = true;
- } else if ((bi->vcell >= bi->empty_edv + 300 + EDV_HYS)
- && (bi->edv_detection == true)) {
- bi->update_time = NORMAL_POLL;
- bi->edv_detection = false;
- } else if ((bi->vcell <= bi->empty_edv && bi->edv_cnt == 2)) {
- bi->edv_flag = true;
- bi->rm = 0;
- rt5025_convert_masec_to_permille(bi);
- bi->edv_detection = false;
- bi->update_time = NORMAL_POLL;
- } else if ((bi->vcell > bi->empty_edv + EDV_HYS)) {
- bi->min_volt2_alert = false;
- bi->edv_flag = false;
- }
-
- if (bi->internal_status == POWER_SUPPLY_STATUS_CHARGING)
- bi->edv_flag = false;
-
-#if RT5025_CSV
-#else
- RTINFO("tp_cnt=%d, tp_flag=%d, edv_detection=%d, edv_cnt=%d, edv_flag=%d\n",
- bi->tp_cnt, bi->tp_flag, bi->edv_detection,
- bi->edv_cnt, bi->edv_flag);
-#endif
-
- /* return;*/
-}
-
-static u16 get_crc16_value(u8 *data, int size)
-{
- u16 fcs = 0xffff;
- int len = size;
- int i = 0;
- u16 temp = 0;
-
- while (len > 0) {
- fcs = (u16)((fcs >> 8) ^ crctab16[(fcs ^ data[i]) & 0xff]);
- len--;
- i++;
- }
- temp = (u16)~fcs;
- return temp;
-}
-
-static int IsCrc16Good(u8 *data, int size)
-{
- u16 fcs = 0xffff;
- int len = size;
- int i = 0;
-
- while (len > 0) {
- fcs = (u16)((fcs >> 8) ^ crctab16[((fcs ^ data[i]) & 0xff)]);
- len--;
- i++;
- }
- return (fcs == 0xf0b8);
-}
-
-static int rt5025_battery_parameter_backup(struct rt5025_battery_info *bi)
-{
- u16 crc_value = 0;
- u8 data[15] = {0};
-
- RTINFO("\n");
- /*backup fcc_aging, rm, cycle_count, acc_dchg_cap*/
- /*fcc_aging*/
- data[0] = (bi->fcc_aging >> 8) & 0xff;
- data[1] = (bi->fcc_aging) & 0xff;
- /*acc_dchg_cap*/
- data[2] = (bi->acc_dchg_cap >> 24) & 0xff;
- data[3] = (bi->acc_dchg_cap >> 16) & 0xff;
- data[4] = (bi->acc_dchg_cap >> 8) & 0xff;
- data[5] = (bi->acc_dchg_cap) & 0xff;
- /*cycle_count*/
- data[6] = (bi->cycle_cnt) & 0xff;
- /*soc*/
- data[7] = (bi->permille >> 8) & 0xff;
- data[8] = (bi->permille) & 0xff;
- /*gauge_timer*/
- data[9] = (bi->pre_gauge_timer >> 8) & 0xff;
- data[10] = bi->pre_gauge_timer & 0xff;
- /*CRC value*/
- crc_value = get_crc16_value(data, 13);
- data[13] = crc_value & 0xff;
- data[14] = (crc_value >> 8) & 0xff;
- rt5025_write_reg(bi->client, RT5025_REG_RESV1, data, 15);
- return 0;
-}
-
-static int rt5025_battery_parameter_restore(struct rt5025_battery_info *bi)
-{
- u8 data[15];
-
- RTINFO("\n");
- rt5025_read_reg(bi->client, RT5025_REG_RESV1, data, 15);
- /*restore fcc_aging, rm ,cycle_count, acc_dchg_cap*/
- /*fcc_aging*/
- bi->fcc = bi->fcc_aging = data[0] << 8 | data[1];
- /*acc_dchg_cap*/
- bi->acc_dchg_cap = data[2] << 24 | data[3] << 16 | data[4] << 8 | data[5];
- /*cycle_count*/
- bi->cycle_cnt = data[6];
- /*soc*/
- bi->permille = data[7] << 8 | data[8];
- /*pre_gauge_timer*/
- bi->pre_gauge_timer = bi->gauge_timer = (data[9] << 8) + data[10];
-
- return 0;
-}
-
-/*return value; 1-> initialized, 0-> no initial value*/
-static int rt5025_battery_parameter_initcheck(struct rt5025_battery_info *bi)
-{
- u8 data[15] = {0};
- int ret = 0;
-
- if (rt5025_read_reg(bi->client, RT5025_REG_RESV1, data, 15) < 0) {
- pr_err("%s: check initial value error\n", __func__);
- return 0;
- } else {
- ret = IsCrc16Good(data, 15);
- }
- RTINFO("initial check = %d\n", ret);
-
- return ret;
-}
-
-static void rt5025_register_init(struct rt5025_battery_info *bi)
-{
- u8 data[1];
-
- /* enable the channel of current,qc,ain,vbat and vadc */
- if (rt5025_read_reg(bi->client, RT5025_REG_CHANNELL, data, 1) < 0)
- pr_err("%s: failed to read channel\n", __func__);
-
- RTINFO("initial change enable=%02x\n", data[0]);
- data[0] = data[0] | CHANNEL_L_BIT_CADC_EN | CHANNEL_L_BIT_AINCH | \
- CHANNEL_L_BIT_VBATSCH | CHANNEL_L_BIT_VADC_EN | CHANNEL_L_BIT_INTEMPCH;
- if (rt5025_write_reg(bi->client, RT5025_REG_CHANNELL, data, 1) < 0)
- pr_err("%s: failed to write channel\n", __func__);
-
- /* set the alert threshold value */
- irq_thres[MINVOLT2] = VALRTMIN2_VALUE;
- irq_thres[VOLT_RLS] = VRLS_VALUE;
-
- bi->chg_cc_unuse = 0;
- bi->dchg_cc_unuse = 0;
- bi->pre_gauge_timer = 0;
- bi->online = 1;
- bi->batt_present = 1;
- bi->status = bi->internal_status = POWER_SUPPLY_STATUS_DISCHARGING;
- bi->health = POWER_SUPPLY_HEALTH_GOOD;
-
- bi->init_cap = true;
- bi->avg_flag = true;
-
- bi->fcc_aging = rt5025_battery_param2[4].y;
- bi->fcc = rt5025_battery_param2[4].y;
- bi->dc = rt5025_battery_param2[4].y;
- bi->rm = 0;
-
- bi->edv_cnt = 0;
- bi->edv_flag = false;
- bi->edv_detection = false;
- bi->init_once = true;
-
- bi->tp_cnt = 0;
- bi->tp_flag = false;
-
- bi->acc_dchg_cap = 0;
- bi->cycle_cnt = 0;
- bi->empty_edv = rt5025_battery_param2[4].x;
- bi->edv_region = 0;
- bi->soc1_lock_cnt = 0;
- /*eoc fcc update function: initial variable. */
- bi->cal_eoc_fcc = 0;
- bi->cal_soc_offset = 0;
-
-
- /*if has initial data, rewrite to the stored data*/
- if (rt5025_battery_parameter_initcheck(bi)) {
- bi->init_cap = false;
- rt5025_battery_parameter_restore(bi);
- bi->rm = bi->permille*bi->fcc_aging * 36 / 10;
- }
-
- bi->update_time = NORMAL_POLL;
- bi->device_suspend = false;
- RTINFO("register initialized\n");
-}
-
-static void rt5025_soc_aging(struct rt5025_battery_info *bi)
-{
- if (bi->cycle_cnt >= rt5025_battery_param2[3].x) {
- bi->fcc_aging = bi->fcc_aging * (1000 - rt5025_battery_param2[3].y) / 1000;
- bi->rm = bi->rm * (1000 - rt5025_battery_param2[3].y) / 1000;
- bi->cycle_cnt -= rt5025_battery_param2[3].x;
- }
- RTINFO("fcc_aging=%d, rm=%d, cycle_cnt=%d\n",
- bi->fcc_aging, bi->rm, bi->cycle_cnt);
-}
-
-static void rt5025_temp_comp(struct rt5025_battery_info *bi)
-{
- int i = 1;
- int size;
- int slope, const_term;
- int delta_y, delta_x;
-
- size = 3;
- while ((bi->ext_temp < rt5025_battery_param2[i].x) &&
- (i < (size - 1))) {
- i++;
- }
-
- delta_x = rt5025_battery_param2[i-1].x - rt5025_battery_param2[i].x;
- delta_y = (rt5025_battery_param2[i-1].y - rt5025_battery_param2[i].y);
-
- slope = delta_y * 1000 / delta_x;
-
- const_term = (rt5025_battery_param2[i].y) - ((rt5025_battery_param2[i].x * slope) / 1000);
-
- if (bi->ext_temp >= rt5025_battery_param2[0].x)
- bi->tempcmp = rt5025_battery_param2[0].y;
- else if (bi->ext_temp <= rt5025_battery_param2[size-1].x)
- bi->tempcmp = rt5025_battery_param2[size-1].y;
- else
- bi->tempcmp = (bi->ext_temp * slope) / 1000 + const_term;
-
- bi->fcc = bi->fcc_aging + bi->fcc_aging * bi->tempcmp / 1000;
- if (bi->fcc >= (bi->dc*3>>1))
- bi->fcc = bi->dc*3>>1;
- if (bi->fcc <= (bi->dc>>1))
- bi->fcc = bi->dc>>1;
- bi->rm = bi->fcc * bi->permille * 36 / 10;
- RTINFO("tempcmp=%d, ext_temp=%d, fcc=%d, rm=%d\n",
- bi->tempcmp, bi->ext_temp, bi->fcc, bi->rm);
- /*return; */
-}
-
-static void rt5025_soc_temp_comp(struct rt5025_battery_info *bi)
-{
- RTINFO("soc->%d++\n", bi->soc);
- bi->temp_range_0_5 = 0;
- bi->temp_range_5_10 = 0;
- bi->temp_range_10_15 = 0;
- bi->temp_range_15_20 = 0;
- bi->temp_range_20_30 = 0;
- bi->temp_range_30_35 = 0;
- bi->temp_range_35_40 = 0;
- bi->temp_range_40_45 = 0;
- bi->temp_range_45_50 = 0;
-
- if (bi->ext_temp < 50)
- bi->temp_range_0_5 = 1;
- else if (50 <= bi->ext_temp && bi->ext_temp < 100)
- bi->temp_range_5_10 = 1;
- else if (100 <= bi->ext_temp && bi->ext_temp < 150)
- bi->temp_range_10_15 = 1;
- else if (150 <= bi->ext_temp && bi->ext_temp < 200)
- bi->temp_range_15_20 = 1;
- else if (200 <= bi->ext_temp && bi->ext_temp <= 300)
- bi->temp_range_20_30 = 1;
- else if (300 < bi->ext_temp && bi->ext_temp <= 350)
- bi->temp_range_30_35 = 1;
- else if (350 < bi->ext_temp && bi->ext_temp <= 400)
- bi->temp_range_35_40 = 1;
- else if (400 < bi->ext_temp && bi->ext_temp <= 450)
- bi->temp_range_40_45 = 1;
- else if (450 < bi->ext_temp)
- bi->temp_range_45_50 = 1;
-
- if ((bi->temp_range_0_5 == 1) && (bi->range_0_5_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 1;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_5_10 == 1)
- && (bi->range_5_10_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 1;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_10_15 == 1)
- && (bi->range_10_15_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 1;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_15_20 == 1)
- && (bi->range_15_20_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 1;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_20_30 == 1)
- && (bi->range_20_30_done == 0)) {
- bi->fcc = bi->fcc_aging;
- bi->rm = bi->fcc * bi->permille * 36 / 10;
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 1;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_30_35 == 1)
- && (bi->range_30_35_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 1;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_35_40 == 1)
- && (bi->range_35_40_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 1;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_40_45 == 1)
- && (bi->range_40_45_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 1;
- bi->range_45_50_done = 0;
- } else if ((bi->temp_range_45_50 == 1)
- && (bi->range_45_50_done == 0)) {
- rt5025_temp_comp(bi);
- bi->range_0_5_done = 0;
- bi->range_5_10_done = 0;
- bi->range_10_15_done = 0;
- bi->range_15_20_done = 0;
- bi->range_20_30_done = 0;
- bi->range_30_35_done = 0;
- bi->range_35_40_done = 0;
- bi->range_40_45_done = 0;
- bi->range_45_50_done = 1;
- }
- RTINFO("soc->%d--\n", bi->soc);
-}
-
-static void rt5025_update(struct rt5025_battery_info *bi)
-{
- int batt_type = 1;
- /* Update voltage */
- rt5025_get_vcell(bi);
- /* Update current */
- rt5025_get_current(bi);
- /* Update internal temperature */
- rt5025_get_internal_temp(bi);
- /* Update external temperature */
- rt5025_get_external_temp(bi);
- /* Read timer */
- rt5025_get_timer(bi);
- /* Update chg cc */
- rt5025_get_chg_cc(bi);
- /* Update dchg cc */
- rt5025_get_dchg_cc(bi);
- /* Update cycle count check */
- rt5025_cycle_count(bi);
- /* Calculate cycle count */
- rt5025_soc_aging(bi);
- /* calculate initial soc */
- if (bi->init_cap) {
- rt5025_init_capacity(bi);
- #if RT5025_CSV
- pr_info("vcell,offset,current,timer,interval,QCHG,QDCHG,tp_cnt,tp_flag,edv_det,edv_cnt,edv_flag,soc,permille,RM,FCC,smooth_flag,acc_QD,cycle,update_time\n");
- #endif
- }
-
- /* Relearn SOC */
- rt5025_soc_relearn_check(bi);
- /* SOC_Temp_Comp*/
- rt5025_soc_temp_comp(bi);
- /* Update SOC */
- rt5025_get_soc(bi);
-
- /* SOC Control Process */
- rt5025_soc_lock(bi);
- rt5025_soc_irreversible(bi);
-
- if (bi->soc <= 99)
- bi->last_tp = false;
-
- if (rt5025_battery_param1[0].x >= 4250)
- batt_type = 0;
- else if (rt5025_battery_param1[0].x >= 4100)
- batt_type = 1;
-
- switch (batt_type) {
- case 0:
- if ((bi->vcell >= 4250) && (bi->internal_status == POWER_SUPPLY_STATUS_CHARGING))
- wake_lock(&bi->full_battery_wake_lock);
- else
- wake_unlock(&bi->full_battery_wake_lock);
- break;
- case 1:
- default:
- if ((bi->vcell >= 4100) && (bi->internal_status == POWER_SUPPLY_STATUS_CHARGING))
- wake_lock(&bi->full_battery_wake_lock);
- else
- wake_unlock(&bi->full_battery_wake_lock);
- break;
- }
-
- /* Update RTTF or RTTE */
-
-#if TEMPERATURE_ALERT
- if ((bi->max_temp_irq == false) &&
- (((irq_thres[MAXTEMP] * IRQ_THRES_UNIT) / 100 - bi->ain_volt) > irq_thres[TEMP_RLS])) {
- rt5025_alert_setting(bi, MAXTEMP, true);
- } else if ((bi->min_temp_irq == false) &&
- ((bi->ain_volt - (irq_thres[MINTEMP] * IRQ_THRES_UNIT) / 100) > irq_thres[TEMP_RLS])) {
- rt5025_alert_setting(bi, MINTEMP, true);
- }
-#endif
-
-#if VOLTAGE_ALERT
- if ((bi->min_volt2_irq == false) &&
- (bi->vcell > (bi->empty_edv + EDV_HYS)))
- rt5025_alert_setting(bi, MINVOLT2, true);
-#endif
- bi->last_suspend = false;
-#if RT5025_CSV
- printk(KERN_INFO "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
- bi->vcell, bi->curr_offset, bi->curr, bi->gauge_timer,
- bi->time_interval, bi->chg_cc, bi->dchg_cc,
- bi->tp_cnt, bi->tp_flag, bi->edv_detection,
- bi->edv_cnt, bi->edv_flag, bi->soc, bi->permille,
- bi->rm, bi->fcc, bi->smooth_flag, bi->acc_dchg_cap,
- bi->cycle_cnt, bi->update_time);
-#else
- RTINFO("[RT5025] update_time=%d\n", bi->update_time);
- RTINFO("\n");
-#endif
-}
-
-static void rt5025_update_work(struct work_struct *work)
-{
- struct delayed_work *delayed_work = (struct delayed_work *)container_of(work,
- struct delayed_work, work);
- struct rt5025_battery_info *bi = (struct rt5025_battery_info *)container_of(delayed_work,
- struct rt5025_battery_info, monitor_work);
-
- wake_lock(&bi->monitor_wake_lock);
- rt5025_update(bi);
- if (bi->soc != bi->last_soc) {
- power_supply_changed(&bi->battery);
- bi->last_soc = bi->soc;
- }
-
- wake_unlock(&bi->monitor_wake_lock);
- if (!bi->device_suspend)
- schedule_delayed_work(&bi->monitor_work, bi->update_time*HZ);
-}
-
-static enum power_supply_property rt5025_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_TEMP_AMBIENT,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_TECHNOLOGY,
-#if 0
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
- POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
-#endif
-};
-
-static int rt5025_battery_sleepvth_setting(struct rt5025_battery_info *bi)
-{
- u32 temp;
- u8 vmax_th, vmin_th;
- u8 vbat[2];
-
- RTINFO("\n");
- rt5025_read_reg(bi->client, RT5025_REG_VBATSH, vbat, 2);
- temp = ((vbat[0] << 8) + vbat[1]) * 61;
- vmax_th = (temp + 5000) / 1953;
- vmin_th = (temp - 5000) / 1953;
-
- rt5025_write_reg(bi->client, RT5025_REG_VALRTMAX, &vmax_th, 1);
- rt5025_write_reg(bi->client, RT5025_REG_VALRTMIN1, &vmin_th, 1);
-
- RTINFO("vmax_th=0x%02x, vmin_th=0x%02x\n", vmax_th, vmin_th);
- return 0;
-}
-
-static int rt5025_gauge_reginit(struct i2c_client *client)
-{
- rt5025_reg_block_write(client, RT5025_REG_VALRTMAX,
- 5, gauge_init_regval);
- rt5025_reg_write(client, RT5025_REG_IRQCTL, 0x00);
- rt5025_reg_read(client, RT5025_REG_IRQFLG);
- RTINFO("\n");
- return 0;
-}
-
-static int rt5025_battery_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct rt5025_battery_info *bi = platform_get_drvdata(pdev);
-
- RTINFO("\n");
- /*rt5025_get_timer(bi);*/
- /*bi->last_event = ktime_get();*/
- bi->last_event = current_kernel_time();
-
- /*cy add for battery parameter backup
- //rt5025_battery_parameter_backup(bi);
-
- //rt5025_channel_cc(bi, false);
- //rt5025_update(bi);*/
- bi->device_suspend = true;
- cancel_delayed_work_sync(&bi->monitor_work);
- /* prevent suspend before starting the alarm */
- /*bi->update_time = SUSPEND_POLL;*/
- rt5025_alert_setting(bi, MAXVOLT, false);
- rt5025_alert_setting(bi, MINVOLT1, false);
- rt5025_battery_sleepvth_setting(bi);
- if (bi->status == POWER_SUPPLY_STATUS_CHARGING)
- rt5025_alert_setting(bi, MAXVOLT, true);
- else if (bi->status == POWER_SUPPLY_STATUS_DISCHARGING)
- rt5025_alert_setting(bi, MINVOLT1, true);
- RTINFO("RM=%d\n", bi->rm);
- return 0;
-}
-
-static int rt5025_battery_resume(struct platform_device *pdev)
-{
- struct rt5025_battery_info *bi = platform_get_drvdata(pdev);
-
- /*ktime_t now;
- //struct timespec now = current_kernel_time();
- //struct timeval tv;
- //long time_interval;
-
- //now = ktime_get();
- //tv = ktime_to_timeval(ktime_sub(now, bi->last_event));
- //RTINFO("Sleep time = %d\n",(u32)tv.tv_sec);
- //bi->rm = bi->rm - ((u32)tv.tv_sec * SLEEP_CURRENT);
-
- //time_interval = now.tv_sec - bi->last_event.tv_sec;
- //bi->rm = bi->rm - (time_interval * SLEEP_CURRENT);
- //RTINFO("Sleep time=%d, RM=%d",(int)time_interval,bi->rm);
-
- //rt5025_channel_cc(bi, true);*/
- bi->last_suspend = true;
- bi->device_suspend = false;
- schedule_delayed_work(&bi->monitor_work, 0);
- RTINFO("\n");
- return 0;
-}
-
-static int rt5025_battery_remove(struct platform_device *pdev)
-{
- struct rt5025_battery_info *bi = platform_get_drvdata(pdev);
-
- power_supply_unregister(&bi->battery);
- cancel_delayed_work(&bi->monitor_work);
- wake_lock_destroy(&bi->monitor_wake_lock);
- RTINFO("\n");
- return 0;
-}
-
-static int rt5025_battery_probe(struct platform_device *pdev)
-{
- struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct rt5025_battery_info *bi;
- int ret;
-
- bi = devm_kzalloc(&pdev->dev, sizeof(*bi), GFP_KERNEL);
- if (!bi)
- return -ENOMEM;
-
- bi->client = chip->i2c;
-
- INIT_DELAYED_WORK(&bi->monitor_work, rt5025_update_work);
-
- wake_lock_init(&bi->monitor_wake_lock,
- WAKE_LOCK_SUSPEND, "rt-battery-monitor");
- wake_lock_init(&bi->low_battery_wake_lock,
- WAKE_LOCK_SUSPEND, "low_battery_wake_lock");
- wake_lock_init(&bi->status_wake_lock,
- WAKE_LOCK_SUSPEND, "battery-status-changed");
- wake_lock_init(&bi->smooth100_wake_lock,
- WAKE_LOCK_SUSPEND, "smooth100_soc_wake_lock");
- wake_lock_init(&bi->smooth0_wake_lock,
- WAKE_LOCK_SUSPEND, "smooth0_soc_wake_lock");
- wake_lock_init(&bi->full_battery_wake_lock,
- WAKE_LOCK_SUSPEND, "full_battery_wake_lock");
-#if RT5025_TEST_WAKE_LOCK
- wake_lock_init(&bi->test_wake_lock, WAKE_LOCK_SUSPEND, "rt-test");
-#endif
- mutex_init(&bi->status_change_lock);
- /* Write trimed data */
- /*rt5025_pretrim(client);*/
- rt5025_gauge_reginit(bi->client);
- /* enable channel */
- rt5025_register_init(bi);
- /* enable gauge IRQ */
- rt5025_alert_init(bi);
-
- /* register callback functions */
- /*
- chip->cb.rt5025_gauge_irq_handler = rt5025_irq_handler;
- chip->cb.rt5025_gauge_set_status = rt5025_set_status;
- chip->cb.rt5025_gauge_set_online = rt5025_set_online;
- chip->cb.rt5025_gauge_suspend = rt5025_gauge_suspend;
- chip->cb.rt5025_gauge_resume = rt5025_gauge_resume;
- chip->cb.rt5025_gauge_remove = rt5025_gauge_remove;
- rt5025_register_gauge_callbacks(&chip->cb);
- */
-
- platform_set_drvdata(pdev, bi);
-
- bi->battery.name = RT_BATT_NAME;
- bi->battery.type = POWER_SUPPLY_TYPE_BATTERY;
- bi->battery.set_property = rt5025_set_property;
- bi->battery.get_property = rt5025_get_property;
- bi->battery.properties = rt5025_battery_props;
- bi->battery.num_properties = ARRAY_SIZE(rt5025_battery_props);
-
- ret = power_supply_register(&pdev->dev, &bi->battery);
- if (ret) {
- pr_err("[RT5025] power supply register failed\n");
- goto err_wake_lock;
- }
-
- /*wake_lock(&bi->monitor_wake_lock);*/
-#if RT5025_TEST_WAKE_LOCK
- wake_lock(&bi->test_wake_lock);
-#endif
- schedule_delayed_work(&bi->monitor_work, INIT_POLL*HZ);
- chip->battery_info = bi;
-
- pr_info("rt5025-battery driver is successfully loaded\n");
-
- return 0;
-err_wake_lock:
- wake_lock_destroy(&bi->monitor_wake_lock);
- return ret;
-}
-
-static void rt5025_battery_shutdown(struct platform_device *pdev)
-{
- struct rt5025_battery_info *bi = platform_get_drvdata(pdev);
-
- RTINFO("\n");
- if (bi->soc == 0 && bi->cal_fcc != 0) {
- /*d. FCC update limitation +/-3%; 2013/12/27
- //bi->fcc_aging = bi->cal_fcc/3600 - (bi->fcc -bi->fcc_aging);*/
- u16 fcc_new = 0;
-
- fcc_new = bi->cal_fcc / 3600 - (bi->fcc - bi->fcc_aging);
- if (fcc_new > ((bi->fcc_aging * 103) / 100))
- bi->fcc_aging = (bi->fcc_aging * 103) / 100;
- else if (fcc_new < ((bi->fcc_aging * 97) / 100))
- bi->fcc_aging = (bi->fcc_aging * 97) / 100;
- else
- bi->fcc_aging = fcc_new;
-
- RTINFO("bi->cal_fcc=%d\n", bi->cal_fcc);
- }
- rt5025_battery_parameter_backup(bi);
- RTINFO("\n");
-}
-
-static struct of_device_id rt_match_table[] = {
- { .compatible = "rt,rt5025-battery",},
- {},
-};
-
-static struct platform_driver rt5025_battery_driver = {
- .driver = {
- .name = RT5025_DEV_NAME "-battery",
- .owner = THIS_MODULE,
- .of_match_table = rt_match_table,
- },
- .probe = rt5025_battery_probe,
- .remove = rt5025_battery_remove,
- .shutdown = rt5025_battery_shutdown,
- .suspend = rt5025_battery_suspend,
- .resume = rt5025_battery_resume,
-};
-
-static int rt5025_battery_init(void)
-{
- return platform_driver_register(&rt5025_battery_driver);
-}
-fs_initcall_sync(rt5025_battery_init);
-
-static void rt5025_battery_exit(void)
-{
- platform_driver_unregister(&rt5025_battery_driver);
-}
-module_exit(rt5025_battery_exit);
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Nick Hung <nick_hung@richtek.com>");
-MODULE_DESCRIPTION("battery gauge driver for RT5025");
-MODULE_ALIAS("platform:" RT5025_DEV_NAME "-battery");
-MODULE_VERSION(RT5025_DRV_VER);
diff --git a/drivers/power/rt5025-charger.c b/drivers/power/rt5025-charger.c
deleted file mode 100755
index d7aee678401a..000000000000
--- a/drivers/power/rt5025-charger.c
+++ /dev/null
@@ -1,1224 +0,0 @@
-/*
- * drivers/power/rt5025-charger.c
- * Driver for Richtek RT5025 PMIC Charger driver
- *
- * Copyright (C) 2014 Richtek Technology Corp.
- * cy_huang <cy_huang@richtek.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 as
- * published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/of.h>
-#include <linux/power_supply.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif /* #ifdef CONFIG_HAS_EARLYSUSPEND */
-
-#include <linux/mfd/rt5025.h>
-#include <linux/power/rt5025-charger.h>
-#ifdef CONFIG_RT_POWER
-#include <linux/power/rt-power.h>
-#endif /* #ifdef CONFIG_RT_POWER */
-
-static unsigned char chg_init_regval[] = {
- 0x12, /*REG 0x02*/
- 0x8C, /*REG 0x03*/
- 0x03, /*REG 0x04*/
- 0x20, /*REG 0x05*/
- 0x14, /*REG 0x06*/
- 0x40, /*REG 0x07*/
- 0xDA, /*REG 0x30*/
- 0xDA, /*REG 0x32*/
- 0x43, /*REG 0x34*/
-};
-
-static char *rtdef_chg_name = "rt-charger";
-
-static char *rt_charger_supply_list[] = {
- "none",
-};
-
-static enum power_supply_property rt_charger_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_CHARGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_MAX,
- POWER_SUPPLY_PROP_CURRENT_AVG,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
-};
-
-static void rt_charger_set_batt_status(struct rt5025_charger_info *ci);
-
-static int rt_charger_get_property(struct power_supply *psy, enum power_supply_property psp, \
- union power_supply_propval *val)
-{
- struct rt5025_charger_info *ci = dev_get_drvdata(psy->dev->parent);
- int ret = 0;
- int regval = 0;
- #ifdef CONFIG_BATTERY_RT5025
- struct power_supply *bat_psy = power_supply_get_by_name(RT_BATT_NAME);
- union power_supply_propval pval;
- #endif
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = ci->online;
- break;
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = ci->chg_status;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- regval = rt5025_reg_read(ci->i2c, RT5025_REG_CHGCTL7);
- if (regval < 0) {
- ret = -EINVAL;
- } else {
- if (regval & RT5025_CHGCEN_MASK)
- val->intval = 1;
- else
- val->intval = 0;
- }
- break;
- case POWER_SUPPLY_PROP_TEMP:
- val->intval = 0;
- #ifdef CONFIG_BATTERY_RT5025
- if (bat_psy) {
- ret = bat_psy->get_property(bat_psy, POWER_SUPPLY_PROP_TEMP_AMBIENT,\
- &pval);
- if (ret < 0)
- dev_err(ci->dev, "get ic temp fail\n");
- else
- val->intval = pval.intval;
- }
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- break;
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- val->intval = ci->charger_cable;
- break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- val->intval = 2000;
- break;
- case POWER_SUPPLY_PROP_CURRENT_AVG:
- regval = rt5025_reg_read(ci->i2c, RT5025_REG_CHGCTL4);
- if (regval < 0) {
- ret = -EINVAL;
- } else {
- regval &= RT5025_CHGAICR_MASK;
- regval >>= RT5025_CHGAICR_SHFT;
- switch (regval) {
- case 0:
- val->intval = 100;
- break;
- case 1:
- val->intval = 500;
- break;
- case 2:
- val->intval = 1000;
- break;
- case 3:
- val->intval = 0;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- }
- break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- regval = rt5025_reg_read(ci->i2c, RT5025_REG_CHGCTL4);
- if (regval < 0) {
- ret = -EINVAL;
- } else {
- regval &= RT5025_CHGICC_MASK;
- regval >>= RT5025_CHGICC_SHFT;
- val->intval = 500 + regval * 100;
- }
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- regval = rt5025_reg_read(ci->i2c, RT5025_REG_CHGCTL3);
- if (regval < 0) {
- ret = -EINVAL;
- } else {
- regval &= RT5025_CHGCV_MASK;
- regval >>= RT5025_CHGCV_SHFT;
- val->intval = regval * 20 + 3500;
- }
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = 3500;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- val->intval = 4440;
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int rt_charger_set_property(struct power_supply *psy, enum power_supply_property psp, \
- const union power_supply_propval *val)
-{
- struct rt5025_charger_info *ci = dev_get_drvdata(psy->dev->parent);
- int ret = 0;
- int regval = 0;
- RTINFO("prop = %d, val->intval = %d\n", psp, val->intval);
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- ci->online = val->intval;
- if (ci->online) {
- if (ci->te_en) {
- ret = rt5025_set_bits(ci->i2c, RT5025_REG_CHGCTL2, RT5025_CHGTEEN_MASK);
- /*charger workaround*/
- mdelay(150);
- /*turn on recharge irq enable*/
- chg_init_regval[8] |= RT5025_CHRCHGI_MASK;
- rt5025_reg_write(ci->i2c, RT5025_REG_IRQEN3, chg_init_regval[8]);
- /*turn on chterm irq enable*/
- chg_init_regval[7] |= RT5025_CHTERMI_MASK;
- rt5025_reg_write(ci->i2c, RT5025_REG_IRQEN2, chg_init_regval[7]);
- }
- ci->chg_status = POWER_SUPPLY_STATUS_CHARGING;
- rt_charger_set_batt_status(ci);
- } else {
- if (ci->te_en) {
- ret = rt5025_clr_bits(ci->i2c, RT5025_REG_CHGCTL2, RT5025_CHGTEEN_MASK);
- /*charger workaround*/
- /*turn off chterm irq enable*/
- chg_init_regval[7] &= ~RT5025_CHTERMI_MASK;
- rt5025_reg_write(ci->i2c, RT5025_REG_IRQEN2, chg_init_regval[7]);
- /*turn off recharge irq enable*/
- chg_init_regval[8] &= ~RT5025_CHRCHGI_MASK;
- rt5025_reg_write(ci->i2c, RT5025_REG_IRQEN3, chg_init_regval[8]);
- }
- ci->chg_status = POWER_SUPPLY_STATUS_DISCHARGING;
- rt_charger_set_batt_status(ci);
- }
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- if (ci->online && val->intval) {
- int icc;
- int battemp_icc;
- int inttemp_icc;
- union power_supply_propval pval;
-
- if (ci->charger_cable == POWER_SUPPLY_TYPE_MAINS)
- battemp_icc = inttemp_icc = (ci->screen_on ?\
- ci->screenon_icc:ci->acchg_icc);
- else if (ci->charger_cable == POWER_SUPPLY_TYPE_USB_DCP)
- battemp_icc = inttemp_icc = (ci->screen_on ?\
- ci->screenon_icc:ci->usbtachg_icc);
- else
- battemp_icc = inttemp_icc = (ci->screen_on ?\
- ci->screenon_icc:ci->usbchg_icc);
- if (ci->battemp_region == RT5025_BATTEMP_COLD ||\
- ci->battemp_region == RT5025_BATTEMP_HOT)
- battemp_icc = 10;
- else if (ci->battemp_region == RT5025_BATTEMP_COOL ||\
- ci->battemp_region == RT5025_BATTEMP_WARM)
- battemp_icc /= 2;
-
- if (ci->inttemp_region == RT5025_INTTEMP_WARM)
- inttemp_icc -= 300;
- else if (ci->inttemp_region == RT5025_INTTEMP_HOT)
- inttemp_icc -= 800;
-
- if (inttemp_icc < 0)
- inttemp_icc = 10;
-
- icc = min(battemp_icc, inttemp_icc);
- pval.intval = icc;
- ret = psy->set_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &pval);
- if (ret < 0)
- dev_err(ci->dev, "set final icc fail\n");
- }
- break;
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- ci->charger_cable = val->intval;
- break;
- case POWER_SUPPLY_PROP_CURRENT_AVG:
- if (0 < val->intval && val->intval <= 100)
- regval = 0;
- else if (val->intval <= 500)
- regval = 1;
- else if (val->intval <= 1000)
- regval = 2;
- else
- regval = 3;
- if (!ci->batabs)
- ret = rt5025_assign_bits(ci->i2c, RT5025_REG_CHGCTL4, \
- RT5025_CHGAICR_MASK, regval << RT5025_CHGAICR_SHFT);
- break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- if (val->intval < 0) {
- ci->otg_en = 1;
- regval = -1;
- #ifdef CONFIG_RT_SUPPORT_ACUSB_DUALIN
- ret = rt5025_set_bits(ci->i2c, RT5025_REG_CHGCTL2, RT5025_VBUSHZ_MASK);
- if (ret < 0)
- dev_err(ci->dev, "set vbus hz fail\n");
- #else
- ret = rt5025_clr_bits(ci->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBCEN_MASK);
- if (ret < 0)
- dev_err(ci->dev, "shutdown chg buck fail\n");
- #endif /* #ifdef CONFIG_RT_SUPPORT_ACUSB_DUALIN */
- } else if (val->intval == 0) {
- ci->otg_en = 0;
- regval = -1;
- #ifdef CONFIG_RT_SUPPORT_ACUSB_DUALIN
- ret = rt5025_clr_bits(ci->i2c, RT5025_REG_CHGCTL2, RT5025_VBUSHZ_MASK);
- if (ret < 0)
- dev_err(ci->dev, "clear vbus hz fail\n");
- #else
- ret = rt5025_set_bits(ci->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBCEN_MASK);
- if (ret < 0)
- dev_err(ci->dev, "turnon chg buck fail\n");
- #endif /* #ifdef CONFIG_RT_SUPPORT_ACUSB_DUALIN */
- } else if (val->intval > 0 && val->intval < 500) {
- regval = 0;
- } else if (val->intval > 2000) {
- regval = 15;
- } else {
- regval = (val->intval - 500) / 100;
- }
-
- if (regval >= 0)
- ret = rt5025_assign_bits(ci->i2c, RT5025_REG_CHGCTL4, RT5025_CHGICC_MASK, \
- regval<<RT5025_CHGICC_SHFT);
-
- if (val->intval > 0 && val->intval < 500)
- rt5025_clr_bits(ci->i2c, RT5025_REG_CHGCTL7, RT5025_CHGCEN_MASK);
- else
- rt5025_set_bits(ci->i2c, RT5025_REG_CHGCTL7, RT5025_CHGCEN_MASK);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- if (val->intval < 3500)
- regval = 0;
- else if (val->intval > 4440)
- regval = 0x3A;
- else
- regval = (val->intval - 3500) / 20;
- ret = rt5025_assign_bits(ci->i2c, RT5025_REG_CHGCTL3, RT5025_CHGCV_MASK, \
- regval << RT5025_CHGCV_SHFT);
- break;
- case POWER_SUPPLY_PROP_TEMP:
- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- case POWER_SUPPLY_PROP_STATUS:
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-#ifdef CONFIG_BATTERY_RT5025
-static int rt5025_set_tempalrt(struct rt5025_charger_info *ci)
-{
- int rc = 0;
-
- rt5025_assign_bits(ci->i2c, RT5025_REG_IRQCTL,\
- RT5025_TALRTMX_MASK|RT5025_TALRTMN_MASK, 0x00);
- if (ci->battemp_region == RT5025_BATTEMP_HOT) {
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMAX, ci->temp_scalar[6]);
- rt5025_assign_bits(ci->i2c, RT5025_REG_IRQCTL,\
- RT5025_TALRTMX_MASK, 0xFF);
- } else if (ci->battemp_region == RT5025_BATTEMP_WARM) {
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMAX, ci->temp_scalar[4]);
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMIN, ci->temp_scalar[7]);
- rt5025_assign_bits(ci->i2c, RT5025_REG_IRQCTL,\
- RT5025_TALRTMX_MASK|RT5025_TALRTMN_MASK, 0xFF);
- } else if (ci->battemp_region == RT5025_BATTEMP_NORMAL) {
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMAX, ci->temp_scalar[2]);
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMIN, ci->temp_scalar[5]);
- rt5025_assign_bits(ci->i2c, RT5025_REG_IRQCTL,\
- RT5025_TALRTMX_MASK|RT5025_TALRTMN_MASK, 0xFF);
- } else if (ci->battemp_region == RT5025_BATTEMP_COOL) {
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMAX, ci->temp_scalar[0]);
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMIN, ci->temp_scalar[3]);
- rt5025_assign_bits(ci->i2c, RT5025_REG_IRQCTL,\
- RT5025_TALRTMX_MASK|RT5025_TALRTMN_MASK, 0xFF);
- } else {
- rt5025_reg_write(ci->i2c, RT5025_REG_TALRTMIN, ci->temp_scalar[1]);
- rt5025_assign_bits(ci->i2c, RT5025_REG_IRQCTL,\
- RT5025_TALRTMN_MASK, 0xFF);
- }
- return rc;
-}
-#endif /* #ifdef CONFIG_BATTERY_RT5025 */
-
-static void rt_charger_set_batt_status(struct rt5025_charger_info *ci)
-{
- #ifdef CONFIG_BATTERY_RT5025
- struct power_supply *psy = power_supply_get_by_name(RT_BATT_NAME);
- union power_supply_propval pval;
- int rc = 0;
-
- if (!psy) {
- dev_err(ci->dev, "can't get battery supply\n");
- return;
- }
- pval.intval = ci->chg_status;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_STATUS, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set battery status fail\n");
- power_supply_changed(psy);
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
-}
-
-static int rt_charger_check_battery_present(struct rt5025_charger_info *ci)
-{
- int rc = 1;
- #ifdef CONFIG_BATTERY_RT5025
- struct power_supply *psy = power_supply_get_by_name(RT_BATT_NAME);
- union power_supply_propval pval;
-
- if (!psy) {
- dev_err(ci->dev, "can't get battery supply\n");
- return rc;
- }
- rc = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
- if (rc < 0) {
- dev_err(ci->dev, "get battery voltage fail\n");
- } else {
- if (pval.intval < (ci->chg_volt - 200) * 1000)
- rc = 0;
- else
- rc = 1;
- }
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- return rc;
-}
-
-static void rt5025_batabs_irq_handler(void *info, int eventno)
-{
- struct rt5025_charger_info *ci = info;
- struct power_supply *psy = &ci->psy;
- union power_supply_propval pval;
- int rc = 0;
-
- #ifdef CONFIG_BATTERY_RT5025
- struct power_supply *bat_psy = power_supply_get_by_name(RT_BATT_NAME);
-
- pval.intval = 0;
- if (!bat_psy) {
- dev_err(ci->dev, "get rt-battery supply fail\n");
- } else {
- rc = bat_psy->set_property(bat_psy,
- POWER_SUPPLY_PROP_PRESENT, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set battery not present fail\n");
- power_supply_changed(bat_psy);
- }
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- /*set aicr to disable*/
- pval.intval = 2000;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_CURRENT_AVG, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set aicr to disable fail\n");
- /*set icc to 2000*/
- pval.intval = 2000;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set icc to 2000 fail\n");
- /*set online = 0, due to bat absense*/
- pval.intval = 0;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set charger offline fail\n");
- ci->batabs = 1;
- ci->te_en = 0;
-}
-
-static void rt5025_acin_irq_handler(void *info, int eventno)
-{
- #ifdef CONFIG_RT_POWER
- struct rt5025_charger_info *ci = info;
- #ifndef CONFIG_RT_SUPPORT_ACUSB_DUALIN
- struct power_supply *psy = power_supply_get_by_name(RT_USB_NAME);
- #else
- struct power_supply *psy = power_supply_get_by_name(RT_AC_NAME);
- #endif /* #ifdef CONFIG_RT_SUPPORT_ACUSB_DUALIN */
- union power_supply_propval pval;
- int rc = 0;
-
- if (!psy) {
- dev_err(ci->dev, "could not get psy supply\n");
- return;
- }
- pval.intval = 1;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set ac online fail\n");
- power_supply_changed(psy);
- dev_info(ci->dev, "%s\n", __func__);
- #endif /* #ifdef CONFIG_RT_POWER */
-}
-
-static void rt5025_acout_irq_handler(void *info, int eventno)
-{
- #ifdef CONFIG_RT_POWER
- struct rt5025_charger_info *ci = info;
- #ifndef CONFIG_RT_SUPPORT_ACUSB_DUALIN
- struct power_supply *psy = power_supply_get_by_name(RT_USB_NAME);
- #else
- struct power_supply *psy = power_supply_get_by_name(RT_AC_NAME);
- #endif /* ifdef CONFIG_RT_SUPPORT_ACUSB_DUALIN */
- union power_supply_propval pval;
- int rc = 0;
-
- if (!psy) {
- dev_err(ci->dev, "could not get rt-usb supply\n");
- return;
- }
- pval.intval = 0;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set ac offline fail\n");
- power_supply_changed(psy);
- dev_info(ci->dev, "%s\n", __func__);
- #endif /* #ifdef CONFIG_RT_POWER */
-}
-
-static void rt5025_usbin_irq_handler(void *info, int eventno)
-{
- #ifdef CONFIG_RT_POWER
- struct rt5025_charger_info *ci = info;
- struct power_supply *psy = power_supply_get_by_name(RT_USB_NAME);
- union power_supply_propval pval;
- int rc = 0;
-
- if (!psy) {
- dev_err(ci->dev, "could not get rt-usb supply\n");
- return;
- }
- if (!ci->otg_en) {
- pval.intval = 1;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set ac online fail\n");
- power_supply_changed(psy);
- }
- dev_info(ci->dev, "%s\n", __func__);
- #endif /* #ifdef CONFIG_RT_POWER */
-}
-
-static void rt5025_usbout_irq_handler(void *info, int eventno)
-{
- #ifdef CONFIG_RT_POWER
- struct rt5025_charger_info *ci = info;
- struct power_supply *psy = power_supply_get_by_name(RT_USB_NAME);
- union power_supply_propval pval;
- int rc = 0;
-
- if (!psy) {
- dev_err(ci->dev, "could not get rt-usb supply\n");
- return;
- }
- if (!ci->otg_en) {
- pval.intval = 0;
- rc = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set ac offline fail\n");
- power_supply_changed(psy);
- }
- dev_info(ci->dev, "%s\n", __func__);
- #endif /* #ifdef CONFIG_RT_POWER */
-}
-
-static void rt5025_talrtmax_irq_handler(void *info, int eventno)
-{
- #ifdef CONFIG_BATTERY_RT5025
- struct rt5025_charger_info *ci = info;
- union power_supply_propval pval;
- int rc = 0;
-
- switch (ci->battemp_region) {
- case RT5025_BATTEMP_COLD:
- dev_warn(ci->dev, "cold than cold???\n");
- break;
- case RT5025_BATTEMP_COOL:
- dev_info(ci->dev, "cool-> cold\n");
- ci->battemp_region = RT5025_BATTEMP_COLD;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_NORMAL:
- dev_info(ci->dev, "normal-> cool\n");
- ci->battemp_region = RT5025_BATTEMP_COOL;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_WARM:
- dev_info(ci->dev, "warm-> normal\n");
- ci->battemp_region = RT5025_BATTEMP_NORMAL;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_HOT:
- dev_info(ci->dev, "hot-> warm\n");
- ci->battemp_region = RT5025_BATTEMP_WARM;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- default:
- break;
- }
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
-}
-
-static void rt5025_talrtmin_irq_handler(void *info, int eventno)
-{
- #ifdef CONFIG_BATTERY_RT5025
- struct rt5025_charger_info *ci = info;
- union power_supply_propval pval;
- int rc = 0;
-
- switch (ci->battemp_region) {
- case RT5025_BATTEMP_COLD:
- dev_info(ci->dev, "cold-> cool\n");
- ci->battemp_region = RT5025_BATTEMP_COOL;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_COOL:
- dev_info(ci->dev, "cool-> normal\n");
- ci->battemp_region = RT5025_BATTEMP_NORMAL;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_NORMAL:
- dev_info(ci->dev, "normal-> warm\n");
- ci->battemp_region = RT5025_BATTEMP_WARM;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy,
- POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_WARM:
- dev_info(ci->dev, "warm-> hot\n");
- ci->battemp_region = RT5025_BATTEMP_HOT;
- rt5025_set_tempalrt(ci);
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT,\
- &pval);
- if (rc < 0)
- dev_err(ci->dev, "set present fail\n");
- break;
- case RT5025_BATTEMP_HOT:
- dev_warn(ci->dev, "hot than hot???\n");
- break;
- default:
- break;
- }
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
-}
-
-static void rt5025_general_irq_handler(void *info, int eventno)
-{
- struct rt5025_charger_info *ci = info;
-
- RTINFO("eventno=%02d\n", eventno);
- switch (eventno) {
- case CHGEVENT_CHRCHGI:
- if (!ci->online) {
- dev_warn(ci->dev, "recharge false alarm\n");
- } else {
- union power_supply_propval pval;
-
- dev_info(ci->dev, "recharge occur\n");
- ci->chg_status = POWER_SUPPLY_STATUS_CHARGING;
- pval.intval = ci->chg_volt;
- rt_charger_set_batt_status(ci);
- ci->psy.set_property(&ci->psy,
- POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
- }
- break;
- case CHGEVENT_CHTERMI:
- if (!ci->online) {
- dev_warn(ci->dev, "eoc false alarm\n");
- } else {
- if (rt_charger_check_battery_present(ci)) {
- union power_supply_propval pval;
-
- if (ci->chg_status == POWER_SUPPLY_STATUS_FULL)
- return;
- dev_info(ci->dev, "eoc really occur\n");
- ci->chg_status = POWER_SUPPLY_STATUS_FULL;
- rt_charger_set_batt_status(ci);
- pval.intval = ci->chg_volt-50;
- ci->psy.set_property(&ci->psy,
- POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
- } else {
- dev_info(ci->dev, "no battery condition\n");
- rt5025_batabs_irq_handler(ci, eventno);
- }
- }
- break;
- case CHGEVENT_TALRTMAX:
- #ifdef CONFIG_BATTERY_RT5025
- rt5025_set_tempalrt(ci);
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- break;
- case CHGEVENT_TALRTMIN:
- #ifdef CONFIG_BATTERY_RT5025
- rt5025_set_tempalrt(ci);
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- break;
- default:
- break;
- }
-}
-
-static rt_irq_handler rt_chgirq_handler[CHGEVENT_MAX] = {
- [CHGEVENT_TIMEOUT_CC] = rt5025_general_irq_handler,
- [CHGEVENT_TIMEOUT_PC] = rt5025_general_irq_handler,
- [CHGEVENT_CHVSREGI] = rt5025_general_irq_handler,
- [CHGEVENT_CHTREGI] = rt5025_general_irq_handler,
- [CHGEVENT_CHRCHGI] = rt5025_general_irq_handler,
- [CHGEVENT_CHTERMI] = rt5025_general_irq_handler,
- [CHGEVENT_CHBATOVI] = rt5025_general_irq_handler,
- [CHGEVENT_CHGOODI_INUSB] = rt5025_general_irq_handler,
- [CHGEVENT_CHBADI_INUSB] = rt5025_general_irq_handler,
- [CHGEVENT_CHSLPI_INUSB] = rt5025_usbout_irq_handler,
- [CHGEVENT_CHGOODI_INAC] = rt5025_general_irq_handler,
- [CHGEVENT_CHBADI_INAC] = rt5025_general_irq_handler,
- [CHGEVENT_CHSLPI_INAC] = rt5025_acout_irq_handler,
- [CHGEVENT_BATABS] = rt5025_batabs_irq_handler,
- [CHGEVENT_INUSB_PLUGIN] = rt5025_usbin_irq_handler,
- [CHGEVENT_INUSBOVP] = rt5025_general_irq_handler,
- [CHGEVENT_INAC_PLUGIN] = rt5025_acin_irq_handler,
- [CHGEVENT_INACOVP] = rt5025_general_irq_handler,
- [CHGEVENT_TALRTMIN] = rt5025_talrtmin_irq_handler,
- [CHGEVENT_TALRTMAX] = rt5025_talrtmax_irq_handler,
-};
-
-void rt5025_charger_irq_handler(struct rt5025_charger_info *ci, unsigned int irqevent)
-{
- int i;
- #ifdef CONFIG_BATTERY_RT5025
- unsigned int enable_irq_event = (RT5025_TALRTMX_MASK | RT5025_TALRTMN_MASK)<<24 | \
- (chg_init_regval[6] << 16) | (chg_init_regval[7] << 8) | chg_init_regval[8];
- #else
- unsigned int enable_irq_event = (chg_init_regval[6] << 16)
- | (chg_init_regval[7] << 8)| \
- chg_init_regval[8];
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- unsigned int final_irq_event = irqevent&enable_irq_event;
-
- /*charger workaround (TE+RECHARGE)*/
- if (final_irq_event & (1 << CHGEVENT_CHTERMI) && \
- final_irq_event & (1 << CHGEVENT_CHRCHGI))
- final_irq_event &= ~((1 << CHGEVENT_CHTERMI) | (1 << CHGEVENT_CHRCHGI));
- i = rt5025_reg_read(ci->i2c, RT5025_REG_CHGCTL1);
- if (i < 0) {
- dev_err(ci->dev, "read CHGCTL1 fail\n");
- i = 0;
- }
- /*acin+acout*/
- if (final_irq_event & (1 << CHGEVENT_INAC_PLUGIN) && \
- final_irq_event & (1 << CHGEVENT_CHSLPI_INAC)) {
- if (i & RT5025_ACUSABLE_MASK)
- final_irq_event &= ~(1<<CHGEVENT_CHSLPI_INAC);
- else
- final_irq_event &= ~(1<<CHGEVENT_INAC_PLUGIN);
- }
- /*usbin+usbout*/
- if (final_irq_event & (1 << CHGEVENT_INUSB_PLUGIN) && \
- final_irq_event & (1 << CHGEVENT_CHSLPI_INUSB)) {
- if (i & RT5025_USBUSABLE_MASK)
- final_irq_event &= ~(1 << CHGEVENT_CHSLPI_INUSB);
- else
- final_irq_event &= ~(1 << CHGEVENT_INUSB_PLUGIN);
- }
- for (i = 0; i < CHGEVENT_MAX; i++) {
- if ((final_irq_event & (1 << i)) && rt_chgirq_handler[i])
- rt_chgirq_handler[i](ci, i);
- }
-}
-EXPORT_SYMBOL(rt5025_charger_irq_handler);
-
-static void rt5025_tempmon_work(struct work_struct *work)
-{
- struct rt5025_charger_info *ci = container_of(work, \
- struct rt5025_charger_info, tempmon_work.work);
- #ifdef CONFIG_BATTERY_RT5025
- struct power_supply *psy = power_supply_get_by_name(RT_BATT_NAME);
- union power_supply_propval pval;
- int inttemp_region;
- #endif
-
- RTINFO("\n");
- #ifdef CONFIG_BATTERY_RT5025
- if (!psy) {
- dev_err(ci->dev, "could not get rt-battery psy\n");
- return;
- }
- if (!ci->init_once) {
- /*battemp init*/
- int i = 0;
-
- pval.intval = 23; /* magic code*/
- psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &pval);
- for (i = 3; i >= 0; i--)
- if (pval.intval > ci->temp[i])
- break;
- if (i == 3)
- ci->battemp_region = RT5025_BATTEMP_HOT;
- else if (i == 2)
- ci->battemp_region = RT5025_BATTEMP_WARM;
- else if (i == 1)
- ci->battemp_region = RT5025_BATTEMP_NORMAL;
- else if (i == 0)
- ci->battemp_region = RT5025_BATTEMP_COOL;
- else
- ci->battemp_region = RT5025_BATTEMP_COLD;
- rt5025_set_tempalrt(ci);
- ci->init_once = 1;
- }
-
- psy->get_property(psy, POWER_SUPPLY_PROP_TEMP_AMBIENT, &pval);
- if (pval.intval > 1000)
- inttemp_region = RT5025_INTTEMP_HOT;
- else if (pval.intval > 750)
- inttemp_region = RT5025_INTTEMP_WARM;
- else
- inttemp_region = RT5025_INTTEMP_NORMAL;
-
- if (inttemp_region != ci->inttemp_region) {
- ci->inttemp_region = inttemp_region;
- pval.intval = 1;
- rt_charger_set_property(&ci->psy,
- POWER_SUPPLY_PROP_PRESENT, &pval);
- }
- #endif /* #ifdef CONFIG_BATTERY_RT5025 */
- if (!ci->suspend)
- schedule_delayed_work(&ci->tempmon_work, 5*HZ);
-}
-
-static int rt5025_charger_reginit(struct i2c_client *client)
-{
- rt5025_reg_block_write(client, RT5025_REG_CHGCTL2, 6, chg_init_regval);
- /*set all to be masked*/
- rt5025_reg_write(client, RT5025_REG_IRQEN1, 0x00);
- rt5025_reg_write(client, RT5025_REG_IRQEN2, 0x00);
- rt5025_reg_write(client, RT5025_REG_IRQEN3, 0x00);
- /*just clear the old irq event*/
- rt5025_reg_read(client, RT5025_REG_IRQSTAT1);
- rt5025_reg_read(client, RT5025_REG_IRQSTAT2);
- rt5025_reg_read(client, RT5025_REG_IRQSTAT3);
- /*set enable irqs as we want*/
- rt5025_reg_write(client, RT5025_REG_IRQEN1, chg_init_regval[6]);
- rt5025_reg_write(client, RT5025_REG_IRQEN2, chg_init_regval[7]);
- rt5025_reg_write(client, RT5025_REG_IRQEN3, chg_init_regval[8]);
- RTINFO("\n");
- return 0;
-}
-
-static int rt_parse_dt(struct rt5025_charger_info *ci, struct device *dev)
-{
- #ifdef CONFIG_OF
- struct device_node *np = dev->of_node;
- u32 val;
-
- if (of_property_read_bool(np, "rt,te_en"))
- ci->te_en = 1;
-
- if (of_property_read_u32(np, "rt,iprec", &val)) {
- dev_info(dev, "no iprec property, use default value\n");
- } else{
- if (val > RT5025_IPREC_MAX)
- val = RT5025_IPREC_MAX;
- chg_init_regval[4] &= (~RT5025_CHGIPREC_MASK);
- chg_init_regval[4] |= (val << RT5025_CHGIPREC_SHFT);
- }
-
- if (of_property_read_u32(np, "rt,ieoc", &val)) {
- dev_info(dev, "no ieoc property, use the default value\n");
- } else {
- if (val > RT5025_IEOC_MAX)
- val = RT5025_IEOC_MAX;
- chg_init_regval[4] &= (~RT5025_CHGIEOC_MASK);
- chg_init_regval[4] |= (val << RT5025_CHGIEOC_SHFT);
- }
-
- if (of_property_read_u32(np, "rt,vprec", &val)) {
- dev_info(dev, "no vprec property, use the default value\n");
- } else {
- if (val > RT5025_VPREC_MAX)
- val = RT5025_VPREC_MAX;
- chg_init_regval[4] &= (~RT5025_CHGVPREC_MASK);
- chg_init_regval[4] |= (val << RT5025_CHGVPREC_SHFT);
- }
-
- if (of_property_read_u32(np, "rt,vdpm", &val)) {
- dev_info(dev, "no vdpm property, use the default value\n");
- } else {
- if (val > RT5025_VDPM_MAX)
- val = RT5025_VDPM_MAX;
- chg_init_regval[3] &= (~RT5025_CHGVDPM_MASK);
- chg_init_regval[3] |= (val << RT5025_CHGVDPM_SHFT);
- }
-
- if (of_property_read_u32(np, "rt,chg_volt", &val)) {
- dev_info(dev, "no chg_volt property, use 4200 as the default value\n");
- ci->chg_volt = 4200;
- } else {
- ci->chg_volt = val;
- }
-
- if (of_property_read_u32(np, "rt,acchg_icc", &val)) {
- dev_info(dev, "no acchg_icc property, use 2000 as the default value\n");
- ci->acchg_icc = 2000;
- } else {
- ci->acchg_icc = val;
- }
-
- if (of_property_read_u32(np, "rt,usbtachg_icc", &val)) {
- dev_info(dev, "no usbtachg_icc property, use 2000 as the default value\n");
- ci->usbtachg_icc = 2000;
- } else {
- ci->usbtachg_icc = val;
- }
-
- if (of_property_read_u32(np, "rt,usbchg_icc", &val)) {
- dev_info(dev, "no usbchg_icc property, use 500 as the default value\n");
- ci->usbchg_icc = 500;
- } else {
- ci->usbchg_icc = val;
- }
-
- if (of_property_read_u32(np, "rt,screenon_icc", &val)) {
- dev_info(dev, "no screenon_icc property, use 500 as the default value\n");
- ci->screenon_icc = 500;
- } else {
- ci->screenon_icc = val;
- }
-
- if (of_property_read_bool(np, "rt,screenon_adjust")) {
- ci->screenon_adjust = 1;
- ci->screen_on = 1;
- }
-
- if (of_property_read_u32_array(np, "rt,temp",
- ci->temp, 4)) {
- dev_info(dev, "no temperature property, use default value\n");
- ci->temp[0] = 0;
- ci->temp[1] = 150;
- ci->temp[2] = 500;
- ci->temp[3] = 600;
- }
-
- if (of_property_read_u32_array(np, "rt,temp_scalar",
- ci->temp_scalar, 8)) {
- dev_info(dev, "no temp_scalar property, use default value\n");
- ci->temp_scalar[0] = 0x30;
- ci->temp_scalar[1] = 0x2B;
- ci->temp_scalar[2] = 0x28;
- ci->temp_scalar[3] = 0x22;
- ci->temp_scalar[4] = 0x15;
- ci->temp_scalar[5] = 0x10;
- ci->temp_scalar[6] = 0x10;
- ci->temp_scalar[7] = 0x0D;
- }
- #endif /* #ifdef CONFIG_OF */
- rt5025_charger_reginit(ci->i2c);
- RTINFO("\n");
- return 0;
-}
-
-static int rt_parse_pdata(struct rt5025_charger_info *ci, struct device *dev)
-{
- struct rt5025_charger_data *pdata = dev->platform_data;
- int i = 0;
-
- if (pdata->te_en)
- ci->te_en = 1;
-
- chg_init_regval[4] &= (~RT5025_CHGIPREC_MASK);
- chg_init_regval[4] |= (pdata->iprec << RT5025_CHGIPREC_SHFT);
-
- chg_init_regval[4] &= (~RT5025_CHGIEOC_MASK);
- chg_init_regval[4] |= (pdata->ieoc << RT5025_CHGIEOC_SHFT);
-
- chg_init_regval[4] &= (~RT5025_CHGVPREC_MASK);
- chg_init_regval[4] |= (pdata->vprec << RT5025_CHGVPREC_SHFT);
-
- chg_init_regval[3] &= (~RT5025_CHGVDPM_MASK);
- chg_init_regval[3] |= (pdata->vdpm << RT5025_CHGVDPM_SHFT);
-
- ci->chg_volt = pdata->chg_volt;
- ci->acchg_icc = pdata->acchg_icc;
- ci->usbtachg_icc = pdata->usbtachg_icc;
- ci->usbchg_icc = pdata->usbchg_icc;
- ci->screenon_icc = pdata->screenon_icc;
- if (pdata->screenon_adjust) {
- ci->screenon_adjust = 1;
- /*default probe screen will on*/
- ci->screen_on = 1;
- }
- for (i = 0; i < 4; i++)
- ci->temp[i] = pdata->temp[i];
- for (i = 0; i < 8; i++)
- ci->temp_scalar[i] = pdata->temp_scalar[i];
- rt5025_charger_reginit(ci->i2c);
- RTINFO("\n");
- return 0;
-}
-
-#ifdef CONFIG_RT_POWER
-static struct platform_device rt_power_dev = {
- .name = "rt-power",
- .id = -1,
-};
-#endif /* #ifdef CONFIG_RT_POWER */
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void rt5025_charger_earlysuspend(struct early_suspend *handler)
-{
- struct rt5025_charger_info *ci = container_of(handler, \
- struct rt5025_charger_info, early_suspend);
- union power_supply_propval pval;
- int rc = 0;
-
- if (ci->screenon_adjust) {
- ci->screen_on = 0;
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy,
- POWER_SUPPLY_PROP_PRESENT, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set charger present property fail\n");
- }
-}
-
-static void rt5025_charger_earlyresume(struct early_suspend *handler)
-{
- struct rt5025_charger_info *ci = container_of(handler, \
- struct rt5025_charger_info, early_suspend);
- union power_supply_propval pval;
- int rc = 0;
-
- if (ci->screenon_adjust) {
- ci->screen_on = 1;
- pval.intval = 1;
- rc = ci->psy.set_property(&ci->psy,
- POWER_SUPPLY_PROP_PRESENT, &pval);
- if (rc < 0)
- dev_err(ci->dev, "set charger present property fail\n");
- }
-}
-#endif /* #ifdef CONFIG_HAS_EARLYSUSPEND */
-
-static int rt5025_charger_probe(struct platform_device *pdev)
-{
- struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct rt5025_platform_data *pdata =
- (pdev->dev.parent)->platform_data;
- #ifdef CONFIG_RT_POWER
- struct rt_power_data *rt_power_pdata;
- #endif /* #ifdef CONFIG_RT_POWER */
- struct rt5025_charger_info *ci;
- bool use_dt = pdev->dev.of_node;
- int ret = 0;
-
- ci = devm_kzalloc(chip->dev, sizeof(struct rt5025_charger_info), GFP_KERNEL);
- if (!ci)
- return -ENOMEM;
-
- ci->i2c = chip->i2c;
- ci->dev = &pdev->dev;
- ci->chg_status = POWER_SUPPLY_STATUS_DISCHARGING;
- ci->battemp_region = RT5025_BATTEMP_NORMAL;
- ci->inttemp_region = RT5025_INTTEMP_NORMAL;
- #ifdef CONFIG_RT_JEITA_REMOVE
- ci->init_once = 1;
- #endif /* #ifdef RT_JEITA_REMOVE */
-
- if (use_dt) {
- rt_parse_dt(ci, &pdev->dev);
- } else {
- if (!pdata) {
- ret = -EINVAL;
- goto out_dev;
- }
- pdev->dev.platform_data = pdata->chg_pdata;
- rt_parse_pdata(ci, &pdev->dev);
- }
- INIT_DELAYED_WORK(&ci->tempmon_work, rt5025_tempmon_work);
-
- platform_set_drvdata(pdev, ci);
- /*power supply register*/
- ci->psy.name = rtdef_chg_name;
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
- ci->psy.type = POWER_SUPPLY_TYPE_UNKNOWN;
- #else
- ci->psy.type = -1;
- #endif /* #ifdef (LINUX_VERSION_CODE */
- ci->psy.supplied_to = rt_charger_supply_list;
- ci->psy.properties = rt_charger_props;
- ci->psy.num_properties = ARRAY_SIZE(rt_charger_props);
- ci->psy.get_property = rt_charger_get_property;
- ci->psy.set_property = rt_charger_set_property;
- ret = power_supply_register(&pdev->dev, &ci->psy);
- if (ret < 0) {
- dev_err(&pdev->dev, "couldn't create power supply for rt-charger\n");
- goto out_dev;
- }
-
- #ifdef CONFIG_HAS_EARLYSUSPEND
- ci->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;
- ci->early_suspend.suspend = rt5025_charger_earlysuspend;
- ci->early_suspend.resume = rt5025_charger_earlyresume;
- register_early_suspend(&ci->early_suspend);
- #endif /* CONFIG_HAS_EARLYSUSPEND */
-
- #ifdef CONFIG_RT_POWER
- rt_power_pdata = devm_kzalloc(&pdev->dev,
- sizeof(*rt_power_pdata), GFP_KERNEL);
- if (!rt_power_pdata) {
- ret = -ENOMEM;
- goto out_psy;
- }
- rt_power_pdata->chg_volt = ci->chg_volt;
- rt_power_pdata->acchg_icc = ci->acchg_icc;
- rt_power_pdata->usbtachg_icc = ci->usbtachg_icc;
- rt_power_pdata->usbchg_icc = ci->usbchg_icc;
-
- rt_power_dev.dev.platform_data = rt_power_pdata;
- rt_power_dev.dev.parent = &pdev->dev;
- ret = platform_device_register(&rt_power_dev);
- if (ret < 0)
- goto out_psy;
- #endif /* #ifdef CONFIG_RT_POWER */
-
- chip->charger_info = ci;
- schedule_delayed_work(&ci->tempmon_work, 1*HZ);
- dev_info(&pdev->dev, "driver successfully loaded\n");
- return 0;
-#ifdef CONFIG_RT_POWER
-out_psy:
-#endif /* #ifdef CONFIG_RT_POWER */
- #ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&ci->early_suspend);
- #endif /* #ifdef CONFIG_HAS_EARLYSUSPEND */
- power_supply_unregister(&ci->psy);
-out_dev:
- return ret;
-}
-
-static int rt5025_charger_remove(struct platform_device *pdev)
-{
- struct rt5025_charger_info *ci = platform_get_drvdata(pdev);
-
- power_supply_unregister(&ci->psy);
- #ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&ci->early_suspend);
- #endif /* #ifdef CONFIG_HAS_EARLYSUSPEND */
- #ifdef CONFIG_RT_POWER
- platform_device_unregister(&rt_power_dev);
- #endif /* #ifdef CONFIG_RT_POWER */
- return 0;
-}
-
-static int rt5025_charger_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct rt5025_charger_info *ci = platform_get_drvdata(pdev);
- union power_supply_propval pval;
-
- ci->suspend = 1;
- cancel_delayed_work_sync(&ci->tempmon_work);
- /*force inttemp to normal temp*/
- ci->inttemp_region = RT5025_INTTEMP_NORMAL;
- pval.intval = 1;
- rt_charger_set_property(&ci->psy, POWER_SUPPLY_PROP_PRESENT, &pval);
- return 0;
-}
-
-static int rt5025_charger_resume(struct platform_device *pdev)
-{
- struct rt5025_charger_info *ci = platform_get_drvdata(pdev);
-
- ci->suspend = 0;
- schedule_delayed_work(&ci->tempmon_work, msecs_to_jiffies(50));
- return 0;
-}
-
-static const struct of_device_id rt_match_table[] = {
- { .compatible = "rt,rt5025-charger",},
- {},
-};
-
-static struct platform_driver rt5025_charger_driver = {
- .driver = {
- .name = RT5025_DEV_NAME "-charger",
- .owner = THIS_MODULE,
- .of_match_table = rt_match_table,
- },
- .probe = rt5025_charger_probe,
- .remove = rt5025_charger_remove,
- .suspend = rt5025_charger_suspend,
- .resume = rt5025_charger_resume,
-};
-
-static int rt5025_charger_init(void)
-{
- return platform_driver_register(&rt5025_charger_driver);
-}
-fs_initcall_sync(rt5025_charger_init);
-
-static void rt5025_charger_exit(void)
-{
- platform_driver_unregister(&rt5025_charger_driver);
-}
-
-module_exit(rt5025_charger_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("CY Huang <cy_huang@richtek.com>");
-MODULE_DESCRIPTION("Charger driver for RT5025");
-MODULE_ALIAS("platform:"RT5025_DEV_NAME "-charger");
-MODULE_VERSION(RT5025_DRV_VER);
diff --git a/drivers/power/rt5025-power.c b/drivers/power/rt5025-power.c
deleted file mode 100755
index 6d654d7bbe38..000000000000
--- a/drivers/power/rt5025-power.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/* drivers/power/rt5025-power.c
- * I2C Driver for Richtek RT5025 PMIC
- * Multi function device - multi functional baseband PMIC Power part
- *
- * Copyright (C) 2013
- * Author: CY Huang <cy_huang@richtek.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 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/power_supply.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/version.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/mfd/rt5025.h>
-#include <linux/power/rt5025-power.h>
-#include <linux/delay.h>
-
-static struct platform_device *dev_ptr;
-
-
-static enum power_supply_property rt5025_adap_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
-
-static char *rt5025_supply_list[] = {
- "rt5025-battery",
-};
-
-
-int rt5025_set_charging_current_switch (struct i2c_client *i2c, int onoff)
-{
- int ret;
- if (onoff)
- ret = rt5025_set_bits(i2c, RT5025_REG_CHGCTL7, RT5025_CHGCEN_MASK);
- else
- ret = rt5025_clr_bits(i2c, RT5025_REG_CHGCTL7, RT5025_CHGCEN_MASK);
- return ret;
-}
-EXPORT_SYMBOL(rt5025_set_charging_current_switch);
-
-int rt5025_set_charging_buck(struct i2c_client *i2c, int onoff)
-{
- int ret;
- if (onoff)
- ret = rt5025_set_bits(i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
- else
- ret = rt5025_clr_bits(i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
- return ret;
-}
-EXPORT_SYMBOL(rt5025_set_charging_buck);
-
-int rt5025_ext_set_charging_buck(int onoff)
-{
- struct rt5025_power_info *pi = platform_get_drvdata(dev_ptr);
- int ret;
- if (onoff)
- {
- pi->otg_en = 0;
- ret = rt5025_set_bits(pi->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
- msleep(100);
- }
- else
- {
- pi->otg_en = 1;
- ret = rt5025_clr_bits(pi->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
- msleep(100);
- }
- return ret;
-}
-EXPORT_SYMBOL(rt5025_ext_set_charging_buck);
-
-int rt5025_charger_reset_and_reinit(struct rt5025_power_info *pi)
-{
- struct rt5025_platform_data *pdata = pi->dev->parent->platform_data;
- int ret;
-
- RTINFO("\n");
-
- //do charger reset
- ret = rt5025_reg_read(pi->i2c, RT5025_REG_CHGCTL4);
- if (ret < 0)
- return ret;
- rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL4, ret|RT5025_CHGRST_MASK);
- mdelay(200);
-
- rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL2, pdata->power_data->CHGControl2.val);
- rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL3, pdata->power_data->CHGControl3.val);
- rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL4, pdata->power_data->CHGControl4.val);
- rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL5, pdata->power_data->CHGControl5.val);
- rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL6, pdata->power_data->CHGControl6.val);
- //rt5025_reg_write(pi->i2c, RT5025_REG_CHGCTL7, pd->CHGControl7.val);
- rt5025_assign_bits(pi->i2c, RT5025_REG_CHGCTL7, 0xEF, pdata->power_data->CHGControl7.val);
- rt5025_reg_write(pi->i2c, 0xA9, 0x60 );
- return 0;
-}
-EXPORT_SYMBOL(rt5025_charger_reset_and_reinit);
-
-static int rt5025_set_charging_current(struct i2c_client *i2c, int cur_value)
-{
- int ret = 0;
- u8 data = 0;
-
- //ICC Setting
- #if 0
- if (cur_value > 2000)
- data |= 0x0f<<3;
- else if (cur_value >= 500 && cur_value <= 2000)
- {
- data = (cur_value-500)/100;
- data<<=3;
- }
- #endif
-
- //AICR Setting
- if (cur_value > 1000)
- data |= 0x03<<1;
- else if (cur_value > 500 && cur_value <= 1000)
- data |= 0x02<<1;
- else if (cur_value > 100 && cur_value >= 500)
- data |= 0x01<<1;
-
- rt5025_assign_bits(i2c, RT5025_REG_CHGCTL4, RT5025_CHGAICR_MASK, data);
- return ret;
-}
-
-static int rt5025_chgstat_changed(struct rt5025_power_info *info, unsigned new_val)
-{
- int ret = 0;
- switch (new_val)
- {
- case 0x00:
- #if 0
- rt5025_set_charging_current_switch(info->i2c, 1);
- rt5025_set_charging_buck(info->i2c, 1);
- #endif
- info->chg_stat = 0x00;
- #if 1
- if (info->chip->battery_info)
- {
- if (info->chg_term <= 1)
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
- else if (info->chg_term == 2)
- {
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
- //info->chg_term = 0;
- }
- else if (info->chg_term > 2)
- ;
- }
- #else
- if (info->event_callback)
- info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_CHARGING);
- #endif
- break;
- case 0x01:
- //rt5025_set_charging_current_switch(info->i2c, 1);
- info->chg_stat = 0x01;
- #if 1
- if (info->chip->battery_info)
- {
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
- info->chg_term = 0;
- }
- #else
- if (info->event_callback)
- info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_CHARGING);
- #endif
- break;
- case 0x02:
- #if 0
- rt5025_set_charging_current_switch(info->i2c, 0);
- #endif
- info->chg_stat = 0x02;
- #if 1
- if (info->chip->battery_info)
- {
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
- info->chg_term = 0;
- }
- #else
- if (info->event_callback)
- info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_FULL);
- #endif
- break;
- case 0x03:
- #if 0
- rt5025_set_charging_buck(info->i2c, 0);
- rt5025_set_charging_current_switch(info->i2c, 0);
- #endif
- info->chg_stat = 0x03;
- #if 1
- if (info->chip->battery_info)
- {
- if (info->chg_term <= 1)
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
- else if (info->chg_term == 2)
- {
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
- //info->chg_term = 0;
- }
- else if (info->chg_term > 2)
- ;
- }
- #else
- if (info->event_callback)
- info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_DISCHARGING);
- #endif
- break;
- default:
- break;
- }
- return ret;
-}
-
-#if 0
-int rt5025_power_passirq_to_gauge(struct rt5025_power_info *info)
-{
- if (info->event_callback)
- info->event_callback->rt5025_gauge_irq_handler();
- return 0;
-}
-EXPORT_SYMBOL(rt5025_power_passirq_to_gauge);
-#endif
-
-int rt5025_power_charge_detect(struct rt5025_power_info *info)
-{
- int ret = 0;
- unsigned char chgstatval = 0;
- unsigned old_usbval, old_acval, old_chgval, new_usbval, new_acval, new_chgval;
-
- old_acval = info->ac_online;
- old_usbval = info->usb_online;
- old_chgval = info->chg_stat;
-
- mdelay(50);
-
- ret = rt5025_reg_read(info->i2c, RT5025_REG_CHGSTAT);
- if (ret<0)
- {
- dev_err(info->dev, "read chg stat reg fail\n");
- return ret;
- }
- chgstatval = ret;
- RTINFO("chgstat = 0x%02x\n", chgstatval);
-
- if (info->otg_en)
- {
- ret = rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
- msleep(100);
- }
-
- new_acval = (chgstatval&RT5025_CHG_ACONLINE)>>RT5025_CHG_ACSHIFT;
- if (old_acval != new_acval)
- {
- info->ac_online = new_acval;
- power_supply_changed(&info->ac);
- }
-
- new_usbval = (info->otg_en? \
- 0:(chgstatval&RT5025_CHG_USBONLINE)>>RT5025_CHG_USBSHIFT);
- if (old_usbval != new_usbval)
- {
- info->usb_online = new_usbval;
- power_supply_changed(&info->usb);
- }
-
- if (info->otg_en && new_acval == 0)
- {
- ret = rt5025_clr_bits(info->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
- msleep(100);
- }
-
- //if (old_acval != new_acval || old_usbval != new_usbval)
- if (new_acval || new_usbval)
- {
- info->usb_cnt = 0;
- schedule_delayed_work(&info->usb_detect_work, 0); //no delay
- }
-
- new_chgval = (chgstatval&RT5025_CHGSTAT_MASK)>>RT5025_CHGSTAT_SHIFT;
-
- if (new_acval || new_usbval)
- {
- //if (old_chgval != new_chgval)
- //{
- ret = rt5025_chgstat_changed(info, new_chgval);
- //}
- }
- else
- {
- #if 0
- rt5025_set_charging_buck(info->i2c, 0);
- rt5025_set_charging_current_switch(info->i2c, 0);
- #endif
- info->chg_stat = RT5025_CHGSTAT_UNKNOWN;
- if (info->chip->jeita_info)
- rt5025_notify_charging_cable(info->chip->jeita_info, JEITA_NO_CHARGE);
- #if 1
- if (info->chip->battery_info)
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_DISCHARGING);
- #else
- if (info->event_callback)
- info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_NOT_CHARGING);
- #endif
- }
-
- return ret;
-}
-EXPORT_SYMBOL(rt5025_power_charge_detect);
-
-static int rt5025_adap_get_props(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct rt5025_power_info *info = dev_get_drvdata(psy->dev->parent);
- switch(psp)
- {
- case POWER_SUPPLY_PROP_ONLINE:
- if (psy->type == POWER_SUPPLY_TYPE_MAINS)
- val->intval = info->ac_online;
- else if (psy->type == POWER_SUPPLY_TYPE_USB)
- val->intval = info->usb_online;
- else
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-
-extern int dwc_vbus_status(void);
-
-
-static void usb_detect_work_func(struct work_struct *work)
-{
- struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
- struct rt5025_power_info *pi = (struct rt5025_power_info *)container_of(delayed_work, struct rt5025_power_info, usb_detect_work);
-
- RTINFO("rt5025: %s ++", __func__);
-
- mutex_lock(&pi->var_lock);
- if (pi->ac_online)
- {
- rt5025_set_charging_current(pi->i2c, 2000);
- rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_AC_ADAPTER);
- pi->usb_cnt = 0;
- }
- else if (pi->usb_online)
- {
- RTINFO("%s: usb_cnt %d\n", __func__, pi->usb_cnt);
- switch(dwc_vbus_status())
- {
- case 2: // USB Wall charger
- rt5025_set_charging_current(pi->i2c, 2000);
- rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_USB_TA);
- RTINFO("rt5025: detect usb wall charger\n");
- break;
- case 1: //normal USB
- default:
- rt5025_set_charging_current(pi->i2c, 2000);
- rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NORMAL_USB);
- RTINFO("rt5025: detect normal usb\n");
- break;
- }
- if (pi->usb_cnt++ < 60)
- schedule_delayed_work(&pi->usb_detect_work, 1*HZ);
- }
- else
- {
- //default to prevent over current charging
- rt5025_set_charging_current(pi->i2c, 500);
- rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NO_CHARGE);
- //reset usb_cnt;
- pi->usb_cnt = 0;
- }
- mutex_unlock(&pi->var_lock);
-
- RTINFO("rt5025: %s --", __func__);
-}
-
-static int __devinit rt5025_init_charger(struct rt5025_power_info *info, struct rt5025_power_data* pd)
-{
- //unsigned char data;
- info->ac_online = 0;
- info->usb_online =0;
- //init charger buckck & charger current en to disable stat
- info->chg_stat = RT5025_CHGSTAT_UNKNOWN;
- #if 0
- if (info->event_callback)
- info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_DISCHARGING);
- #endif
- //rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL4, RT5025_CHGRST_MASK);
- //udelay(200);
- //init register setting
- rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL2, pd->CHGControl2.val);
- rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL3, pd->CHGControl3.val);
- rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL4, pd->CHGControl4.val);
- rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL5, pd->CHGControl5.val);
- rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL6, pd->CHGControl6.val);
- //rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL7, pd->CHGControl7.val);
- rt5025_assign_bits(info->i2c, RT5025_REG_CHGCTL7, 0xEF, pd->CHGControl7.val);
- rt5025_reg_write(info->i2c, 0xA9, 0x60 );
- //Special buck setting
- #if 0
- //Buck 1
- data = rt5025_reg_read(info->i2c, 0x47);
- data ^=0xc2;
- rt5025_reg_write(info->i2c, 0x47, data);
- //Buck 2
- data = rt5025_reg_read(info->i2c, 0x48);
- data ^=0xc2;
- rt5025_reg_write(info->i2c, 0x48, data);
- //Buck 3
- data = rt5025_reg_read(info->i2c, 0x49);
- data ^=0xc2;
- rt5025_reg_write(info->i2c, 0x49, data);
- #endif //#if 0
-
- rt5025_power_charge_detect(info);
-
- return 0;
-}
-
-static int __devinit rt5025_power_probe(struct platform_device *pdev)
-{
- struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct rt5025_platform_data *pdata = chip->dev->platform_data;
- struct rt5025_power_info *pi;
- int ret = 0;
-
- pi = kzalloc(sizeof(*pi), GFP_KERNEL);
- if (!pi)
- return -ENOMEM;
-
- pi->i2c = chip->i2c;
- pi->dev = &pdev->dev;
- pi->chip = chip;
- mutex_init(&pi->var_lock);
- INIT_DELAYED_WORK(&pi->usb_detect_work, usb_detect_work_func);
-
- #if 0
- ret = rt5025_gauge_init(pi);
- if (ret)
- goto out;
- #endif
-
- platform_set_drvdata(pdev, pi);
- dev_ptr = pdev;
-
- pi->ac.name = "rt5025-dc";
- pi->ac.type = POWER_SUPPLY_TYPE_MAINS;
- pi->ac.supplied_to = rt5025_supply_list;
- pi->ac.properties = rt5025_adap_props;
- pi->ac.num_properties = ARRAY_SIZE(rt5025_adap_props);
- pi->ac.get_property = rt5025_adap_get_props;
- ret = power_supply_register(&pdev->dev, &pi->ac);
- if (ret)
- goto out;
-
- pi->usb.name = "rt5025-usb";
- pi->usb.type = POWER_SUPPLY_TYPE_USB;
- pi->ac.supplied_to = rt5025_supply_list;
- pi->usb.properties = rt5025_adap_props;
- pi->usb.num_properties = ARRAY_SIZE(rt5025_adap_props);
- pi->usb.get_property = rt5025_adap_get_props;
- ret = power_supply_register(&pdev->dev, &pi->usb);
- if (ret)
- goto out_usb;
-
- rt5025_init_charger(pi, pdata->power_data);
- chip->power_info = pi;
-
- pr_info("rt5025-power driver is successfully loaded\n");
-
- return ret;
-out_usb:
- power_supply_unregister(&pi->ac);
-out:
- kfree(pi);
-
- return ret;
-}
-
-static int rt5025_power_suspend(struct platform_device *pdev, pm_message_t state)
-{
- #if 0
- struct rt5025_power_info *pi = platform_get_drvdata(pdev);
-
- if (pi->event_callback)
- pi->event_callback->rt5025_gauge_suspend();
- #endif
- RTINFO("\n");
- return 0;
-}
-
-static int rt5025_power_resume(struct platform_device *pdev)
-{
- #if 0
- struct rt5025_power_info *pi = platform_get_drvdata(pdev);
-
- if (pi->event_callback)
- pi->event_callback->rt5025_gauge_resume();
- #endif
- RTINFO("\n");
- return 0;
-}
-
-static int __devexit rt5025_power_remove(struct platform_device *pdev)
-{
- struct rt5025_power_info *pi = platform_get_drvdata(pdev);
- struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
-
- #if 0
- if (pi->event_callback)
- pi->event_callback->rt5025_gauge_remove();
- #endif
- power_supply_unregister(&pi->usb);
- power_supply_unregister(&pi->ac);
- chip->power_info = NULL;
- kfree(pi);
- RTINFO("\n");
-
- return 0;
-}
-
-static struct platform_driver rt5025_power_driver =
-{
- .driver = {
- .name = RT5025_DEVICE_NAME "-power",
- .owner = THIS_MODULE,
- },
- .probe = rt5025_power_probe,
- .remove = __devexit_p(rt5025_power_remove),
- .suspend = rt5025_power_suspend,
- .resume = rt5025_power_resume,
-};
-
-static int __init rt5025_power_init(void)
-{
- return platform_driver_register(&rt5025_power_driver);
-}
-late_initcall_sync(rt5025_power_init);
-
-static void __exit rt5025_power_exit(void)
-{
- platform_driver_unregister(&rt5025_power_driver);
-}
-module_exit(rt5025_power_exit);
-
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
-MODULE_DESCRIPTION("Power/Gauge driver for RT5025");
-MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-power");
-MODULE_VERSION(RT5025_DRV_VER);
diff --git a/drivers/power/rt5025-swjeita.c b/drivers/power/rt5025-swjeita.c
deleted file mode 100755
index 62041ad22cf2..000000000000
--- a/drivers/power/rt5025-swjeita.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/* drivers/power/rt5025-swjeita.c
- * swjeita Driver for Richtek RT5025 PMIC
- * Multi function device - multi functional baseband PMIC swjeita part
- *
- * Copyright (C) 2013
- * Author: CY Huang <cy_huang@richtek.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 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/mfd/rt5025.h>
-#include <linux/power/rt5025-swjeita.h>
-
-#define TEMP_TOLERANCE 30 /*'c*10 gap for tolerance*/
-
-static int rt5025_set_charging_cc_switch (struct i2c_client *i2c, int onoff)
-{
- int ret;
-
- RTINFO("onoff = %d\n", onoff);
- if (onoff)
- ret = rt5025_set_bits(i2c, RT5025_REG_CHGCTL7, RT5025_CHGCCEN_MASK);
- else
- ret = rt5025_clr_bits(i2c, RT5025_REG_CHGCTL7, RT5025_CHGCCEN_MASK);
- return ret;
-}
-
-static int rt5025_set_charging_cc(struct i2c_client *i2c, int cur_value)
-{
- int ret;
- u8 data;
-
- RTINFO("current value = %d\n", cur_value);
- if (cur_value < 500)
- data = 0;
- else if (cur_value > 2000)
- data = 0xf << RT5025_CHGICC_SHIFT;
- else
- data = ((cur_value - 500) / 100) << RT5025_CHGICC_SHIFT;
-
- ret = rt5025_assign_bits(i2c, RT5025_REG_CHGCTL4, RT5025_CHGICC_MASK, data);
-
- if (cur_value < 500)
- rt5025_set_charging_cc_switch(i2c, 0);
- else
- rt5025_set_charging_cc_switch(i2c, 1);
-
- return ret;
-}
-
-static int rt5025_set_charging_cv(struct i2c_client *i2c, int voltage)
-{
- int ret;
- u8 data;
-
- RTINFO("voltage = %d\n", voltage);
- if (voltage < 3500)
- data = 0;
- else if (voltage > 4440)
- data = 0x2f << RT5025_CHGCV_SHIFT;
- else
- data = ((voltage - 3500) / 20) << RT5025_CHGCV_SHIFT;
-
- ret = rt5025_assign_bits(i2c, RT5025_REG_CHGCTL3, RT5025_CHGCV_MASK, data);
- return ret;
-}
-
-static int rt5025_sel_external_temp_index(struct rt5025_swjeita_info *swji)
-{
- int temp = swji->cur_temp;
- int sect_index;
-
- RTINFO("\n");
- if (temp < swji->temp[0])
- sect_index = 0;
- else if (temp >= swji->temp[0] && temp < swji->temp[1])
- sect_index = 1;
- else if (temp >= swji->temp[1] && temp < swji->temp[2])
- sect_index = 2;
- else if (temp >= swji->temp[2] && temp < swji->temp[3])
- sect_index = 3;
- else if (temp >= swji->temp[3])
- sect_index = 4;
-
- RTINFO("sect_index = %d\n", sect_index);
- return sect_index;
-}
-
-static int rt5025_get_external_temp_index(struct rt5025_swjeita_info *swji)
-{
- u8 data[2];
- long int temp;
- int sect_index;
-
- RTINFO("\n");
- if (rt5025_reg_block_read(swji->i2c, RT5025_REG_AINH, 2, data) < 0)
- pr_err("%s: failed to read ext_temp register\n", __func__);
-
- temp = (data[0] * 256 + data[1]) * 61 / 100;
- temp = (temp * (-91738) + 81521000) / 100000;
-
- swji->cur_temp = temp;
-
- RTINFO("cur_section = %d, cur_temp = %d\n", swji->cur_section, swji->cur_temp);
-
- switch (swji->cur_section) {
- case 0:
- if (temp < swji->temp[0] + TEMP_TOLERANCE)
- sect_index = rt5025_sel_external_temp_index(swji);
- else
- sect_index = swji->cur_section;
- break;
- case 1:
- if (temp <= swji->temp[0] - TEMP_TOLERANCE || temp >= swji->temp[1] + TEMP_TOLERANCE)
- sect_index = rt5025_sel_external_temp_index(swji);
- else
- sect_index = swji->cur_section;
- break;
- case 2:
- if (temp <= swji->temp[1] - TEMP_TOLERANCE || temp >= swji->temp[2] + TEMP_TOLERANCE)
- sect_index = rt5025_sel_external_temp_index(swji);
- else
- sect_index = swji->cur_section;
- break;
- case 3:
- if (temp <= swji->temp[2] - TEMP_TOLERANCE || temp >= swji->temp[3] + TEMP_TOLERANCE)
- sect_index = rt5025_sel_external_temp_index(swji);
- else
- sect_index = swji->cur_section;
- break;
- case 4:
- if (temp <= swji->temp[3] - TEMP_TOLERANCE)
- sect_index = rt5025_sel_external_temp_index(swji);
- else
- sect_index = swji->cur_section;
- break;
- default:
- sect_index = swji->cur_section;
- break;
- }
- RTINFO("sect_index = %d\n", sect_index);
- return sect_index;
-}
-
-static inline int rt5025_set_ainadc_onoff(struct rt5025_swjeita_info *swji, int enable)
-{
- int ret;
-
- RTINFO("enable = %d\n", enable);
- if (enable)
- ret = rt5025_set_bits(swji->i2c, RT5025_REG_CHANNELL, RT5025_AINEN_MASK);
- else
- ret = rt5025_clr_bits(swji->i2c, RT5025_REG_CHANNELL, RT5025_AINEN_MASK);
-
- return ret;
-}
-
-static inline int rt5025_set_intadc_onoff(struct rt5025_swjeita_info *swji, int enable)
-{
- int ret;
-
- RTINFO("enable = %d\n", enable);
- if (enable)
- ret = rt5025_set_bits(swji->i2c, RT5025_REG_CHANNELL, RT5025_INTEN_MASK);
- else
- ret = rt5025_clr_bits(swji->i2c, RT5025_REG_CHANNELL, RT5025_INTEN_MASK);
-
- return ret;
-}
-
-static int rt5025_set_exttemp_alert(struct rt5025_swjeita_info *swji, int index)
-{
- int ret = 0;
-
- RTINFO("index = %d\n", index);
-
- switch (index) {
- case 0:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[1]);
- break;
- case 1:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[0]);
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[3]);
- break;
- case 2:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[2]);
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[5]);
- break;
- case 3:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[4]);
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[7]);
- break;
- case 4:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[6]);
- break;
- }
-
- return ret;
-}
-
-static int rt5025_exttemp_alert_switch(struct rt5025_swjeita_info *swji, int onoff)
-{
- if (!onoff) {
- rt5025_clr_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMXEN_MASK);
- rt5025_clr_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMNEN_MASK);
- } else {
- switch (swji->cur_section) {
- case 0:
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMNEN_MASK);
- break;
- case 1:
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMXEN_MASK);
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMNEN_MASK);
- break;
- case 2:
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMXEN_MASK);
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMNEN_MASK);
- break;
- case 3:
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMXEN_MASK);
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMNEN_MASK);
- break;
- case 4:
- rt5025_set_bits(swji->i2c, RT5025_REG_IRQCTL, RT5025_TMXEN_MASK);
- break;
- }
- }
-
- RTINFO("index=%d, onoff=%d\n", swji->cur_section, onoff);
- return 0;
-}
-
-int rt5025_notify_charging_cable(struct rt5025_swjeita_info *swji, int cable_type)
-{
- int sect_index;
- int ret = 0;
-
- RTINFO("cable_type = %d\n", cable_type);
-
- rt5025_exttemp_alert_switch(swji, 0);
-
- sect_index = rt5025_get_external_temp_index(swji);
- if (swji->cur_section != sect_index || swji->init_once == 0) {
- rt5025_set_exttemp_alert(swji, sect_index);
- swji->cur_section = sect_index;
- swji->init_once = 1;
- }
-
- switch (cable_type) {
- case JEITA_NORMAL_USB:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]\
- - swji->dec_current);
- rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
- break;
- case JEITA_USB_TA:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]\
- - swji->dec_current);
- rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
- break;
- case JEITA_AC_ADAPTER:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]\
- - swji->dec_current);
- rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
- break;
- case JEITA_NO_CHARGE:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]);
- rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
- break;
- }
- swji->cur_cable = cable_type;
-
- rt5025_exttemp_alert_switch(swji, 1);
-
- return ret;
-}
-EXPORT_SYMBOL(rt5025_notify_charging_cable);
-
-int rt5025_swjeita_irq_handler(struct rt5025_swjeita_info *swji, unsigned char event)
-{
- int ret = 0;
- RTINFO("event = 0x%02x\n", event);
-
- if (event&(RT5025_TMXEN_MASK | RT5025_TMNEN_MASK))
- rt5025_notify_charging_cable(swji, swji->cur_cable);
-
- return ret;
-}
-EXPORT_SYMBOL(rt5025_swjeita_irq_handler);
-
-static void rt5025_get_internal_temp(struct rt5025_swjeita_info *swji)
-{
- u8 data[2];
- s32 temp;
- if (rt5025_reg_block_read(swji->i2c, RT5025_REG_INTTEMP_MSB, 2, data) < 0)
- pr_err("%s: Failed to read internal TEMPERATURE\n", __func__);
-
- temp = ((data[0] & 0x1F) << 8) + data[1];
- temp *= 15625;
- temp /= 100000;
-
- temp = (data[0] & 0x20) ? -temp : temp;
- swji->cur_inttemp = temp;
-
- RTINFO("internal temperature: %d\n", temp);
-}
-
-static void thermal_reg_work_func(struct work_struct *work)
-{
- struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
- struct rt5025_swjeita_info *swji = (struct rt5025_swjeita_info *)container_of(delayed_work, struct rt5025_swjeita_info, thermal_reg_work);
- int therm_region = 0;
-
- RTINFO("%s ++", __func__);
- rt5025_get_internal_temp(swji);
-
- #if 1
- switch (swji->cur_therm_region) {
- case 0:
- if (swji->cur_inttemp >= 820)
- therm_region = 1;
- else
- therm_region = 0;
- break;
- case 1:
- if (swji->cur_inttemp <= 780)
- therm_region = 0;
- else if (swji->cur_inttemp >= 1020)
- therm_region = 2;
- else
- therm_region = 1;
- break;
- case 2:
- if (swji->cur_inttemp <= 980)
- therm_region = 1;
- else
- therm_region = 2;
- break;
- }
- #else
- if (swji->cur_inttemp < 800)
- therm_region = 0;
- else if (swji->cur_inttemp >= 800 && swji->cur_inttemp < 1000)
- therm_region = 1;
- else
- therm_region = 2;
- #endif /* #if 1*/
-
- if (therm_region != swji->cur_therm_region) {
- switch (therm_region) {
- case 0:
- swji->dec_current = 0;
- break;
- case 1:
- swji->dec_current = 300;
- break;
- case 2:
- swji->dec_current = 800;
- break;
- }
- swji->cur_therm_region = therm_region;
- rt5025_notify_charging_cable(swji, swji->cur_cable);
- }
-
- if (!swji->suspend)
- schedule_delayed_work(&swji->thermal_reg_work, 5*HZ);
-
- RTINFO("%s --", __func__);
-}
-
-static int rt5025_swjeita_probe(struct platform_device *pdev)
-{
- struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct rt5025_platform_data *pdata = chip->dev->platform_data;
- struct rt5025_swjeita_info *swji;
- int ret = 0;
-
- swji = kzalloc(sizeof(*swji), GFP_KERNEL);
- if (!swji)
- return -ENOMEM;
-
- #if 0 /* for debug pdata->jeita_data*/
- for (ret = 0; ret < 4; ret++)
- RTINFO("jeita temp value %d\n", pdata->jeita_data->temp[ret]);
- for (ret = 0; ret < 4; ret++) {
- RTINFO("jeita temp_cc value %d, %d, %d, %d, %d\n", pdata->jeita_data->temp_cc[ret][0], \
- pdata->jeita_data->temp_cc[ret][1], pdata->jeita_data->temp_cc[ret][2], \
- pdata->jeita_data->temp_cc[ret][3], pdata->jeita_data->temp_cc[ret][4]);
- }
- for (ret = 0; ret < 4; ret++) {
- RTINFO("jeita temp_cv value %d, %d, %d, %d, %d\n", pdata->jeita_data->temp_cv[ret][0], \
- pdata->jeita_data->temp_cv[ret][1], pdata->jeita_data->temp_cv[ret][2], \
- pdata->jeita_data->temp_cv[ret][3], pdata->jeita_data->temp_cv[ret][4]);
- }
- for (ret = 0; ret < 8; ret++) {
- RTINFO("temp_scalar[%d] = 0x%02x\n", ret, pdata->jeita_data->temp_scalar[ret]);
- }
- ret = 0;
- #endif /* #if 0 */
-
- swji->i2c = chip->i2c;
- swji->chip = chip;
- swji->cur_section = 2;
- /*initial as the normal temperature*/
- swji->cur_cable = JEITA_NO_CHARGE;
- swji->temp = pdata->jeita_data->temp;
- swji->temp_scalar = pdata->jeita_data->temp_scalar;
- swji->temp_cc = pdata->jeita_data->temp_cc;
- swji->temp_cv = pdata->jeita_data->temp_cv;
- INIT_DELAYED_WORK(&swji->thermal_reg_work, thermal_reg_work_func);
- platform_set_drvdata(pdev, swji);
-
- rt5025_set_ainadc_onoff(swji, 1);
- rt5025_set_intadc_onoff(swji, 1);
- mdelay(100);
- rt5025_notify_charging_cable(swji, swji->cur_cable);
- schedule_delayed_work(&swji->thermal_reg_work, 1*HZ);
-
- chip->jeita_info = swji;
- RTINFO("rt5025-swjeita driver is successfully loaded\n");
- return ret;
-}
-
-static int rt5025_swjeita_remove(struct platform_device *pdev)
-{
- struct rt5025_swjeita_info *swji = platform_get_drvdata(pdev);
-
- swji->chip->jeita_info = NULL;
- kfree(swji);
- RTINFO("\n");
- return 0;
-}
-
-static int rt5025_swjeita_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct rt5025_swjeita_info *swji = platform_get_drvdata(pdev);
-
- swji->suspend = 1;
- cancel_delayed_work_sync(&swji->thermal_reg_work);
- swji->cur_therm_region = swji->dec_current = 0;
- rt5025_notify_charging_cable(swji, swji->cur_cable);
- RTINFO("\n");
- return 0;
-}
-
-static int rt5025_swjeita_resume(struct platform_device *pdev)
-{
- struct rt5025_swjeita_info *swji = platform_get_drvdata(pdev);
-
- swji->suspend = 0;
- schedule_delayed_work(&swji->thermal_reg_work, 0);
- RTINFO("\n");
- return 0;
-}
-
-static struct platform_driver rt5025_swjeita_driver = {
- .driver = {
- .name = RT5025_DEVICE_NAME "-swjeita",
- .owner = THIS_MODULE,
- },
- .probe = rt5025_swjeita_probe,
- .remove = __devexit_p(rt5025_swjeita_remove),
- .suspend = rt5025_swjeita_suspend,
- .resume = rt5025_swjeita_resume,
-};
-
-static int rt5025_swjeita_init(void)
-{
- return platform_driver_register(&rt5025_swjeita_driver);
-}
-module_init(rt5025_swjeita_init);
-
-static void rt5025_swjeita_exit(void)
-{
- platform_driver_unregister(&rt5025_swjeita_driver);
-}
-module_exit(rt5025_swjeita_exit);
-
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
-MODULE_DESCRIPTION("Swjeita driver for RT5025");
-MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-swjeita");
-MODULE_VERSION(RT5025_DRV_VER);