From 9d40ac5867b9aefe0722bc1f110b965ff294d30d Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 15 Nov 2014 10:00:36 +0800 Subject: add via modify part source code for wm8880 4.4 kitkat --- ANDROID_3.4.5/drivers/power/wmt_battery/Makefile | 15 + .../power/wmt_battery/charger/g2214/Kconfig | 5 + .../power/wmt_battery/charger/g2214/Makefile | 7 + .../wmt_battery/charger/g2214/g2214_charger.c | 762 +++++++ .../power/wmt_battery/charger/mp2625/Kconfig | 5 + .../power/wmt_battery/charger/mp2625/Makefile | 6 + .../wmt_battery/charger/mp2625/mp2625_charger.c | 428 ++++ .../power/wmt_battery/gauge/bq27xx/Makefile | 6 + .../wmt_battery/gauge/bq27xx/bq27x00_battery.c | 1011 +++++++++ .../power/wmt_battery/gauge/saradc/Makefile | 4 + .../wmt_battery/gauge/saradc/saradc_battery.c | 341 +++ .../power/wmt_battery/gauge/sp2541/Makefile | 5 + .../wmt_battery/gauge/sp2541/sp2541_battery.c | 765 +++++++ .../power/wmt_battery/gauge/ug31xx/Makefile | 13 + .../ggb/ug31xx_ggb_data_cw500_20130801_103638.h | 233 ++ .../ggb/ug31xx_ggb_data_mp718_20131004_070110.h | 233 ++ .../ggb/ug31xx_ggb_data_t73v_20131120_001204.h | 233 ++ .../ggb/ug31xx_ggb_data_wms7320_20130718_200031.h | 233 ++ .../ug31xx_ggb_data_wms8309_c7_20130725_164935.h | 233 ++ .../ug31xx_ggb_data_wms8309_c7_20130910_130553.h | 233 ++ .../ug31xx_ggb_data_wms8309_wm8_20130820_110949.h | 233 ++ .../power/wmt_battery/gauge/ug31xx/global.h | 31 + .../power/wmt_battery/gauge/ug31xx/stdafx.h | 8 + .../power/wmt_battery/gauge/ug31xx/typeDefine.h | 462 ++++ .../power/wmt_battery/gauge/ug31xx/uG31xx.h | 127 ++ .../power/wmt_battery/gauge/ug31xx/uG31xx_API.c | 2307 ++++++++++++++++++++ .../power/wmt_battery/gauge/ug31xx/uG31xx_API.h | 521 +++++ .../wmt_battery/gauge/ug31xx/uG31xx_API_Backup.c | 601 +++++ .../wmt_battery/gauge/ug31xx/uG31xx_API_Backup.h | 79 + .../wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.b | Bin 0 -> 40924 bytes .../wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.h | 143 ++ .../gauge/ug31xx/uG31xx_API_Measurement.c | 1389 ++++++++++++ .../gauge/ug31xx/uG31xx_API_Measurement.h | 127 ++ .../wmt_battery/gauge/ug31xx/uG31xx_API_Otp.c | 876 ++++++++ .../wmt_battery/gauge/ug31xx/uG31xx_API_Otp.h | 84 + .../wmt_battery/gauge/ug31xx/uG31xx_API_System.c | 1196 ++++++++++ .../wmt_battery/gauge/ug31xx/uG31xx_API_System.h | 211 ++ .../wmt_battery/gauge/ug31xx/uG31xx_Platform.h | 17 + .../wmt_battery/gauge/ug31xx/uG31xx_Reg_Def.h | 667 ++++++ .../power/wmt_battery/gauge/ug31xx/ug31xx_gauge.c | 782 +++++++ .../power/wmt_battery/gauge/ug31xx/ug31xx_gauge.h | 65 + .../power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c | 152 ++ .../power/wmt_battery/gauge/ug31xx/ug31xx_i2c.h | 43 + .../power/wmt_battery/gauge/vt1603/Makefile | 5 + .../power/wmt_battery/gauge/vt1603/batt_leds.c | 189 ++ .../power/wmt_battery/gauge/vt1603/batt_leds.h | 12 + .../power/wmt_battery/gauge/vt1603/vt1603.c | 513 +++++ .../power/wmt_battery/gauge/vt1603/vt1603.h | 124 ++ .../drivers/power/wmt_battery/wmt_battery.c | 66 + 49 files changed, 15801 insertions(+) create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Kconfig create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/g2214_charger.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Kconfig create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/mp2625_charger.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/bq27x00_battery.c create mode 100644 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/Makefile create mode 100644 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/saradc_battery.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/sp2541_battery.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_cw500_20130801_103638.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_mp718_20131004_070110.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_t73v_20131120_001204.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms7320_20130718_200031.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130725_164935.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130910_130553.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_wm8_20130820_110949.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/global.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/stdafx.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/typeDefine.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.b create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Platform.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Reg_Def.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/Makefile create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.c create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.h create mode 100755 ANDROID_3.4.5/drivers/power/wmt_battery/wmt_battery.c (limited to 'ANDROID_3.4.5/drivers/power/wmt_battery') diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/Makefile new file mode 100755 index 00000000..e4287ba0 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/Makefile @@ -0,0 +1,15 @@ + +# charger +obj-y += charger/g2214/ +obj-y += charger/mp2625/ + +# gauge +obj-y += gauge/vt1603/ +obj-y += gauge/ug31xx/ +obj-y += gauge/sp2541/ +obj-y += gauge/bq27xx/ +obj-y += gauge/saradc/ + +# core +obj-y += wmt_battery.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Kconfig b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Kconfig new file mode 100755 index 00000000..1ca457f8 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Kconfig @@ -0,0 +1,5 @@ +config G2214_CHARGER + tristate "GMT G2214 Charger driver (GMT & others)" + depends on I2C + help + Say Y here to enable support for charger with g2214 chip. \ No newline at end of file diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Makefile new file mode 100755 index 00000000..188872a7 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for GMT charger core. +# + +obj-y += g2214_charger.o + + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/g2214_charger.c b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/g2214_charger.c new file mode 100755 index 00000000..944790e8 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/g2214/g2214_charger.c @@ -0,0 +1,762 @@ +/* + * g2214_charger.c - WonderMedia Charger Driver. + * + * Copyright (C) 2013 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "gmt-charger" + +#undef pr_err +#define pr_err(fmt, args...) printk("[" DRVNAME "] " fmt, ##args) + +#define REG_A0 0x00 +#define REG_A1 0x01 +#define REG_A2 0x02 +#define REG_A3 0x03 +#define REG_A4 0x04 +#define REG_A5 0x05 +#define REG_A6 0x06 +#define REG_A7 0x07 +#define REG_A8 0x08 +#define REG_A9 0x09 +#define REG_A10 0x0A +#define REG_A11 0x0B +#define REG_A12 0x0C +#define REG_A13 0x0D + +struct g2214_charger { + struct gmt2214_dev *gmt_dev; + struct device *dev; + struct mutex lock; + + struct power_supply psy_ac; + struct power_supply psy_usb; + struct delayed_work monitor_work; + + int ac_online; + int usb_online; + int charger_status; + int sleeping; + + union { + struct { + unsigned int cable_type:4; + unsigned int current_sw_mode:1; + unsigned int pc_charging:1; + }; + uint32_t flag; + }; + + int iset_dcin; + int iset_vbus; + int vseta; + int iseta_small; + int iseta_large; + int safety_time; + int otg_power; + int pc_power_mode; +}; + +static struct g2214_charger *g_charger = NULL; + +static int parse_charger_param(struct g2214_charger *ch) +{ + static const char uboot_env[] = "wmt.charger.param"; + char buf[64]; + size_t l = sizeof(buf); + int n; + + if (wmt_getsyspara((char *)uboot_env, buf, &l)) + return -ENODEV; + if (prefixcmp(buf, "g2214:")) + return -ENODEV; + if (!ch) + return 0; + + n = sscanf(buf + 6, "%x:%d:%d:%d:%d:%d:%d:%d:%d", + &ch->flag, + &ch->iset_dcin, &ch->iset_vbus, &ch->vseta, + &ch->iseta_small, &ch->iseta_large, + &ch->safety_time, &ch->otg_power, &ch->pc_power_mode); + if (n < 8) { + pr_err("%s invalid\n", uboot_env); + return -EINVAL; + } + + pr_info("charger match g2214, %s cable, %s current switch\n" + "PC connected is %scharging\n" + "dcin %d mA, vbus %d mA, %d mV\n" + "charging current %d~%d mA %d hour, %s otg power\n" + "pc power in %s mode\n", + (ch->cable_type == CABLE_TYPE_DC) ? "DC" : "USB", + (ch->current_sw_mode == CURRENT_SWITCH_DYNAMIC) ? "dynamic" : "sleep", + (ch->pc_charging == PC_CONNECTED_NOT_CHARGING) ? "not " : "", + ch->iset_dcin, ch->iset_vbus, ch->vseta, + ch->iseta_small, ch->iseta_large, + ch->safety_time, ch->otg_power ? "switch" : "no", + ch->pc_power_mode ? "lowpower" : "normal"); + return 0; +} + +static int g2214_read(struct g2214_charger *ch, uint8_t reg) +{ + unsigned int rt_value = 0; + gmt2214_reg_read(ch->gmt_dev, reg, &rt_value); + return rt_value; +} + +static int g2214_write(struct g2214_charger *ch, uint8_t reg, uint8_t val) +{ + return gmt2214_reg_write(ch->gmt_dev, reg, val); +} + +static inline void g2214_enotg_config(struct g2214_charger *ch, int enable) +{ + int val = g2214_read(ch, REG_A8); + if (enable) + val |= BIT3; + else + val &= ~BIT3; + g2214_write(ch, REG_A8, val); +} + +static inline void g2214_vseta_config(struct g2214_charger *ch) +{ + int val, vseta; + + if (ch->vseta < 4150) + vseta = 0; + else if (ch->vseta < 4200) + vseta = 1; + else if (ch->vseta < 4350) + vseta = 2; + else + vseta = 3; + + val = g2214_read(ch, REG_A8); + val &= ~(3 << 6); + val |= vseta << 6; + g2214_write(ch, REG_A8, val); +} + +static inline void g2214_current_config(struct g2214_charger *ch, + int dcin_mA, int vbus_mA, int charge_mA) +{ + int iset_dcin, iset_vbus, iseta; + + if (dcin_mA <= 1000) + iset_dcin = 0; + else if (dcin_mA <= 1500) + iset_dcin = 1; + else if (dcin_mA <= 2000) + iset_dcin = 2; + else + iset_dcin = 3; + + if (vbus_mA <= 95) + iset_vbus = 0; + else if (vbus_mA <= 475) + iset_vbus = 1; + else if (vbus_mA <= 950) + iset_vbus = 2; + else + iset_vbus = 3; + + if (charge_mA < 300 || charge_mA > 1800) + iseta = 2; + else + iseta = ((charge_mA - 300) / 100); + + g2214_write(ch, REG_A5, iset_dcin << 6 | iset_vbus << 4 | iseta); +} + +static void current_refresh(struct g2214_charger *ch) +{ + int dcin_mA, vbus_mA, charge_mA; + + dcin_mA = ch->iset_dcin; + + switch (ch->charger_status) { + case POWER_SUPPLY_STATUS_DISCHARGING: + vbus_mA = ch->pc_power_mode ? 95 : 475; + charge_mA = ch->iseta_small; + break; + case POWER_SUPPLY_STATUS_FULL: + case POWER_SUPPLY_STATUS_CHARGING: + vbus_mA = ch->iset_vbus; + if (ch->current_sw_mode == CURRENT_SWITCH_DYNAMIC) { + charge_mA = ch->iseta_large; + } else { + charge_mA = ch->sleeping ? ch->iseta_large + : ch->iseta_small; + } + if (ch->cable_type == CABLE_TYPE_USB && wmt_is_pc_connected()) { + vbus_mA = 475; + charge_mA = ch->iseta_small; + } + break; + default: + return; + } + + printk(KERN_DEBUG " ## %s: dcin_mA %d, vbus_mA %d, charge_mA %d\n", + __func__, dcin_mA, vbus_mA, charge_mA); + g2214_current_config(ch, dcin_mA, vbus_mA, charge_mA); + g2214_vseta_config(ch); +} + +static void g2214_endpm_config(struct g2214_charger *ch, int en) +{ + int val = g2214_read(ch, REG_A0); + if (en) + val |= BIT3; + else + val &= ~BIT3; + g2214_write(ch, REG_A0, val); +} + +static void g2214_safety_time_init(struct g2214_charger *ch) +{ + int val; + int safety_time = ch->safety_time - 1; + + if (safety_time < 0) + safety_time = 0; + else if (safety_time > 16) + safety_time = 15; + + val = g2214_read(ch, REG_A6); + val &= (~(BIT4 | BIT5 | BIT6 | BIT7)); + val |= (safety_time << 4); + g2214_write(ch, REG_A6, val); +} + +static void g2214_ntc_init(struct g2214_charger *ch) +{ + int val; + val = g2214_read(ch, REG_A0); + val &= ~BIT1; //Enable Auto NTC-R Type Detection + g2214_write(ch, REG_A0, val); + g2214_write(ch, REG_A7, 0); //Set HOT boundary to 60 +} + +static int g2214_reg_init(struct g2214_charger *ch) +{ + g2214_safety_time_init(ch); + g2214_enotg_config(ch, 0); + g2214_current_config(ch, ch->iset_dcin, ch->iset_vbus, ch->iseta_small); + g2214_endpm_config(ch, ch->current_sw_mode == CURRENT_SWITCH_DYNAMIC); + g2214_ntc_init(ch); + return 0; +} + +static void g2214_regs_dump(struct g2214_charger *ch) +{ + int reg; + for (reg = REG_A0; reg <= REG_A13; reg++) + printk(KERN_DEBUG " ## reg A%d: 0x%x\n ", + reg, g2214_read(ch, reg)); +} + +static void g2214_charge_enable(struct g2214_charger *ch, int en) +{ + int val = g2214_read(ch, REG_A6); + if (en) + val &= ~BIT3; + else + val |= BIT3; + g2214_write(ch, REG_A6, val); +} + +static inline int g2214_is_full(struct g2214_charger *ch) +{ + return !!(g2214_read(ch, REG_A12) & 0x10); +} + +static int g2214_read_status(struct g2214_charger *ch, int *pst) +{ + if (!wmt_is_dc_plugin()) { + *pst = POWER_SUPPLY_STATUS_DISCHARGING; + return 0; + } + + switch (ch->cable_type) { + case CABLE_TYPE_DC: + *pst = POWER_SUPPLY_STATUS_CHARGING; + break; + case CABLE_TYPE_USB: + if (wmt_is_otg_plugin()) { + *pst = POWER_SUPPLY_STATUS_DISCHARGING; + } else if (wmt_is_pc_connected()) { + if (ch->pc_charging == PC_CONNECTED_CHARGING) + *pst = POWER_SUPPLY_STATUS_CHARGING; + else + *pst = POWER_SUPPLY_STATUS_DISCHARGING; + } else { + *pst = POWER_SUPPLY_STATUS_CHARGING; + } + break; + default: + return -EINVAL; + } + + if (*pst == POWER_SUPPLY_STATUS_CHARGING) { + if (g2214_is_full(ch)) + *pst = POWER_SUPPLY_STATUS_FULL; + } + return 0; +} + +static void charger_monitor_work(struct work_struct *work) +{ + struct g2214_charger *ch= + container_of(work, struct g2214_charger, monitor_work.work); + int ac_online = 0; + int usb_online = 0; + int charger_status; + int ts_meter = 0; + + g2214_regs_dump(ch); + + if (wmt_is_otg_plugin() && ch->otg_power) + g2214_enotg_config(ch, 1); + else { + g2214_enotg_config(ch, 0); + msleep(30); + } + + g2214_write(ch, REG_A9, 0xFF); + + g2214_read_status(ch, &charger_status); + + ts_meter = (g2214_read(ch, REG_A10) & 0xE0) >> 5; + if (ts_meter == 0x11) { + charger_status = POWER_SUPPLY_STATUS_DISCHARGING; + g2214_charge_enable(ch, 0); + printk("Battery Overheat, Charge Disable\n"); + } else if (ts_meter <= 0) + g2214_charge_enable(ch, 1); + + if (charger_status == POWER_SUPPLY_STATUS_CHARGING || + charger_status == POWER_SUPPLY_STATUS_FULL) { + if (ch->cable_type == CABLE_TYPE_USB && + ch->pc_charging == PC_CONNECTED_CHARGING && + wmt_is_pc_connected()) + usb_online = 1; + else + ac_online = 1; + } + + if (ch->charger_status != charger_status || + ch->ac_online != ac_online) { + ch->charger_status = charger_status; + ch->ac_online = ac_online; + power_supply_changed(&ch->psy_ac); + } + + if (ch->pc_charging == PC_CONNECTED_CHARGING && + ch->usb_online != usb_online) { + ch->usb_online = usb_online; + power_supply_changed(&ch->psy_usb); + } + + current_refresh(ch); + led_power_enable(charger_status == POWER_SUPPLY_STATUS_CHARGING || + charger_status == POWER_SUPPLY_STATUS_FULL); + + g2214_write(ch, REG_A9, 0xF0); + g2214_write(ch, REG_A12, g2214_read(ch, REG_A12) & (~BIT0)); +} + +void g2214_pc_connected(void) +{ + if (g_charger) + schedule_delayed_work(&g_charger->monitor_work, 1.5*HZ); +} + +static irqreturn_t otg_irq(int irq, void *data) +{ + struct g2214_charger *ch = data; + + if (REG8_VAL(USB_BASE_ADD + 0x7F1) & BIT7) { + REG8_VAL(USB_BASE_ADD + 0x7F1) = BIT7; + schedule_delayed_work(&ch->monitor_work, 0); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +// g2214 + dcdet use wakeup0 interrupt +static irqreturn_t g2214_dcdet_irq(int irq, void *data) +{ + struct g2214_charger *ch = data; + + // turn off the led immediately + if (!wmt_is_dc_plugin()) + led_power_enable(0); + + if (PMCIS_VAL & BIT0) { + pmc_clear_intr_status(WKS_WK0); + schedule_delayed_work(&ch->monitor_work, 0); + return IRQ_HANDLED; + } + + if (PMCIS_VAL & BIT27) { + pmc_clear_intr_status(WKS_DCDET); + schedule_delayed_work(&ch->monitor_work, 1.5*HZ); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static inline void pid_check_irq_enable(void) +{ + REG8_VAL(USB_BASE_ADD+0x7F2) |= BIT1; +} + +static inline void pid_check_irq_disable(void) +{ + REG8_VAL(USB_BASE_ADD+0x7F2) &= ~BIT1; +} + +static int irqs_init(struct g2214_charger *ch) +{ + unsigned long iflag = IRQF_SHARED; + int ret; + + ret = devm_request_irq(ch->dev, IRQ_UHDC, otg_irq, iflag, "USBOTG", ch); + if (ret < 0) { + dev_err(ch->dev, "IRQ_UHDC irq request failed %d\n", ret); + return ret; + } + + if (REG32_VAL(0xfe120000) == 0x35100101) + iflag |= IRQF_NO_SUSPEND; + + ret = devm_request_irq(ch->dev, IRQ_PMC_WAKEUP, g2214_dcdet_irq, iflag, + "G2214-DCDET", ch); + if (ret < 0) { + pr_err("register DCDET irq failed\n"); + return ret; + } + + pid_check_irq_enable(); + pmc_enable_wakeup_isr(WKS_WK0, 2); + wmt_dcdet_irq_enable(); + return 0; +} + +static void irqs_release(struct g2214_charger *ch) +{ + pid_check_irq_disable(); + wmt_dcdet_irq_disable(); + pmc_disable_wakeup_isr(WKS_WK0); +} + +static enum power_supply_property ac_properties[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_STATUS, +}; + +static int ac_get_property(struct power_supply *psy, + enum power_supply_property prop, + union power_supply_propval *val) +{ + struct g2214_charger *ch = + container_of(psy, struct g2214_charger, psy_ac); + switch (prop) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = ch->ac_online; + break; + case POWER_SUPPLY_PROP_STATUS: + return g2214_read_status(ch, &val->intval); + default: + return -EINVAL; + } + return 0; +} + +static int usb_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct g2214_charger *ch = + container_of(psy, struct g2214_charger, psy_usb); + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = ch->usb_online; + break; + default: + return -EINVAL; + } + return 0; +} + +static enum power_supply_property usb_properties[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static char *power_supplied_to[] = { + "battery", +}; + +static int power_supply_init(struct g2214_charger *ch) +{ + int ret; + + ch->psy_ac.name = "ac", + ch->psy_ac.type = POWER_SUPPLY_TYPE_MAINS, + ch->psy_ac.supplied_to = power_supplied_to, + ch->psy_ac.num_supplicants = ARRAY_SIZE(power_supplied_to), + ch->psy_ac.properties = ac_properties, + ch->psy_ac.num_properties = ARRAY_SIZE(ac_properties), + ch->psy_ac.get_property = ac_get_property, + ret = power_supply_register(ch->dev, &ch->psy_ac); + if (ret) { + dev_err(ch->dev, "register ac power supply failed.\n"); + } + + if (ch->pc_charging == PC_CONNECTED_CHARGING) { + ch->psy_usb.name = "usb", + ch->psy_usb.type = POWER_SUPPLY_TYPE_USB, + ch->psy_usb.supplied_to = power_supplied_to, + ch->psy_usb.num_supplicants = ARRAY_SIZE(power_supplied_to), + ch->psy_usb.properties = usb_properties, + ch->psy_usb.num_properties = ARRAY_SIZE(usb_properties), + ch->psy_usb.get_property = usb_get_property, + ret = power_supply_register(ch->dev, &ch->psy_usb); + if (ret) { + dev_err(ch->dev, "register ac power supply failed.\n"); + return ret; + } + } + + return ret; +} + +static void power_supply_release(struct g2214_charger *ch) +{ + power_supply_unregister(&ch->psy_ac); +} + +#define G2214_PROC_NAME "driver/g2214_regs" + +static int g2214_proc_show(struct seq_file *seq, void *offset) +{ + int reg; + for (reg = REG_A0; reg <= REG_A13; reg++) + seq_printf(seq, "reg A%d: 0x%x\n ", + reg, g2214_read(g_charger, reg)); + return 0; +} + +static int g2214_proc_open(struct inode *inode, struct file *file) +{ + int ret; + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + + ret = single_open(file, g2214_proc_show, NULL); + if (ret) + module_put(THIS_MODULE); + return ret; +} + +static ssize_t g2214_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + char cmd[32]; + unsigned long len = count; + int reg, val; + + if (len > sizeof(cmd)) + len = sizeof(cmd); + + if (copy_from_user(cmd, buffer, len)) + return -EFAULT; + if (sscanf(cmd, "r%d=0x%02x", ®, &val) != 2) + return -EINVAL; + if (reg > REG_A13) + return -EINVAL; + + if (g_charger) { + g2214_write(g_charger, reg, val); + pr_info("## %s: reg %d -> 0x%02x\n", __func__, reg, val); + } + + return count; +} + +static int g2214_proc_release(struct inode *inode, struct file *file) +{ + int res = single_release(inode, file); + module_put(THIS_MODULE); + return res; +} + +static const struct file_operations g2214_proc_fops = { + .open = g2214_proc_open, + .read = seq_read, + .write = g2214_proc_write, + .llseek = seq_lseek, + .release = g2214_proc_release, +}; + +static inline void g2214_proc_setup(void) +{ + proc_create(G2214_PROC_NAME, 0, NULL, &g2214_proc_fops); +} + +static inline void g2214_proc_cleanup(void) +{ + remove_proc_entry(G2214_PROC_NAME, NULL); +} + +static int g2214_reboot_notifie(struct notifier_block *nb, unsigned long event, void *unused) +{ + struct g2214_charger *ch = g_charger; + cancel_delayed_work_sync(&ch->monitor_work); + g2214_enotg_config(ch, 0); + g2214_write(ch, REG_A9, 0xFF); + g2214_write(ch, REG_A11, 0xFF); + return NOTIFY_OK; +} + +static struct notifier_block g2214_reboot_notifier = { + .notifier_call = g2214_reboot_notifie, +}; + + +static int __devinit g2214_probe(struct platform_device *pdev) +{ + struct g2214_charger *ch; + int ret; + + ch = devm_kzalloc(&pdev->dev, sizeof(*ch), GFP_KERNEL); + if (!ch) + return -ENOMEM; + + if ((ret = parse_charger_param(ch))) + return ret; + parse_charger_led(); + + ch->dev = &pdev->dev; + ch->gmt_dev = dev_get_drvdata(pdev->dev.parent); + platform_set_drvdata(pdev, ch); + + if ((ret = power_supply_init(ch))) + return ret; + + INIT_DELAYED_WORK(&ch->monitor_work, charger_monitor_work); + + if ((ret = irqs_init(ch))) { + power_supply_release(ch); + return ret; + } + + g_charger = ch; + g2214_reg_init(ch); + g2214_proc_setup(); + + register_reboot_notifier(&g2214_reboot_notifier); + schedule_delayed_work(&ch->monitor_work, 0); + pr_info(DRVNAME " install success.\n"); + return 0; +} + +static int __devexit g2214_remove(struct platform_device *pdev) +{ + struct g2214_charger *ch = platform_get_drvdata(pdev); + irqs_release(ch); + cancel_delayed_work_sync(&ch->monitor_work); + power_supply_release(ch); + g2214_proc_cleanup(); + g_charger = NULL; + return 0; +} + +static int g2214_suspend(struct device *dev) +{ + struct g2214_charger *ch = dev_get_drvdata(dev); + cancel_delayed_work_sync(&ch->monitor_work); + ch->sleeping = 1; + current_refresh(ch); + g2214_write(ch, REG_A11, 0xCF); + return 0; +} + +static int g2214_resume(struct device *dev) +{ + struct g2214_charger *ch = dev_get_drvdata(dev); + + // turn off the led immediately + if (!wmt_is_dc_plugin()) + led_power_enable(0); + + pid_check_irq_enable(); + ch->sleeping = 0; + current_refresh(ch); + schedule_delayed_work(&ch->monitor_work, HZ); + g2214_write(ch, REG_A11, 0xFF); + return 0; +} + +static const struct dev_pm_ops g2214_pm_ops = { + .suspend = g2214_suspend, + .resume = g2214_resume, +}; + +static struct platform_driver g2214_driver = { + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + .pm = &g2214_pm_ops, + }, + .probe = g2214_probe, + .remove = __devexit_p(g2214_remove), +}; + +static int __init g2214_init(void) +{ + if (parse_charger_param(NULL)) + return -ENODEV; + return platform_driver_register(&g2214_driver); +} + +static void __exit g2214_exit(void) +{ + return platform_driver_unregister(&g2214_driver); +} + +module_init(g2214_init); +module_exit(g2214_exit); + +MODULE_AUTHOR("WonderMedia Technologies, Inc."); +MODULE_DESCRIPTION("GMT2144 battery charger driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("i2c:g2214"); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Kconfig b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Kconfig new file mode 100755 index 00000000..38282c65 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Kconfig @@ -0,0 +1,5 @@ +config MP2625_CHARGER + tristate "MP2625 Charger driver" + depends on I2C + help + Say Y here to enable support for charger with mp2625 chip. diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Makefile new file mode 100755 index 00000000..9bcfa83d --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for MP2625 charger core. +# + +obj-y += mp2625_charger.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/mp2625_charger.c b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/mp2625_charger.c new file mode 100755 index 00000000..581e89d8 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/charger/mp2625/mp2625_charger.c @@ -0,0 +1,428 @@ +/* + * mp2625_charger.c - WonderMedia Charger Driver. + * + * Copyright (C) 2013 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "mp2625-charger" + +#undef pr_err +#undef pr_info +#define pr_err(fmt, args...) printk("[" DRVNAME "] " fmt, ##args) +#define pr_info(fmt, args...) printk("[" DRVNAME "] " fmt, ##args) + +struct mp2625_charger { + struct device *dev; + int ac_online; + int usb_online; + int charger_status; + int sleeping; + + union { + struct { + unsigned int cable_type:4; + unsigned int current_sw_mode:1; + unsigned int pc_charging:1; + }; + uint32_t flag; + }; + + int full_pin; + int full_level; + int current_pin; + int current_large_level; + + struct power_supply psy_ac; + struct power_supply psy_usb; + struct delayed_work dwork; +}; + +static struct mp2625_charger *g_charger; + +static int parse_charger_param(struct mp2625_charger *ch) +{ + static char uboot_env[] = "wmt.charger.param"; + char buf[64]; + size_t l = sizeof(buf); + int ret; + + if (wmt_getsyspara(uboot_env, buf, &l)) + return -ENODEV; + if (prefixcmp(buf, "mp2625:")) + return -ENODEV; + if (!ch) + return 0; + + ret = sscanf(buf + 7, "%x:%d:%d:%d:%d", + &ch->flag, + &ch->full_pin, &ch->full_level, + &ch->current_pin, &ch->current_large_level); + if (ret < 5) { + pr_err("Invalid uboot env: %s\n", uboot_env); + return -EINVAL; + } + + if (ch->cable_type != CABLE_TYPE_DC && + ch->cable_type != CABLE_TYPE_USB) { + pr_err("Invalid type %d\n", ch->cable_type); + return -EINVAL; + } + + if (gpio_is_valid(ch->full_pin)) { + ret = devm_gpio_request(ch->dev, ch->full_pin, "charger full"); + if (ret) { + pr_err("gpio%d request fail %d\n", ch->full_pin, ret); + return ret; + } + wmt_gpio_setpull(ch->full_pin, (ch->full_level) ? + WMT_GPIO_PULL_DOWN : WMT_GPIO_PULL_UP); + gpio_direction_input(ch->full_pin); + } + + if (gpio_is_valid(ch->current_pin)) { + ret = devm_gpio_request(ch->dev, ch->current_pin, "charger current"); + if (ret) { + pr_err("gpio%d request fail %d\n", ch->current_pin, ret); + return ret; + } + gpio_direction_output(ch->current_pin, !ch->current_large_level); + } + + pr_info("charger match " DRVNAME ", %s cable, full %d, current %d\n" + "%s current switch, PC connected is %scharging\n", + (ch->cable_type == CABLE_TYPE_DC) ? "DC" : "USB", + ch->full_pin, ch->current_pin, + (ch->current_sw_mode == CURRENT_SWITCH_DYNAMIC) ? "dynamic" : "sleep", + (ch->pc_charging == PC_CONNECTED_NOT_CHARGING) ? "not " : ""); + return 0; +} + +static inline void set_current(struct mp2625_charger *ch) +{ + int large; + int charging = (ch->charger_status == POWER_SUPPLY_STATUS_CHARGING || + ch->charger_status == POWER_SUPPLY_STATUS_FULL); + + if (ch->current_sw_mode == CURRENT_SWITCH_DYNAMIC) + large = charging; + else + large = ch->sleeping ? 1 : 0; + + if (ch->cable_type == CABLE_TYPE_USB && wmt_is_pc_connected()) + large = 0; + + if (gpio_is_valid(ch->current_pin)) { + gpio_direction_output(ch->current_pin, + large ? ch->current_large_level : + !ch->current_large_level); + printk(KERN_DEBUG "set %s current\n", large ? "large" : "small"); + } +} + +static int ac_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct mp2625_charger *ch = + container_of(psy, struct mp2625_charger, psy_ac); + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = ch->ac_online; + break; + case POWER_SUPPLY_PROP_STATUS: + val->intval = ch->charger_status; + break; + default: + return -EINVAL; + } + return 0; +} + +static enum power_supply_property ac_properties[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_STATUS, +}; + +static int usb_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct mp2625_charger *ch = + container_of(psy, struct mp2625_charger, psy_usb); + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = ch->usb_online; + break; + default: + return -EINVAL; + } + return 0; +} + +static enum power_supply_property usb_properties[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static char *power_supplied_to[] = { + "battery", +}; + +static int power_supply_init(struct mp2625_charger *ch) +{ + int ret; + + ch->psy_ac.name = "ac", + ch->psy_ac.type = POWER_SUPPLY_TYPE_MAINS, + ch->psy_ac.supplied_to = power_supplied_to, + ch->psy_ac.num_supplicants = ARRAY_SIZE(power_supplied_to), + ch->psy_ac.properties = ac_properties, + ch->psy_ac.num_properties = ARRAY_SIZE(ac_properties), + ch->psy_ac.get_property = ac_get_property, + ret = power_supply_register(ch->dev, &ch->psy_ac); + if (ret) { + dev_err(ch->dev, "register ac power supply failed.\n"); + return ret; + } + + if (ch->pc_charging == PC_CONNECTED_CHARGING) { + ch->psy_usb.name = "usb", + ch->psy_usb.type = POWER_SUPPLY_TYPE_USB, + ch->psy_usb.supplied_to = power_supplied_to, + ch->psy_usb.num_supplicants = ARRAY_SIZE(power_supplied_to), + ch->psy_usb.properties = usb_properties, + ch->psy_usb.num_properties = ARRAY_SIZE(usb_properties), + ch->psy_usb.get_property = usb_get_property, + ret = power_supply_register(ch->dev, &ch->psy_usb); + if (ret) { + dev_err(ch->dev, "register ac power supply failed.\n"); + return ret; + } + } + + return 0; +} + +static void power_supply_release(struct mp2625_charger *ch) +{ + power_supply_unregister(&ch->psy_ac); + if (ch->pc_charging == PC_CONNECTED_CHARGING) + power_supply_unregister(&ch->psy_usb); +} + +static void mp2625_charger_work(struct work_struct *work) +{ + struct mp2625_charger *ch = + container_of(work, struct mp2625_charger, dwork.work); + int ac_online = 0; + int usb_online = 0; + int charger_status = 0; + + if (wmt_is_dc_plugin()) { + if (ch->cable_type == CABLE_TYPE_USB && wmt_is_pc_connected()) { + if (ch->pc_charging == PC_CONNECTED_CHARGING) { + charger_status = POWER_SUPPLY_STATUS_CHARGING; + usb_online = 1; + } else + charger_status = POWER_SUPPLY_STATUS_NOT_CHARGING; + } else { + charger_status = POWER_SUPPLY_STATUS_CHARGING; + ac_online = 1; + } + + if (charger_status == POWER_SUPPLY_STATUS_CHARGING && + gpio_get_value(ch->full_pin) == ch->full_level) + charger_status = POWER_SUPPLY_STATUS_FULL; + } else + charger_status = POWER_SUPPLY_STATUS_DISCHARGING; + + if (ch->ac_online != ac_online || + ch->charger_status != charger_status) { + ch->ac_online = ac_online; + ch->charger_status = charger_status; + power_supply_changed(&ch->psy_ac); + } + + if (ch->pc_charging == PC_CONNECTED_CHARGING && + ch->usb_online != usb_online) { + ch->usb_online = usb_online; + power_supply_changed(&ch->psy_usb); + } + + set_current(ch); + led_power_enable(charger_status == POWER_SUPPLY_STATUS_CHARGING || + charger_status == POWER_SUPPLY_STATUS_FULL); +} + +void mp2625_pc_connected(void) +{ + if (g_charger) + schedule_delayed_work(&g_charger->dwork, 0); +} + +static irqreturn_t dcdet_irq(int irq, void *data) +{ + struct mp2625_charger *ch = data; + + if (PMCIS_VAL & BIT27) { + pmc_clear_intr_status(WKS_DCDET); + schedule_delayed_work(&ch->dwork, HZ/2); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static int irqs_init(struct mp2625_charger *ch) +{ + unsigned long iflag = IRQF_SHARED; + int ret; + + if (REG32_VAL(0xfe120000) == 0x35100101) + iflag |= IRQF_NO_SUSPEND; + + ret = devm_request_irq(ch->dev, IRQ_PMC_WAKEUP, dcdet_irq, + iflag, "WMT-DCDET", ch); + if (ret < 0) { + pr_err("register DCDET irq failed\n"); + return ret; + } + + wmt_dcdet_irq_enable(); + return 0; +} + +static void irqs_release(struct mp2625_charger *ch) +{ + wmt_dcdet_irq_disable(); +} + +static int mp2625_probe(struct platform_device *pdev) +{ + struct mp2625_charger *ch; + int ret; + + ch = devm_kzalloc(&pdev->dev, sizeof(*ch), GFP_KERNEL); + if (!ch) + return -ENOMEM; + + ch->dev = &pdev->dev; + platform_set_drvdata(pdev, ch); + + ret = parse_charger_param(ch); + if (ret) + return ret;; + parse_charger_led(); + + if ((ret = power_supply_init(ch))) + return ret; + + INIT_DELAYED_WORK(&ch->dwork, mp2625_charger_work); + + if ((ret = irqs_init(ch))) { + power_supply_release(ch); + return ret; + } + + g_charger = ch; + schedule_delayed_work(&ch->dwork, 0); + + pr_info(DRVNAME " install success.\n"); + return 0; +} + +static int __devexit mp2625_remove(struct platform_device *pdev) +{ + struct mp2625_charger *ch = platform_get_drvdata(pdev); + irqs_release(ch); + cancel_delayed_work_sync(&ch->dwork); + power_supply_release(ch); + g_charger = NULL; + return 0; +} + +static int mp2625_suspend(struct device *dev) +{ + struct mp2625_charger *ch = dev_get_drvdata(dev); + cancel_delayed_work_sync(&ch->dwork); + ch->sleeping = 1; + set_current(ch); + return 0; +} + +static int mp2625_resume(struct device *dev) +{ + struct mp2625_charger *ch = dev_get_drvdata(dev); + schedule_delayed_work(&ch->dwork, HZ/2); + ch->sleeping = 0; + set_current(ch); + return 0; +} + +static const struct dev_pm_ops mp2625_pm_ops = { + .suspend = mp2625_suspend, + .resume = mp2625_resume, +}; + +static struct platform_driver mp2625_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRVNAME, + .pm = &mp2625_pm_ops, + }, + .probe = mp2625_probe, + .remove = mp2625_remove, +}; + +static struct platform_device *pdev; + +static int __init mp2625_init(void) +{ + int ret; + + ret = parse_charger_param(NULL); + if (ret) + return ret; + + ret = platform_driver_register(&mp2625_driver); + if (ret) + return ret; + + pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(pdev)) { + ret = PTR_ERR(pdev); + platform_driver_unregister(&mp2625_driver); + } + return ret; +} + +static void __exit mp2625_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&mp2625_driver); +} + +module_init(mp2625_init); +module_exit(mp2625_exit); + +MODULE_AUTHOR("WonderMedia"); +MODULE_DESCRIPTION("MP2625 Charger Driver"); +MODULE_LICENSE("GPL"); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/Makefile new file mode 100755 index 00000000..446fbf59 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/Makefile @@ -0,0 +1,6 @@ + +s_wmt_batt_bq27xx-objs += \ + bq27x00_battery.o + +obj-m += s_wmt_batt_bq27xx.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/bq27x00_battery.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/bq27x00_battery.c new file mode 100755 index 00000000..7a123615 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/bq27xx/bq27x00_battery.c @@ -0,0 +1,1011 @@ +/* + * BQ27x00 battery driver + * + * Copyright (C) 2008 Rodolfo Giometti + * Copyright (C) 2008 Eurotech S.p.A. + * Copyright (C) 2010-2011 Lars-Peter Clausen + * Copyright (C) 2011 Pali Rohár + * + * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. + * + * This package 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. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +/* + * Datasheets: + * http://focus.ti.com/docs/prod/folders/print/bq27000.html + * http://focus.ti.com/docs/prod/folders/print/bq27500.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_VERSION "1.2.0" + +#define BQ27x00_REG_TEMP 0x06 +#define BQ27x00_REG_VOLT 0x08 +#define BQ27x00_REG_AI 0x14 +#define BQ27x00_REG_FLAGS 0x0A +#define BQ27x00_REG_TTE 0x16 +#define BQ27x00_REG_TTF 0x18 +#define BQ27x00_REG_TTECP 0x26 +#define BQ27x00_REG_NAC 0x0C /* Nominal available capacity */ +#define BQ27x00_REG_LMD 0x12 /* Last measured discharge */ +#define BQ27x00_REG_CYCT 0x2A /* Cycle count total */ +#define BQ27x00_REG_AE 0x22 /* Available energy */ + +#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ +#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */ +#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */ +#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */ +#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */ +#define BQ27000_FLAG_FC BIT(5) +#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */ + +#define BQ27500_REG_SOC 0x2C +#define BQ27500_REG_DCAP 0x3C /* Design capacity */ +#define BQ27500_FLAG_DSC BIT(0) +#define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */ +#define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */ +#define BQ27500_FLAG_FC BIT(9) + +#define BQ27000_RS 20 /* Resistor sense */ + +#define CONFIG_BATTERY_BQ27X00_I2C + +struct bq27x00_device_info; +struct bq27x00_access_methods { + int (*read)(struct bq27x00_device_info *di, u8 reg, bool single); +}; + +enum bq27x00_chip { BQ27000, BQ27500 }; + +struct bq27x00_reg_cache { + int temperature; + int time_to_empty; + int time_to_empty_avg; + int time_to_full; + int charge_full; + int cycle_count; + int capacity; + int energy; + int flags; +}; + +struct bq27x00_device_info { + struct device *dev; + int id; + enum bq27x00_chip chip; + + struct bq27x00_reg_cache cache; + int charge_design_full; + + unsigned long last_update; + struct delayed_work work; + + struct power_supply bat; + + struct bq27x00_access_methods bus; + + struct mutex lock; +}; + +static enum power_supply_property bq27x00_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_ENERGY_NOW, +}; + +static int i2c_bus = 0; +static unsigned int poll_interval = 5; +module_param(poll_interval, uint, 0644); +MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ + "0 disables polling"); + +/* + * Common code for BQ27x00 devices + */ + +static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg, + bool single) +{ + return di->bus.read(di, reg, single); +} + +/* + * Return the battery Relative State-of-Charge + * Or < 0 if something fails. + */ +static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di) +{ + int rsoc; + + if (di->chip == BQ27500) + rsoc = bq27x00_read(di, BQ27500_REG_SOC, false); + else + rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true); + + if (rsoc < 0) + dev_dbg(di->dev, "error reading relative State-of-Charge\n"); + + return rsoc; +} + +/* + * Return a battery charge value in µAh + * Or < 0 if something fails. + */ +static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg) +{ + int charge; + + charge = bq27x00_read(di, reg, false); + if (charge < 0) { + dev_dbg(di->dev, "error reading charge register %02x: %d\n", + reg, charge); + return charge; + } + + if (di->chip == BQ27500) + charge *= 1000; + else + charge = charge * 3570 / BQ27000_RS; + + return charge; +} + +/* + * Return the battery Nominal available capaciy in µAh + * Or < 0 if something fails. + */ +static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di) +{ + return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC); +} + +/* + * Return the battery Last measured discharge in µAh + * Or < 0 if something fails. + */ +static inline int bq27x00_battery_read_lmd(struct bq27x00_device_info *di) +{ + return bq27x00_battery_read_charge(di, BQ27x00_REG_LMD); +} + +/* + * Return the battery Initial last measured discharge in µAh + * Or < 0 if something fails. + */ +static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di) +{ + int ilmd; + + if (di->chip == BQ27500) + ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); + else + ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true); + + if (ilmd < 0) { + dev_dbg(di->dev, "error reading initial last measured discharge\n"); + return ilmd; + } + + if (di->chip == BQ27500) + ilmd *= 1000; + else + ilmd = ilmd * 256 * 3570 / BQ27000_RS; + + return ilmd; +} + +/* + * Return the battery Available energy in µWh + * Or < 0 if something fails. + */ +static int bq27x00_battery_read_energy(struct bq27x00_device_info *di) +{ + int ae; + + ae = bq27x00_read(di, BQ27x00_REG_AE, false); + if (ae < 0) { + dev_dbg(di->dev, "error reading available energy\n"); + return ae; + } + + if (di->chip == BQ27500) + ae *= 1000; + else + ae = ae * 29200 / BQ27000_RS; + + return ae; +} + +/* + * Return the battery temperature in tenths of degree Celsius + * Or < 0 if something fails. + */ +static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di) +{ + int temp; + + temp = bq27x00_read(di, BQ27x00_REG_TEMP, false); + if (temp < 0) { + dev_err(di->dev, "error reading temperature\n"); + return temp; + } + + if (di->chip == BQ27500) + temp -= 2731; + else + temp = ((temp * 5) - 5463) / 2; + + return temp; +} + +/* + * Return the battery Cycle count total + * Or < 0 if something fails. + */ +static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di) +{ + int cyct; + + cyct = bq27x00_read(di, BQ27x00_REG_CYCT, false); + if (cyct < 0) + dev_err(di->dev, "error reading cycle count total\n"); + + return cyct; +} + +/* + * Read a time register. + * Return < 0 if something fails. + */ +static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg) +{ + int tval; + + tval = bq27x00_read(di, reg, false); + if (tval < 0) { + dev_dbg(di->dev, "error reading time register %02x: %d\n", + reg, tval); + return tval; + } + + if (tval == 65535) + return -ENODATA; + + return tval * 60; +} + +static void bq27x00_update(struct bq27x00_device_info *di) +{ + struct bq27x00_reg_cache cache = {0, }; + bool is_bq27500 = di->chip == BQ27500; + short voltage_now = 0,current_now = 0,capacity_now = 0; + + cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); + if (cache.flags >= 0) { + if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) { + dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n"); + cache.capacity = -ENODATA; + cache.energy = -ENODATA; + cache.time_to_empty = -ENODATA; + cache.time_to_empty_avg = -ENODATA; + cache.time_to_full = -ENODATA; + cache.charge_full = -ENODATA; + } else { + cache.capacity = bq27x00_battery_read_rsoc(di); + cache.energy = bq27x00_battery_read_energy(di); + cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE); + cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP); + cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF); + cache.charge_full = bq27x00_battery_read_lmd(di); + } + cache.temperature = bq27x00_battery_read_temperature(di); + cache.cycle_count = bq27x00_battery_read_cyct(di); + + /* We only have to read charge design full once */ + if (di->charge_design_full <= 0) + di->charge_design_full = bq27x00_battery_read_ilmd(di); + voltage_now = bq27x00_read(di, BQ27x00_REG_VOLT, false)*2; + current_now = bq27x00_read(di, BQ27x00_REG_AI, false); + capacity_now = bq27x00_read(di, BQ27x00_REG_NAC, false); + } + + if (memcmp(&di->cache, &cache, sizeof(cache)) != 0) { + di->cache = cache; + power_supply_changed(&di->bat); + } + + //printk("%s percentage=%d,voltage=%d,current=%d,temperature=%d,%d,flag=%d\n",__FUNCTION__,cache.capacity,voltage_now,current_now,cache.temperature,capacity_now,cache.flags); + + di->last_update = jiffies; +} + +static void bq27x00_battery_poll(struct work_struct *work) +{ + struct bq27x00_device_info *di = + container_of(work, struct bq27x00_device_info, work.work); + + bq27x00_update(di); + + if (poll_interval > 0) { + /* The timer does not have to be accurate. */ + set_timer_slack(&di->work.timer, poll_interval * HZ / 4); + schedule_delayed_work(&di->work, poll_interval * HZ); + } +} + +/* + * Return the battery average current in µA + * Note that current can be negative signed as well + * Or 0 if something fails. + */ +static int bq27x00_battery_current(struct bq27x00_device_info *di, + union power_supply_propval *val) +{ + int curr; + int flags; + + curr = bq27x00_read(di, BQ27x00_REG_AI, false); + if (curr < 0) { + dev_err(di->dev, "error reading current\n"); + return curr; + } + + if (di->chip == BQ27500) { + /* bq27500 returns signed value */ + val->intval = (int)((s16)curr) * 1000; + } else { + flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false); + if (flags & BQ27000_FLAG_CHGS) { + dev_dbg(di->dev, "negative current!\n"); + curr = -curr; + } + + val->intval = curr * 3570 / BQ27000_RS; + } + + return 0; +} + +static int bq27x00_battery_status(struct bq27x00_device_info *di, + union power_supply_propval *val) +{ + int status; + + status = charger_get_status(); + if (status < 0) + return status; + + if (status == POWER_SUPPLY_STATUS_CHARGING) { + if (di->chip == BQ27500) { + if (di->cache.flags & BQ27500_FLAG_FC) + status = POWER_SUPPLY_STATUS_FULL; + /*else if (di->cache.flags & BQ27500_FLAG_DSC) + status = POWER_SUPPLY_STATUS_DISCHARGING; + else + status = POWER_SUPPLY_STATUS_CHARGING;*/ + } else { + if (di->cache.flags & BQ27000_FLAG_FC) + status = POWER_SUPPLY_STATUS_FULL; + /*else if (di->cache.flags & BQ27000_FLAG_CHGS) + status = POWER_SUPPLY_STATUS_CHARGING; + else if (power_supply_am_i_supplied(&di->bat)) + status = POWER_SUPPLY_STATUS_NOT_CHARGING; + else + status = POWER_SUPPLY_STATUS_DISCHARGING;*/ + } + } + + val->intval = status; + + return 0; +} + +static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di, + union power_supply_propval *val) +{ + int level; + + if (di->chip == BQ27500) { + if (di->cache.flags & BQ27500_FLAG_FC) + level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; + else if (di->cache.flags & BQ27500_FLAG_SOC1) + level = POWER_SUPPLY_CAPACITY_LEVEL_LOW; + else if (di->cache.flags & BQ27500_FLAG_SOCF) + level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; + else + level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; + } else { + if (di->cache.flags & BQ27000_FLAG_FC) + level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; + else if (di->cache.flags & BQ27000_FLAG_EDV1) + level = POWER_SUPPLY_CAPACITY_LEVEL_LOW; + else if (di->cache.flags & BQ27000_FLAG_EDVF) + level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; + else + level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; + } + + val->intval = level; + + return 0; +} + +/* + * Return the battery Voltage in milivolts + * Or < 0 if something fails. + */ +static int bq27x00_battery_voltage(struct bq27x00_device_info *di, + union power_supply_propval *val) +{ + int volt; + + volt = bq27x00_read(di, BQ27x00_REG_VOLT, false); + if (volt < 0) { + dev_err(di->dev, "error reading voltage\n"); + return volt; + } + + val->intval = volt * 1000 * 2; + + return 0; +} + +static int bq27x00_simple_value(int value, + union power_supply_propval *val) +{ + if (value < 0) + return value; + + val->intval = value; + + return 0; +} + +#define to_bq27x00_device_info(x) container_of((x), \ + struct bq27x00_device_info, bat); + +static int bq27x00_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + struct bq27x00_device_info *di = to_bq27x00_device_info(psy); + + mutex_lock(&di->lock); + if (time_is_before_jiffies(di->last_update + 5 * HZ)) { + cancel_delayed_work_sync(&di->work); + bq27x00_battery_poll(&di->work.work); + } + mutex_unlock(&di->lock); + + if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0) + return -ENODEV; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = bq27x00_battery_status(di, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = bq27x00_battery_voltage(di, val); + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = di->cache.flags < 0 ? 0 : 1; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + ret = bq27x00_battery_current(di, val); + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret = bq27x00_simple_value(di->cache.capacity, val); + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + ret = bq27x00_battery_capacity_level(di, val); + break; + case POWER_SUPPLY_PROP_TEMP: + ret = bq27x00_simple_value(di->cache.temperature, val); + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: + ret = bq27x00_simple_value(di->cache.time_to_empty, val); + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: + ret = bq27x00_simple_value(di->cache.time_to_empty_avg, val); + break; + case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: + ret = bq27x00_simple_value(di->cache.time_to_full, val); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + ret = bq27x00_simple_value(bq27x00_battery_read_nac(di), val); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + ret = bq27x00_simple_value(di->cache.charge_full, val); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + ret = bq27x00_simple_value(di->charge_design_full, val); + break; + case POWER_SUPPLY_PROP_CYCLE_COUNT: + ret = bq27x00_simple_value(di->cache.cycle_count, val); + break; + case POWER_SUPPLY_PROP_ENERGY_NOW: + ret = bq27x00_simple_value(di->cache.energy, val); + break; + default: + return -EINVAL; + } + + return ret; +} + +static void bq27x00_external_power_changed(struct power_supply *psy) +{ + struct bq27x00_device_info *di = to_bq27x00_device_info(psy); + + cancel_delayed_work_sync(&di->work); + schedule_delayed_work(&di->work, 0); +} + +static int bq27x00_powersupply_init(struct bq27x00_device_info *di) +{ + int ret; + + di->bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->bat.properties = bq27x00_battery_props; + di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props); + di->bat.get_property = bq27x00_battery_get_property; + di->bat.external_power_changed = bq27x00_external_power_changed; + + INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll); + mutex_init(&di->lock); + + ret = power_supply_register(di->dev, &di->bat); + if (ret) { + dev_err(di->dev, "failed to register battery: %d\n", ret); + return ret; + } + + dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION); + + bq27x00_update(di); + + return 0; +} + +static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di) +{ + /* + * power_supply_unregister call bq27x00_battery_get_property which + * call bq27x00_battery_poll. + * Make sure that bq27x00_battery_poll will not call + * schedule_delayed_work again after unregister (which cause OOPS). + */ + poll_interval = 0; + + cancel_delayed_work_sync(&di->work); + + power_supply_unregister(&di->bat); + + mutex_destroy(&di->lock); +} + + +/* i2c specific code */ +#ifdef CONFIG_BATTERY_BQ27X00_I2C + +/* If the system has several batteries we need a different name for each + * of them... + */ +static DEFINE_IDR(battery_id); +static DEFINE_MUTEX(battery_mutex); + +static int bq27x00_read_i2c(struct bq27x00_device_info *di, u8 reg, bool single) +{ + struct i2c_client *client = to_i2c_client(di->dev); + struct i2c_msg msg[2]; + unsigned char data[2]; + int ret; + + if (!client->adapter) + return -ENODEV; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].buf = ® + msg[0].len = sizeof(reg); + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = data; + if (single) + msg[1].len = 1; + else + msg[1].len = 2; + + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret < 0) + return ret; + + if (!single) + ret = get_unaligned_le16(data); + else + ret = data[0]; + + return ret; +} + +static int bq27x00_battery_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + char *name; + struct bq27x00_device_info *di; + int num; + int retval = 0; + + /* Get new ID for the new battery device */ + retval = idr_pre_get(&battery_id, GFP_KERNEL); + if (retval == 0) + return -ENOMEM; + mutex_lock(&battery_mutex); + retval = idr_get_new(&battery_id, client, &num); + mutex_unlock(&battery_mutex); + if (retval < 0) + return retval; + + name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num); + if (!name) { + dev_err(&client->dev, "failed to allocate device name\n"); + retval = -ENOMEM; + goto batt_failed_1; + } + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) { + dev_err(&client->dev, "failed to allocate device info data\n"); + retval = -ENOMEM; + goto batt_failed_2; + } + + di->id = num; + di->dev = &client->dev; + di->chip = id->driver_data; + di->bat.name = name; + di->bus.read = &bq27x00_read_i2c; + + if (bq27x00_powersupply_init(di)) + goto batt_failed_3; + + i2c_set_clientdata(client, di); + + return 0; + +batt_failed_3: + kfree(di); +batt_failed_2: + kfree(name); +batt_failed_1: + mutex_lock(&battery_mutex); + idr_remove(&battery_id, num); + mutex_unlock(&battery_mutex); + + return retval; +} + +static int bq27x00_battery_remove(struct i2c_client *client) +{ + struct bq27x00_device_info *di = i2c_get_clientdata(client); + + bq27x00_powersupply_unregister(di); + + kfree(di->bat.name); + + mutex_lock(&battery_mutex); + idr_remove(&battery_id, di->id); + mutex_unlock(&battery_mutex); + + kfree(di); + + return 0; +} + +static int bq27x00_battery_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct bq27x00_device_info *di = i2c_get_clientdata(client); + cancel_delayed_work_sync(&di->work); + return 0; +} + +static int bq27x00_battery_resume(struct i2c_client *client) +{ + struct bq27x00_device_info *di = i2c_get_clientdata(client); + schedule_delayed_work(&di->work, 1 * HZ); + return 0; +} + +static const struct i2c_device_id bq27x00_id[] = { + { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */ + { "bq27500", BQ27500 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, bq27x00_id); + +static struct i2c_driver bq27x00_battery_driver = { + .driver = { + .name = "bq27x00-battery", + }, + .probe = bq27x00_battery_probe, + .remove = bq27x00_battery_remove, + .suspend = bq27x00_battery_suspend, + .resume = bq27x00_battery_resume, + .id_table = bq27x00_id, +}; + +static struct i2c_board_info bq27x00_board_info = { + I2C_BOARD_INFO("bq27500", 0x55), +}; + +static inline int bq27x00_battery_i2c_init(void) +{ + struct i2c_client *client; + struct i2c_adapter *adap; + + int ret = i2c_add_driver(&bq27x00_battery_driver); + if (ret) + printk(KERN_ERR "Unable to register BQ27x00 i2c driver\n"); + adap = i2c_get_adapter(i2c_bus); + if (!adap) + return -ENODEV; + client = i2c_new_device(adap, &bq27x00_board_info); + i2c_put_adapter(adap); + if (!client) { + printk("bq27x00 i2c_new_device failed\n"); + return -ENODEV; + } + + return ret; +} + +static inline void bq27x00_battery_i2c_exit(void) +{ + i2c_del_driver(&bq27x00_battery_driver); +} + +#else + +static inline int bq27x00_battery_i2c_init(void) { return 0; } +static inline void bq27x00_battery_i2c_exit(void) {}; + +#endif + +/* platform specific code */ +#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM + +static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg, + bool single) +{ + struct device *dev = di->dev; + struct bq27000_platform_data *pdata = dev->platform_data; + unsigned int timeout = 3; + int upper, lower; + int temp; + + if (!single) { + /* Make sure the value has not changed in between reading the + * lower and the upper part */ + upper = pdata->read(dev, reg + 1); + do { + temp = upper; + if (upper < 0) + return upper; + + lower = pdata->read(dev, reg); + if (lower < 0) + return lower; + + upper = pdata->read(dev, reg + 1); + } while (temp != upper && --timeout); + + if (timeout == 0) + return -EIO; + + return (upper << 8) | lower; + } + + return pdata->read(dev, reg); +} + +static int __devinit bq27000_battery_probe(struct platform_device *pdev) +{ + struct bq27x00_device_info *di; + struct bq27000_platform_data *pdata = pdev->dev.platform_data; + int ret; + + if (!pdata) { + dev_err(&pdev->dev, "no platform_data supplied\n"); + return -EINVAL; + } + + if (!pdata->read) { + dev_err(&pdev->dev, "no hdq read callback supplied\n"); + return -EINVAL; + } + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) { + dev_err(&pdev->dev, "failed to allocate device info data\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, di); + + di->dev = &pdev->dev; + di->chip = BQ27000; + + di->bat.name = pdata->name ?: dev_name(&pdev->dev); + di->bus.read = &bq27000_read_platform; + + ret = bq27x00_powersupply_init(di); + if (ret) + goto err_free; + + return 0; + +err_free: + platform_set_drvdata(pdev, NULL); + kfree(di); + + return ret; +} + +static int __devexit bq27000_battery_remove(struct platform_device *pdev) +{ + struct bq27x00_device_info *di = platform_get_drvdata(pdev); + + bq27x00_powersupply_unregister(di); + + platform_set_drvdata(pdev, NULL); + kfree(di); + + return 0; +} + +static int bq27000_battery_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct bq27x00_device_info *di = platform_get_drvdata(pdev); + cancel_delayed_work_sync(&di->work); + return 0; +} + +static int bq27000_battery_resume(struct platform_device *pdev) +{ + struct bq27x00_device_info *di = platform_get_drvdata(pdev); + schedule_delayed_work(&di->work, 1 * HZ); + return 0; +} + +static struct platform_driver bq27000_battery_driver = { + .probe = bq27000_battery_probe, + .remove = __devexit_p(bq27000_battery_remove), + .suspend = bq27000_battery_suspend; + .resume = bq27000_battery_resume; + .driver = { + .name = "bq27000-battery", + .owner = THIS_MODULE, + }, +}; + +static inline int bq27x00_battery_platform_init(void) +{ + int ret = platform_driver_register(&bq27000_battery_driver); + if (ret) + printk(KERN_ERR "Unable to register BQ27000 platform driver\n"); + + return ret; +} + +static inline void bq27x00_battery_platform_exit(void) +{ + platform_driver_unregister(&bq27000_battery_driver); +} + +#else + +static inline int bq27x00_battery_platform_init(void) { return 0; } +static inline void bq27x00_battery_platform_exit(void) {}; + +#endif + +/* + * Module stuff + */ + +static int parse_battery_param(void) +{ + char env[] = "wmt.battery.param"; + char buf[64]; + char *p; + size_t l = sizeof(buf); + int i; + + if (wmt_getsyspara(env, buf, &l)) + return -EINVAL; + + if (prefixcmp(buf, "bq27xx:")) + return -ENODEV; + + p = strchr(buf, ':'); + + i = sscanf(p + 1, "%d", &i2c_bus); + if (i < 1) { + printk("Parse_param err: Can't get i2c bus num\n"); + return -EINVAL; + } + + return 0; +} + + +static int __init bq27x00_battery_init(void) +{ + int ret; + + if (parse_battery_param()) + return -ENODEV; + + ret = bq27x00_battery_i2c_init(); + if (ret) + return ret; + + ret = bq27x00_battery_platform_init(); + if (ret) + bq27x00_battery_i2c_exit(); + + return ret; +} +module_init(bq27x00_battery_init); + +static void __exit bq27x00_battery_exit(void) +{ + bq27x00_battery_platform_exit(); + bq27x00_battery_i2c_exit(); +} +module_exit(bq27x00_battery_exit); + +MODULE_AUTHOR("Rodolfo Giometti "); +MODULE_DESCRIPTION("BQ27x00 battery monitor driver"); +MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/Makefile new file mode 100644 index 00000000..8b63f3f3 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/Makefile @@ -0,0 +1,4 @@ + +s_wmt_batt_saradc-objs += saradc_battery.o +obj-m += s_wmt_batt_saradc.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/saradc_battery.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/saradc_battery.c new file mode 100644 index 00000000..9bdf50c8 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/saradc/saradc_battery.c @@ -0,0 +1,341 @@ +/* + * adc_battery.c - WonderMedia Adc Battery Driver. + * + * Copyright (C) 2013 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#define DRVNAME "adc-batt" + +#undef pr_err +#define pr_err(fmt, args...) printk("[" DRVNAME "] " fmt, ##args) +#undef pr_info +#define pr_info(fmt, args...) printk("[" DRVNAME "] " fmt, ##args) + +enum { + COMPENSATION_VOLUME = 0, + COMPENSATION_BRIGHTNESS, + COMPENSATION_WIFI, + COMPENSATION_VIDEO, + COMPENSATION_USB, + COMPENSATION_HDMI, + COMPENSATION_COUNT +}; + +static const char *compensation_strings[] = { + "volume", + "brightness", + "wifi", + "video", + "usb", + "hdmi" +}; + +struct adc_device_info { + struct device *dev; + struct power_supply ps_bat; + struct mutex mutex; + + int compensation[COMPENSATION_COUNT]; + int capacity; + int sleeping; + int debug; +}; + +static struct adc_device_info *adc_dev_info = NULL; + +static inline int adc_manual_read_volt(void) +{ + extern unsigned int ReadBattery(void); + return ReadBattery(); +} + +static inline int volt_reg_to_mV(int value) +{ + // voltage = adc * (3300/128) * (1430/1000) = adc * 4719 / 128 + + return ((value * 4719) / 128); +} + +static int adc_bat_read_voltage(struct adc_device_info *di, int *intval) +{ + int ret; + + ret = adc_manual_read_volt(); + if (ret < 0) + return ret; + + *intval = volt_reg_to_mV(ret); + return 0; +} + +static int adc_bat_read_status(struct adc_device_info *di, int *intval) +{ + int status; + + status = charger_get_status(); + if (status < 0) + return status; + + if (status == POWER_SUPPLY_STATUS_CHARGING && di->capacity == 100) + status = POWER_SUPPLY_STATUS_FULL; + + *intval = status; + return 0; +} + +static int adc_proc_read(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + int l = 0, i; + int ret, status, dcin, voltage, full; + struct adc_device_info *di = adc_dev_info; + + mutex_lock(&di->mutex); + + ret = adc_bat_read_status(di, &status); + if (ret) { + pr_err("adc_bat_read_status failed\n"); + return 0; + } + ret = adc_bat_read_voltage(di, &voltage); + if (ret) { + pr_err("adc_bat_read_voltage failed\n"); + return 0; + } + dcin = power_supply_is_system_supplied(); + full = charger_is_full(); + + l += sprintf(buf + l, "status : %d\n", status); + l += sprintf(buf + l, "dcin : %d\n", dcin); + l += sprintf(buf + l, "voltage : %d\n", voltage); + l += sprintf(buf + l, "full : %d\n", full); + l += sprintf(buf + l, "sleeping : %d\n", di->sleeping); + l += sprintf(buf + l, "debug : %d\n", di->debug); + + for (i = 0; i < COMPENSATION_COUNT; i++) { + l += sprintf(buf +l, "compensation %10s : %d\n", + compensation_strings[i], di->compensation[i]); + } + + /* clear after read */ + di->sleeping = 0; + + mutex_unlock(&di->mutex); + return l; +} + +static int adc_proc_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int bm, usage; + struct adc_device_info *di = adc_dev_info; + + if (sscanf(buffer, "capacity=%d", &di->capacity)) { + power_supply_changed(&di->ps_bat); + goto out; + } + + if (sscanf(buffer, "debug=%d", &di->debug)) + goto out; + + if (sscanf(buffer, "MODULE_CHANGE:%d-%d", &bm, &usage) < 2) { + return 0; + } + + if (bm < 0 || bm >= COMPENSATION_COUNT) { + printk("bm %d error, [0, %d)\n", bm, COMPENSATION_COUNT); + return 0; + } + + if (usage > 100 || usage < 0) { + printk("usage %d error\n", usage); + return 0; + } + + mutex_lock(&di->mutex); + di->compensation[bm] = usage; + mutex_unlock(&di->mutex); +out: + return count; +} + +#define BATTERY_PROC_NAME "battery_calibration" + +static void adc_proc_init(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry(BATTERY_PROC_NAME, 0666, NULL); + if (entry) { + entry->read_proc = adc_proc_read; + entry->write_proc = adc_proc_write; + } +} + +static void adc_proc_cleanup(void) +{ + remove_proc_entry(BATTERY_PROC_NAME, NULL); +} + +#define to_adc_device_info(x) container_of((x), \ + struct adc_device_info, ps_bat); + +static int adc_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + struct adc_device_info *di = to_adc_device_info(psy); + + mutex_lock(&di->mutex); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = adc_bat_read_status(di, &val->intval); + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = di->capacity; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = adc_bat_read_voltage(di, &val->intval); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&di->mutex); + return ret; +} + +static void adc_external_power_changed(struct power_supply *psy) +{ + power_supply_changed(psy); +} + +static enum power_supply_property adc_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, +}; + +static int __devinit adc_batt_probe(struct platform_device *pdev) +{ + struct adc_device_info *di; + int ret; + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) { + dev_err(&pdev->dev, "no memery\n"); + return -ENOMEM; + } + + di->dev = &pdev->dev; + di->capacity = 50; + + mutex_init(&di->mutex); + + di->ps_bat.name = "battery"; + di->ps_bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->ps_bat.properties = adc_battery_props; + di->ps_bat.num_properties = ARRAY_SIZE(adc_battery_props); + di->ps_bat.get_property = adc_battery_get_property; + di->ps_bat.external_power_changed = adc_external_power_changed; + + ret = power_supply_register(di->dev, &di->ps_bat); + if (ret) { + dev_err(di->dev, "failed to register battery: %d\n", ret); + kfree(di); + return ret; + } + + platform_set_drvdata(pdev, di); + adc_dev_info = di; + + adc_proc_init(); + + pr_info("ADC Battery Driver Installed!\n"); + return 0; +} + +static int __devexit adc_batt_remove(struct platform_device *pdev) +{ + struct adc_device_info *di = platform_get_drvdata(pdev); + adc_proc_cleanup(); + power_supply_unregister(&di->ps_bat); + kfree(di); + adc_dev_info = NULL; + pr_info("ADC Battery Driver Removed!\n"); + return 0; +} + +static int adc_suspend(struct platform_device *pdev, pm_message_t state) +{ + return 0; +} + +static int adc_resume(struct platform_device *pdev) +{ + struct adc_device_info *di = platform_get_drvdata(pdev); + di->sleeping = 1; + return 0; +} + +static struct platform_driver adc_batt_driver = { + .driver = { + .name = DRVNAME, + }, + .probe = adc_batt_probe, + .remove = __devexit_p(adc_batt_remove), + .suspend = adc_suspend, + .resume = adc_resume, +}; + +static struct platform_device *pdev; + +static int __init adc_batt_init(void) +{ + pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(pdev)) { + return PTR_ERR(pdev); + } + return platform_driver_register(&adc_batt_driver); +} + +static void __exit adc_batt_exit(void) +{ + platform_driver_unregister(&adc_batt_driver); + platform_device_unregister(pdev); +} + +module_init(adc_batt_init); +module_exit(adc_batt_exit); + +MODULE_AUTHOR("WonderMedia"); +MODULE_DESCRIPTION("WonderMedia Adc Battery Driver"); +MODULE_LICENSE("GPL"); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/Makefile new file mode 100755 index 00000000..43637d92 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/Makefile @@ -0,0 +1,5 @@ + +s_wmt_batt_sp2541-objs += sp2541_battery.o + +obj-m += s_wmt_batt_sp2541.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/sp2541_battery.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/sp2541_battery.c new file mode 100755 index 00000000..2c619925 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/sp2541/sp2541_battery.c @@ -0,0 +1,765 @@ +/* + * SP2541 battery driver + * + * This package 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. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RAM_READ_CMD 0x55 +#define EEPROM_READ_CMD 0xF5 +#define EEPROM_WRITE_CMD 0xFA + +#define DRIVER_VERSION "1.1.0" +#define SP2541_REG_TEMP 0x06 +#define SP2541_REG_VOLT 0x08 +#define SP2541_REG_AI 0x14 +#define SP2541_REG_FLAGS 0x0A +#define SP2541_REG_TTE 0x16 +#define SP2541_REG_TTF 0x18 +#define SP2541_REG_TTECP 0x26 +#define SP2541_REG_RSOC 0x0B /* Relative State-of-Charge */ +#define SP2541_REG_SOC 0x2c + +#define SP2541_FLAG_DSC BIT(0) +#define SP2541_FLAG_CHGS BIT(8) +#define SP2541_FLAG_FC BIT(9) +#define SP2541_FLAG_OTD BIT(14) +#define SP2541_FLAG_OTC BIT(15) + +#define SP2541_SPEED 100 * 1000 + +struct battery_param { + char rom_name[32]; + int i2c_bus; + int interval; +}; + +static struct battery_param battery_param; + +/* 0x07a0 ~ 0x07af + * 0x07b0 ~ 0x07bf + */ +union rom_version { + struct { + uint32_t magic; + uint32_t version; + } v; + uint8_t bytes[8]; +}; + +#define __ROM_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define SP2514_MAGIC __ROM_VERSION('W', 'M', 'T') + +#define ROM_VERSION(ver) \ + { \ + .v.magic = SP2514_MAGIC, \ + .v.version = ver, \ + } + +struct rom_entry { + uint16_t address; + uint16_t value; +}; +#define ROM_ENTRY(a, l, v) { .address = a, .length = l, .value = v } + +struct rom_struct { + union rom_version rv; + struct rom_entry *table; + size_t table_size; +}; + +#define ROM_STRUCT(ver) \ + { \ + .rv = ROM_VERSION(ver), \ + } + +static struct rom_entry *rom_entry; +static struct rom_struct rom_table = ROM_STRUCT(0); + +struct sp2541_struct { + struct device *dev; + struct i2c_client *client; + int capacity; + struct rom_struct *rom; + + struct power_supply psy_bat; + struct delayed_work dwork; + unsigned int interval; +}; + +static int parse_battery_param(void) +{ + char env[] = "wmt.battery.param"; + char buf[64]; + char *p; + size_t l = sizeof(buf); + int i; + + if (wmt_getsyspara(env, buf, &l)) + return -EINVAL; + + if (prefixcmp(buf, "sp2541_")) + return -ENODEV; + + p = strchr(buf, ':'); + strncpy(battery_param.rom_name, buf + 7, p - buf - 7); + pr_info("rom name -- %s\n", battery_param.rom_name); + + i = sscanf(p + 1, "%d:%d", + &battery_param.i2c_bus, &battery_param.interval); + if (i < 2) + return -EINVAL; + + return 0; +} + +//#define SP2541_BIG_ENDIAN +#ifdef SP2541_BIG_ENDIAN +static u16 get_bigend_le16(const void *_ptr) +{ + const uint8_t *ptr = _ptr; + return (ptr[0]<<8) | (ptr[1]); +} + +static inline uint16_t __get_le16(const void *buf) +{ + return get_bigend_le16(buf); +} +#else +static inline uint16_t __get_le16(const void *buf) +{ + return get_unaligned_le16(buf); +} +#endif + +static int sp2541_read(struct sp2541_struct *sp, uint8_t cmd, uint8_t reg, + uint8_t buf[], unsigned len) +{ + struct i2c_client *client = sp->client; + struct i2c_msg xfer[2]; + char data[2] = { cmd, reg }; + int ret; + + xfer[0].addr = client->addr; + xfer[0].flags = 0 | I2C_M_NOSTART; + xfer[0].len = 2; + xfer[0].buf = data; + xfer[1].addr = client->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = len; + xfer[1].buf = buf; + + ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer)); + if (ret != ARRAY_SIZE(xfer)) { + pr_err("read[r:%d] errcode[%d]\n", reg, ret); + if (ret < 0) + return ret; + else + return -EIO; + } + + return 0; +} + +static int sp2541_write(struct sp2541_struct *sp, uint8_t cmd, uint8_t reg, + const uint8_t buf) +{ + struct i2c_client *client = sp->client; + struct i2c_msg xfer; + char data[3] = { cmd, reg, buf }; + int ret; + + xfer.addr = client->addr; + xfer.flags = 0; + xfer.len = 3; + xfer.buf = data; + + ret = i2c_transfer(client->adapter, &xfer, 1); + if (ret != 1) { + pr_err("read[r:%d] errcode[%d]\n", reg, ret); + if (ret < 0) + return ret; + else + return -EIO; + } + + return 0; +} + +static int eeprom_read_byte(struct sp2541_struct *sp, uint16_t addr, uint8_t *value) +{ + uint8_t tmp; + int i; + + if (sp2541_write(sp, EEPROM_WRITE_CMD, 0x00, (addr >> 0) & 0xff) || + sp2541_write(sp, EEPROM_WRITE_CMD, 0x01, (addr >> 8) & 0xff) || + sp2541_write(sp, EEPROM_WRITE_CMD, 0x03, 0x06)) + return -EIO; + + for (i = 0; i < 10; i++) { + if (sp2541_read(sp, EEPROM_READ_CMD, 0x03, &tmp, 1)) + return -EIO; + if (tmp == 0) + break; + } + if (i == 10) + return -EBUSY; + + if (sp2541_read(sp, EEPROM_READ_CMD, 0x02, value, 1)) + return -EIO; + + return 0; +} + +static int eeprom_write_byte(struct sp2541_struct *sp, uint16_t addr, uint8_t value) +{ + uint8_t tmp; + int i; + + if (sp2541_write(sp, EEPROM_WRITE_CMD, 0x00, (addr >> 0) & 0xff) || + sp2541_write(sp, EEPROM_WRITE_CMD, 0x01, (addr >> 8) & 0xff) || + sp2541_write(sp, EEPROM_WRITE_CMD, 0x02, value) || + sp2541_write(sp, EEPROM_WRITE_CMD, 0x03, 0x05)) + return -EIO; + + for (i = 0; i < 10; i++) { + if (sp2541_read(sp, EEPROM_READ_CMD, 0x03, &tmp, 1)) + return -EIO; + if (tmp == 0) + break; + } + if (i == 10) + return -EBUSY; + + return 0; +} + +static int eeprom_read(struct sp2541_struct *sp, uint16_t start, + uint8_t *buf, size_t len) +{ + int ret, i; + for (i = 0; i < len; i++) { + ret = eeprom_read_byte(sp, start + i, buf + len - i - 1); + if (ret) + return ret; + } + return 0; +} + +static int eeprom_write(struct sp2541_struct *sp, uint16_t start, + uint8_t *buf, size_t len) +{ + int ret, i, j; + for (i = 0; i < len; i++) { + //pr_info("wirte addr=0x%x,val=0x%x\n", start + i, buf[len - i - 1]); + for (j = 0; j < 3; j++) { + ret = eeprom_write_byte(sp, start + i, buf[len - i - 1]); + if (ret) + pr_err("eeprom write byte err #%d\n", j); + else + break; + } + if (j == 3) + return ret; + } + return 0; +} + +static int eeprom_update(struct sp2541_struct *sp, + struct rom_entry *table, size_t count) +{ + int ret, i; + for (i = 0; i < count; i++) { + ret = eeprom_write(sp, table[i].address, + (uint8_t *)&table[i].value, + 1);//table[i].length); + if (ret) + return ret; + } + return 0; +} + +static int sp2541_load_romtable(struct sp2541_struct *sp) +{ + char table_name[32]; + const struct firmware *fw_entry; + int count, i; + unsigned int val1, val2, version; + + sprintf(table_name, "%s.EEP", battery_param.rom_name); + for (i = 0; i < 3; i++) { + if(request_firmware(&fw_entry, table_name, sp->dev)!=0) + pr_err("cat't request firmware #%d\n", i); + else + break; + } + if (i == 3) + return -EINVAL; + + if (fw_entry->size <= 0) { + pr_err("load firmware error\n"); + release_firmware(fw_entry); + return -EINVAL; + } + count = (fw_entry->size - 13) / 13; //13 bytes per line, last line is version + rom_entry = kzalloc(count * sizeof(*rom_entry), GFP_KERNEL); + + for (i = 0; i < count; i++) { + sscanf(fw_entry->data + i * 13, "%x=%x", &val1, &val2); + rom_entry[i].address = val1 & 0xFFFF; + rom_entry[i].value = val2 & 0xFF; + //pr_info("%d: %x = %x\n", i, rom_entry[i].address, rom_entry[i].value); + } + sscanf(fw_entry->data + i * 13, "version=%d", &version); + //pr_info("version is %d\n", version); + + rom_table.rv.v.version = version; + rom_table.table = rom_entry; + rom_table.table_size = count; + release_firmware(fw_entry); + return 0; +} + +static int sp2541_eeprom_check(struct sp2541_struct *sp) +{ + union rom_version version; + int ret; + + if (sp2541_load_romtable(sp)) + return 0; + sp->rom = &rom_table; + + ret = eeprom_read(sp, 0x7a0, (uint8_t *)&version, sizeof(version)); + if (ret) + return ret; + + if (version.v.magic != SP2514_MAGIC || + version.v.version != sp->rom->rv.v.version) { + pr_info("old version %d\nnew version %d\n", version.v.version, + sp->rom->rv.v.version); + ret = eeprom_update(sp, sp->rom->table, sp->rom->table_size); + if (ret) { + pr_err("eeprom_update failed\n"); + return ret; + } + + // update version + ret = eeprom_write(sp, 0x07a0, + (uint8_t *)&sp->rom->rv, + sizeof(sp->rom->rv)); + if (ret) { + pr_err("sp2541 version update failed\n"); + return ret; + } + } + + if (rom_entry != NULL) + kfree(rom_entry); + rom_table.table = NULL; + rom_table.table_size = 0; + + return 0; +} + +static int sp2541_battery_temperature(struct sp2541_struct *sp) +{ + int ret; + int temp = 0; + uint8_t buf[2] ={0}; + + ret = sp2541_read(sp, RAM_READ_CMD,SP2541_REG_TEMP,buf,2); + if (ret<0) { + dev_err(sp->dev, "error reading temperature\n"); + return ret; + } + + temp = __get_le16(buf); + + temp = (temp/10) - 273; + return temp; +} + +static int sp2541_battery_voltage(struct sp2541_struct *sp) +{ + uint8_t buf[2] = {0}; + int volt = 0; + int ret; + + ret = sp2541_read(sp, RAM_READ_CMD,SP2541_REG_VOLT,buf,2); + if (ret<0) { + dev_err(sp->dev, "error reading voltage\n"); + return ret; + } + + volt = __get_le16(buf); + + return volt; +} + +/* + * Return the battery average current + * Note that current can be negative signed as well + * Or 0 if something fails. + */ +static int sp2541_battery_current(struct sp2541_struct *sp) +{ + int ret; + int curr = 0; + uint8_t buf[2] = {0}; + + ret = sp2541_read(sp, RAM_READ_CMD,SP2541_REG_AI,buf,2); + if (ret<0) { + dev_err(sp->dev, "error reading current\n"); + return 0; + } + + curr = __get_le16(buf); + + if (curr > 0x8000) { + //curr = 0xFFFF^(curr-1); + curr = curr-0x10000; + } + + return curr; +} + +/* + * Return the battery Relative State-of-Charge + * Or < 0 if something fails. + */ +static int sp2541_battery_rsoc(struct sp2541_struct *sp) +{ + int ret; + int rsoc = 0; + uint8_t buf[2]; + + ret = sp2541_read(sp, RAM_READ_CMD,SP2541_REG_SOC,buf,2); + if (ret<0) { + dev_err(sp->dev, "error reading relative State-of-Charge\n"); + return ret; + } + + rsoc = __get_le16(buf); + + return rsoc; +} + +static int sp2541_battery_status(struct sp2541_struct *sp, + union power_supply_propval *val) +{ + int status = 0; + int capacity; +#if 0 + uint8_t buf[2] = {0}; + int flags = 0; + int ret = 0; + + ret = sp2541_read(sp, RAM_READ_CMD,SP2541_REG_FLAGS, buf, 2); + if (ret < 0) { + dev_err(sp->dev, "error reading flags\n"); + return ret; + } + + flags = __get_le16(buf); +#endif + + status = charger_get_status(); + if (status < 0) + return status; + capacity = sp2541_battery_rsoc(sp); + + if (status == POWER_SUPPLY_STATUS_CHARGING && capacity == 100)//(flags & SP2541_FLAG_FC)) + status = POWER_SUPPLY_STATUS_FULL; + + val->intval = status; + return 0; +} + +static int sp2541_health_status(struct sp2541_struct *sp, + union power_supply_propval *val) +{ + uint8_t buf[2] = {0}; + int flags = 0; + int status; + int ret; + + ret = sp2541_read(sp, RAM_READ_CMD,SP2541_REG_FLAGS, buf, 2); + if (ret < 0) { + dev_err(sp->dev, "error reading flags\n"); + return ret; + } + + flags = __get_le16(buf); + + if ((flags & SP2541_FLAG_OTD)||(flags & SP2541_FLAG_OTC)) + status = POWER_SUPPLY_HEALTH_OVERHEAT; + else + status = POWER_SUPPLY_HEALTH_GOOD; + + val->intval = status; + return 0; +} + +static int sp2541_battery_time(struct sp2541_struct *sp, int reg, + union power_supply_propval *val) +{ + uint8_t buf[2] = {0}; + int tval = 0; + int ret; + + ret = sp2541_read(sp, RAM_READ_CMD,reg,buf,2); + if (ret < 0) { + dev_err(sp->dev, "error reading register %02x\n", reg); + return ret; + } + + tval = __get_le16(buf); + + if (tval == 65535) + return -ENODATA; + + val->intval = tval * 60; + return 0; +} + +#define to_sp2541_struct(x) container_of((x), struct sp2541_struct, psy_bat) + +static int sp2541_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct sp2541_struct *sp = to_sp2541_struct(psy); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = sp2541_battery_status(sp, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_PRESENT: + val->intval = sp2541_battery_voltage(sp); + if (psp == POWER_SUPPLY_PROP_PRESENT) { + val->intval = val->intval <= 0 ? 0 : 1; + } + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = sp2541_battery_current(sp); + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = sp2541_battery_rsoc(sp); + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = sp2541_battery_temperature(sp); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_HEALTH: + ret = sp2541_health_status(sp, val); + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: + ret = sp2541_battery_time(sp, SP2541_REG_TTE, val); + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: + ret = sp2541_battery_time(sp, SP2541_REG_TTECP, val); + break; + case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: + ret = sp2541_battery_time(sp, SP2541_REG_TTF, val); + break; + default: + return -EINVAL; + } + + return ret; +} + +static enum power_supply_property sp2541_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_HEALTH, +}; + +static void sp2541_external_power_changed(struct power_supply *psy) +{ + power_supply_changed(psy); +} + +static void sp2541_battery_work(struct work_struct *work) +{ + struct sp2541_struct *sp = + container_of(work, struct sp2541_struct, dwork.work); + static int last_cap = -1; + + int curr_cap = sp2541_battery_rsoc(sp); + if (curr_cap != last_cap) { + power_supply_changed(&sp->psy_bat); + last_cap = curr_cap; + } + + schedule_delayed_work(&sp->dwork, sp->interval); +} + +static int sp2541_battery_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct sp2541_struct *sp; + int ret; + + sp = devm_kzalloc(&client->dev, sizeof(*sp), GFP_KERNEL); + if (!sp) { + dev_err(&client->dev, "failed to allocate device info data\n"); + return -ENOMEM; + } + + sp->client = client; + sp->dev = &client->dev; + i2c_set_clientdata(client, sp); + + ret = sp2541_eeprom_check(sp); + if (ret) { + dev_err(sp->dev, "eeprom check failed\n"); + return ret; + } + + sp->interval = msecs_to_jiffies(battery_param.interval); + + sp->psy_bat.name = "battery"; + sp->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY; + sp->psy_bat.properties = sp2541_battery_props; + sp->psy_bat.num_properties = ARRAY_SIZE(sp2541_battery_props); + sp->psy_bat.get_property = sp2541_battery_get_property; + sp->psy_bat.external_power_changed = sp2541_external_power_changed; + + ret = power_supply_register(&client->dev, &sp->psy_bat); + if (ret) { + dev_err(&client->dev, "failed to register battery\n"); + return ret; + } + + INIT_DELAYED_WORK(&sp->dwork, sp2541_battery_work); + + schedule_delayed_work(&sp->dwork, sp->interval); + dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION); + return 0; +} + +static int sp2541_battery_remove(struct i2c_client *client) +{ + struct sp2541_struct *sp = i2c_get_clientdata(client); + cancel_delayed_work_sync(&sp->dwork); + power_supply_unregister(&sp->psy_bat); + return 0; +} + +static int sp2541_i2c_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sp2541_struct *sp = i2c_get_clientdata(client); + cancel_delayed_work_sync(&sp->dwork); + return 0; +} + +static int sp2541_i2c_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sp2541_struct *sp = i2c_get_clientdata(client); + schedule_delayed_work(&sp->dwork, 1*HZ); + return 0; +} + +static SIMPLE_DEV_PM_OPS(sp2541_dev_pm_ops, + sp2541_i2c_suspend, sp2541_i2c_resume); + +static const struct i2c_device_id sp2541_id[] = { + { "sp2541", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, sp2541_id); + +static struct i2c_driver sp2541_battery_driver = { + .driver = { + .name = "sp2541", + .owner = THIS_MODULE, + .pm = &sp2541_dev_pm_ops, + }, + .probe = sp2541_battery_probe, + .remove = __devexit_p(sp2541_battery_remove), + .id_table = sp2541_id, +}; + +static struct i2c_board_info sp2541_i2c_info = { + I2C_BOARD_INFO("sp2541", 0x14), +}; + +static struct i2c_client *i2c_client; + +static int __init sp2541_battery_init(void) +{ + struct i2c_adapter *i2c_adap; + int ret; + + if (parse_battery_param()) + return -ENODEV; + + i2c_adap = i2c_get_adapter(battery_param.i2c_bus); + if (!i2c_adap) { + pr_err("get i2c%d adapter failed\n", battery_param.i2c_bus); + return -ENODEV; + } + i2c_client = i2c_new_device(i2c_adap, &sp2541_i2c_info); + i2c_put_adapter(i2c_adap); + if (!i2c_client) { + pr_err("Unable to add I2C device for 0x%x\n", sp2541_i2c_info.addr); + return -ENODEV; + } + + ret = i2c_add_driver(&sp2541_battery_driver); + if (ret) { + pr_err("Unable to register sp2541_struct driver\n"); + } + + return ret; +} + +static void __exit sp2541_battery_exit(void) +{ + i2c_del_driver(&sp2541_battery_driver); + i2c_unregister_device(i2c_client); +} + +module_init(sp2541_battery_init); +module_exit(sp2541_battery_exit); + +MODULE_AUTHOR("clb"); +MODULE_DESCRIPTION("sp2541_struct battery monitor driver"); +MODULE_LICENSE("GPL"); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/Makefile new file mode 100755 index 00000000..758c6033 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/Makefile @@ -0,0 +1,13 @@ + +s_wmt_batt_ug31xx-objs += \ + uG31xx_API.o \ + ug31xx_i2c.o \ + ug31xx_gauge.o \ + uG31xx_API_Measurement.o \ + uG31xx_API_Otp.o \ + uG31xx_API_System.o \ + uG31xx_API_Backup.o \ + uG31xx_API_Capacity.b \ + +obj-m += s_wmt_batt_ug31xx.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_cw500_20130801_103638.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_cw500_20130801_103638.h new file mode 100755 index 00000000..ee375b15 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_cw500_20130801_103638.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 4000 +/// EDVF = 3500 +/// Taper Current = 150 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_cw500 [] = { + 0x5f,0x47,0x47,0x5f,0xed,0xc9,0x00,0x00, + 0xb6,0xfa,0x3a,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x6f,0x6e,0x64, + 0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x00, + 0x00,0x00,0x00,0x00,0x43,0x57,0x35,0x30, + 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0x4d, + 0x61,0x78,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x5a, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x01,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0xa0,0x0f,0xac,0x0d,0x14,0x00, + 0x96,0x00,0x36,0x10,0x3c,0x00,0x06,0x00, + 0x00,0x00,0x00,0x00,0xe4,0x0c,0x48,0x0d, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x01,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x1e,0x61,0xae,0x5c,0xce,0x57,0x94,0x52, + 0x14,0x4d,0x6a,0x47,0xac,0x41,0xff,0x3b, + 0x77,0x36,0x2b,0x31,0x2c,0x2c,0x85,0x27, + 0x3d,0x23,0x58,0x1f,0xd3,0x1b,0xab,0x18, + 0xdb,0x15,0x5c,0x13,0x27,0x11,0xe8,0x03, + 0xbc,0x02,0xc2,0x01,0xc8,0x00,0x00,0x00, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x58, + 0x10,0x37,0x10,0x19,0x10,0xfe,0x0f,0xe5, + 0x0f,0xcf,0x0f,0xbb,0x0f,0xa9,0x0f,0x98, + 0x0f,0x87,0x0f,0x75,0x0f,0x5c,0x0f,0x3e, + 0x0f,0x24,0x0f,0xf5,0x0e,0xac,0x0d,0x68, + 0x10,0x25,0x10,0xfb,0x0f,0xd3,0x0f,0xab, + 0x0f,0x85,0x0f,0x62,0x0f,0x41,0x0f,0x23, + 0x0f,0x0a,0x0f,0xf4,0x0e,0xe3,0x0e,0xd0, + 0x0e,0xbd,0x0e,0xaa,0x0e,0x96,0x0e,0x80, + 0x0e,0x67,0x0e,0x51,0x0e,0x2d,0x0e,0xac, + 0x0d,0x68,0x10,0x25,0x10,0xfb,0x0f,0xd3, + 0x0f,0xab,0x0f,0x85,0x0f,0x62,0x0f,0x41, + 0x0f,0x23,0x0f,0x0a,0x0f,0xf4,0x0e,0xe3, + 0x0e,0xd0,0x0e,0xbd,0x0e,0xaa,0x0e,0x96, + 0x0e,0x80,0x0e,0x67,0x0e,0x51,0x0e,0x2d, + 0x0e,0xac,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x64, + 0x10,0x46,0x10,0x2b,0x10,0x11,0x10,0xfc, + 0x0f,0xe8,0x0f,0xd6,0x0f,0xc5,0x0f,0xb5, + 0x0f,0xa4,0x0f,0x8f,0x0f,0x73,0x0f,0x54, + 0x0f,0x2c,0x0f,0xac,0x0d,0x68,0x10,0x1b, + 0x10,0xf2,0x0f,0xcb,0x0f,0xa0,0x0f,0x7a, + 0x0f,0x58,0x0f,0x38,0x0f,0x1d,0x0f,0x04, + 0x0f,0xef,0x0e,0xde,0x0e,0xcc,0x0e,0xba, + 0x0e,0xa9,0x0e,0x98,0x0e,0x84,0x0e,0x6d, + 0x0e,0x57,0x0e,0x31,0x0e,0xac,0x0d,0x68, + 0x10,0x1b,0x10,0xf2,0x0f,0xcb,0x0f,0xa0, + 0x0f,0x7a,0x0f,0x58,0x0f,0x38,0x0f,0x1d, + 0x0f,0x04,0x0f,0xef,0x0e,0xde,0x0e,0xcc, + 0x0e,0xba,0x0e,0xa9,0x0e,0x98,0x0e,0x84, + 0x0e,0x6d,0x0e,0x57,0x0e,0x31,0x0e,0xac, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x65,0x10,0x4e,0x10,0x39, + 0x10,0x26,0x10,0x14,0x10,0x03,0x10,0xf2, + 0x0f,0xdd,0x0f,0xc3,0x0f,0xa2,0x0f,0x69, + 0x0f,0xac,0x0d,0x68,0x10,0x00,0x10,0xdb, + 0x0f,0xbc,0x0f,0x92,0x0f,0x6e,0x0f,0x4e, + 0x0f,0x30,0x0f,0x16,0x0f,0xfe,0x0e,0xe8, + 0x0e,0xd8,0x0e,0xc5,0x0e,0xb4,0x0e,0xa3, + 0x0e,0x93,0x0e,0x7f,0x0e,0x69,0x0e,0x4e, + 0x0e,0x19,0x0e,0xac,0x0d,0x68,0x10,0x00, + 0x10,0xdb,0x0f,0xbc,0x0f,0x92,0x0f,0x6e, + 0x0f,0x4e,0x0f,0x30,0x0f,0x16,0x0f,0xfe, + 0x0e,0xe8,0x0e,0xd8,0x0e,0xc5,0x0e,0xb4, + 0x0e,0xa3,0x0e,0x93,0x0e,0x7f,0x0e,0x69, + 0x0e,0x4e,0x0e,0x19,0x0e,0xac,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x49,0x10,0x06,0x10,0xac, + 0x0d,0x68,0x10,0x2a,0x10,0xfc,0x0f,0xa3, + 0x0f,0x59,0x0f,0x35,0x0f,0x1b,0x0f,0xff, + 0x0e,0xe6,0x0e,0xd2,0x0e,0xc1,0x0e,0xb5, + 0x0e,0xa9,0x0e,0x9e,0x0e,0x92,0x0e,0x81, + 0x0e,0x6f,0x0e,0x54,0x0e,0x2f,0x0e,0xf6, + 0x0d,0xac,0x0d,0x68,0x10,0x2a,0x10,0xfc, + 0x0f,0xa3,0x0f,0x59,0x0f,0x35,0x0f,0x1b, + 0x0f,0xff,0x0e,0xe6,0x0e,0xd2,0x0e,0xc1, + 0x0e,0xb5,0x0e,0xa9,0x0e,0x9e,0x0e,0x92, + 0x0e,0x81,0x0e,0x6f,0x0e,0x54,0x0e,0x2f, + 0x0e,0xf6,0x0d,0xac,0x0d,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x4a,0x09,0x00, + 0x00,0x54,0x01,0x12,0x03,0xe3,0x04,0x4b, + 0x04,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0, + 0x0c,0xed,0x00,0x02,0x03,0xcd,0x04,0x32, + 0x04,0xb9,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x27,0x0d,0xba,0x01,0x46,0x03,0x92, + 0x05,0x94,0x02,0x8b,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x99,0x07,0x00,0x00,0x97, + 0x00,0xbd,0x02,0x44,0x04,0x9e,0x05,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x86,0x0c,0x7d, + 0x00,0xc2,0x02,0x8a,0x04,0xbb,0x04,0xe3, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xea, + 0x0c,0x62,0x01,0x1f,0x03,0xb8,0x05,0xaf, + 0x02,0x87,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xc1,0x04,0x00,0x00,0xed,0x00,0xe3, + 0x00,0xf0,0x02,0x1c,0x07,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xa5,0x0b,0x17,0x00,0x4a, + 0x02,0xf9,0x03,0x4a,0x05,0x7e,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x8e,0x0c,0xe2, + 0x00,0xf2,0x02,0x76,0x05,0x42,0x03,0xa0, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x08, + 0x02,0x00,0x00,0x0e,0x00,0x9e,0x00,0x5b, + 0x01,0x06,0x0b,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x6f,0x09,0x60,0x00,0x7a,0x01,0xec, + 0x01,0xa7,0x05,0xe0,0x03,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x8d,0x0b,0x1f,0x01,0x3c, + 0x01,0x73,0x04,0xbe,0x04,0x3f,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_mp718_20131004_070110.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_mp718_20131004_070110.h new file mode 100755 index 00000000..1ea6271b --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_mp718_20131004_070110.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 6800 +/// EDVF = 3400 +/// Taper Current = 100 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_mp718 [] = { + 0x5f,0x47,0x47,0x5f,0x65,0xcb,0x00,0x00, + 0xb6,0xd6,0x8d,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x6f,0x6e,0x64, + 0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x00, + 0x00,0x00,0x00,0x00,0x4d,0x37,0x31,0x38, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x6f, + 0x6e,0x64,0x65,0x72,0x6d,0x65,0x64,0x69, + 0x61,0x00,0x00,0x00,0x00,0x00,0x53,0x5a, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x02,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0x90,0x1a,0x48,0x0d,0x14,0x00, + 0x64,0x00,0x36,0x10,0x3c,0x00,0x06,0x00, + 0x00,0x00,0x00,0x00,0xe4,0x0c,0x48,0x0d, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x01,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x1e,0x61,0xae,0x5c,0xce,0x57,0x94,0x52, + 0x14,0x4d,0x6a,0x47,0xac,0x41,0xff,0x3b, + 0x77,0x36,0x2b,0x31,0x2c,0x2c,0x85,0x27, + 0x3d,0x23,0x58,0x1f,0xd3,0x1b,0xab,0x18, + 0xdb,0x15,0x5c,0x13,0x27,0x11,0xe8,0x03, + 0xbc,0x02,0xc2,0x01,0xc8,0x00,0x00,0x00, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x68,0x10,0x68, + 0x10,0x4a,0x10,0x1b,0x10,0xf2,0x0f,0xcc, + 0x0f,0xaa,0x0f,0x8c,0x0f,0x71,0x0f,0x58, + 0x0f,0x3e,0x0f,0x27,0x0f,0x17,0x0f,0x09, + 0x0f,0xfe,0x0e,0xf5,0x0e,0xe3,0x0e,0xc3, + 0x0e,0xa0,0x0e,0x87,0x0e,0x48,0x0d,0x68, + 0x10,0x2a,0x10,0xf6,0x0f,0xca,0x0f,0xa1, + 0x0f,0x7c,0x0f,0x5a,0x0f,0x3b,0x0f,0x1d, + 0x0f,0xff,0x0e,0xe5,0x0e,0xd2,0x0e,0xc3, + 0x0e,0xb7,0x0e,0xac,0x0e,0x9d,0x0e,0x88, + 0x0e,0x68,0x0e,0x49,0x0e,0x1b,0x0e,0x48, + 0x0d,0x68,0x10,0x2a,0x10,0xf6,0x0f,0xca, + 0x0f,0xa1,0x0f,0x7c,0x0f,0x5a,0x0f,0x3b, + 0x0f,0x1d,0x0f,0xff,0x0e,0xe5,0x0e,0xd2, + 0x0e,0xc3,0x0e,0xb7,0x0e,0xac,0x0e,0x9d, + 0x0e,0x88,0x0e,0x68,0x0e,0x49,0x0e,0x1b, + 0x0e,0x48,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x35,0x10,0x09,0x10,0xe3,0x0f,0xc1, + 0x0f,0xa3,0x0f,0x89,0x0f,0x70,0x0f,0x59, + 0x0f,0x42,0x0f,0x31,0x0f,0x23,0x0f,0x19, + 0x0f,0x0f,0x0f,0x00,0x0f,0xe2,0x0e,0xbe, + 0x0e,0xa3,0x0e,0x48,0x0d,0x68,0x10,0x26, + 0x10,0xf2,0x0f,0xc4,0x0f,0x9c,0x0f,0x77, + 0x0f,0x55,0x0f,0x35,0x0f,0x17,0x0f,0xfc, + 0x0e,0xe5,0x0e,0xd3,0x0e,0xc5,0x0e,0xba, + 0x0e,0xb1,0x0e,0xa5,0x0e,0x91,0x0e,0x71, + 0x0e,0x50,0x0e,0x19,0x0e,0x48,0x0d,0x68, + 0x10,0x26,0x10,0xf2,0x0f,0xc4,0x0f,0x9c, + 0x0f,0x77,0x0f,0x55,0x0f,0x35,0x0f,0x17, + 0x0f,0xfc,0x0e,0xe5,0x0e,0xd3,0x0e,0xc5, + 0x0e,0xba,0x0e,0xb1,0x0e,0xa5,0x0e,0x91, + 0x0e,0x71,0x0e,0x50,0x0e,0x19,0x0e,0x48, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x54, + 0x10,0x24,0x10,0xfb,0x0f,0xd8,0x0f,0xba, + 0x0f,0x9f,0x0f,0x87,0x0f,0x71,0x0f,0x5c, + 0x0f,0x4a,0x0f,0x3c,0x0f,0x31,0x0f,0x26, + 0x0f,0x19,0x0f,0xfe,0x0e,0xda,0x0e,0xbe, + 0x0e,0x48,0x0d,0x68,0x10,0x23,0x10,0xf1, + 0x0f,0xc1,0x0f,0x97,0x0f,0x71,0x0f,0x4e, + 0x0f,0x2e,0x0f,0x11,0x0f,0xf8,0x0e,0xe4, + 0x0e,0xd2,0x0e,0xc5,0x0e,0xba,0x0e,0xb1, + 0x0e,0xa5,0x0e,0x92,0x0e,0x71,0x0e,0x50, + 0x0e,0x0c,0x0e,0x48,0x0d,0x68,0x10,0x23, + 0x10,0xf1,0x0f,0xc1,0x0f,0x97,0x0f,0x71, + 0x0f,0x4e,0x0f,0x2e,0x0f,0x11,0x0f,0xf8, + 0x0e,0xe4,0x0e,0xd2,0x0e,0xc5,0x0e,0xba, + 0x0e,0xb1,0x0e,0xa5,0x0e,0x92,0x0e,0x71, + 0x0e,0x50,0x0e,0x0c,0x0e,0x48,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x64, + 0x10,0x36,0x10,0x0d,0x10,0xeb,0x0f,0xcd, + 0x0f,0xb4,0x0f,0x9e,0x0f,0x8a,0x0f,0x79, + 0x0f,0x6a,0x0f,0x5e,0x0f,0x53,0x0f,0x46, + 0x0f,0x2f,0x0f,0x0b,0x0f,0xee,0x0e,0x48, + 0x0d,0x68,0x10,0x1e,0x10,0xee,0x0f,0xc0, + 0x0f,0x93,0x0f,0x6c,0x0f,0x47,0x0f,0x28, + 0x0f,0x0c,0x0f,0xf5,0x0e,0xe1,0x0e,0xd3, + 0x0e,0xc6,0x0e,0xbb,0x0e,0xb0,0x0e,0xa4, + 0x0e,0x91,0x0e,0x74,0x0e,0x4b,0x0e,0xf5, + 0x0d,0x48,0x0d,0x68,0x10,0x1e,0x10,0xee, + 0x0f,0xc0,0x0f,0x93,0x0f,0x6c,0x0f,0x47, + 0x0f,0x28,0x0f,0x0c,0x0f,0xf5,0x0e,0xe1, + 0x0e,0xd3,0x0e,0xc6,0x0e,0xbb,0x0e,0xb0, + 0x0e,0xa4,0x0e,0x91,0x0e,0x74,0x0e,0x4b, + 0x0e,0xf5,0x0d,0x48,0x0d,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x42,0x1a,0x70, + 0x01,0x50,0x06,0x08,0x0d,0x78,0x05,0x20, + 0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x1a,0x89,0x03,0xd3,0x07,0x7a,0x0d,0x20, + 0x02,0xb5,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x2d,0x1b,0x75,0x04,0x57,0x08,0x39, + 0x0d,0x27,0x01,0x9a,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xbf,0x18,0xa1,0x00,0x67, + 0x05,0xbb,0x0a,0xfa,0x07,0xee,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x4b,0x1a,0xc2, + 0x02,0x4f,0x07,0xab,0x0d,0x8e,0x02,0xe2, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcb, + 0x1a,0xee,0x03,0x17,0x08,0x63,0x0d,0x60, + 0x01,0xa6,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x84,0x16,0x3a,0x00,0x03,0x04,0x71, + 0x08,0xd5,0x09,0xda,0x02,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x79,0x19,0x22,0x02,0xbc, + 0x06,0xa3,0x0d,0xf7,0x02,0x35,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x5b,0x1a,0x69, + 0x03,0xc1,0x07,0x84,0x0d,0xad,0x01,0xc3, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x22, + 0x12,0x0c,0x00,0x1c,0x02,0xf3,0x05,0x05, + 0x0a,0x69,0x06,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x09,0x18,0x57,0x01,0xe5,0x05,0xc1, + 0x0c,0x0a,0x04,0x05,0x02,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x5d,0x19,0x9a,0x02,0x1e, + 0x07,0x67,0x0d,0x3c,0x02,0x35,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_t73v_20131120_001204.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_t73v_20131120_001204.h new file mode 100755 index 00000000..12e6c67b --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_t73v_20131120_001204.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 3000 +/// EDVF = 3400 +/// Taper Current = 150 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_t73v [] = { + 0x5f,0x47,0x47,0x5f,0x00,0xc6,0x00,0x00, + 0xd4,0x1b,0xca,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x47,0x6f,0x6f,0x64, + 0x74,0x69,0x6d,0x65,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x54,0x37,0x33,0x56, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x55, + 0x53,0x54,0x59,0x2d,0x33,0x37,0x37,0x30, + 0x31,0x30,0x30,0x50,0x4c,0x00,0x31,0x33, + 0x31,0x30,0x31,0x36,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x01,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0xb8,0x0b,0x48,0x0d,0x14,0x00, + 0x96,0x00,0x36,0x10,0x3c,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x74,0x0e,0xd8,0x0e, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x05,0x62,0x8a,0x5d,0x9c,0x58,0x4c,0x53, + 0xb3,0x4d,0xeb,0x47,0x15,0x42,0x4b,0x3c, + 0xc7,0x36,0x80,0x31,0x86,0x2c,0xe5,0x27, + 0xa2,0x23,0xc0,0x1f,0x3d,0x1c,0x17,0x19, + 0x47,0x16,0xc6,0x13,0x8e,0x11,0xe8,0x03, + 0x84,0x03,0xee,0x02,0x58,0x02,0xc2,0x01, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x21,0x38,0x00,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x49,0x10,0x23, + 0x10,0x01,0x10,0xe2,0x0f,0xc8,0x0f,0xb0, + 0x0f,0x9b,0x0f,0x8a,0x0f,0x7b,0x0f,0x6e, + 0x0f,0x63,0x0f,0x58,0x0f,0x44,0x0f,0x27, + 0x0f,0x09,0x0f,0xd8,0x0e,0x48,0x0d,0x68, + 0x10,0x25,0x10,0xf4,0x0f,0xc7,0x0f,0x9c, + 0x0f,0x76,0x0f,0x53,0x0f,0x2f,0x0f,0x0e, + 0x0f,0xf3,0x0e,0xdf,0x0e,0xce,0x0e,0xbf, + 0x0e,0xb3,0x0e,0xa7,0x0e,0x99,0x0e,0x88, + 0x0e,0x6f,0x0e,0x53,0x0e,0x24,0x0e,0x48, + 0x0d,0x68,0x10,0x25,0x10,0xf4,0x0f,0xc7, + 0x0f,0x9c,0x0f,0x76,0x0f,0x53,0x0f,0x2f, + 0x0f,0x0e,0x0f,0xf3,0x0e,0xdf,0x0e,0xce, + 0x0e,0xbf,0x0e,0xb3,0x0e,0xa7,0x0e,0x99, + 0x0e,0x88,0x0e,0x6f,0x0e,0x53,0x0e,0x24, + 0x0e,0x48,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x49,0x10,0x23,0x10,0x01, + 0x10,0xe2,0x0f,0xc8,0x0f,0xb0,0x0f,0x9b, + 0x0f,0x8a,0x0f,0x7b,0x0f,0x6e,0x0f,0x63, + 0x0f,0x58,0x0f,0x44,0x0f,0x27,0x0f,0x09, + 0x0f,0xd8,0x0e,0x48,0x0d,0x68,0x10,0x25, + 0x10,0xf4,0x0f,0xc7,0x0f,0x9c,0x0f,0x76, + 0x0f,0x53,0x0f,0x2f,0x0f,0x0e,0x0f,0xf3, + 0x0e,0xdf,0x0e,0xce,0x0e,0xbf,0x0e,0xb3, + 0x0e,0xa7,0x0e,0x99,0x0e,0x88,0x0e,0x6f, + 0x0e,0x53,0x0e,0x24,0x0e,0x48,0x0d,0x68, + 0x10,0x25,0x10,0xf4,0x0f,0xc7,0x0f,0x9c, + 0x0f,0x76,0x0f,0x53,0x0f,0x2f,0x0f,0x0e, + 0x0f,0xf3,0x0e,0xdf,0x0e,0xce,0x0e,0xbf, + 0x0e,0xb3,0x0e,0xa7,0x0e,0x99,0x0e,0x88, + 0x0e,0x6f,0x0e,0x53,0x0e,0x24,0x0e,0x48, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x49,0x10,0x23,0x10,0x01,0x10,0xe2, + 0x0f,0xc8,0x0f,0xb0,0x0f,0x9b,0x0f,0x8a, + 0x0f,0x7b,0x0f,0x6e,0x0f,0x63,0x0f,0x58, + 0x0f,0x44,0x0f,0x27,0x0f,0x09,0x0f,0xd8, + 0x0e,0x48,0x0d,0x68,0x10,0x25,0x10,0xf4, + 0x0f,0xc7,0x0f,0x9c,0x0f,0x76,0x0f,0x53, + 0x0f,0x2f,0x0f,0x0e,0x0f,0xf3,0x0e,0xdf, + 0x0e,0xce,0x0e,0xbf,0x0e,0xb3,0x0e,0xa7, + 0x0e,0x99,0x0e,0x88,0x0e,0x6f,0x0e,0x53, + 0x0e,0x24,0x0e,0x48,0x0d,0x68,0x10,0x25, + 0x10,0xf4,0x0f,0xc7,0x0f,0x9c,0x0f,0x76, + 0x0f,0x53,0x0f,0x2f,0x0f,0x0e,0x0f,0xf3, + 0x0e,0xdf,0x0e,0xce,0x0e,0xbf,0x0e,0xb3, + 0x0e,0xa7,0x0e,0x99,0x0e,0x88,0x0e,0x6f, + 0x0e,0x53,0x0e,0x24,0x0e,0x48,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x49, + 0x10,0x23,0x10,0x01,0x10,0xe2,0x0f,0xc8, + 0x0f,0xb0,0x0f,0x9b,0x0f,0x8a,0x0f,0x7b, + 0x0f,0x6e,0x0f,0x63,0x0f,0x58,0x0f,0x44, + 0x0f,0x27,0x0f,0x09,0x0f,0xd8,0x0e,0x48, + 0x0d,0x68,0x10,0x25,0x10,0xf4,0x0f,0xc7, + 0x0f,0x9c,0x0f,0x76,0x0f,0x53,0x0f,0x2f, + 0x0f,0x0e,0x0f,0xf3,0x0e,0xdf,0x0e,0xce, + 0x0e,0xbf,0x0e,0xb3,0x0e,0xa7,0x0e,0x99, + 0x0e,0x88,0x0e,0x6f,0x0e,0x53,0x0e,0x24, + 0x0e,0x48,0x0d,0x68,0x10,0x25,0x10,0xf4, + 0x0f,0xc7,0x0f,0x9c,0x0f,0x76,0x0f,0x53, + 0x0f,0x2f,0x0f,0x0e,0x0f,0xf3,0x0e,0xdf, + 0x0e,0xce,0x0e,0xbf,0x0e,0xb3,0x0e,0xa7, + 0x0e,0x99,0x0e,0x88,0x0e,0x6f,0x0e,0x53, + 0x0e,0x24,0x0e,0x48,0x0d,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x3b,0x0b,0x66, + 0x00,0x7d,0x02,0xe4,0x04,0x72,0x03,0x82, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x82, + 0x0b,0x79,0x01,0x1b,0x03,0x3b,0x06,0xb1, + 0x00,0x4c,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x96,0x0b,0xe7,0x01,0x69,0x03,0xd9, + 0x05,0x6c,0x00,0x41,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x3b,0x0b,0x66,0x00,0x7d, + 0x02,0xe4,0x04,0x72,0x03,0x82,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x82,0x0b,0x79, + 0x01,0x1b,0x03,0x3b,0x06,0xb1,0x00,0x4c, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x96, + 0x0b,0xe7,0x01,0x69,0x03,0xd9,0x05,0x6c, + 0x00,0x41,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x3b,0x0b,0x66,0x00,0x7d,0x02,0xe4, + 0x04,0x72,0x03,0x82,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x82,0x0b,0x79,0x01,0x1b, + 0x03,0x3b,0x06,0xb1,0x00,0x4c,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x96,0x0b,0xe7, + 0x01,0x69,0x03,0xd9,0x05,0x6c,0x00,0x41, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3b, + 0x0b,0x66,0x00,0x7d,0x02,0xe4,0x04,0x72, + 0x03,0x82,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x82,0x0b,0x79,0x01,0x1b,0x03,0x3b, + 0x06,0xb1,0x00,0x4c,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x96,0x0b,0xe7,0x01,0x69, + 0x03,0xd9,0x05,0x6c,0x00,0x41,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms7320_20130718_200031.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms7320_20130718_200031.h new file mode 100755 index 00000000..9520f0f7 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms7320_20130718_200031.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 4000 +/// EDVF = 3400 +/// Taper Current = 100 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_wms7320 [] = { + 0x5f,0x47,0x47,0x5f,0x6d,0xc8,0x00,0x00, + 0x5f,0x5b,0x2a,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x6f,0x6e,0x64, + 0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x00, + 0x00,0x00,0x00,0x00,0x57,0x4d,0x53,0x37, + 0x33,0x32,0x30,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x6f, + 0x6e,0x64,0x65,0x72,0x6d,0x65,0x64,0x69, + 0x61,0x00,0x00,0x00,0x00,0x00,0x53,0x5a, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x02,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0xa0,0x0f,0x48,0x0d,0x14,0x00, + 0x64,0x00,0x36,0x10,0x3c,0x00,0x06,0x00, + 0x00,0x00,0x00,0x00,0xe4,0x0c,0x48,0x0d, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x01,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x1e,0x61,0xae,0x5c,0xce,0x57,0x94,0x52, + 0x14,0x4d,0x6a,0x47,0xac,0x41,0xff,0x3b, + 0x77,0x36,0x2b,0x31,0x2c,0x2c,0x85,0x27, + 0x3d,0x23,0x58,0x1f,0xd3,0x1b,0xab,0x18, + 0xdb,0x15,0x5c,0x13,0x27,0x11,0xe8,0x03, + 0xbc,0x02,0xc2,0x01,0xc8,0x00,0x00,0x00, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x5b, + 0x10,0x4d,0x10,0x2d,0x10,0x20,0x10,0x0f, + 0x10,0xff,0x0f,0xe1,0x0f,0xcc,0x0f,0xb2, + 0x0f,0x99,0x0f,0x4f,0x0f,0x48,0x0d,0x68, + 0x10,0xdd,0x0f,0xb0,0x0f,0x85,0x0f,0x5f, + 0x0f,0x3d,0x0f,0x1c,0x0f,0xf9,0x0e,0xcf, + 0x0e,0xb9,0x0e,0xab,0x0e,0xa4,0x0e,0x9f, + 0x0e,0x98,0x0e,0x8b,0x0e,0x72,0x0e,0x45, + 0x0e,0x05,0x0e,0xc9,0x0d,0xa2,0x0d,0x48, + 0x0d,0x68,0x10,0xdd,0x0f,0xb0,0x0f,0x85, + 0x0f,0x5f,0x0f,0x3d,0x0f,0x1c,0x0f,0xf9, + 0x0e,0xcf,0x0e,0xb9,0x0e,0xab,0x0e,0xa4, + 0x0e,0x9f,0x0e,0x98,0x0e,0x8b,0x0e,0x72, + 0x0e,0x45,0x0e,0x05,0x0e,0xc9,0x0d,0xa2, + 0x0d,0x48,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x66, + 0x10,0x14,0x10,0x48,0x0d,0x68,0x10,0xdd, + 0x0f,0xb0,0x0f,0x85,0x0f,0x5f,0x0f,0x3d, + 0x0f,0x1c,0x0f,0xf9,0x0e,0xcf,0x0e,0xb9, + 0x0e,0xab,0x0e,0xa4,0x0e,0x9f,0x0e,0x98, + 0x0e,0x8b,0x0e,0x72,0x0e,0x45,0x0e,0x05, + 0x0e,0xc9,0x0d,0xa2,0x0d,0x48,0x0d,0x68, + 0x10,0xdd,0x0f,0xb0,0x0f,0x85,0x0f,0x5f, + 0x0f,0x3d,0x0f,0x1c,0x0f,0xf9,0x0e,0xcf, + 0x0e,0xb9,0x0e,0xab,0x0e,0xa4,0x0e,0x9f, + 0x0e,0x98,0x0e,0x8b,0x0e,0x72,0x0e,0x45, + 0x0e,0x05,0x0e,0xc9,0x0d,0xa2,0x0d,0x48, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x3f, + 0x10,0x48,0x0d,0x68,0x10,0xdd,0x0f,0xb0, + 0x0f,0x85,0x0f,0x5f,0x0f,0x3d,0x0f,0x1c, + 0x0f,0xf9,0x0e,0xcf,0x0e,0xb9,0x0e,0xab, + 0x0e,0xa4,0x0e,0x9f,0x0e,0x98,0x0e,0x8b, + 0x0e,0x72,0x0e,0x45,0x0e,0x05,0x0e,0xc9, + 0x0d,0xa2,0x0d,0x48,0x0d,0x68,0x10,0xdd, + 0x0f,0xb0,0x0f,0x85,0x0f,0x5f,0x0f,0x3d, + 0x0f,0x1c,0x0f,0xf9,0x0e,0xcf,0x0e,0xb9, + 0x0e,0xab,0x0e,0xa4,0x0e,0x9f,0x0e,0x98, + 0x0e,0x8b,0x0e,0x72,0x0e,0x45,0x0e,0x05, + 0x0e,0xc9,0x0d,0xa2,0x0d,0x48,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x48, + 0x0d,0x68,0x10,0xdd,0x0f,0xb0,0x0f,0x85, + 0x0f,0x5f,0x0f,0x3d,0x0f,0x1c,0x0f,0xf9, + 0x0e,0xcf,0x0e,0xb9,0x0e,0xab,0x0e,0xa4, + 0x0e,0x9f,0x0e,0x98,0x0e,0x8b,0x0e,0x72, + 0x0e,0x45,0x0e,0x05,0x0e,0xc9,0x0d,0xa2, + 0x0d,0x48,0x0d,0x68,0x10,0xdd,0x0f,0xb0, + 0x0f,0x85,0x0f,0x5f,0x0f,0x3d,0x0f,0x1c, + 0x0f,0xf9,0x0e,0xcf,0x0e,0xb9,0x0e,0xab, + 0x0e,0xa4,0x0e,0x9f,0x0e,0x98,0x0e,0x8b, + 0x0e,0x72,0x0e,0x45,0x0e,0x05,0x0e,0xc9, + 0x0d,0xa2,0x0d,0x48,0x0d,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xa0, + 0x0f,0xd8,0x0e,0x10,0x0e,0x48,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xa0,0x0f,0xd8,0x0e,0x10,0x0e,0x48, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xa0,0x0f,0xd8,0x0e,0x10, + 0x0e,0x48,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xa0,0x0f,0xd8, + 0x0e,0x10,0x0e,0x48,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xb9,0x07,0x00, + 0x00,0x7c,0x00,0xaa,0x02,0x91,0x04,0xa2, + 0x04,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1, + 0x0b,0xb2,0x00,0xde,0x02,0xcf,0x04,0x91, + 0x03,0x9c,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xec,0x0b,0x3b,0x01,0xf1,0x02,0x7f, + 0x05,0x3f,0x02,0x81,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xe0,0x02,0x00,0x00,0x00, + 0x00,0x1b,0x00,0xc5,0x02,0xcf,0x0a,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xe8,0x0b,0x00, + 0x00,0x83,0x01,0xdc,0x03,0x88,0x06,0x4f, + 0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbe, + 0x0d,0x43,0x00,0x72,0x03,0x24,0x07,0xe3, + 0x02,0x85,0x01,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xe2,0x03,0x00,0x00,0x83,0x00,0xe2, + 0x02,0x7c,0x00,0x82,0x06,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xa2,0x09,0x49,0x00,0xcc, + 0x00,0x57,0x03,0x34,0x05,0xb6,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x8a,0x0a,0x61, + 0x00,0xd6,0x01,0x83,0x05,0xcf,0x02,0xa8, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb3, + 0x00,0x00,0x00,0x00,0x00,0x29,0x00,0x89, + 0x00,0x17,0x04,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xf4,0x04,0x00,0x00,0x58,0x01,0x7c, + 0x00,0x20,0x03,0x1c,0x07,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xa5,0x09,0xab,0x00,0x38, + 0x03,0x87,0x00,0x39,0x05,0x6c,0x02,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130725_164935.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130725_164935.h new file mode 100755 index 00000000..7cf4a54a --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130725_164935.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 3900 +/// EDVF = 3500 +/// Taper Current = 150 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_wms8309_c7_3900mAh [] = { + 0x5f,0x47,0x47,0x5f,0xbb,0xfa,0x00,0x00, + 0x1f,0x69,0x33,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x6f,0x6e,0x64, + 0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x00, + 0x00,0x00,0x00,0x00,0x57,0x4d,0x53,0x38, + 0x33,0x30,0x39,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0x4d, + 0x61,0x78,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x5a, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x02,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0x3c,0x0f,0xac,0x0d,0x14,0x00, + 0x96,0x00,0x36,0x10,0x3c,0x00,0x06,0x00, + 0x00,0x00,0x00,0x00,0xe4,0x0c,0x48,0x0d, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x01,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x1e,0x61,0xae,0x5c,0xce,0x57,0x94,0x52, + 0x14,0x4d,0x6a,0x47,0xac,0x41,0xff,0x3b, + 0x77,0x36,0x2b,0x31,0x2c,0x2c,0x85,0x27, + 0x3d,0x23,0x58,0x1f,0xd3,0x1b,0xab,0x18, + 0xdb,0x15,0x5c,0x13,0x27,0x11,0xe8,0x03, + 0xbc,0x02,0xc2,0x01,0xc8,0x00,0x00,0x00, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x68,0x10,0x68, + 0x10,0x5b,0x10,0x2f,0x10,0x03,0x10,0xde, + 0x0f,0xbb,0x0f,0x9c,0x0f,0x7e,0x0f,0x62, + 0x0f,0x4a,0x0f,0x36,0x0f,0x28,0x0f,0x1e, + 0x0f,0x15,0x0f,0x0a,0x0f,0xf7,0x0e,0xdb, + 0x0e,0xbe,0x0e,0xa4,0x0e,0xac,0x0d,0x68, + 0x10,0x38,0x10,0x11,0x10,0xed,0x0f,0xca, + 0x0f,0xab,0x0f,0x8a,0x0f,0x6e,0x0f,0x52, + 0x0f,0x39,0x0f,0x22,0x0f,0x65,0x0f,0x57, + 0x0f,0x4c,0x0f,0x40,0x0f,0x31,0x0f,0x1b, + 0x0f,0x02,0x0f,0xea,0x0e,0xa0,0x0e,0xac, + 0x0d,0x68,0x10,0x38,0x10,0x11,0x10,0xed, + 0x0f,0xca,0x0f,0xab,0x0f,0x8a,0x0f,0x6e, + 0x0f,0x52,0x0f,0x39,0x0f,0x22,0x0f,0x65, + 0x0f,0x57,0x0f,0x4c,0x0f,0x40,0x0f,0x31, + 0x0f,0x1b,0x0f,0x02,0x0f,0xea,0x0e,0xa0, + 0x0e,0xac,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x4a,0x10,0x10,0x10,0xed,0x0f,0xcd, + 0x0f,0xaf,0x0f,0x93,0x0f,0x7b,0x0f,0x65, + 0x0f,0x52,0x0f,0x45,0x0f,0x3a,0x0f,0x31, + 0x0f,0x27,0x0f,0x14,0x0f,0xf9,0x0e,0xdb, + 0x0e,0xbd,0x0e,0xac,0x0d,0x68,0x10,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xac,0x0d,0x68, + 0x10,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x34,0x10,0x0f,0x10,0xee,0x0f,0xcf, + 0x0f,0xb4,0x0f,0x9d,0x0f,0x8a,0x0f,0x7a, + 0x0f,0x6c,0x0f,0x5f,0x0f,0x53,0x0f,0x47, + 0x0f,0x37,0x0f,0x1e,0x0f,0xfe,0x0e,0xd9, + 0x0e,0xac,0x0d,0x68,0x10,0x1f,0x10,0xf3, + 0x0f,0xc1,0x0f,0x87,0x0f,0x68,0x0f,0x46, + 0x0f,0x25,0x0f,0x09,0x0f,0xf2,0x0e,0xde, + 0x0e,0xd1,0x0e,0xc2,0x0e,0xb7,0x0e,0xae, + 0x0e,0xa3,0x0e,0x92,0x0e,0x7b,0x0e,0x63, + 0x0e,0x31,0x0e,0xac,0x0d,0x68,0x10,0x1f, + 0x10,0xf3,0x0f,0xc1,0x0f,0x87,0x0f,0x68, + 0x0f,0x46,0x0f,0x25,0x0f,0x09,0x0f,0xf2, + 0x0e,0xde,0x0e,0xd1,0x0e,0xc2,0x0e,0xb7, + 0x0e,0xae,0x0e,0xa3,0x0e,0x92,0x0e,0x7b, + 0x0e,0x63,0x0e,0x31,0x0e,0xac,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x51,0x10,0x37,0x10,0x1d,0x10,0x05, + 0x10,0xee,0x0f,0xdb,0x0f,0xc8,0x0f,0xb8, + 0x0f,0xa8,0x0f,0x99,0x0f,0x8a,0x0f,0x78, + 0x0f,0x61,0x0f,0x43,0x0f,0x12,0x0f,0xac, + 0x0d,0x68,0x10,0x05,0x10,0xc9,0x0f,0x8a, + 0x0f,0x67,0x0f,0x4c,0x0f,0x2d,0x0f,0x17, + 0x0f,0xfe,0x0e,0xe8,0x0e,0xd5,0x0e,0xc5, + 0x0e,0xb9,0x0e,0xaf,0x0e,0xa7,0x0e,0x9b, + 0x0e,0x8b,0x0e,0x75,0x0e,0x5c,0x0e,0x1c, + 0x0e,0xac,0x0d,0x68,0x10,0x05,0x10,0xc9, + 0x0f,0x8a,0x0f,0x67,0x0f,0x4c,0x0f,0x2d, + 0x0f,0x17,0x0f,0xfe,0x0e,0xe8,0x0e,0xd5, + 0x0e,0xc5,0x0e,0xb9,0x0e,0xaf,0x0e,0xa7, + 0x0e,0x9b,0x0e,0x8b,0x0e,0x75,0x0e,0x5c, + 0x0e,0x1c,0x0e,0xac,0x0d,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x1c,0x0e,0x02, + 0x01,0xef,0x02,0x18,0x05,0x12,0x05,0xd8, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x62, + 0x0e,0xf2,0x01,0x50,0x03,0xcb,0x06,0x53, + 0x02,0x9e,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x74,0x0e,0x4c,0x02,0x6c,0x03,0xf3, + 0x06,0xc8,0x01,0x95,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x83,0x0d,0x85,0x00,0x83, + 0x02,0x8e,0x04,0xec,0x05,0x24,0x01,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x20,0x0e,0xa4, + 0x01,0x17,0x03,0x03,0x07,0x60,0x02,0xa1, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x48, + 0x0e,0x24,0x02,0x3d,0x03,0x45,0x07,0xa0, + 0x01,0x8f,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x76,0x0c,0x2b,0x00,0x0b,0x02,0xd2, + 0x03,0x6c,0x06,0xd6,0x01,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xb6,0x0d,0x2c,0x01,0xed, + 0x02,0xa8,0x06,0xf3,0x02,0xc5,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xf5,0x0d,0xd1, + 0x01,0x12,0x03,0x4b,0x07,0xc5,0x01,0x97, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7d, + 0x09,0x0d,0x00,0xf4,0x00,0x9d,0x02,0xde, + 0x05,0xfe,0x03,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x95,0x0c,0x7e,0x00,0x1b,0x02,0x32, + 0x05,0xc8,0x04,0x37,0x01,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x0f,0x0d,0xef,0x00,0xd3, + 0x02,0x15,0x07,0x36,0x02,0xc5,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130910_130553.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130910_130553.h new file mode 100755 index 00000000..aa7d7316 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_c7_20130910_130553.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 3000 +/// EDVF = 3500 +/// Taper Current = 150 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_wms8309_c7_3000mAh [] = { + 0x5f,0x47,0x47,0x5f,0x56,0xbe,0x00,0x00, + 0x31,0x88,0x6e,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x6f,0x6e,0x64, + 0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x00, + 0x00,0x00,0x00,0x00,0x43,0x57,0x35,0x30, + 0x30,0x2d,0x33,0x30,0x30,0x30,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0x4d, + 0x61,0x78,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x5a, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x01,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0xb8,0x0b,0xac,0x0d,0x14,0x00, + 0x96,0x00,0x36,0x10,0x3c,0x00,0x06,0x00, + 0x00,0x00,0x00,0x00,0xe4,0x0c,0x48,0x0d, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x01,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x1e,0x61,0xae,0x5c,0xce,0x57,0x94,0x52, + 0x14,0x4d,0x6a,0x47,0xac,0x41,0xff,0x3b, + 0x77,0x36,0x2b,0x31,0x2c,0x2c,0x85,0x27, + 0x3d,0x23,0x58,0x1f,0xd3,0x1b,0xab,0x18, + 0xdb,0x15,0x5c,0x13,0x27,0x11,0xe8,0x03, + 0xbc,0x02,0xc2,0x01,0xc8,0x00,0x00,0x00, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x59,0x10,0x44,0x10,0x32,0x10,0x20, + 0x10,0x0b,0x10,0xef,0x0f,0xc8,0x0f,0x9c, + 0x0f,0x77,0x0f,0x28,0x0f,0xac,0x0d,0x68, + 0x10,0x0c,0x10,0xeb,0x0f,0xd5,0x0f,0xc4, + 0x0f,0xb4,0x0f,0xa0,0x0f,0x83,0x0f,0x66, + 0x0f,0x4d,0x0f,0x37,0x0f,0x28,0x0f,0x16, + 0x0f,0x03,0x0f,0xea,0x0e,0xcc,0x0e,0xab, + 0x0e,0x84,0x0e,0x5c,0x0e,0x2d,0x0e,0xac, + 0x0d,0x68,0x10,0x0c,0x10,0xeb,0x0f,0xd5, + 0x0f,0xc4,0x0f,0xb4,0x0f,0xa0,0x0f,0x83, + 0x0f,0x66,0x0f,0x4d,0x0f,0x37,0x0f,0x28, + 0x0f,0x16,0x0f,0x03,0x0f,0xea,0x0e,0xcc, + 0x0e,0xab,0x0e,0x84,0x0e,0x5c,0x0e,0x2d, + 0x0e,0xac,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x63, + 0x10,0x4b,0x10,0x36,0x10,0x22,0x10,0x0d, + 0x10,0xf5,0x0f,0xd4,0x0f,0xac,0x0f,0x84, + 0x0f,0x3d,0x0f,0xac,0x0d,0x68,0x10,0x0a, + 0x10,0xe9,0x0f,0xd3,0x0f,0xc1,0x0f,0xaf, + 0x0f,0x99,0x0f,0x7d,0x0f,0x62,0x0f,0x4b, + 0x0f,0x35,0x0f,0x24,0x0f,0x11,0x0f,0xfc, + 0x0e,0xe5,0x0e,0xcb,0x0e,0xac,0x0e,0x86, + 0x0e,0x61,0x0e,0x34,0x0e,0xac,0x0d,0x68, + 0x10,0x0a,0x10,0xe9,0x0f,0xd3,0x0f,0xc1, + 0x0f,0xaf,0x0f,0x99,0x0f,0x7d,0x0f,0x62, + 0x0f,0x4b,0x0f,0x35,0x0f,0x24,0x0f,0x11, + 0x0f,0xfc,0x0e,0xe5,0x0e,0xcb,0x0e,0xac, + 0x0e,0x86,0x0e,0x61,0x0e,0x34,0x0e,0xac, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x52,0x10,0x3c,0x10,0x25,0x10,0x0e, + 0x10,0xf2,0x0f,0xcd,0x0f,0xa3,0x0f,0x5f, + 0x0f,0xac,0x0d,0x68,0x10,0x05,0x10,0xe5, + 0x0f,0xcf,0x0f,0xbb,0x0f,0xa6,0x0f,0x8e, + 0x0f,0x74,0x0f,0x5c,0x0f,0x45,0x0f,0x30, + 0x0f,0x1f,0x0f,0x0b,0x0f,0xf5,0x0e,0xdd, + 0x0e,0xc4,0x0e,0xa5,0x0e,0x82,0x0e,0x60, + 0x0e,0x24,0x0e,0xac,0x0d,0x68,0x10,0x05, + 0x10,0xe5,0x0f,0xcf,0x0f,0xbb,0x0f,0xa6, + 0x0f,0x8e,0x0f,0x74,0x0f,0x5c,0x0f,0x45, + 0x0f,0x30,0x0f,0x1f,0x0f,0x0b,0x0f,0xf5, + 0x0e,0xdd,0x0e,0xc4,0x0e,0xa5,0x0e,0x82, + 0x0e,0x60,0x0e,0x24,0x0e,0xac,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x67,0x10,0x4e,0x10,0x34, + 0x10,0x16,0x10,0xed,0x0f,0xa6,0x0f,0xac, + 0x0d,0x68,0x10,0xf6,0x0f,0xda,0x0f,0xc3, + 0x0f,0xac,0x0f,0x95,0x0f,0x7c,0x0f,0x68, + 0x0f,0x51,0x0f,0x3b,0x0f,0x26,0x0f,0x11, + 0x0f,0xfb,0x0e,0xe3,0x0e,0xcf,0x0e,0xb5, + 0x0e,0x99,0x0e,0x79,0x0e,0x4f,0x0e,0x0b, + 0x0e,0xac,0x0d,0x68,0x10,0xf6,0x0f,0xda, + 0x0f,0xc3,0x0f,0xac,0x0f,0x95,0x0f,0x7c, + 0x0f,0x68,0x0f,0x51,0x0f,0x3b,0x0f,0x26, + 0x0f,0x11,0x0f,0xfb,0x0e,0xe3,0x0e,0xcf, + 0x0e,0xb5,0x0e,0x99,0x0e,0x79,0x0e,0x4f, + 0x0e,0x0b,0x0e,0xac,0x0d,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x2a,0x09,0x00, + 0x00,0xcf,0x00,0x51,0x04,0x0a,0x04,0x51, + 0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xed, + 0x0a,0x7d,0x00,0x26,0x04,0x44,0x04,0x05, + 0x02,0x9d,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x0e,0x0b,0x6c,0x01,0x7f,0x04,0xc0, + 0x03,0x62,0x01,0x7e,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xe5,0x08,0x00,0x00,0xad, + 0x00,0x1b,0x04,0x1c,0x04,0x85,0x02,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xe7,0x0a,0x69, + 0x00,0x07,0x04,0x5b,0x04,0x19,0x02,0x99, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0e, + 0x0b,0x4d,0x01,0x7b,0x04,0xe0,0x03,0x64, + 0x01,0x75,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x09,0x08,0x00,0x00,0x59,0x00,0x7e, + 0x03,0x31,0x04,0x30,0x03,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x94,0x0a,0x3e,0x00,0xb1, + 0x03,0x5a,0x04,0x4a,0x02,0xc4,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xeb,0x0a,0x05, + 0x01,0x70,0x04,0xf7,0x03,0x7e,0x01,0x79, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xeb, + 0x05,0x00,0x00,0x14,0x00,0xd9,0x01,0xfd, + 0x03,0xbf,0x04,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x95,0x09,0x10,0x00,0x99,0x02,0x53, + 0x04,0x97,0x02,0x52,0x01,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x53,0x0a,0x79,0x00,0x10, + 0x04,0x11,0x04,0xb7,0x01,0xa0,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_wm8_20130820_110949.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_wm8_20130820_110949.h new file mode 100755 index 00000000..c107e274 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ggb/ug31xx_ggb_data_wms8309_wm8_20130820_110949.h @@ -0,0 +1,233 @@ + +/* This file is auto-generated. Don't edit this file. */ + +/// R-Sense = 20 +/// ILMD = 5000 +/// EDVF = 3500 +/// Taper Current = 200 +/// Taper Voltage = 4150 +/// Taper Time = 60 + +char FactoryGGBXFile_wms8309_wm8 [] = { + 0x5f,0x47,0x47,0x5f,0x1d,0xcc,0x00,0x00, + 0xfd,0x0e,0x54,0x95,0x0e,0x00,0x00,0x00, + 0xbd,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x4d,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x57,0x4d,0x53,0x38, + 0x33,0x30,0x39,0x2d,0x31,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x4d, + 0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x37, + 0x31,0x30,0x38,0x31,0x30,0x33,0x50,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x02,0x00,0x01,0x01,0x00,0x00, + 0x70,0x00,0x64,0x00,0x00,0x00,0x00,0x14, + 0x00,0x00,0x88,0x13,0xac,0x0d,0x14,0x00, + 0xc8,0x00,0x36,0x10,0x3c,0x00,0x06,0x00, + 0x00,0x00,0x00,0x00,0xe4,0x0c,0x48,0x0d, + 0x00,0x00,0x32,0x00,0x26,0x02,0xf4,0x01, + 0x5c,0xff,0x77,0x01,0x63,0x05,0x00,0x00, + 0x00,0x00,0x01,0x00,0xf0,0xdf,0xf4,0x67, + 0xe8,0xcf,0xee,0x1b,0xe8,0x03,0xe8,0x03, + 0x00,0x00,0xe8,0x03,0x00,0x00,0x10,0x27, + 0x1e,0x61,0xae,0x5c,0xce,0x57,0x94,0x52, + 0x14,0x4d,0x6a,0x47,0xac,0x41,0xff,0x3b, + 0x77,0x36,0x2b,0x31,0x2c,0x2c,0x85,0x27, + 0x3d,0x23,0x58,0x1f,0xd3,0x1b,0xab,0x18, + 0xdb,0x15,0x5c,0x13,0x27,0x11,0xe8,0x03, + 0xbc,0x02,0xc2,0x01,0xc8,0x00,0x00,0x00, + 0x1e,0x00,0xe8,0x03,0xff,0x77,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x41,0x10,0x1a, + 0x10,0xf8,0x0f,0xd9,0x0f,0xbe,0x0f,0xa5, + 0x0f,0x8d,0x0f,0x77,0x0f,0x65,0x0f,0x56, + 0x0f,0x48,0x0f,0x3b,0x0f,0x27,0x0f,0x0a, + 0x0f,0xeb,0x0e,0xce,0x0e,0xac,0x0d,0x68, + 0x10,0x2f,0x10,0x00,0x10,0xd3,0x0f,0xaa, + 0x0f,0x84,0x0f,0x61,0x0f,0x3f,0x0f,0x1c, + 0x0f,0xfe,0x0e,0xe8,0x0e,0xd9,0x0e,0xc9, + 0x0e,0xbb,0x0e,0xad,0x0e,0x9f,0x0e,0x8c, + 0x0e,0x70,0x0e,0x55,0x0e,0x3a,0x0e,0xac, + 0x0d,0x68,0x10,0x2f,0x10,0x00,0x10,0xd3, + 0x0f,0xaa,0x0f,0x84,0x0f,0x61,0x0f,0x3f, + 0x0f,0x1c,0x0f,0xfe,0x0e,0xe8,0x0e,0xd9, + 0x0e,0xc9,0x0e,0xbb,0x0e,0xad,0x0e,0x9f, + 0x0e,0x8c,0x0e,0x70,0x0e,0x55,0x0e,0x3a, + 0x0e,0xac,0x0d,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x62,0x10,0x38,0x10,0x13, + 0x10,0xf3,0x0f,0xd7,0x0f,0xbf,0x0f,0xab, + 0x0f,0x9a,0x0f,0x8b,0x0f,0x7e,0x0f,0x72, + 0x0f,0x67,0x0f,0x57,0x0f,0x3c,0x0f,0x17, + 0x0f,0xf7,0x0e,0xac,0x0d,0x68,0x10,0x20, + 0x10,0xee,0x0f,0xc0,0x0f,0x95,0x0f,0x6e, + 0x0f,0x4b,0x0f,0x29,0x0f,0x09,0x0f,0xef, + 0x0e,0xdb,0x0e,0xce,0x0e,0xc1,0x0e,0xb7, + 0x0e,0xaf,0x0e,0xa5,0x0e,0x96,0x0e,0x7b, + 0x0e,0x59,0x0e,0x3b,0x0e,0xac,0x0d,0x68, + 0x10,0x20,0x10,0xee,0x0f,0xc0,0x0f,0x95, + 0x0f,0x6e,0x0f,0x4b,0x0f,0x29,0x0f,0x09, + 0x0f,0xef,0x0e,0xdb,0x0e,0xce,0x0e,0xc1, + 0x0e,0xb7,0x0e,0xaf,0x0e,0xa5,0x0e,0x96, + 0x0e,0x7b,0x0e,0x59,0x0e,0x3b,0x0e,0xac, + 0x0d,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x53,0x10,0x31, + 0x10,0x14,0x10,0xfa,0x0f,0xe4,0x0f,0xd2, + 0x0f,0xc1,0x0f,0xb2,0x0f,0xa4,0x0f,0x96, + 0x0f,0x86,0x0f,0x6c,0x0f,0x48,0x0f,0x27, + 0x0f,0xac,0x0d,0x68,0x10,0x21,0x10,0xf3, + 0x0f,0xc8,0x0f,0x9c,0x0f,0x76,0x0f,0x51, + 0x0f,0x2e,0x0f,0x10,0x0f,0xf8,0x0e,0xe4, + 0x0e,0xd6,0x0e,0xc7,0x0e,0xba,0x0e,0xaf, + 0x0e,0xa3,0x0e,0x91,0x0e,0x77,0x0e,0x62, + 0x0e,0x3f,0x0e,0xac,0x0d,0x68,0x10,0x21, + 0x10,0xf3,0x0f,0xc8,0x0f,0x9c,0x0f,0x76, + 0x0f,0x51,0x0f,0x2e,0x0f,0x10,0x0f,0xf8, + 0x0e,0xe4,0x0e,0xd6,0x0e,0xc7,0x0e,0xba, + 0x0e,0xaf,0x0e,0xa3,0x0e,0x91,0x0e,0x77, + 0x0e,0x62,0x0e,0x3f,0x0e,0xac,0x0d,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x68,0x10,0x68,0x10,0x68,0x10,0x68, + 0x10,0x5d,0x10,0x51,0x10,0x42,0x10,0x31, + 0x10,0x1f,0x10,0x0f,0x10,0xfe,0x0f,0xeb, + 0x0f,0xd1,0x0f,0xae,0x0f,0x85,0x0f,0xac, + 0x0d,0x68,0x10,0x25,0x10,0xed,0x0f,0xae, + 0x0f,0x81,0x0f,0x5c,0x0f,0x3a,0x0f,0x1c, + 0x0f,0x03,0x0f,0xee,0x0e,0xdc,0x0e,0xcf, + 0x0e,0xc0,0x0e,0xb3,0x0e,0xa7,0x0e,0x99, + 0x0e,0x86,0x0e,0x71,0x0e,0x56,0x0e,0x1c, + 0x0e,0xac,0x0d,0x68,0x10,0x25,0x10,0xed, + 0x0f,0xae,0x0f,0x81,0x0f,0x5c,0x0f,0x3a, + 0x0f,0x1c,0x0f,0x03,0x0f,0xee,0x0e,0xdc, + 0x0e,0xcf,0x0e,0xc0,0x0e,0xb3,0x0e,0xa7, + 0x0e,0x99,0x0e,0x86,0x0e,0x71,0x0e,0x56, + 0x0e,0x1c,0x0e,0xac,0x0d,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x68,0x10,0xb9, + 0x0f,0x0a,0x0f,0x5b,0x0e,0xac,0x0d,0x00, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68, + 0x10,0xb9,0x0f,0x0a,0x0f,0x5b,0x0e,0xac, + 0x0d,0x00,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x68,0x10,0xb9,0x0f,0x0a,0x0f,0x5b, + 0x0e,0xac,0x0d,0x00,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x68,0x10,0xb9,0x0f,0x0a, + 0x0f,0x5b,0x0e,0xac,0x0d,0x00,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xf9,0x11,0xc1, + 0x00,0xb7,0x03,0xc5,0x05,0xba,0x07,0xa4, + 0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0c, + 0x13,0x48,0x02,0x75,0x04,0x96,0x08,0xb7, + 0x03,0xbd,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x35,0x13,0xdf,0x02,0xb8,0x04,0xd9, + 0x08,0xc4,0x02,0xa8,0x00,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x1a,0x12,0x20,0x00,0x23, + 0x03,0x2c,0x05,0xaa,0x09,0x97,0x02,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x11,0x14,0xa2, + 0x01,0x50,0x04,0xca,0x09,0x53,0x04,0xcb, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4c, + 0x14,0x5e,0x02,0xd0,0x04,0x51,0x0a,0xcc, + 0x02,0xaa,0x00,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x2e,0x0f,0x11,0x00,0x9b,0x02,0x7c, + 0x04,0x05,0x08,0x05,0x04,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x35,0x12,0x48,0x01,0xec, + 0x03,0xd7,0x07,0x28,0x05,0xec,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x9b,0x12,0x23, + 0x02,0x58,0x04,0x31,0x09,0xef,0x02,0xa3, + 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7a, + 0x0a,0x00,0x00,0xb4,0x00,0x89,0x03,0x3d, + 0x06,0x96,0x08,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xb9,0x10,0x73,0x01,0xae,0x01,0xe4, + 0x05,0xb3,0x07,0xb6,0x01,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x48,0x12,0xab,0x01,0x0d, + 0x04,0xb1,0x08,0xde,0x03,0xdd,0x00,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff, +}; + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/global.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/global.h new file mode 100755 index 00000000..e328bec3 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/global.h @@ -0,0 +1,31 @@ +#ifndef _GLOBAL_H_ +#define _GLOBAL_H_ + +#define UG31XX_DEBUG_ENABLE +//#define UG31XX_RESET_DATABASE ///< [AT-PM] : DEFAULT off ; 04/13/2013 + +#if defined (uG31xx_OS_WINDOWS) + + #pragma pack(push) + #pragma pack(1) + + #ifdef UG31XX_DEBUG_ENABLE + #define DEBUG_LOG + #define uG31xx_NAC_LMD_ADJUST_DEBUG_ENABLE + #define TABLE_BACKUP_DEBUG_ENABLE + #define DEBUG_LOG_AT_PM + #define CALIBRATE_ADC_DEBUG_LOG + #endif ///< end of UG31XX_DEBUG_ENABLE + + #define EXPORTS _declspec(dllexport) + +#elif defined(uG31xx_OS_ANDROID) + + #define EXPORTS + +#endif + +#define ENABLE_BQ27520_SW_CMD +//#define ENABLE_NTC_CHECK + +#endif diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/stdafx.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/stdafx.h new file mode 100755 index 00000000..8db0f146 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/stdafx.h @@ -0,0 +1,8 @@ +/** + * @filename stdafx.h + * + * Dummy header file + * + * @author AllenTeng + */ + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/typeDefine.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/typeDefine.h new file mode 100755 index 00000000..d4034026 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/typeDefine.h @@ -0,0 +1,462 @@ +/// =========================================== +/// typeDefine.h +/// =========================================== + +#ifndef _TYPE_DEFINE_H_ +#define _TYPE_DEFINE_H_ + +typedef unsigned char _upi_u8_; +typedef unsigned short _upi_u16_; +typedef unsigned int _upi_u32_; +typedef unsigned long long _upi_u64_; +typedef char _upi_s8_; +typedef short _upi_s16_; +typedef int _upi_s32_; +typedef long long _upi_s64_; +typedef char _upi_bool_; + +#define _UPI_TRUE_ (1) +#define _UPI_FALSE_ (0) +#define _UPI_NULL_ (NULL) + + +#ifdef uG31xx_OS_WINDOWS +#pragma pack(push) +#pragma pack(1) +#endif + +#define CELL_PARAMETER_ALARM_EN_UV (1<<0) +#define CELL_PARAMETER_ALARM_EN_UET (1<<1) +#define CELL_PARAMETER_ALARM_EN_OET (1<<2) + +typedef struct CELL_PARAMETER +{ + _upi_u16_ totalSize; //Total struct size + _upi_u16_ fw_ver; //CellParameter struct version + + char customer[16]; //Customer name defined by uPI //####2012/08/29##### + char project[16]; //Project name defined by uPI + _upi_u16_ ggb_version; //0x0102 => 2.1 + + char customerSelfDef[16]; //Customer name record by customer + char projectSelfDef[16]; //Project name record by customer + _upi_u16_ cell_type_code; + + _upi_u8_ ICType; /*[2:0]=000 -> uG3100 [2:0]=001 -> uG3101 + [2:0]=010 -> uG3102 [2:0]=100 -> uG3103_2 + [2:0]=101 -> uG3103_3 */ + + _upi_u8_ gpio1; /*bit[4] cbc_en32 + bit[3] cbc_en21 + bit[2] pwm + bit[1] alarm + bit[0] gpio */ + _upi_u8_ gpio2; /*bit[4] cbc_en32 + bit[3] cbc_en21 + bit[2] pwm + bit[1] alarm + bit[0] gpio */ + _upi_u8_ gpio34; //11/22/2011 -->reg92 + + _upi_u8_ cellNumber; + _upi_u8_ assignCellOneTo; + _upi_u8_ assignCellTwoTo; + _upi_u8_ assignCellThreeTo; + + _upi_u16_ i2cAddress; //I2C Address(Hex) + _upi_u16_ clock; + + _upi_u8_ tenBitAddressMode; + _upi_u8_ highSpeedMode; + _upi_u8_ chopCtrl; //11/22/2011 -->regC1 + _upi_u8_ rSense; + + _upi_s16_ adc1Offset; //11/22/2011 -->reg58/59 + _upi_u16_ ILMD; + + _upi_u16_ edv1Voltage; + _upi_u16_ standbyCurrent; + + _upi_u16_ TPCurrent; + _upi_u16_ TPVoltage; + + _upi_u16_ TPTime; + _upi_u16_ offsetR; + + _upi_u16_ deltaR; + _upi_u16_ TpBypassCurrent; //20121029 + + _upi_s16_ uvAlarm; + _upi_s16_ uvRelease; + + _upi_s16_ uetAlarm; + _upi_s16_ uetRelease; + + _upi_s16_ oetAlarm; + _upi_s16_ oetRelease; + + _upi_s16_ oscTuneJ; + _upi_s16_ oscTuneK; + + _upi_u8_ maxDeltaQ; + _upi_u8_ timeInterval; + _upi_u8_ alarm_timer; //11/22/2011 00:*5,01:*10,10:*15,11:*20 + _upi_u8_ pwm_timer; /*[1:0]=00:32k [1:0]=01:16k + [1:0]=10:8k [1:0]=11: 4k */ + + _upi_u8_ clkDivA; //11/22/2011 + _upi_u8_ clkDivB; //11/22/2011 + _upi_u8_ alarmEnable; /*[7]:COC [6]:DOC [5]:IT [4]:ET + [3]:VP [2]:V3 [1]:V2 [0]:V1 */ + _upi_u8_ cbcEnable; /*[1]:CBC_EN32 [0]:CBC_EN21 */ + + _upi_u16_ vBat2_8V_IdealAdcCode; //ideal ADC Code + _upi_u16_ vBat2_6V_IdealAdcCode; + + _upi_u16_ vBat3_12V_IdealAdcCode; + _upi_u16_ vBat3_9V_IdealAdcCode; + + _upi_s16_ adc1_pgain; + _upi_s16_ adc1_ngain; + + _upi_s16_ adc1_pos_offset; + _upi_u16_ adc2_gain; + + _upi_s16_ adc2_offset; + _upi_u16_ R; + + _upi_u16_ rtTable[ET_NUMS]; + // SOV_TABLE % + _upi_u16_ SOV_TABLE[SOV_NUMS]; + + _upi_s16_ adc_d1; //2012/06/06/update for IT25 + _upi_s16_ adc_d2; //2012/06/06/update for IT80 + + _upi_s16_ adc_d3; ///< [AT-PM] : Used for ADC calibration IT code ; 08/15/2012 + _upi_s16_ adc_d4; + + _upi_s16_ adc_d5; + _upi_u16_ NacLmdAdjustCfg; + + _upi_u8_ otp1Scale; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) CELL_PARAMETER; +#else ///< else of defined(uG31xx_OS_ANDROID) +}CELL_PARAMETER; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct CELL_TABLE +{ + _upi_s16_ INIT_OCV[TEMPERATURE_NUMS][OCV_TABLE_IDX_COUNT][OCV_NUMS]; //initial OCV Table,0.1C/0.2C OCV/charge table + _upi_s16_ CELL_VOLTAGE_TABLE[TEMPERATURE_NUMS][C_RATE_NUMS][OCV_NUMS]; //cell behavior Model,the voltage data + _upi_s16_ CELL_NAC_TABLE[TEMPERATURE_NUMS][C_RATE_NUMS][OCV_NUMS]; //cell behavior Model,the deltaQ +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) CELL_TABLE; +#else ///< else of defined(uG31xx_OS_ANDROID) +}CELL_TABLE; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct CELL_DATA +{ + CELL_PARAMETER cellParameter; + CELL_TABLE cellTable1; +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) CELL_DATA; +#else ///< else of defined(uG31xx_OS_ANDROID) +}CELL_DATA; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +#if defined(uG31xx_OS_ANDROID) + + // + typedef struct _GGBX_FILE_HEADER + { + _upi_u32_ ggb_tag; //'_GG_' + _upi_u32_ sum16; //16 bits checksum, but store as 4 bytes + _upi_u64_ time_stamp; //seconds pass since 1970 year, 00:00:00 + _upi_u64_ length; //size that not only include ggb content. (multi-file support) + _upi_u64_ num_ggb; //number of ggb files. + } __attribute__((packed)) GGBX_FILE_HEADER; + // + +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct ADC_CHECK +{ + _upi_u16_ regCounter; //check adc counter + _upi_u16_ regVbat1Ave; //check average voltage + _upi_u16_ lastCounter; + _upi_u16_ lastVBat1Ave; + _upi_u16_ failCounterCurrent; + _upi_u16_ failCounterVoltage; +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) ADC_CHECK; +#else ///< else of defined(uG31xx_OS_ANDROID) +}ADC_CHECK; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct USER_REGISTER +{ + _upi_u8_ mode; + _upi_u8_ ctrl1; + _upi_u8_ charge_low; + _upi_u8_ charge_high; + _upi_u8_ counter_low; + _upi_u8_ counter_high; + _upi_u8_ current_low; + _upi_u8_ current_high; + _upi_u8_ vbat1_low; + _upi_u8_ vbat1_high; + _upi_u8_ intr_temper_low; + _upi_u8_ intr_temper_high; + _upi_u8_ ave_current_low; + _upi_u8_ ave_current_high; + _upi_u8_ extr_temper_low; + _upi_u8_ extr_temper_high; + _upi_u8_ rid_low; + _upi_u8_ rid_high; + _upi_u8_ alarm1_status; + _upi_u8_ alarm2_status; + _upi_u8_ intr_status; + _upi_u8_ alram_en; + _upi_u8_ ctrl2; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) USER_REGISTER; +#else ///< else of defined(uG31xx_OS_ANDROID) +}USER_REGISTER; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +//2012/08/24/new add for system suspend +typedef struct _GG_SUSPEND_INFO{ + _upi_u16_ LMD; //battery Qmax (maH) + _upi_u16_ NAC; //battery NAC(maH) + _upi_u16_ RSOC; //Battery Current RSOC(%) + _upi_u32_ currentTime; //the time tick + +#if defined(uG31xx_OS_ANDROID) + }__attribute__((packed)) GG_SUSPEND_INFO,*PGG_SUSPEND_INFO; +#else ///< else of defined(uG31xx_OS_ANDROID) +}GG_SUSPEND_INFO,*PGG_SUSPEND_INFO; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct _GG_BATTERY_INFO{ + _upi_u16_ LMD; //battery Qmax (maH) + _upi_u16_ NAC; //battery NAC(maH) + _upi_u16_ RSOC; //Battery Current RSOC(%) +#if defined(uG31xx_OS_ANDROID) + }__attribute__((packed)) GG_BATTERY_INFO; +#else ///< else of defined(uG31xx_OS_ANDROID) +}GG_BATTERY_INFO; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/// [AT-PM] : Used for TI bq27520 like command ; 10/11/2012 +typedef struct GG_TI_BQ27520 { + _upi_u16_ CntlControlStatus; + _upi_u16_ CntlPrevMacWrite; + + _upi_s16_ AR; + + _upi_u16_ Temp; + + _upi_u16_ Flags; + _upi_s16_ SINow; + _upi_s32_ SIBuf; + _upi_s16_ SISample; + _upi_u16_ SIWindow; + + _upi_s16_ Mli; + _upi_u8_ MliDsgSoc; + + _upi_u16_ AE; + + _upi_s16_ AP; + _upi_u16_ APStartChgE; + _upi_u16_ APStartDsgE; + _upi_u32_ APChgTime; + _upi_u32_ APDsgTime; + + _upi_u16_ CC; + _upi_u16_ CCBuf; + _upi_u16_ CCLastNac; + + _upi_u16_ Dli; + + _upi_u16_ Dlb; + + _upi_s8_ FCSet; + _upi_s8_ FCClear; + _upi_u8_ Soc1Set; + _upi_u8_ Soc1Clear; + _upi_s8_ InitSI; + _upi_s16_ InitMaxLoadCurrent; + _upi_s16_ CCThreshold; + _upi_u32_ Opcfg; + _upi_u16_ Dcap; + + _upi_u32_ LastTime; + _upi_u16_ DeltaSec; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) GG_TI_BQ27520, *PGG_TI_BQ27520; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GG_TI_BQ27520, *PGG_TI_BQ27520; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct GGAdcDeltaCodeMappingST { + _upi_s32_ Adc1V100; + _upi_s32_ Adc1V200; + _upi_s32_ Adc2V100; + _upi_s32_ Adc2V200; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) GGAdcDeltaCodeMappingType; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GGAdcDeltaCodeMappingType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct TableBackupST { + _upi_u16_ lowerBound; + _upi_u8_ resolution; +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) TableBackupType; +#else ///< else of defined(uG31xx_OS_ANDROID) +} TableBackupType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/* define the register of uG31xx */ +typedef struct _GG_USER_REG{ + _upi_u8_ regMode; ///< [AT-PM] : 0x00 - MODE ; 04/08/2013 + _upi_u8_ regCtrl1; ///< [AT-PM] : 0x01 - CTRL1 ; 04/08/2013 + _upi_s16_ regCharge; ///< [AT-PM] : 0x02 - Charge ; 04/08/2013 + _upi_u16_ regCounter; ///< [AT-PM] : 0x04 - Counter ; 04/08/2013 + _upi_s16_ regCurrentAve; ///< [AT-PM] : 0x06 - Ave Current ; 04/08/2013 + _upi_s16_ regVbat1Ave; ///< [AT-PM] : 0x08 - Ave VBat1 ; 04/08/2013 + _upi_u16_ regITAve; ///< [AT-PM] : 0x0A - Ave IT ; 04/08/2013 + _upi_s16_ regOffsetCurrentAve; ///< [AT-PM] : 0x0C - Ave Offset Current ; 04/08/2013 + _upi_u16_ regETAve; ///< [AT-PM] : 0x0E - Ave ET ; 04/08/2013 + _upi_u16_ regRidAve; ///< [AT-PM] : 0x10 - Ave RID ; 04/08/2013 + _upi_u8_ regAlarm1Status; ///< [AT-PM] : 0x12 - Alarm1 Status ; 04/08/2013 + _upi_u8_ regAlarm2Status; ///< [AT-PM] : 0x13 - Alarm2 Status ; 04/08/2013 + _upi_u8_ regIntrStatus; ///< [AT-PM] : 0x14 - INTR Status ; 04/08/2013 + _upi_u8_ regAlarmEnable; ///< [AT-PM] : 0x15 - Alarm EN ; 04/08/2013 + _upi_u8_ regCtrl2; ///< [AT-PM] : 0x16 - CTRL2 ; 04/08/2013 +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) GG_USER_REG, *PGG_USER_REG; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GG_USER_REG, *PGG_USER_REG; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/* define the register of uG31xx */ +typedef struct _GG_USER2_REG{ + _upi_s16_ regVbat2; //0x40,vBat2 + _upi_s16_ regVbat3; //0x42,vBat3 + _upi_s16_ regVbat1; //0x44,vBat1 Average + _upi_s16_ regVbat2Ave; //0x46,vBat2 Average + _upi_s16_ regVbat3Ave; //0x48,vBat3 Average + _upi_u16_ regV1; //0x4a,cell 1 Voltage + _upi_u16_ regV2; //0x4c,0xcell 2 Voltage + _upi_u16_ regV3; //0x4e,cell 3 Voltage + _upi_s16_ regIT; //0x50 + _upi_s16_ regET; //0x52 + _upi_u16_ regRID; //0x54 + _upi_s16_ regCurrent; //0x56 + _upi_s16_ regAdc1Offset; //0x58ADC1 offset +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) GG_USER2_REG, *PGG_USER2_REG; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GG_USER2_REG, *PGG_USER2_REG; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +#define ALARM_STATUS_UV (1<<0) +#define ALARM_STATUS_UET (1<<1) +#define ALARM_STATUS_OET (1<<2) + +/* define device information */ +typedef struct _GG_DEVICE_INFO{ + + _upi_s16_ oldRegCurrent; //for skip the ADC code Error + _upi_s16_ oldRegVbat1; //for skip the ADC code Error + + _upi_s16_ vBat1_AdcCode; //debug use + _upi_s16_ vBat1_AveAdcCode; + + _upi_s16_ fwCalAveCurrent_mA; //f/w calculate average current + _upi_u32_ lastTime; // + _upi_s16_ chargeRegister; //coulomb counter register + _upi_u16_ AdcCounter; //ADC convert counter + + _upi_s16_ preChargeRegister; //coulomb counter register + _upi_s16_ aveCurrentRegister; //2012/0711/jacky + _upi_u16_ preAdcCounter; + _upi_s32_ fwChargeData_mAH; //fw calculate maH (Q= I * T) + + _upi_s32_ chargeData_mAh; //maH calculate from charge register + _upi_u16_ voltage_mV; //total voltage + _upi_s16_ current_mA; // now current + _upi_s16_ AveCurrent_mA; // average current + _upi_s16_ IT; // internal temperature + _upi_s16_ ET; // external temperature + + _upi_u16_ v1_mV; //v1 from hw register + _upi_u16_ v2_mV; //v2 + _upi_u16_ v3_mV; //v3 + + _upi_u16_ vBat1Average_mV; //vbat1 + _upi_u16_ vBat2Average_mV; + _upi_u16_ vBat3Average_mV; + + + _upi_u16_ vCell1_mV; //v Cell1 + _upi_u16_ vCell2_mV; //v Cell2 + _upi_u16_ vCell3_mV; //v Cell3 + + _upi_s16_ CaliAdc1Code; //2012/08/29/Jacky + _upi_s16_ CaliAdc2Code; + + _upi_s16_ CoulombCounter; + + _upi_s32_ CaliChargeReg; + _upi_u16_ Adc1ConvTime; + + _upi_u8_ alarmStatus; +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) GG_DEVICE_INFO, *PGG_DEVICE_INFO; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GG_DEVICE_INFO, *PGG_DEVICE_INFO; +#endif ///< end of defined(uG31xx_OS_ANDROID) + + +/* define battery capacity */ +typedef struct _GG_CAPACITY { + _upi_u16_ LMD; //battery Qmax (maH) + _upi_u16_ NAC; //battery NAC(maH) + _upi_u16_ RSOC; //Battery Current RSOC(%) + + _upi_u8_ Ready; +#if defined(uG31xx_OS_ANDROID) +} __attribute__((packed)) GG_CAPACITY, *PGG_CAPACITY; +#else ///< else of defined(uG31xx_OS_ANDROID) +}GG_CAPACITY, *PGG_CAPACITY; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct GG_MEAS_PARA_ST +{ + _upi_s16_ Adc1Gain; + _upi_s16_ Adc1Offset; + + _upi_s16_ Adc2Gain; + _upi_s16_ Adc2Offset; + + _upi_s16_ ITOffset; + _upi_s16_ ETOffset; + + _upi_u8_ ProductType; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) GG_MEAS_PARA_TYPE; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GG_MEAS_PARA_TYPE; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +#endif + +/// =========================================== +/// End of typeDefine.h +/// =========================================== diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx.h new file mode 100755 index 00000000..b3fd8ee3 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx.h @@ -0,0 +1,127 @@ +/// =========================================== +/// uG31xx.h +/// =========================================== + +#ifndef _UG31XX_H_ +#define _UG31XX_H_ + +#define SECURITY 1 //Security Mode enable +#define NORMAL 0 //Security Mode OFF + +#define HIGH_SPEED 1 //HS Mode +#define FULL_SPEED 0 //FIL speed + +#define TEN_BIT_ADDR 1 //10-bit address Mode +#define SEVEN_BIT_ADDR 0 //7-bit address Mode + +#define I2C_SUCESS 1 // +#define I2C_FAIL 0 + +/// =========================================================================== +/// Constant for Calibration +/// =========================================================================== + +#define IT_TARGET_CODE25 (12155) +#define IT_TARGET_CODE80 (14306) + +#define IT_CODE_25 (23171) +#define IT_CODE_80 (27341) + +//constant +//define IC type +#define uG3100 0 +#define uG3101 1 +#define uG3102 2 +#define uG3103_2 4 +#define uG3103_3 5 + +//constant +//GPIO1/2 define +#define FUN_GPIO 0x01 +#define FUN_ALARM 0x02 +#define FUN_PWM 0x04 +#define FUN_CBC_EN21 0x08 +#define FUN_CBC_EN32 0x10 + +#define BIT_MACRO(x) ((_upi_u8_)1 << (x)) + +#define MAX_CRATE_AVAILABLE (20) + +#define I2C_ADDRESS 0x70 +#define I2C_CLOCK 0x100 + +//const for CELL_TABLE table +#define TEMPERATURE_NUMS (4) +#define C_RATE_NUMS (3) ///< [AT-PM] : 0.5, 0.2, 0.1, 0.02 ; 12/17/2013 +#define OCV_NUMS (21) //include the 0% & 100% +#define SOV_NUMS (5) ///< [AT-PM] : 100%, 70%, 45%, 20%, 0% ; 12/17/2012 +#define ET_NUMS (19) ///< [AT-PM] : -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80 ; 01/25/2013 + +#define NAC_LMD_ADJUST_CFG_NO_LMD_UPDATE_BETWEEN_10_90_EN (1<<0) +#define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_MASK (15<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_00 (0<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_01 (1<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_02 (2<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_03 (3<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_04 (4<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_05 (5<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_06 (6<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_07 (7<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_08 (8<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_09 (9<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_10 (10<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_11 (11<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_12 (12<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_13 (13<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_14 (14<<1) + #define NAC_LMD_ADJUST_CFG_LOCK_AND_SPEED_UP_START_SOV_15 (15<<1) +#define NAC_LMD_ADJUST_CFG_DISPLAY_CC_AS_FCC (1<<5) + +#if defined(uG31xx_OS_ANDROID) + + #define GGBX_FILE_TAG 0x5F47475F // _GG_ + #define GGBX_FACTORY_FILE_TAG 0x5F67675F // _gg_ + +#endif ///< end of defined(uG31xx_OS_ANDROID) + +enum C_RATE_TABLE_VALUES { + C_RATE_TABLE_VALUE_0 = 50, + C_RATE_TABLE_VALUE_1 = 20, + C_RATE_TABLE_VALUE_2 = 10, + C_RATE_TABLE_VALUE_3 = 2 +}; + +enum OCV_TABLE_IDX { + OCV_TABLE_IDX_CHARGE = 0, + OCV_TABLE_IDX_STAND_ALONE, + OCV_TABLE_IDX_100MA, + OCV_TABLE_IDX_COUNT, +}; + +#if defined (uG31xx_OS_WINDOWS) + + #define SleepMiniSecond(x) Sleep(x) + + #ifdef DEBUG_LOG + + #define _L(X) __L(X) + #define __L(X) L##X + + #endif + +#elif defined (uG31xx_OS_ANDROID) + + #define SleepMiniSecond(x) mdelay(x) + +#endif + +#define CONST_PERCENTAGE (100) +#define TIME_CONVERT_TIME_TO_MSEC (10) +#define CONST_CONVERSION_COUNT_THRESHOLD (300) + +#endif + +/// =========================================== +/// End of uG31xx.h +/// =========================================== + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.c new file mode 100755 index 00000000..e4752190 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.c @@ -0,0 +1,2307 @@ +/// =========================================== +/// uG31xx_API.cpp +/// =========================================== + +#include "stdafx.h" //windows need this?? +#include "uG31xx_API.h" + +static _upi_bool_ Ug31DebugEnable; +static _upi_s32_ dsg_charge_before_suspend; +static _upi_s32_ delta_cap_during_suspend; +static _upi_u8_ wakeup_predict_rsoc; +static _upi_u8_ fix_et_at_initial_cnt; +#if defined (uG31xx_OS_WINDOWS) + + #ifdef DEBUG_LOG + + unsigned int debugViewLines = 0; + CString debugViewFileName = _T("uG3100-1"); + CString BackupFile; + + #endif + +#elif defined (uG31xx_OS_ANDROID) + + _upi_u32_ GetTickCount(void) + { + return jiffies_to_msecs(jiffies); //20121121/jacky + } + + _upi_u32_ GetSysTickCount(void) + { + + struct timeval current_tick; + + do_gettimeofday(¤t_tick); + + return current_tick.tv_sec * 1000 + current_tick.tv_usec/1000; + } + +#endif + +#if defined(uG31xx_OS_ANDROID) + + int ug31_printk(int level, const char *fmt, ...) + { + #ifdef UG31XX_DEBUG_ENABLE + va_list args; + int r; + + r = 0; + if(Ug31DebugEnable == _UPI_TRUE_) + { + va_start(args, fmt); + r = vprintk(fmt, args); + va_end(args); + } + return (r); + #else ///< else of UG31XX_DEBUG_ENABLE + return (0); + #endif ///< end of UG31XX_DEBUG_ENABLE + } + +#endif ///< end of defined(uG31xx_OS_ANDROID) + + + +/// =========================================== +/// uG31xx_API.cpp (VAR) +/// =========================================== + + +/* uPI ug31xx hardware control interface */ +struct ug31xx_data { + + /// [AT-PM] : Following variables are used for uG31xx operation ; 11/01/2012 + _upi_u8_ totalCellNums; + _upi_bool_ bFirstData; + + // Global variable + CELL_TABLE cellTable; // data from .GGB file + CELL_PARAMETER cellParameter; // data from .GGB file + GG_BATTERY_INFO batteryInfo; + GG_DEVICE_INFO deviceInfo; + GG_USER_REG userReg; //user register 0x00 ~0x10 + GG_USER2_REG user2Reg; //user register 0x40 ~0x4f + GG_TI_BQ27520 bq27520Cmd; + + OtpDataType otpData; + MeasDataType measData; + CapacityDataType capData; + SystemDataType sysData; + BackupDataType backupData; + + _upi_u8_ EncriptTableStatus; + _upi_u16_ PreviousITAve; +}; + +/// =========================================== +/// End of uG31xx_API.cpp (VAR) +/// =========================================== + +/** + * @brief upiGG_GetAlarmStatus + * + * Get alarm status + * + * @para pAlarmStatus address of alarm status + * @return UG_READ_DEVICE_ALARM_SUCCESS if success + */ +GGSTATUS upiGG_GetAlarmStatus(char *pObj, _upi_u8_ *pAlarmStatus) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + UpiMeasAlarmThreshold(&pUg31xx->measData); + *pAlarmStatus = UpiAlarmStatus(&pUg31xx->sysData); + + pUg31xx->userReg.regAlarm1Status = (_upi_u8_)(pUg31xx->sysData.alarmSts & 0x00ff); + pUg31xx->userReg.regAlarm2Status = (_upi_u8_)(pUg31xx->sysData.alarmSts >> 8); + + return (UG_READ_DEVICE_ALARM_SUCCESS); +} + +// Read GG_USER_REG from device to global variable and output +GGSTATUS upiGG_ReadAllRegister(char *pObj, GG_USER_REG* pUserReg, GG_USER2_REG* pUser2Reg) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + if(!API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_MODE, + sizeof(GG_USER_REG), + &pUg31xx->userReg.regMode)) + { + return (UG_READ_REG_FAIL); + } + if(!API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_VBAT2_LOW, + sizeof(GG_USER2_REG), + (_upi_u8_* )&pUg31xx->user2Reg.regVbat2)) //read + { + return (UG_READ_REG_FAIL); + } + + return (UG_READ_REG_SUCCESS); +} + +// 07/04/1022/Jacky +_upi_u16_ CalculateVoltageFromUserReg(struct ug31xx_data *pUg31xx, _upi_s16_ voltageAdcCode, _upi_s16_ curr, _upi_u16_ offsetR, _upi_u16_ deltaR) +{ + _upi_u16_ voltage_return; + + voltage_return = (_upi_u16_)voltageAdcCode; + if(curr < 0) { + voltage_return = voltage_return + offsetR*abs(curr)/1000 + deltaR; + } else{ + voltage_return = voltage_return - offsetR*abs(curr)/1000 + deltaR; + } + return (voltage_return); +} + +// Read GG_USER_REG from device and calculate GG_DEVICE_INFO, then write to global variable and output +// TODO: offsetR and deltaR will input from .GGB in the future modify +GGSTATUS upiGG_ReadDeviceInfo(char *pObj, GG_DEVICE_INFO* pExtDeviceInfo) +{ + // Get current user register data + GGSTATUS status = UG_READ_DEVICE_INFO_SUCCESS; + struct ug31xx_data *pUg31xx; + _upi_s32_ tmp; + MEAS_RTN_CODE rtn; + + pUg31xx = (struct ug31xx_data *)pObj; + + if(!API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_MODE, + REG_AVE_RID_HIGH - REG_MODE + 1, + &pUg31xx->userReg.regMode)) + { + status = UG_READ_ADC_FAIL; + } + else + { + if(!API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_INTR_STATUS, + REG_CTRL2 - REG_INTR_STATUS + 1, + &pUg31xx->userReg.regIntrStatus)) + { + status = UG_READ_ADC_FAIL; + } + else + { + if(!API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_VBAT2_LOW, + sizeof(GG_USER2_REG), + (_upi_u8_* )&pUg31xx->user2Reg.regVbat2)) //read + { + status = UG_READ_ADC_FAIL; + } + } + } + + /// [AT-PM] : Check IT AVE code, which should be continuous ; 12/28/2012 + if(pUg31xx->PreviousITAve != 0) + { + tmp = (_upi_s32_)pUg31xx->PreviousITAve; + tmp = tmp - pUg31xx->userReg.regITAve; + if((tmp > 1000) || (tmp < -1000)) + { + #ifdef DEBUG_LOG + wDebug::LOGE(debugViewFileName.GetBuffer(),debugViewLines++,_T("[%s]: IT AVE Code abnormal -> %d/%d"), + _L(__FUNCTION__), pUg31xx->userReg.regITAve, pUg31xx->PreviousITAve); + debugViewFileName.ReleaseBuffer(); + #endif + pUg31xx->userReg.regITAve = pUg31xx->PreviousITAve; + } + } + pUg31xx->PreviousITAve = pUg31xx->userReg.regITAve; + + /// [AT-PM] : Check OTP is empty or not ; 01/25/2013 + if(pUg31xx->otpData.empty == OTP_IS_EMPTY) + { + return (UG_OTP_ISEMPTY); + } + + /// [AT-PM] : Check product type ; 01/25/2013 + if(pUg31xx->otpData.productType != UG31XX_PRODUCT_TYPE_0) + { + return (UG_OTP_PRODUCT_DISMATCH); + } + + pUg31xx->measData.sysData = &pUg31xx->sysData; + pUg31xx->measData.otp = &pUg31xx->otpData; + rtn = UpiMeasurement(&pUg31xx->measData); + if(rtn != MEAS_RTN_PASS) + { + return ((GGSTATUS)(rtn + UG_MEAS_FAIL)); + } + + pUg31xx->deviceInfo.chargeRegister = pUg31xx->userReg.regCharge; //coulomb counter + pUg31xx->deviceInfo.AdcCounter = pUg31xx->userReg.regCounter; //adc1 convert counter + pUg31xx->deviceInfo.aveCurrentRegister = pUg31xx->userReg.regCurrentAve; //2012/07/11 + pUg31xx->deviceInfo.current_mA = pUg31xx->measData.curr; + pUg31xx->deviceInfo.AveCurrent_mA = pUg31xx->measData.curr; + pUg31xx->deviceInfo.IT = pUg31xx->measData.intTemperature; + pUg31xx->deviceInfo.ET = pUg31xx->measData.extTemperature; + pUg31xx->deviceInfo.v1_mV = pUg31xx->measData.bat1Voltage; + pUg31xx->deviceInfo.vCell1_mV = pUg31xx->measData.bat1Voltage; + pUg31xx->deviceInfo.vBat1Average_mV = CalculateVoltageFromUserReg(pUg31xx, + pUg31xx->measData.bat1Voltage, + pUg31xx->measData.curr, + pUg31xx->cellParameter.offsetR, + pUg31xx->cellParameter.deltaR); + pUg31xx->deviceInfo.voltage_mV = pUg31xx->deviceInfo.vBat1Average_mV; + pUg31xx->deviceInfo.chargeData_mAh = pUg31xx->measData.deltaCap; + + pUg31xx->sysData.otpData = &pUg31xx->otpData; + UpiCalibrationOsc(&pUg31xx->sysData); //osc calibration + + UpiAdcStatus(&pUg31xx->sysData); + + if(fix_et_at_initial_cnt > 0) + { + fix_et_at_initial_cnt = fix_et_at_initial_cnt - 1; + + if(pUg31xx->deviceInfo.ET > UG31XX_MAX_TEMPERATURE_BEFORE_READY) + { + pUg31xx->deviceInfo.ET = UG31XX_MAX_TEMPERATURE_BEFORE_READY; + } + if(pUg31xx->deviceInfo.ET < UG31XX_MIN_TEMPERATURE_BEFORE_READY) + { + pUg31xx->deviceInfo.ET = UG31XX_MIN_TEMPERATURE_BEFORE_READY; + } + } + memcpy(pExtDeviceInfo, &pUg31xx->deviceInfo, sizeof(GG_DEVICE_INFO)); + return (status); +} + +void dumpInfo(struct ug31xx_data *pUg31xx) +{ + int i=0; + int j; + int k; + +/// dump parameter setting + UG31_LOGI("/// 2012/12/16/1611====================================\n"); + UG31_LOGI("/// CELL_PARAMETER\n"); + UG31_LOGI("/// ====================================2012/12/16/1611\n"); + UG31_LOGI("Total struct size: %d\n", pUg31xx->cellParameter.totalSize); + UG31_LOGI("firmware version: 0x%02X\n", pUg31xx->cellParameter.fw_ver) + UG31_LOGI("customer: %s\n", pUg31xx->cellParameter.customer) + UG31_LOGI("project: %s\n", pUg31xx->cellParameter.project) + UG31_LOGI("ggb version: 0x%02X\n", pUg31xx->cellParameter.ggb_version) + UG31_LOGI("customer self-define: %s\n", pUg31xx->cellParameter.customerSelfDef) + UG31_LOGI("project self-define: %s\n", pUg31xx->cellParameter.projectSelfDef) + UG31_LOGI("cell type : 0x%04X\n", pUg31xx->cellParameter.cell_type_code); + UG31_LOGI("ICType: 0x%02X\n", pUg31xx->cellParameter.ICType); + UG31_LOGI("gpio1: 0x%02X\n", pUg31xx->cellParameter.gpio1); + UG31_LOGI("gpio2: 0x%02X\n", pUg31xx->cellParameter.gpio2); + UG31_LOGI("gpio34: 0x%02X\n", pUg31xx->cellParameter.gpio34); + UG31_LOGI("Chop control ?? : 0x%02X\n", pUg31xx->cellParameter.chopCtrl); + UG31_LOGI("ADC1 offset ?? : %d\n", pUg31xx->cellParameter.adc1Offset); + UG31_LOGI("Cell number ?? : %d\n", pUg31xx->cellParameter.cellNumber); + UG31_LOGI("Assign cell one to: %d\n", pUg31xx->cellParameter.assignCellOneTo); + UG31_LOGI("Assign cell two to: %d\n", pUg31xx->cellParameter.assignCellTwoTo); + UG31_LOGI("Assign cell three to: %d\n", pUg31xx->cellParameter.assignCellThreeTo); + UG31_LOGI("I2C Address: : 0x%02X\n", pUg31xx->cellParameter.i2cAddress); + UG31_LOGI("I2C 10bit address: : 0x%02X\n", pUg31xx->cellParameter.tenBitAddressMode); + UG31_LOGI("I2C high speed: 0x%02X\n", pUg31xx->cellParameter.highSpeedMode); + UG31_LOGI("clock(kHz): %d\n", pUg31xx->cellParameter.clock); + UG31_LOGI("RSense(m ohm): %d\n", pUg31xx->cellParameter.rSense); + UG31_LOGI("ILMD(mAH) ?? : %d\n", pUg31xx->cellParameter.ILMD); + UG31_LOGI("EDV1 Voltage(mV): %d\n", pUg31xx->cellParameter.edv1Voltage); + UG31_LOGI("Standby current ?? : %d\n", pUg31xx->cellParameter.standbyCurrent); + UG31_LOGI("TP Current(mA)?? : %d\n", pUg31xx->cellParameter.TPCurrent); + UG31_LOGI("TP Voltage(mV)?? : %d\n", pUg31xx->cellParameter.TPVoltage); + UG31_LOGI("TP Time ?? : %d\n", pUg31xx->cellParameter.TPTime); + UG31_LOGI("Offset R ?? : %d\n", pUg31xx->cellParameter.offsetR); + UG31_LOGI("Delta R ?? : %d\n", pUg31xx->cellParameter.deltaR); + UG31_LOGI("max delta Q(%%) ?? : %d\n", pUg31xx->cellParameter.maxDeltaQ); + UG31_LOGI("TP Bypass Current ?? : %d\n", pUg31xx->cellParameter.TpBypassCurrent); //20121029/Jacky + UG31_LOGI("time interval (s) : %d\n", pUg31xx->cellParameter.timeInterval); + UG31_LOGI("ADC1 pgain: %d\n", pUg31xx->cellParameter.adc1_pgain); + UG31_LOGI("ADC1 ngain: %d\n", pUg31xx->cellParameter.adc1_ngain); + UG31_LOGI("ADC1 pos. offset: %d\n", pUg31xx->cellParameter.adc1_pos_offset); + UG31_LOGI("ADC2 gain: %d\n", pUg31xx->cellParameter.adc2_gain); + UG31_LOGI("ADC2 offset: %d\n", pUg31xx->cellParameter.adc2_offset); + UG31_LOGI("R ?? : %d\n", pUg31xx->cellParameter.R); + for (i=0; icellParameter.rtTable)/sizeof(_upi_u16_); i++) { + UG31_LOGI("RTTable[%02d]: %d\n", i, pUg31xx->cellParameter.rtTable[i]); + } + for (i=0; icellParameter.SOV_TABLE)/sizeof(_upi_u16_); i++) { + UG31_LOGI("SOV Table[%02d]: %d\n", i, pUg31xx->cellParameter.SOV_TABLE[i]/10); + } + UG31_LOGI("ADC d1: %d\n", pUg31xx->cellParameter.adc_d1); + UG31_LOGI("ADC d2: %d\n", pUg31xx->cellParameter.adc_d2); + UG31_LOGI("ADC d3: %d\n", pUg31xx->cellParameter.adc_d3); + UG31_LOGI("ADC d4: %d\n", pUg31xx->cellParameter.adc_d4); + UG31_LOGI("ADC d5: %d\n", pUg31xx->cellParameter.adc_d5); + UG31_LOGI("NacLmdAdjustCfg: %d\n", pUg31xx->cellParameter.NacLmdAdjustCfg); //20121124 + + /// [AT-PM] : Dump NAC table ; 01/27/2013 + i = 0; + while(i < TEMPERATURE_NUMS) + { + j = 0; + while(j < C_RATE_NUMS) + { + k = 0; + while(k < SOV_NUMS) + { + UG31_LOGI("NAC Table [%d][%d][%d] = %d\n", i, j, k, pUg31xx->cellTable.CELL_NAC_TABLE[i][j][k]); + k = k + 1; + } + j = j + 1; + } + i = i + 1; + } +} + +/// count Time Elapsed in suspend/power Off +_upi_u32_ CountTotalTime(_upi_u32_ savedTimeTag) +{ + _upi_u32_ totalTime; + _upi_u32_ currentTime; + + totalTime = 0; +#if defined(uG31xx_OS_ANDROID) + currentTime = GetSysTickCount(); +#else ///< else of defined(uG31xx_OS_ANDROID) + currentTime = GetTickCount(); +#endif ///< end of defined(uG31xx_OS_ANDROID) + if(currentTime > savedTimeTag) + { + totalTime = currentTime - savedTimeTag; //count the delta Time + } + else + { + totalTime = currentTime; + } + UG31_LOGE("[%s]current time/save Time/totalTime = %d/%d/%d \n", + __func__, + currentTime, + savedTimeTag, + totalTime + ); + return(totalTime); +} + +#define MS_IN_A_DAY (86400000) +#define INIT_CAP_FROM_CC_FACTOR (10) + +/** + * @brief CheckInitCapacityFromCC + * + * Check the initial capacity from coulomb counter with time interval + * The delta RSOC should be less than n days x 0.1% + * + * @para pUg31xx address of struct ug31xx_data + * @para lastRsoc last RSOC before employ coulomb counter value + * @return _UPI_NULL_ + */ +void CheckInitCapacityFromCC(struct ug31xx_data *pUg31xx, _sys_u8_ lastRsoc) +{ + _upi_s32_ tmp32; + + tmp32 = (_upi_s16_)pUg31xx->sysData.rsocFromIC; + tmp32 = tmp32 - lastRsoc; + if(tmp32 < 0) + { + tmp32 = (_upi_s32_)CountTotalTime(pUg31xx->sysData.timeTagFromIC)/MS_IN_A_DAY/INIT_CAP_FROM_CC_FACTOR; + tmp32 = tmp32*(-1) + lastRsoc; + if(tmp32 < 0) + { + tmp32 = 1; + } + UG31_LOGI("[%s]: RSOC should be limited to %d (%d <-> %d)\n", __func__, + tmp32, lastRsoc, pUg31xx->sysData.rsocFromIC); + pUg31xx->sysData.rsocFromIC = (_sys_u8_)tmp32; + tmp32 = tmp32*pUg31xx->sysData.fccFromIC/CONST_PERCENTAGE; + pUg31xx->sysData.rmFromIC = (_sys_u16_)tmp32; + } +} + +#define MAX_DELTA_RSOC_THRESHOLD_FOR_WAKEUP (25) +#define MIN_DELTA_RSOC_THRESHOLD_FOR_WAKEUP (-25) +#define MAX_DELTA_TIME_THRESHOLD_FOR_WAKEUP (MS_IN_A_DAY*5) +#define MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE (0) +#define MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE (-5) + +// Read GGB file and initial +#ifdef uG31xx_OS_WINDOWS +GGSTATUS upiGG_Initial(char **pObj,const wchar_t* GGBFilename,const wchar_t* OtpFileName, const wchar_t* BackupFileName, char ForceReset, unsigned char MaxETFixCnt) +#elif defined(uG31xx_OS_ANDROID) +GGSTATUS upiGG_Initial(char **pObj,GGBX_FILE_HEADER *pGGBXBuf, char ForceReset, unsigned char MaxETFixCnt) +#endif +{ + _upi_bool_ firstPowerOn; + struct ug31xx_data *pUg31xx; + SYSTEM_RTN_CODE rtn; + _upi_s16_ deltaQC = 0; + _upi_s32_ tmp32; + MEAS_RTN_CODE rtnMeas; + _sys_u8_ lastRsocFromIC; + + UG31_LOGI("[%s]: uG31xx API Version = %d.%08x.%04x\n", __func__, + UG31XX_API_MAIN_VERSION, UG31XX_API_OTP_VERSION, UG31XX_API_SUB_VERSION); + + Ug31DebugEnable = _UPI_TRUE_; + firstPowerOn = _UPI_FALSE_; + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + *pObj = (char *)malloc(sizeof(struct ug31xx_data)); + #else ///< else of uG31xx_BOOT_LOADER + *pObj = (char *)kmalloc(sizeof(struct ug31xx_data),GFP_KERNEL); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + *pObj = (char *)malloc(sizeof(struct ug31xx_data)); + #endif ///< end of defined(uG31xx_OS_ANDROID) + pUg31xx = (struct ug31xx_data *)(*pObj); + + memset(pUg31xx, 0, sizeof(struct ug31xx_data)); + + #ifdef uG31xx_OS_WINDOWS + pUg31xx->sysData.ggbFilename = GGBFilename; + pUg31xx->sysData.otpFileName = OtpFileName; + pUg31xx->sysData.backupFileName = BackupFileName; + BackupFile = BackupFileName; + #elif defined(uG31xx_OS_ANDROID) + pUg31xx->sysData.ggbXBuf = pGGBXBuf; + #endif + pUg31xx->sysData.ggbParameter = &pUg31xx->cellParameter; + pUg31xx->sysData.ggbCellTable = &pUg31xx->cellTable; + rtn = UpiInitSystemData(&pUg31xx->sysData); + if(rtn != SYSTEM_RTN_PASS) + { + if(rtn == SYSTEM_RTN_READ_GGB_FAIL) + { + return (UG_READ_GGB_FAIL); + } + return (UG_NOT_DEF); + } + + // Initial I2C and Open HID + #if defined(uG31xx_OS_WINDOWS) + + if(!API_I2C_Init(pUg31xx->cellParameter.clock, pUg31xx->cellParameter.i2cAddress)) + { + return UG_I2C_INIT_FAIL; + } + + #endif ///< end of defined(uG31xx_OS_WINDOWS) + UpiLoadBatInfoFromIC(&pUg31xx->sysData); + + pUg31xx->capData.ggbTable = &pUg31xx->cellTable; + pUg31xx->capData.ggbParameter = &pUg31xx->cellParameter; + pUg31xx->capData.measurement = &pUg31xx->measData; + UpiInitNacTable(&pUg31xx->capData); + + /// [AT-PM] : Check IC is active or not ; 01/28/2013 + #ifdef UG31XX_RESET_DATABASE + firstPowerOn = _UPI_TRUE_; + #else ///< else of UG31XX_RESET_DATABASE + if(ForceReset == 0) + { + firstPowerOn = UpiCheckICActive(); + } + else + { + firstPowerOn = _UPI_TRUE_; + UG31_LOGI("[%s]: Force to reset uG3105 driver. (%d)\n", __func__, ForceReset); + } + #endif ///< end of UG31XX_RESET_DATABASE + if(firstPowerOn == _UPI_TRUE_) + { + UG31_LOGE("[%s]#####firstPowerOn= %d \n",__func__,firstPowerOn); + rtn = UpiActiveUg31xx(); + if(rtn != SYSTEM_RTN_PASS) + { + return (UG_ACTIVE_FAIL); + } + + UpiSetupAdc(&pUg31xx->sysData); + UpiSetupSystem(&pUg31xx->sysData); + + pUg31xx->backupData.icDataAvailable = BACKUP_BOOL_FALSE; + } + else + { + UG31_LOGE("[%s]#####Last time tag = %d\n", __func__, pUg31xx->sysData.timeTagFromIC); + pUg31xx->measData.lastTimeTick = pUg31xx->sysData.timeTagFromIC; + pUg31xx->measData.lastDeltaCap = pUg31xx->sysData.deltaCapFromIC; + pUg31xx->measData.adc1ConvertTime = pUg31xx->sysData.adc1ConvTime; + + pUg31xx->backupData.icDataAvailable = BACKUP_BOOL_TRUE; + } + + /// [AT-PM] : Load OTP data ; 01/31/2013 + API_I2C_Read(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, OTP1_BYTE1, OTP1_SIZE, pUg31xx->otpData.otp1); + API_I2C_Read(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, OTP2_BYTE1, OTP2_SIZE, pUg31xx->otpData.otp2); + API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, OTP6_BYTE1, OTP3_SIZE, pUg31xx->otpData.otp3); + UpiConvertOtp(&pUg31xx->otpData); + + /// [AT-PM] : Check product type ; 01/25/2013 + if(pUg31xx->otpData.productType != UG31XX_PRODUCT_TYPE_0) + { + return (UG_OTP_PRODUCT_DISMATCH); + } + + if(firstPowerOn == _UPI_TRUE_) + { + SleepMiniSecond(1000); + fix_et_at_initial_cnt = MaxETFixCnt; + } + + UG31_LOGI("[%s]: Do measurement\n", __func__); + + pUg31xx->measData.sysData = &pUg31xx->sysData; + pUg31xx->measData.otp = &pUg31xx->otpData; + rtnMeas = UpiMeasurement(&pUg31xx->measData); + if(rtnMeas != MEAS_RTN_PASS) + { + return ((GGSTATUS)(rtnMeas + UG_MEAS_FAIL)); + } + if(firstPowerOn == _UPI_TRUE_) + { + /// [AT-PM] : Initialize alarm function ; 04/08/2013 + UpiMeasAlarmThreshold(&pUg31xx->measData); + UpiInitAlarm(&pUg31xx->sysData); + } + + UG31_LOGI("[%s]: Current Status = %d mV / %d mA / %d 0.1oC\n", __func__, + pUg31xx->measData.bat1Voltage, pUg31xx->measData.curr, pUg31xx->measData.intTemperature); + + UpiInitCapacity(&pUg31xx->capData); + pUg31xx->capData.rsoc = CalculateRsoc(pUg31xx->capData.rm, pUg31xx->capData.fcc); + if((firstPowerOn == _UPI_TRUE_) || (pUg31xx->sysData.fccFromIC == 0)) + { + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + UG31_LOGI("[%s]: Init data from table -> %d/%d = %d\n", __func__, + pUg31xx->batteryInfo.NAC, pUg31xx->batteryInfo.LMD, pUg31xx->batteryInfo.RSOC); + } + else + { + pUg31xx->capData.tableUpdateIdx = pUg31xx->sysData.tableUpdateIdxFromIC; + + /// [AT-PM] : Calculate the RSOC/NAC/LMD from coulomb counter ; 01/27/2013 + deltaQC = (_upi_s16_)pUg31xx->measData.stepCap; + pUg31xx->sysData.voltage = pUg31xx->measData.bat1Voltage; + lastRsocFromIC = pUg31xx->sysData.rsocFromIC; + UpiUpdateBatInfoFromIC(&pUg31xx->sysData, deltaQC); + if(CountTotalTime(pUg31xx->sysData.timeTagFromIC) > MAX_DELTA_TIME_THRESHOLD_FOR_WAKEUP) + { + /// [AT-PM] : Check the data accuracy ; 01/27/2013 + deltaQC = (_upi_s16_)pUg31xx->sysData.rsocFromIC; + deltaQC = deltaQC - pUg31xx->capData.rsoc; + if((deltaQC > MAX_DELTA_RSOC_THRESHOLD_FOR_WAKEUP) || (deltaQC < MIN_DELTA_RSOC_THRESHOLD_FOR_WAKEUP)) + { + deltaQC = (_upi_s16_)pUg31xx->capData.rsoc; + deltaQC = deltaQC - pUg31xx->sysData.rsocFromICBackup; + if((deltaQC > MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE) || (deltaQC < MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE)) + { + if(deltaQC > MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE) + { + deltaQC = MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE; + } + if(deltaQC < MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE) + { + deltaQC = MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE; + } + deltaQC = deltaQC + pUg31xx->sysData.rsocFromICBackup; + pUg31xx->capData.rsoc = (_cap_u8_)deltaQC; + + } + pUg31xx->capData.fcc = pUg31xx->sysData.fccFromIC; + tmp32 = (_upi_s32_)pUg31xx->capData.fcc; + tmp32 = tmp32*pUg31xx->capData.rsoc/CONST_PERCENTAGE; + pUg31xx->capData.rm = (_cap_u16_)tmp32; + UG31_LOGI("[%s]: Coulomb counter is not available -> Use data from table (%d/%d = %d)\n", __func__, + pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + else + { + CheckInitCapacityFromCC(pUg31xx, lastRsocFromIC); + pUg31xx->capData.rm = (_cap_u16_)pUg31xx->sysData.rmFromIC; + pUg31xx->capData.fcc = (_cap_u16_)pUg31xx->sysData.fccFromIC; + pUg31xx->capData.rsoc = (_cap_u8_)pUg31xx->sysData.rsocFromIC; + UG31_LOGI("[%s]: Use data from coulomb counter (%d/%d = %d)\n", __func__, + pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + } + else + { + CheckInitCapacityFromCC(pUg31xx, lastRsocFromIC); + pUg31xx->capData.rm = (_cap_u16_)pUg31xx->sysData.rmFromIC; + pUg31xx->capData.fcc = (_cap_u16_)pUg31xx->sysData.fccFromIC; + pUg31xx->capData.rsoc = (_cap_u8_)pUg31xx->sysData.rsocFromIC; + UG31_LOGI("[%s]: Use data from coulomb counter (%d/%d = %d)\n", __func__, + pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + UpiResetCoulombCounter(&pUg31xx->measData); + } + UpiInitDsgCharge(&pUg31xx->capData); + + /// [AT-PM] : Save battery information to IC ; 01/31/2013 + pUg31xx->sysData.rmFromIC = pUg31xx->batteryInfo.NAC; + pUg31xx->sysData.fccFromIC = pUg31xx->batteryInfo.LMD; + pUg31xx->sysData.rsocFromIC = (_sys_u8_)pUg31xx->batteryInfo.RSOC; + pUg31xx->sysData.tableUpdateIdxFromIC = pUg31xx->capData.tableUpdateIdx; + pUg31xx->sysData.deltaCapFromIC = pUg31xx->measData.lastDeltaCap; + pUg31xx->sysData.adc1ConvTime = pUg31xx->measData.adc1ConvertTime; + UpiSaveBatInfoTOIC(&pUg31xx->sysData); + + UG31_LOGI("[%s]: Driver version = %d\n", __func__, UG31XX_API_RELEASE_VERSION); + pUg31xx->backupData.targetFileVer = UG31XX_API_RELEASE_VERSION; + pUg31xx->backupData.backupDataIdx = BACKUP_MAX_LOG_SUSPEND_DATA; + while(pUg31xx->backupData.backupDataIdx) + { + pUg31xx->backupData.backupDataIdx = pUg31xx->backupData.backupDataIdx - 1; + pUg31xx->backupData.logData[pUg31xx->backupData.backupDataIdx] = (BackupSuspendDataType *)kmalloc(sizeof(BackupSuspendDataType), GFP_KERNEL); + memset(pUg31xx->backupData.logData[pUg31xx->backupData.backupDataIdx], 0, sizeof(BackupSuspendDataType)); + } + + dumpInfo(pUg31xx); + return (UG_INIT_SUCCESS); +} + +GGSTATUS upiGG_PreSuspend(char *pObj) +{ + GGSTATUS Status = UG_READ_DEVICE_INFO_SUCCESS; + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + UG31_LOGE("[%s]:*****upiGG_PreSuspend *****\n", __func__); + + UpiResetCoulombCounter(&pUg31xx->measData); + + /// [AT-PM] : Save battery information to IC ; 01/31/2013 + pUg31xx->sysData.rmFromIC = pUg31xx->batteryInfo.NAC; + pUg31xx->sysData.fccFromIC = pUg31xx->batteryInfo.LMD; + pUg31xx->sysData.rsocFromIC = (_sys_u8_)pUg31xx->batteryInfo.RSOC; + pUg31xx->sysData.tableUpdateIdxFromIC = pUg31xx->capData.tableUpdateIdx; + pUg31xx->sysData.deltaCapFromIC = pUg31xx->measData.lastDeltaCap; + pUg31xx->sysData.adc1ConvTime = pUg31xx->measData.adc1ConvertTime; + pUg31xx->sysData.voltage = pUg31xx->measData.bat1Voltage; + UpiUpdateBatInfoFromIC(&pUg31xx->sysData, (_sys_s16_) pUg31xx->measData.stepCap); + UpiSaveBatInfoTOIC(&pUg31xx->sysData); + + /// [AT-PM] : Save dsgCharge before suspend ; 08/14/2013 + dsg_charge_before_suspend = (_upi_s32_)pUg31xx->capData.dsgCharge; + if(dsg_charge_before_suspend < 0) + { + dsg_charge_before_suspend = (_upi_s32_)pUg31xx->sysData.fccFromIC; + dsg_charge_before_suspend = dsg_charge_before_suspend - pUg31xx->sysData.rmFromIC; + } + UG31_LOGI("[%s]: dsg_charge_before_suspend = %d\n", __func__, dsg_charge_before_suspend); + + pUg31xx->backupData.capData = &pUg31xx->capData; + pUg31xx->backupData.sysData = &pUg31xx->sysData; + pUg31xx->backupData.measData = &pUg31xx->measData; + UpiUpdateSuspendData(&pUg31xx->backupData, _UPI_FALSE_); + + /// [AT-PM] : Set CAP_STS_NAC_UPDATE_DISQ ; 11/08/2013 + pUg31xx->capData.status = pUg31xx->capData.status | 0x0400; + + #ifdef DEBUG_LOG + wDebug::LOGE(debugViewFileName.GetBuffer(),debugViewLines++,_T("[%s]:Reset Coulumb counter"), _L(__FUNCTION__)); + debugViewFileName.ReleaseBuffer(); + #endif + return(Status); +} + +//==================================================== +//API Call to get the Battery Capacity +// charge full condition: +// if((Iav = TP Voltage)) +//==================================================== +void upiGG_ReadCapacity(char *pObj, GG_CAPACITY *pExtCapacity) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + pUg31xx->capData.ggbTable = &pUg31xx->cellTable; + pUg31xx->capData.ggbParameter = &pUg31xx->cellParameter; + pUg31xx->capData.measurement = &pUg31xx->measData; + UpiReadCapacity(&pUg31xx->capData); + pUg31xx->capData.tableUpdateDelayCnt = 1; + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + + // Output result by assign value from global variable + pExtCapacity->LMD = pUg31xx->batteryInfo.LMD; + pExtCapacity->NAC = pUg31xx->batteryInfo.NAC; + pExtCapacity->RSOC = pUg31xx->batteryInfo.RSOC; + + /// [AT-PM] : If fully charged and keeps charging, reset coulomb counter ; 02/11/2013 + if((pUg31xx->batteryInfo.RSOC == 100) && (pUg31xx->measData.curr >= pUg31xx->cellParameter.standbyCurrent)) + { + pUg31xx->measData.sysData = &pUg31xx->sysData; + pUg31xx->measData.otp = &pUg31xx->otpData; + UpiResetCoulombCounter(&pUg31xx->measData); + } + + /// [AT-PM] : Save battery information to IC ; 01/31/2013 + pUg31xx->sysData.rmFromIC = pUg31xx->batteryInfo.NAC; + pUg31xx->sysData.fccFromIC = pUg31xx->batteryInfo.LMD; + pUg31xx->sysData.rsocFromIC = (_sys_u8_)pUg31xx->batteryInfo.RSOC; + pUg31xx->sysData.tableUpdateIdxFromIC = pUg31xx->capData.tableUpdateIdx; + pUg31xx->sysData.deltaCapFromIC = pUg31xx->measData.lastDeltaCap; + pUg31xx->sysData.adc1ConvTime = pUg31xx->measData.adc1ConvertTime; + UpiSaveBatInfoTOIC(&pUg31xx->sysData); + + /// [AT-PM] : Check data from IC and file ; 06/19/2013 + if((pUg31xx->backupData.backupFileSts == BACKUP_FILE_STS_EXIST) && + (pUg31xx->backupData.icDataAvailable == BACKUP_BOOL_FALSE)) + { + pUg31xx->backupData.icDataAvailable = BACKUP_BOOL_TRUE; + pUg31xx->sysData.timeTagFromIC = pUg31xx->measData.lastTimeTick; + pUg31xx->sysData.deltaCapFromIC = pUg31xx->measData.lastDeltaCap; + UpiSaveBatInfoTOIC(&pUg31xx->sysData); + pUg31xx->capData.rm = (_cap_u16_)pUg31xx->sysData.rmFromIC; + pUg31xx->capData.fcc = (_cap_u16_)pUg31xx->sysData.fccFromIC; + pUg31xx->capData.rsoc = (_cap_u8_)pUg31xx->sysData.rsocFromIC; + pUg31xx->capData.tableUpdateIdx = pUg31xx->sysData.tableUpdateIdxFromIC; + UpiSaveNacTable(&pUg31xx->capData); + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + UpiInitDsgCharge(&pUg31xx->capData); + pUg31xx->measData.adc1ConvertTime = pUg31xx->sysData.adc1ConvTime; + UG31_LOGI("[%s]: Refresh driver information from file\n", __func__); + } + + if(pUg31xx->backupData.icDataAvailable == BACKUP_BOOL_TRUE) + { + pExtCapacity->Ready = UG_CAP_DATA_READY; + } + else + { + pExtCapacity->Ready = UG_CAP_DATA_NOT_READY; + } +} + +_upi_u8_ upiGG_CheckBackupFile(char *pObj) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + pUg31xx->capData.ggbTable = &pUg31xx->cellTable; + pUg31xx->capData.ggbParameter = &pUg31xx->cellParameter; + pUg31xx->capData.measurement = &pUg31xx->measData; + pUg31xx->measData.sysData = &pUg31xx->sysData; + pUg31xx->measData.otp = &pUg31xx->otpData; + + pUg31xx->sysData.rmFromIC = pUg31xx->batteryInfo.NAC; + pUg31xx->sysData.fccFromIC = pUg31xx->batteryInfo.LMD; + pUg31xx->sysData.rsocFromIC = (_sys_u8_)pUg31xx->batteryInfo.RSOC; + pUg31xx->sysData.tableUpdateIdxFromIC = pUg31xx->capData.tableUpdateIdx; + pUg31xx->sysData.deltaCapFromIC = pUg31xx->measData.lastDeltaCap; + pUg31xx->sysData.adc1ConvTime = pUg31xx->measData.adc1ConvertTime; + + /// [AT-PM] : Backup data to file routine ; 02/21/2013 + pUg31xx->backupData.capData = &pUg31xx->capData; + pUg31xx->backupData.sysData = &pUg31xx->sysData; + pUg31xx->backupData.measData = &pUg31xx->measData; + #ifdef uG31xx_OS_WINDOWS + pUg31xx->sysData.backupFileName = BackupFile.GetBuffer(); + #endif ///< end of uG31xx_OS_WINDOWS + UpiBackupData(&pUg31xx->backupData); + #ifdef uG31xx_OS_WINDOWS + BackupFile.ReleaseBuffer(); + #endif ///< end of uG31xx_OS_WINDOWS + + if(pUg31xx->backupData.backupFileSts == BACKUP_FILE_STS_CHECKING) + { + UG31_LOGI("[%s]: Backup File check fail\n", __func__); + return (UPI_CHECK_BACKUP_FILE_FAIL); + } + if(pUg31xx->backupData.backupFileSts == BACKUP_FILE_STS_COMPARE) + { + UG31_LOGI("[%s]: Backup File Version = %d\n", __func__, pUg31xx->backupData.backupFileVer); + if(pUg31xx->backupData.backupFileVer != UG31XX_API_RELEASE_VERSION) + { + return (UPI_CHECK_BACKUP_FILE_MISMATCH); + } + return (UPI_CHECK_BACKUP_FILE_EXIST); + } + return (UPI_CHECK_BACKUP_FILE_FAIL); +} + +//system wakeup +// to read back the preSuspend information from uG31xx RAM area +// re-calculate the deltaQmax( the charge/discharge) during the suspend time +GGSTATUS upiGG_Wakeup(char *pObj, int dc_in_before) +{ + GGSTATUS Status = UG_READ_DEVICE_INFO_SUCCESS; + _upi_s16_ deltaQC = 0; //coulomb counter's deltaQ + _upi_u32_ totalTime; + _upi_s32_ tmp32; + MEAS_RTN_CODE rtn; + _upi_u16_ rmBefore; + _upi_u16_ fccBefore; + _upi_u16_ rsocBefore; + + struct ug31xx_data *pUg31xx; + pUg31xx = (struct ug31xx_data *)pObj; + + ///Load the Saved time tag NAC LMD + UpiLoadBatInfoFromIC(&pUg31xx->sysData); + rmBefore = (_upi_u16_)pUg31xx->sysData.rmFromIC; + fccBefore = (_upi_u16_)pUg31xx->sysData.fccFromIC; + rsocBefore = (_upi_u16_)pUg31xx->sysData.rsocFromIC; + + /// Count total Time + totalTime = CountTotalTime(pUg31xx->sysData.timeTagFromIC); + /// count the deltaQ during suspend + pUg31xx->measData.sysData = &pUg31xx->sysData; + pUg31xx->measData.otp = &pUg31xx->otpData; + pUg31xx->measData.lastTimeTick = pUg31xx->sysData.timeTagFromIC; + pUg31xx->measData.lastDeltaCap = pUg31xx->sysData.deltaCapFromIC; + pUg31xx->measData.adc1ConvertTime = pUg31xx->sysData.adc1ConvTime; + rtn = UpiMeasurement(&pUg31xx->measData); + pUg31xx->measData.adc1ConvertTime = pUg31xx->sysData.adc1ConvTime; + if(rtn != MEAS_RTN_PASS) + { + pUg31xx->backupData.capData = &pUg31xx->capData; + pUg31xx->backupData.sysData = &pUg31xx->sysData; + pUg31xx->backupData.measData = &pUg31xx->measData; + UpiUpdateSuspendData(&pUg31xx->backupData, _UPI_TRUE_); + return ((GGSTATUS)(rtn + UG_MEAS_FAIL)); + } + + /// [AT-PM] : Calculate delta capacity; 08/13/2013 + tmp32 = (_upi_s32_)pUg31xx->measData.deltaCap; + tmp32 = tmp32*(pUg31xx->sysData.adc1ConvTime)/(pUg31xx->measData.adc1ConvertTime); + pUg31xx->measData.deltaCap = (_upi_s16_)tmp32; + pUg31xx->measData.lastDeltaCap = pUg31xx->measData.deltaCap; + tmp32 = tmp32 - pUg31xx->sysData.deltaCapFromIC; + pUg31xx->measData.stepCap = (_upi_s16_)tmp32; + deltaQC = (_upi_s16_)pUg31xx->measData.stepCap; + delta_cap_during_suspend = (_upi_s32_)deltaQC; + + /// [AT-PM] : Calculate the RSOC/NAC/LMD from coulomb counter ; 01/27/2013 + pUg31xx->sysData.voltage = pUg31xx->measData.bat1Voltage; + UpiUpdateBatInfoFromIC(&pUg31xx->sysData, deltaQC); + UG31_LOGE("[%s]: suspend time = %d ms,deltaQ = %d mAh, RSOC =%d, LMD = %d mAh, NAC=%d mAh\n", + __func__, + totalTime, + deltaQC, + pUg31xx->sysData.rsocFromIC, + pUg31xx->sysData.fccFromIC, + pUg31xx->sysData.rmFromIC); + /// [AT-PM] : Calculate the RSOC/NAC/LMD from table ; 01/28/2013 + pUg31xx->capData.ggbTable = &pUg31xx->cellTable; + pUg31xx->capData.ggbParameter = &pUg31xx->cellParameter; + pUg31xx->capData.measurement = &pUg31xx->measData; + pUg31xx->capData.tableUpdateIdx = pUg31xx->sysData.tableUpdateIdxFromIC; + UpiTableCapacity(&pUg31xx->capData); + pUg31xx->capData.rsoc = CalculateRsoc(pUg31xx->capData.rm, pUg31xx->capData.fcc); + wakeup_predict_rsoc = (_upi_u8_)pUg31xx->capData.rsoc; + /// [AT-PM] : Check the data accuracy ; 01/27/2013 + if(totalTime > MAX_DELTA_TIME_THRESHOLD_FOR_WAKEUP) + { + deltaQC = (_upi_s16_)pUg31xx->sysData.rsocFromIC; + deltaQC = deltaQC - pUg31xx->capData.rsoc; + if((deltaQC > MAX_DELTA_RSOC_THRESHOLD_FOR_WAKEUP) || (deltaQC < MIN_DELTA_RSOC_THRESHOLD_FOR_WAKEUP)) + { + deltaQC = (_upi_s16_)pUg31xx->capData.rsoc; + deltaQC = deltaQC - pUg31xx->sysData.rsocFromICBackup; + if((deltaQC > MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE) || (deltaQC < MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE)) + { + if(deltaQC > MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE) + { + deltaQC = MAX_DELTA_RSOC_THRESHOLD_FOR_TABLE; + } + if(deltaQC < MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE) + { + deltaQC = MIN_DELTA_RSOC_THRESHOLD_FOR_TABLE; + } + deltaQC = deltaQC + pUg31xx->sysData.rsocFromICBackup; + pUg31xx->capData.rsoc = (_cap_u8_)deltaQC; + + } + pUg31xx->capData.fcc = pUg31xx->sysData.fccFromIC; + tmp32 = (_upi_s32_)pUg31xx->capData.fcc; + tmp32 = tmp32*pUg31xx->capData.rsoc/CONST_PERCENTAGE; + pUg31xx->capData.rm = (_cap_u16_)tmp32; + UG31_LOGI("[%s]: Coulomb counter is not available -> Use data from table (%d/%d = %d)\n", __func__, + pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + else + { + pUg31xx->capData.rm = (_cap_u16_)pUg31xx->sysData.rmFromIC; + pUg31xx->capData.fcc = (_cap_u16_)pUg31xx->sysData.fccFromIC; + pUg31xx->capData.rsoc = (_cap_u8_)pUg31xx->sysData.rsocFromIC; + UG31_LOGI("[%s]: Use data from coulomb counter (%d/%d = %d)\n", __func__, + pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + } + else + { + pUg31xx->capData.rm = (_cap_u16_)pUg31xx->sysData.rmFromIC; + pUg31xx->capData.fcc = (_cap_u16_)pUg31xx->sysData.fccFromIC; + pUg31xx->capData.rsoc = (_cap_u8_)pUg31xx->sysData.rsocFromIC; + UG31_LOGI("[%s]: Use data from coulomb counter (%d/%d = %d)\n", __func__, + pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + + /// [AT-PM] : Check dc in before suspend ; 10/22/2013 + if(dc_in_before == 0) + { + if(pUg31xx->batteryInfo.RSOC < pUg31xx->capData.rsoc) + { + UG31_LOGI("[%s]: Fix the RSOC the same value before suspend = %d (%d)\n", __func__, rsocBefore, pUg31xx->capData.rsoc); + pUg31xx->capData.rm = (_cap_u16_)rmBefore; + pUg31xx->capData.fcc = (_cap_u16_)fccBefore; + pUg31xx->capData.rsoc = (_cap_u16_)rsocBefore; + } + + tmp32 = (_upi_s32_)totalTime; + tmp32 = tmp32/1000*(pUg31xx->cellParameter.standbyCurrent)/2/3600*(-1); + UG31_LOGI("[%s]: Estimated capacity = %d\n", __func__, tmp32); + + if(deltaQC >= tmp32) + { + UG31_LOGI("[%s]: Apply static discharging current\n", __func__); + + tmp32 = tmp32 + deltaQC; + tmp32 = tmp32/2; + tmp32 = tmp32 + rmBefore; + if(tmp32 < 0) + { + tmp32 = 0; + } + UG31_LOGI("[%s]: New RM = %d (%d)\n", __func__, tmp32, rmBefore); + + pUg31xx->capData.rm = (_cap_u16_)tmp32; + pUg31xx->capData.rsoc = CalculateRsoc(pUg31xx->capData.rm, pUg31xx->capData.fcc); + UG31_LOGI("[%s]: Battery status -> %d / %d = %d\n", __func__, pUg31xx->capData.rm, pUg31xx->capData.fcc, pUg31xx->capData.rsoc); + } + + if(pUg31xx->measData.rawCodeCharge > 0) + { + pUg31xx->measData.ccOffsetAdj = pUg31xx->measData.ccOffsetAdj + 1; + if(pUg31xx->measData.ccOffsetAdj > pUg31xx->cellParameter.standbyCurrent) + { + pUg31xx->measData.ccOffsetAdj = pUg31xx->cellParameter.standbyCurrent; + } + UG31_LOGI("[%s]: Adjust ADC1 offset = %d\n", __func__, pUg31xx->measData.ccOffsetAdj); + } + } + + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + UpiInitDsgCharge(&pUg31xx->capData); + + UpiResetCoulombCounter(&pUg31xx->measData); + + /// [AT-PM] : Save battery information to IC ; 01/31/2013 + pUg31xx->sysData.rmFromIC = pUg31xx->batteryInfo.NAC; + pUg31xx->sysData.fccFromIC = pUg31xx->batteryInfo.LMD; + pUg31xx->sysData.rsocFromIC = (_sys_u8_)pUg31xx->batteryInfo.RSOC; + pUg31xx->sysData.tableUpdateIdxFromIC = pUg31xx->capData.tableUpdateIdx; + pUg31xx->sysData.deltaCapFromIC = pUg31xx->measData.lastDeltaCap; + pUg31xx->sysData.adc1ConvTime = pUg31xx->measData.adc1ConvertTime; + UpiSaveBatInfoTOIC(&pUg31xx->sysData); + + pUg31xx->backupData.capData = &pUg31xx->capData; + pUg31xx->backupData.sysData = &pUg31xx->sysData; + pUg31xx->backupData.measData = &pUg31xx->measData; + UpiUpdateSuspendData(&pUg31xx->backupData, _UPI_TRUE_); + +#if 0 + /// [AT-PM] : Backup data to file routine ; 02/21/2013 + pUg31xx->backupData.capData = &pUg31xx->capData; + pUg31xx->backupData.sysData = &pUg31xx->sysData; + pUg31xx->backupData.measData = &pUg31xx->measData; + UpiBackupData(&pUg31xx->backupData); +#endif + return (Status); +} + +/** + * @brief upiGG_AccessMeasurementParameter + * + * Access measurement parameter + * + * @para read set _UPI_TRUE_ to read data from API + * @para pMeasPara pointer of GG_MEAS_PARA_TYPE + * @return GGSTATUS + */ +GGSTATUS upiGG_AccessMeasurementParameter(char *pObj, _upi_bool_ read, GG_MEAS_PARA_TYPE *pMeasPara) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + /// [AT-PM] : Read data ; 08/29/2012 + if(read == _UPI_TRUE_) + { + pMeasPara->Adc1Gain = pUg31xx->cellParameter.adc1_ngain; + pMeasPara->Adc1Offset = pUg31xx->cellParameter.adc1_pos_offset; + pMeasPara->Adc2Gain = pUg31xx->cellParameter.adc2_gain; + pMeasPara->Adc2Offset = pUg31xx->cellParameter.adc2_offset; + pMeasPara->ITOffset = pUg31xx->cellParameter.adc_d5; + pMeasPara->ETOffset = pUg31xx->cellParameter.adc_d4; + pMeasPara->ProductType = pUg31xx->otpData.productType; + return (UG_SUCCESS); + } + + /// [AT-PM] : Write data ; 08/29/2012 + pUg31xx->cellParameter.adc1_ngain = pMeasPara->Adc1Gain; + pUg31xx->cellParameter.adc1_pos_offset = pMeasPara->Adc1Offset; + pUg31xx->cellParameter.adc2_gain = pMeasPara->Adc2Gain; + pUg31xx->cellParameter.adc2_offset = pMeasPara->Adc2Offset; + pUg31xx->cellParameter.adc_d5 = pMeasPara->ITOffset; + pUg31xx->cellParameter.adc_d4 = pMeasPara->ETOffset; + return (UG_SUCCESS); +} + +#ifdef ENABLE_BQ27520_SW_CMD + +/** + * @brief TI_Cntl + * + * Control() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Cntl(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_u16_ CntlData; + + CntlData = *pData; + switch(CntlData) + { + case UG_STD_CMD_CNTL_CONTROL_STATUS: + *pData = pUg31xx->bq27520Cmd.CntlControlStatus; + break; + case UG_STD_CMD_CNTL_DEVICE_TYPE: + *pData = 0x3103; + break; + case UG_STD_CMD_CNTL_FW_VERSION: + *pData = 0x0001; + break; + case UG_STD_CMD_CNTL_PREV_MACWRITE: + *pData = pUg31xx->bq27520Cmd.CntlPrevMacWrite; + break; + case UG_STD_CMD_CNTL_CHEM_ID: + *pData = 0x0001; + break; + case UG_STD_CMD_CNTL_OCV_CMD: + break; + case UG_STD_CMD_CNTL_BAT_INSERT: + if(!(pUg31xx->bq27520Cmd.Opcfg & UG_STD_CMD_OPCFG_BIE)) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_BAT_DET; + } + break; + case UG_STD_CMD_CNTL_BAT_REMOVE: + if(!(pUg31xx->bq27520Cmd.Opcfg & UG_STD_CMD_OPCFG_BIE)) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags & (~UG_STD_CMD_FLAGS_BAT_DET); + } + break; + case UG_STD_CMD_CNTL_SET_HIBERNATE: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus | UG_STD_CMD_CNTL_CONTROL_STATUS_HIBERNATE; + break; + case UG_STD_CMD_CNTL_CLEAR_HIBERNATE: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus & (~UG_STD_CMD_CNTL_CONTROL_STATUS_HIBERNATE); + break; + case UG_STD_CMD_CNTL_SET_SLEEP_PLUS: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus | UG_STD_CMD_CNTL_CONTROL_STATUS_SNOOZE; + break; + case UG_STD_CMD_CNTL_CLEAR_SLEEP_PLUS: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus & (~UG_STD_CMD_CNTL_CONTROL_STATUS_SNOOZE); + break; + case UG_STD_CMD_CNTL_FACTORY_RESTORE: + break; + case UG_STD_CMD_CNTL_ENABLE_DLOG: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus | UG_STD_CMD_CNTL_CONTROL_STATUS_DLOGEN; + break; + case UG_STD_CMD_CNTL_DISABLE_DLOG: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus & (~UG_STD_CMD_CNTL_CONTROL_STATUS_DLOGEN); + break; + case UG_STD_CMD_CNTL_DF_VERSION: + *pData = 0x0000; + break; + case UG_STD_CMD_CNTL_SEALED: + pUg31xx->bq27520Cmd.CntlControlStatus = pUg31xx->bq27520Cmd.CntlControlStatus | UG_STD_CMD_CNTL_CONTROL_STATUS_SS; + break; + case UG_STD_CMD_CNTL_RESET: + if(!(pUg31xx->bq27520Cmd.CntlControlStatus & UG_STD_CMD_CNTL_CONTROL_STATUS_SS)) + { + } + break; + default: + *pData = 0x0000; + break; + } + + pUg31xx->bq27520Cmd.CntlPrevMacWrite = ((CntlData) > UG_STD_CMD_CNTL_PREV_MACWRITE) ? UG_STD_CMD_CNTL_PREV_MACWRITE : CntlData; + return (UG_SUCCESS); +} + +/** + * @brief TI_AR + * + * AtRate() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_AR(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s16_ AR; + + AR = (_upi_s16_)(*pData); + if(AR != pUg31xx->bq27520Cmd.AR) + { + pUg31xx->bq27520Cmd.AR = AR; + } + return (UG_SUCCESS); +} + +/** + * @brief TI_Artte + * + * AtRateTimeToEmpty() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Artte(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ Artte; + + if(pUg31xx->bq27520Cmd.AR >= 0) + { + *pData = 65535; + } + + Artte = (_upi_s32_)pUg31xx->batteryInfo.NAC; + Artte = Artte*60*(-1)/pUg31xx->bq27520Cmd.AR; + *pData = (_upi_u16_)Artte; + return (UG_SUCCESS); +} + +/** + * @brief TI_Temp + * + * Temperature() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Temp(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + if(pUg31xx->bq27520Cmd.Opcfg & UG_STD_CMD_OPCFG_WRTEMP) + { + /// [AT-PM] : Temperature is from host ; 10/11/2012 + pUg31xx->bq27520Cmd.Temp = *pData; + } + else + { + /// [AT-PM] : Temperature is measured by uG31xx ; 10/11/2012 + if(pUg31xx->bq27520Cmd.Opcfg & UG_STD_CMD_OPCFG_TEMPS) + { + /// [AT-PM] : Report external temperature ; 10/11/2012 + *pData = pUg31xx->deviceInfo.ET; + } + else + { + /// [AT-PM] : Report internal temperature ; 10/11/2012 + *pData = pUg31xx->deviceInfo.IT; + } + } + return (UG_SUCCESS); +} + +/** + * @brief TI_Volt + * + * Voltage() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Volt(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->deviceInfo.voltage_mV; + return (UG_SUCCESS); +} + +/** + * @brief TI_Flags + * + * Flags() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Flags(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + /// [AT-PM] : OTC - Overtemperature in charge ; 10/11/2012 + + /// [AT-PM] : OTD - Overtemperature in discharge ; 10/11/2012 + + /// [AT-PM] : CHG_INH - Charge inhibit ; 10/11/2012 + + /// [AT-PM] : XCHG - Charge suspend alert ; 10/11/2012 + + /// [AT-PM] : FC - Full-charged ; 10/11/2012 + if(pUg31xx->batteryInfo.RSOC < pUg31xx->bq27520Cmd.FCClear) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags & (~UG_STD_CMD_FLAGS_FC); + } + if(pUg31xx->bq27520Cmd.FCSet < 0) + { + if(pUg31xx->batteryInfo.RSOC == 100) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_FC; + } + } + else + { + if(pUg31xx->batteryInfo.RSOC > pUg31xx->bq27520Cmd.FCSet) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_FC; + } + } + + /// [AT-PM] : CHG - (Fast) charging allowed ; 10/11/2012 + if(pUg31xx->bq27520Cmd.Flags & UG_STD_CMD_FLAGS_FC) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags & (~UG_STD_CMD_FLAGS_CHG); + } + else + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_CHG; + } + + /// [AT-PM] : OCV_GD - Good OCV measurement taken ; 10/11/2012 + + /// [AT-PM] : WAIT_ID - Waiting to identify inserted battery ; 10/11/2012 + + /// [AT-PM] : BAT_DET - Battery detected ; 10/11/2012 + if(pUg31xx->userReg.regAlarm2Status & ALARM2_STATUS_OV1_ALARM) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_BAT_DET; + } + else + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags & (~UG_STD_CMD_FLAGS_BAT_DET); + } + + /// [AT-PM] : SOC1 - State-of-charge threshold 1 (SOC1 Set) reached ; 10/11/2012 + if(pUg31xx->batteryInfo.NAC > pUg31xx->bq27520Cmd.Soc1Clear) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags & (~UG_STD_CMD_FLAGS_SOC1); + } + if(pUg31xx->batteryInfo.NAC < pUg31xx->bq27520Cmd.Soc1Set) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_SOC1; + } + + /// [AT-PM] : SYSDOWN - System should shut down ; 10/11/2012 + + /// [AT-PM] : DSG - Discharging detected ; 10/11/2012 + if(pUg31xx->deviceInfo.AveCurrent_mA <= 0) + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags | UG_STD_CMD_FLAGS_DSG; + } + else + { + pUg31xx->bq27520Cmd.Flags = pUg31xx->bq27520Cmd.Flags & (~UG_STD_CMD_FLAGS_DSG); + } + + *pData = pUg31xx->bq27520Cmd.Flags; + return (UG_SUCCESS); +} + +/** + * @brief TI_Nac + * + * NominalAvailableCapacity() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Nac(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->batteryInfo.NAC; + return (UG_SUCCESS); +} + +/** + * @brief TI_Fac + * + * FullAvailableCapacity() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Fac(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->batteryInfo.LMD; + return (UG_SUCCESS); +} + +/** + * @brief TI_RM + * + * RemainingCapacity() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_RM(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->batteryInfo.NAC; + return (UG_SUCCESS); +} + +/** + * @brief TI_Fcc + * + * FullChargeCapacity() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Fcc(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->batteryInfo.LMD; + return (UG_SUCCESS); +} + +/** + * @brief TI_AI + * + * AverageCurrent() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_AI(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->deviceInfo.AveCurrent_mA; + return (UG_SUCCESS); +} + +/** + * @brief TI_Tte + * + * TimeToEmpty() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Tte(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ Tte; + + if(pUg31xx->deviceInfo.AveCurrent_mA >= 0) + { + *pData = 65535; + return (UG_SUCCESS); + } + + Tte = (_upi_s32_)pUg31xx->batteryInfo.NAC; + Tte = Tte*60*(-1)/pUg31xx->deviceInfo.AveCurrent_mA; + *pData = (_upi_u16_)Tte; + return (UG_SUCCESS); +} + +/** + * @brief TI_Ttf + * + * TimeToFull() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Ttf(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ Ttf; + + if(pUg31xx->deviceInfo.AveCurrent_mA <= 0) + { + *pData = 65535; + return (UG_SUCCESS); + } + + Ttf = (_upi_s32_)pUg31xx->batteryInfo.LMD; + Ttf = Ttf - pUg31xx->batteryInfo.NAC; + Ttf = Ttf*90/pUg31xx->deviceInfo.AveCurrent_mA; + *pData = (_upi_u16_)Ttf; + return (UG_SUCCESS); +} + +/** + * @brief TI_SI + * + * StandbyCurrent() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_SI(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s16_ LowerBound; + _upi_s32_ NewSI; + + /// [AT-PM] : Set initial SI ; 10/11/2012 + if(pUg31xx->bq27520Cmd.SINow == 0) + { + pUg31xx->bq27520Cmd.SINow = pUg31xx->bq27520Cmd.InitSI; + } + + LowerBound = pUg31xx->bq27520Cmd.InitSI*2; + if(LowerBound > 0) + { + LowerBound = LowerBound*(-1); + } + + /// [AT-PM] : SI criteria - 2 x InitSI < Current < 0 ; 10/11/2012 + if((pUg31xx->deviceInfo.AveCurrent_mA < 0) && (pUg31xx->deviceInfo.AveCurrent_mA > LowerBound)) + { + /// [AT-PM] : Update SI every 1 minute ; 10/11/2012 + if((pUg31xx->bq27520Cmd.SIWindow >= 60) && (pUg31xx->bq27520Cmd.SISample > 0)) + { + NewSI = pUg31xx->bq27520Cmd.SIBuf/pUg31xx->bq27520Cmd.SISample; + NewSI = NewSI*7 + pUg31xx->bq27520Cmd.SINow*93; + NewSI = NewSI/100; + pUg31xx->bq27520Cmd.SINow = (_upi_s16_)NewSI; + pUg31xx->bq27520Cmd.SISample = -1; + pUg31xx->bq27520Cmd.SIBuf = 0; + pUg31xx->bq27520Cmd.SIWindow = 0; + } + else + { + pUg31xx->bq27520Cmd.SISample = pUg31xx->bq27520Cmd.SISample + 1; + pUg31xx->bq27520Cmd.SIWindow = pUg31xx->bq27520Cmd.SIWindow + pUg31xx->bq27520Cmd.DeltaSec; + + /// [AT-PM] : Ignore the first sample ; 10/11/2012 + if(pUg31xx->bq27520Cmd.SISample > 0) + { + pUg31xx->bq27520Cmd.SIBuf = pUg31xx->bq27520Cmd.SIBuf + pUg31xx->deviceInfo.AveCurrent_mA; + } + } + } + else + { + /// [AT-PM] : Ignore the last sample ; 10/11/2012 + if(pUg31xx->bq27520Cmd.SISample > 0) + { + NewSI = pUg31xx->bq27520Cmd.SIBuf/pUg31xx->bq27520Cmd.SISample; + NewSI = NewSI*7 + pUg31xx->bq27520Cmd.SINow*93; + NewSI = NewSI/100; + pUg31xx->bq27520Cmd.SINow = (_upi_s16_)NewSI; + } + pUg31xx->bq27520Cmd.SISample = -1; + pUg31xx->bq27520Cmd.SIBuf = 0; + pUg31xx->bq27520Cmd.SIWindow = 0; + } + + *pData = pUg31xx->bq27520Cmd.SINow; + return (UG_SUCCESS); +} + +/** + * @brief TI_Stte + * + * StandbyTimeToEmpty() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Stte(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ Stte; + + if(pUg31xx->bq27520Cmd.SINow >= 0) + { + *pData = 65535; + return (UG_SUCCESS); + } + + Stte = (_upi_s32_)pUg31xx->batteryInfo.NAC; + Stte = Stte*60*(-1)/pUg31xx->bq27520Cmd.SINow; + *pData = (_upi_u16_)Stte; + return (UG_SUCCESS); +} + +/** + * @brief TI_Mli + * + * MaxLoadCurrent() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Mli(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ NewMli; + + /// [AT-PM] : Set initial MLI ; 10/11/2012 + if(pUg31xx->bq27520Cmd.Mli == 0) + { + pUg31xx->bq27520Cmd.Mli = pUg31xx->bq27520Cmd.InitMaxLoadCurrent; + } + + /// [AT-PM] : Get the start charging SOC ; 10/11/2012 + if(pUg31xx->bq27520Cmd.Flags & UG_STD_CMD_FLAGS_DSG) + { + pUg31xx->bq27520Cmd.MliDsgSoc = (_upi_u8_)pUg31xx->batteryInfo.RSOC; + } + + /// [AT-PM] : MLI criteria - Current < MLI ; 10/11/2012 + if(pUg31xx->deviceInfo.AveCurrent_mA < pUg31xx->bq27520Cmd.Mli) + { + pUg31xx->bq27520Cmd.Mli = pUg31xx->deviceInfo.AveCurrent_mA; + } + + /// [AT-PM] : Reduce MLI at FC ; 10/11/2012 + if((pUg31xx->bq27520Cmd.Flags & UG_STD_CMD_FLAGS_FC) && (pUg31xx->bq27520Cmd.MliDsgSoc < 50)) + { + NewMli = (_upi_s32_)pUg31xx->bq27520Cmd.InitMaxLoadCurrent; + NewMli = NewMli + pUg31xx->bq27520Cmd.Mli; + NewMli = NewMli/2; + pUg31xx->bq27520Cmd.Mli = (_upi_s16_)NewMli; + } + + *pData = (_upi_u16_)pUg31xx->bq27520Cmd.Mli; + return (UG_SUCCESS); +} + +/** + * @brief TI_Stte + * + * MaxLoadTimeToEmpty() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Mltte(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ Mltte; + + if(pUg31xx->deviceInfo.AveCurrent_mA >= 0) + { + *pData = 65535; + return (UG_SUCCESS); + } + + Mltte = (_upi_s32_)pUg31xx->batteryInfo.NAC; + Mltte = Mltte*60*(-1)/pUg31xx->bq27520Cmd.Mli; + *pData = (_upi_u16_)Mltte; + return (UG_SUCCESS); +} + +/** + * @brief TI_AE + * + * AvailableEnergy() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_AE(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_u32_ AE; + + AE = (_upi_u32_)pUg31xx->batteryInfo.NAC; + AE = AE*pUg31xx->deviceInfo.voltage_mV/1000; + pUg31xx->bq27520Cmd.AE = (_upi_u16_)AE; + *pData = pUg31xx->bq27520Cmd.AE; + return (UG_SUCCESS); +} + +/** + * @brief TI_AP + * + * AveragePower() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_AP(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ AP; + + if((pUg31xx->deviceInfo.AveCurrent_mA == 0) || (pUg31xx->bq27520Cmd.APDsgTime == 0)) + { + pUg31xx->bq27520Cmd.AP = 0; + *pData = 0; + return (UG_SUCCESS); + } + + AP = (_upi_s32_)pUg31xx->batteryInfo.NAC; + AP = AP*pUg31xx->deviceInfo.voltage_mV/1000; + + /// [AT-PM] : Average discharging power ; 10/11/2012 + if(pUg31xx->deviceInfo.AveCurrent_mA > 0) + { + pUg31xx->bq27520Cmd.APStartDsgE = AP; + pUg31xx->bq27520Cmd.APDsgTime = 0; + + pUg31xx->bq27520Cmd.APChgTime = pUg31xx->bq27520Cmd.APChgTime + pUg31xx->bq27520Cmd.DeltaSec; + AP = AP - pUg31xx->bq27520Cmd.APStartChgE; + AP = AP*3600/pUg31xx->bq27520Cmd.APChgTime; + pUg31xx->bq27520Cmd.AP = (_upi_s16_)AP; + } + + /// [AT-PM] : Average charging power ; 10/11/2012 + if(pUg31xx->deviceInfo.AveCurrent_mA < 0) + { + pUg31xx->bq27520Cmd.APStartChgE = AP; + pUg31xx->bq27520Cmd.APChgTime = 0; + + pUg31xx->bq27520Cmd.APDsgTime = pUg31xx->bq27520Cmd.APDsgTime + pUg31xx->bq27520Cmd.DeltaSec; + AP = AP - pUg31xx->bq27520Cmd.APStartDsgE; + AP = AP*3600/pUg31xx->bq27520Cmd.APDsgTime; + pUg31xx->bq27520Cmd.AP = (_upi_s16_)AP; + } + + *pData = (_upi_u16_)pUg31xx->bq27520Cmd.AP; + return (UG_SUCCESS); +} + +/** + * @brief TI_Ttecp + * + * TimeToEmptyAtConstantPower() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Ttecp(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_s32_ Ttecp; + + if(pUg31xx->bq27520Cmd.AP >= 0) + { + *pData = 65535; + return (UG_SUCCESS); + } + + Ttecp = (_upi_s32_)pUg31xx->bq27520Cmd.AE; + Ttecp = Ttecp*60*(-1)/pUg31xx->bq27520Cmd.AP; + *pData = (_upi_u16_)Ttecp; + return (UG_SUCCESS); +} + +/** + * @brief TI_Soh + * + * StateOfHealth() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Soh(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + _upi_u32_ Soh; + + Soh = (_upi_u32_)pUg31xx->batteryInfo.LMD; + Soh = Soh*100/pUg31xx->bq27520Cmd.Dcap; + + Soh = Soh & UG_STD_CMD_SOH_VALUE_MASK; + Soh = Soh | UG_STD_CMD_SOH_STATUS_READY; + *pData = (_upi_u16_)Soh; + return (UG_SUCCESS); +} + +/** + * @brief TI_CC + * + * CycleCount() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_CC(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + if(pUg31xx->deviceInfo.AveCurrent_mA < 0) + { + pUg31xx->bq27520Cmd.CCBuf = pUg31xx->bq27520Cmd.CCBuf + pUg31xx->bq27520Cmd.CCLastNac - pUg31xx->batteryInfo.NAC; + } + pUg31xx->bq27520Cmd.CCLastNac = pUg31xx->batteryInfo.NAC; + + if(pUg31xx->bq27520Cmd.CCBuf >= pUg31xx->bq27520Cmd.CCThreshold) + { + pUg31xx->bq27520Cmd.CC = pUg31xx->bq27520Cmd.CC + 1; + pUg31xx->bq27520Cmd.CCBuf = pUg31xx->bq27520Cmd.CCBuf - pUg31xx->bq27520Cmd.CCThreshold; + } + + *pData = pUg31xx->bq27520Cmd.CC; + return (UG_SUCCESS); +} + +/** + * @brief TI_Soc + * + * StateOfCharge() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Soc(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->batteryInfo.RSOC; + return (UG_SUCCESS); +} + +/** + * @brief TI_Nic + * + * NormalizedImpedanceCal() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Nic(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = 0; + return (UG_SUCCESS); +} + +/** + * @brief TI_Icr + * + * InstantaneousCurrentReading() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Icr(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->deviceInfo.current_mA; + return (UG_SUCCESS); +} + +/** + * @brief TI_Dli + * + * DataLogIndex() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Dli(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->bq27520Cmd.Dli; + return (UG_SUCCESS); +} + +/** + * @brief TI_Dlb + * + * DataLogBuffer() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Dlb(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->bq27520Cmd.Dlb; + return (UG_SUCCESS); +} + +/** + * @brief TI_Itemp + * + * InternalTemperature() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Itemp(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->deviceInfo.IT; + return (UG_SUCCESS); +} + +/** + * @brief TI_Opcfg + * + * OperationConfiguration() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Opcfg(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = (_upi_u16_)pUg31xx->bq27520Cmd.Opcfg; + return (UG_SUCCESS); +} + +/** + * @brief TI_Dcap + * + * DesignCapacity() command + * + * @para pData address of data + * @return GGSTATUS + */ +GGSTATUS TI_Dcap(struct ug31xx_data *pUg31xx, _upi_u16_ *pData) +{ + *pData = pUg31xx->bq27520Cmd.Dcap; + return (UG_SUCCESS); +} + +typedef GGSTATUS (*TIBq27520FuncPtr)(struct ug31xx_data *pUg31xx, _upi_u16_ *pData); +typedef struct TIBq27520FuncTableST { + TIBq27520FuncPtr pFunc; + _upi_u8_ CmdCode; +} TIBq27520FuncTableType; + + +TIBq27520FuncTableType TI_Command[] = { + { TI_Cntl, UG_STD_CMD_CNTL, }, + { TI_AR, UG_STD_CMD_AR, }, + { TI_Artte, UG_STD_CMD_ARTTE, }, + { TI_Temp, UG_STD_CMD_TEMP, }, + { TI_Volt, UG_STD_CMD_VOLT, }, + { TI_Flags, UG_STD_CMD_FLAGS, }, + { TI_Nac, UG_STD_CMD_NAC, }, + { TI_Fac, UG_STD_CMD_FAC, }, + { TI_RM, UG_STD_CMD_RM, }, + { TI_Fcc, UG_STD_CMD_FCC, }, + { TI_AI, UG_STD_CMD_AI, }, + { TI_Tte, UG_STD_CMD_TTE, }, + { TI_Ttf, UG_STD_CMD_TTF, }, + { TI_SI, UG_STD_CMD_SI, }, + { TI_Stte, UG_STD_CMD_STTE, }, + { TI_Mli, UG_STD_CMD_MLI, }, + { TI_Mltte, UG_STD_CMD_MLTTE, }, + { TI_AE, UG_STD_CMD_AE, }, + { TI_AP, UG_STD_CMD_AP, }, + { TI_Ttecp, UG_STD_CMD_TTECP, }, + { TI_Soh, UG_STD_CMD_SOH, }, + { TI_CC, UG_STD_CMD_CC, }, + { TI_Soc, UG_STD_CMD_SOC, }, + { TI_Nic, UG_STD_CMD_NIC, }, + { TI_Icr, UG_STD_CMD_ICR, }, + { TI_Dli, UG_STD_CMD_DLI, }, + { TI_Dlb, UG_STD_CMD_DLB, }, + { TI_Itemp, UG_STD_CMD_ITEMP, }, + { TI_Opcfg, UG_STD_CMD_OPCFG, }, + { TI_Dcap, UG_EXT_CMD_DCAP, }, +}; + +/** + * @brief upiGG_FetchDataCommand + * + * Read the gas gauge status following TI bq27520's interface + * + * @para CommandCode command code + * @para pData address of returned data + * @return GGSTATUS + */ +GGSTATUS upiGG_FetchDataCommand(char *pObj, _upi_u8_ CommandCode, _upi_u16_ *pData) +{ + GGSTATUS Rtn; + int TotalCmd; + GG_DEVICE_INFO DevInfo; + GG_CAPACITY CapData; + _upi_u32_ DeltaT; + int CmdIdx; + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + Rtn = upiGG_ReadDeviceInfo(pObj, &DevInfo); + if(Rtn != UG_READ_DEVICE_INFO_SUCCESS) + { + return (Rtn); + } + + DeltaT = pUg31xx->measData.deltaTime; + if(DeltaT >= 5000000) + { + upiGG_ReadCapacity(pObj, &CapData); + } + + DeltaT = GetTickCount(); + DeltaT = DeltaT - pUg31xx->bq27520Cmd.LastTime; + pUg31xx->bq27520Cmd.LastTime = GetTickCount(); + pUg31xx->bq27520Cmd.DeltaSec = (_upi_u16_)(DeltaT/1000); + + Rtn = UG_SUCCESS; + TotalCmd = sizeof(TI_Command)/sizeof(TIBq27520FuncTableType); + CmdIdx = 0; + while(1) + { + if(TI_Command[CmdIdx].CmdCode == CommandCode) + { + Rtn = (*TI_Command[CmdIdx].pFunc)(pUg31xx, pData); + break; + } + + CmdIdx = CmdIdx + 1; + if(CmdIdx >= TotalCmd) + { + Rtn = UG_TI_CMD_OVERFLOW; + } + } + + return (Rtn); +} + +/** + * @brief upiGG_FetchDataParameter + * + * Set the parameter for bq27520 like command + * + * @para data parameters of GG_FETCH_DATA_PARA_TYPE + * @return GGSTATUS + */ +GGSTATUS upiGG_FetchDataParameter(char *pObj, GG_FETCH_DATA_PARA_TYPE data) +{ + GGSTATUS Rtn; + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + Rtn = UG_SUCCESS; + + pUg31xx->bq27520Cmd.FCSet = data.FCSet; + pUg31xx->bq27520Cmd.FCClear = data.FCClear; + pUg31xx->bq27520Cmd.Soc1Set = data.Soc1Set; + pUg31xx->bq27520Cmd.Soc1Clear = data.Soc1Clear; + pUg31xx->bq27520Cmd.InitSI = data.InitSI; + pUg31xx->bq27520Cmd.InitMaxLoadCurrent = data.InitMaxLoadCurrent; + pUg31xx->bq27520Cmd.CCThreshold = data.CCThreshold; + pUg31xx->bq27520Cmd.Opcfg = data.Opcfg; + pUg31xx->bq27520Cmd.Dcap = data.Dcap; + return (Rtn); +} + +#endif ///< end of ENABLE_BQ27520_SW_CMD + +/** + * @brief upiGG_DumpRegister + * + * Dump whole register value + * + * @para pBuf address of register value buffer + * @return data size + */ +_upi_u16_ upiGG_DumpRegister(char *pObj, _upi_u8_ * pBuf) +{ + _upi_u16_ idx; + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + idx = 0; + memcpy(pBuf + idx, pUg31xx->otpData.otp1, OTP1_SIZE); + idx = idx + OTP1_SIZE; + memcpy(pBuf + idx, pUg31xx->otpData.otp2, OTP2_SIZE); + idx = idx + OTP2_SIZE; + memcpy(pBuf + idx, pUg31xx->otpData.otp3, OTP3_SIZE); + idx = idx + OTP3_SIZE; + memcpy(pBuf + idx, &pUg31xx->userReg, sizeof(GG_USER_REG)); + idx = idx + sizeof(GG_USER_REG); + memcpy(pBuf + idx, &pUg31xx->user2Reg, sizeof(GG_USER2_REG)); + idx = idx + sizeof(GG_USER2_REG); + return (idx); +} + +/** + * @brief upiGG_DumpCellTable + * + * Dump cell NAC table + * + * @para pTable address of cell table + * @return _UPI_NULL_ + */ +void upiGG_DumpCellTable(char *pObj, CELL_TABLE *pTable) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + memcpy(pTable, &pUg31xx->cellTable, sizeof(CELL_TABLE)); +} + +/** + * @brief upiGG_UnInitial + * + * Un-initialize uG31xx + * + * @para pObj address of memory buffer allocated for uG31xx + * @return GGSTATUS + */ +GGSTATUS upiGG_UnInitial(char **pObj) +{ + struct ug31xx_data *pUg31xx; + pUg31xx = (struct ug31xx_data *)(*pObj); + + UG31_LOGE("[%s]***** upiGG_UnInitial() to free memory ***** \n", __func__); + + pUg31xx->backupData.backupDataIdx = BACKUP_MAX_LOG_SUSPEND_DATA; + while(pUg31xx->backupData.backupDataIdx) + { + pUg31xx->backupData.backupDataIdx = pUg31xx->backupData.backupDataIdx - 1; + kfree(pUg31xx->backupData.logData[pUg31xx->backupData.backupDataIdx]); + } + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + free(*pObj); + #else ///< else of uG31xx_BOOT_LOADER + kfree(*pObj); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + free(*pObj); + #endif ///< end of defined(uG31xx_OS_ANDROID) + return (UG_SUCCESS); +} + +/** + * @brief upiGG_DumpParameter + * + * Dump all parameter setting + * + * @para pTable address of cell parameter + * @return _UPI_NULL_ + */ +void upiGG_DumpParameter(char *pObj, CELL_PARAMETER *pTable) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + memcpy(pTable, &pUg31xx->cellParameter, sizeof(CELL_PARAMETER)); + + // memcpy(&pTable->CELL_NAC_TABLE, &pUg31xx->realData, sizeof(GG_REAL_DATA)); +} + +/** + * @brief upiGG_FetchDebugData + * + * Fetch debug information data + * + * @para pObj address of memory buffer + * @para data address of GG_FETCH_CAP_DATA_TYPE + * @return _UPI_NULL_ + */ +void upiGG_FetchDebugData(char *pObj, GG_FETCH_DEBUG_DATA_TYPE *data) +{ + struct ug31xx_data *pUg31xx; + + pUg31xx = (struct ug31xx_data *)pObj; + + data->versionMain = UG31XX_API_MAIN_VERSION; + data->versionOtp = UG31XX_API_OTP_VERSION; + data->versionSub = UG31XX_API_SUB_VERSION; + + data->capDelta = pUg31xx->measData.stepCap; + data->capDsgCharge = pUg31xx->capData.dsgCharge; + data->capDsgChargeStart = pUg31xx->capData.dsgChargeStart; + data->capDsgChargeTime = pUg31xx->capData.dsgChargeTime; + data->capPreDsgCharge = pUg31xx->capData.preDsgCharge; + data->capSelfHour = pUg31xx->capData.selfDsgHour; + data->capSelfMilliSec = pUg31xx->capData.selfDsgMilliSec; + data->capSelfMin = pUg31xx->capData.selfDsgMin; + data->capSelfSec = pUg31xx->capData.selfDsgSec; + data->capStatus = pUg31xx->capData.status; + data->capTableUpdateIdx = pUg31xx->capData.tableUpdateIdx; + data->capTPTime = pUg31xx->capData.tpTime; + + data->measAdc1ConvertTime = pUg31xx->measData.adc1ConvertTime; + data->measAdc1Gain = pUg31xx->measData.adc1Gain; + data->measAdc1Offset = pUg31xx->measData.adc1Offset; + data->measAdc2Gain = pUg31xx->measData.adc2Gain; + data->measAdc2Offset = pUg31xx->measData.adc2Offset; + data->measCCOffset = pUg31xx->measData.ccOffset; + data->measCharge = pUg31xx->measData.codeCharge; + data->measCodeBat1 = pUg31xx->measData.codeBat1; + data->measCodeCurrent = pUg31xx->measData.codeCurrent; + data->measCodeET = pUg31xx->measData.codeExtTemperature; + data->measCodeIT = pUg31xx->measData.codeIntTemperature; + data->measLastCounter = pUg31xx->measData.lastCounter; + data->measLastDeltaQ = pUg31xx->measData.lastDeltaCap; + data->measLastTimeTick = pUg31xx->measData.lastTimeTick; +} + +/** + * @brief upiGG_DebugSwitch + * + * Enable/disable debug information to UART + * + * @para Enable set _UPI_TRUE_ to enable it + * @return NULL + */ +void upiGG_DebugSwitch(_upi_bool_ enable) +{ + Ug31DebugEnable = enable; +} + +/** + * @brief upiGG_ForceTaper + * + * Force taper condition reached + * + * @para pObj address of memory buffer + * @para charger_full 1 if charger detects full + * @para dc_in_before 1 if dc in before suspend mode + * @para dc_in_now 1 if dc in after suspend mode + * @return NULL + */ +void upiGG_ForceTaper(char *pObj, int charger_full, int dc_in_before, int dc_in_now) +{ + struct ug31xx_data *pUg31xx; + _meas_s16_ now_step_cap; + _meas_s16_ now_current; + _meas_u16_ now_voltage; + _meas_u32_ now_delta_time; + _upi_u8_ cnt; + _upi_s32_ tmp32; + + pUg31xx = (struct ug31xx_data *)pObj; + pUg31xx->capData.ggbTable = &pUg31xx->cellTable; + pUg31xx->capData.ggbParameter = &pUg31xx->cellParameter; + pUg31xx->capData.measurement = &pUg31xx->measData; + pUg31xx->capData.status = pUg31xx->capData.status | 0x0100; + + if(dc_in_before == 0) + { + UG31_LOGI("[%s]: Enter suspend without charger -> no force taper\n", __func__); + return; + } + + tmp32 = dsg_charge_before_suspend - delta_cap_during_suspend; + if(dc_in_now == 0) + { + now_current = pUg31xx->measData.curr; + now_current = now_current/10; + now_voltage = pUg31xx->measData.bat1Voltage; + now_voltage = now_voltage - now_current; + + UG31_LOGI("[%s]: No dc in now (%d)\n", __func__, now_voltage); + tmp32 = tmp32*100; + if((pUg31xx->capData.status & 0x0000000c) == 0x00000008) ///< [AT-PM] : Check current status is dischargign ; 10/11/2013 + { + if((wakeup_predict_rsoc < 95) && + (tmp32 > pUg31xx->cellParameter.ILMD) && + (now_voltage < pUg31xx->cellParameter.TPVoltage)) + { + UG31_LOGI("[%s]: Predicted RSOC < 95 and charged capacity is not enough (%d < %d) and voltage is low (%d < %d ) in discharging -> no force taper\n", + __func__, delta_cap_during_suspend, dsg_charge_before_suspend, now_voltage, pUg31xx->cellParameter.TPVoltage); + return; + } + } + else + { + if((wakeup_predict_rsoc < 98) && (tmp32 > pUg31xx->cellParameter.ILMD)) + { + UG31_LOGI("[%s]: Predicted RSOC (%d) < 98 and charged capacity is not enough (%d < %d) -> no force taper\n", + __func__, wakeup_predict_rsoc, delta_cap_during_suspend, dsg_charge_before_suspend); + return; + } + } + } + else + { + UG31_LOGI("[%s]: DC in now\n", __func__); + if(charger_full == 0) + { + UG31_LOGI("[%s]: No charger detect full event -> no force taper\n", __func__); + return; + } + if(wakeup_predict_rsoc < 90) + { + UG31_LOGI("[%s]: Predicted RSOC (%d) < 90 -> no force taper\n", __func__, wakeup_predict_rsoc); + return; + } + } + + now_step_cap = pUg31xx->measData.stepCap; + now_current = pUg31xx->measData.curr; + now_voltage = pUg31xx->measData.bat1Voltage; + now_delta_time = pUg31xx->measData.deltaTime; + + UG31_LOGI("[%s]: Force to taper START\n", __func__); + + cnt = 100; + while(cnt) + { + /// [AT-PM] : Enter charging mode ; 08/14/2013 + pUg31xx->measData.stepCap = 0; + pUg31xx->measData.deltaTime = 0; + pUg31xx->measData.curr = (_meas_s16_)pUg31xx->cellParameter.TPCurrent - 1; + + UpiReadCapacity(&pUg31xx->capData); + pUg31xx->capData.tableUpdateDelayCnt = 1; + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + + /// [AT-PM] : Force to TP ; 08/14/2013 + pUg31xx->measData.bat1Voltage = (_meas_u16_)pUg31xx->cellParameter.TPVoltage + 1; + pUg31xx->capData.tpTime = (_cap_u32_)pUg31xx->cellParameter.TPTime + 1; + pUg31xx->capData.tpTime = pUg31xx->capData.tpTime*1000; + + UpiReadCapacity(&pUg31xx->capData); + pUg31xx->capData.tableUpdateDelayCnt = 1; + pUg31xx->capData.rm = pUg31xx->capData.fcc; + pUg31xx->capData.rsoc = 100; + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + + /// [AT-PM] : Recover to initial state ; 08/14/2013 + pUg31xx->measData.curr = now_current; + pUg31xx->measData.bat1Voltage = now_voltage; + pUg31xx->measData.deltaTime = now_delta_time; + + UpiReadCapacity(&pUg31xx->capData); + pUg31xx->capData.tableUpdateDelayCnt = 1; + pUg31xx->batteryInfo.NAC = (_upi_u16_)pUg31xx->capData.rm; + pUg31xx->batteryInfo.LMD = (_upi_u16_)pUg31xx->capData.fcc; + pUg31xx->batteryInfo.RSOC = (_upi_u16_)pUg31xx->capData.rsoc; + + UG31_LOGI("[%s]: Force to taper loop %d -> %d / %d = %d\n", __func__, + cnt, pUg31xx->batteryInfo.NAC, pUg31xx->batteryInfo.LMD, pUg31xx->batteryInfo.RSOC); + if(pUg31xx->capData.rsoc >= 100) + { + break; + } + + cnt = cnt - 1; + } + + pUg31xx->measData.stepCap = now_step_cap; + + UG31_LOGI("[%s]: Force to taper END (%d / %d = %d)\n", __func__, + pUg31xx->batteryInfo.NAC, pUg31xx->batteryInfo.LMD, pUg31xx->batteryInfo.RSOC); +} + +/// =========================================== +/// End of uG31xx_API.cpp +/// =========================================== + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.h new file mode 100755 index 00000000..c601852c --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API.h @@ -0,0 +1,521 @@ +/// =========================================== +/// uG31xx_API.h +/// =========================================== + +#ifndef _UG31XXAPI_H_ +#define _UG31XXAPI_H_ + +#include "uG31xx_Platform.h" + +#if defined (uG31xx_OS_WINDOWS) + + #include + +#endif + +#include "global.h" +#include "uG31xx.h" + +#if defined (uG31xx_OS_WINDOWS) + + #include "../../uG31xx_I2C_DLL/uG3100Dll/uG31xx_I2C.h" + #include + + #ifdef DEBUG_LOG + + #include "wDebug.h" + + #endif + +#elif defined (uG31xx_OS_ANDROID) + + #ifdef uG31xx_BOOT_LOADER + + #include + #include + + #include "ug31xx_boot_i2c.h" + + #else ///< else of uG31xx_BOOT_LOADER + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "ug31xx_i2c.h" + + #endif ///< end of uG31xx_BOOT_LOADER + +#endif + +#include "typeDefine.h" +#include "uG31xx_Reg_Def.h" +#include "uG31xx_API_Otp.h" +#include "uG31xx_API_System.h" +#include "uG31xx_API_Measurement.h" +#include "uG31xx_API_Capacity.h" +#include "uG31xx_API_Backup.h" + +#define UG31XX_API_RELEASE_VERSION (20131108) + +#define UG31XX_API_MAIN_VERSION (13) +#define UG31XX_API_OTP_VERSION ((UG31XX_OTP_VERSION_MAIN << 16) | UG31XX_OTP_VERSION_SUB) +#define UG31XX_API_SUB_VERSION ((UG31XX_CAP_VERSION << 16) | (UG31XX_MEAS_VERSION << 8) | UG31XX_SYSTEM_VERSION) + +#define UG31XX_I2C_HIGH_SPEED_MODE (_UPI_FALSE_) +#define UG31XX_I2C_TEM_BITS_MODE (_UPI_FALSE_) + +#define UG31XX_MAX_TEMPERATURE_BEFORE_READY (395) +#define UG31XX_MIN_TEMPERATURE_BEFORE_READY (105) + +#ifdef UG31XX_DEBUG_ENABLE + + #if defined(uG31xx_OS_ANDROID) + + #ifdef uG31xx_BOOT_LOADER + + #define __func__ + + #define UG31_LOGE(...) + #define UG31_LOGI(...) + #define UG31_LOGD(...) + #define UG31_LOGV(...) + + extern int ug31_dprintk(int level, const char *fmt, ...); + + #else ///< else of uG31xx_BOOT_LOADER + + #define LOG_NORMAL (0) + #define LOG_ERROR (1) + #define LOG_DATA (2) + #define LOG_VERBOSE (3) + + #define UG31_TAG "UG31" + #define UG31_LOGE(...) ug31_printk(LOG_ERROR, "<"UG31_TAG"/E>" __VA_ARGS__); + #define UG31_LOGI(...) ug31_printk(LOG_NORMAL, "<"UG31_TAG"/I>" __VA_ARGS__); + #define UG31_LOGD(...) ug31_printk(LOG_DATA, "<"UG31_TAG"/D>" __VA_ARGS__); + #define UG31_LOGV(...) ug31_printk(LOG_VERBOSE, "<"UG31_TAG"/V>" __VA_ARGS__); + + extern int ug31_printk(int level, const char *fmt, ...); + + #endif ///< end of uG31xx_BOOT_LOADER + + #endif ///< end of defined(uG31xx_OS_ANDROID) + + #if defined (uG31xx_OS_WINDOWS) + + #define DEBUG_FILE (_T("uG3105")) + #define __func__ (_T(__FUNCTION__)) + + #define UG31_LOGE(...) wDebug::LOGE(DEBUG_FILE, 0, _T(__VA_ARGS__)); + #define UG31_LOGI(...) wDebug::LOGE(DEBUG_FILE, 0, _T(__VA_ARGS__)); + #define UG31_LOGD(...) wDebug::LOGE(DEBUG_FILE, 0, _T(__VA_ARGS__)); + #define UG31_LOGV(...) wDebug::LOGE(DEBUG_FILE, 0, _T(__VA_ARGS__)); + + #endif ///< end of defined (uG31xx_OS_WINDOWS) + +#else ///< else of UG31XX_DEBUG_ENABLE + + #define UG31_LOGE(...) + #define UG31_LOGI(...) + #define UG31_LOGD(...) + #define UG31_LOGV(...) + +#endif ///< end of UG31XX_DEBUG_ENABLE + +#if defined(uG31xx_OS_ANDROID) + + extern _upi_u32_ GetTickCount(void); + extern _upi_u32_ GetSysTickCount(void); + +#endif + +/* data struct */ +typedef enum _GGSTATUS{ + UG_SUCCESS = 0x00, + UG_FAIL = 0x01, + UG_NOT_DEF = 0x02, + UG_INIT_OCV_FAIL = 0x03, + UG_READ_GGB_FAIL = 0x04, + UG_ACTIVE_FAIL = 0x05, + UG_INIT_SUCCESS = 0x06, + UG_OTP_ISEMPTY = 0x07, + UG_OTP_PRODUCT_DISMATCH = 0x08, + + UG_I2C_INIT_FAIL = 0x10, + UG_I2C_READ_SUCCESS = 0x11, + UG_I2C_READ_FAIL = 0x12, + UG_I2C_WRITE_SUCCESS = 0x13, + UG_I2C_WRITE_FAIL = 0x14, + + UG_READ_REG_SUCCESS = 0x20, + UG_READ_REG_FAIL = 0x21, + + UG_READ_DEVICE_INFO_SUCCESS = 0x22, + UG_READ_DEVICE_INFO_FAIL = 0x23, + UG_READ_DEVICE_ALARM_SUCCESS = 0x24, + UG_READ_DEVICE_ALARM_FAIL = 0x25, + UG_READ_DEVICE_RID_SUCCESS = 0x26, + UG_READ_DEVICE_RID_FAIL = 0x27, + UG_READ_ADC_FAIL = 0x28, //new add for filter ADC Error Code + + UG_TI_CMD_OVERFLOW = 0x30, + + UG_MEAS_FAIL = 0x40, + UG_MEAS_FAIL_BATTERY_REMOVED = 0x41, + UG_MEAS_FAIL_ADC_ABNORMAL = 0x42, + UG_MEAS_FAIL_NTC_SHORT = 0x43, + + UG_CAP_DATA_READY = 0x50, + UG_CAP_DATA_NOT_READY = 0x51, +}GGSTATUS; + +/* + GGSTATUS upiGG_Initial + Description: Initial and active uG31xx function + Input: .GGB(gas gauge battery) setting filename, need include complete path + Output: UG_INIT_SUCCESS -> initial uG31xx success + UG_READ_GGB_FAIL -> read GGB file fail + UG_INIT_I2C_FAIL -> initial I2C to open HID fail + UG_ACTIVE_FAIL -> active uG31xx fail +*/ +#if defined (uG31xx_OS_WINDOWS) + + EXPORTS GGSTATUS upiGG_Initial(char **pObj, const wchar_t* GGBFilename, const wchar_t* OtpFileName, const wchar_t* BackupFileName, char reset, unsigned char MaxETFixCnt); + +#endif + +#if defined(uG31xx_OS_ANDROID) + + GGSTATUS upiGG_Initial(char **pObj, GGBX_FILE_HEADER *pGGBXBuf, char reset, unsigned char MaxETFixCnt); + +#endif + +/* + GGSTATUS upiGG_CountInitQmax + Description: + Input: None + Output: None +*/ +//EXPORTS void upiGG_CountInitQmax(void); + +/* + GGSTATUS upiGG_ReadDevieRegister + Description: Read GG_USER_REG from device to global variable and output + Input: Pointer of sturct GG_USER_REG + Output: UG_READ_REG_SUCCESS -> read success + UG_READ_REG_FAIL -> read fail +*/ +EXPORTS GGSTATUS upiGG_ReadAllRegister(char *pObj,GG_USER_REG* pExtUserReg, GG_USER2_REG* pExtUserReg2); + +/* + GGSTATUS upiGG_ReadDeviceInfo + Description: Read GG_USER_REG from device and calculate GG_DEVICE_INFO, then write to global variable and output + Input: Pointer of struct GG_DEVICE_INFO + Output: UG_READ_DEVICE_INFO_SUCCESS -> calculate derive information sucess + UG_READ_DEVICE_INFO_FAIL -> calculate derive information fail +*/ +EXPORTS GGSTATUS upiGG_ReadDeviceInfo(char *pObj,GG_DEVICE_INFO* pExtDeviceInfo); + +/* GGSTATUS upiGG_ReadCapacity + Description: + Input: + Output: None +*/ +EXPORTS void upiGG_ReadCapacity(char *pObj,GG_CAPACITY *pExtCapacity); + +/** + * @brief upiGG_GetAlarmStatus + * + * Get alarm status + * + * @para pAlarmStatus address of alarm status + * @return UG_READ_DEVICE_ALARM_SUCCESS if success + */ +EXPORTS GGSTATUS upiGG_GetAlarmStatus(char *pObj, _upi_u8_ *pAlarmStatus); + +/* +new add function for System suspend & wakeup + +*/ +EXPORTS GGSTATUS upiGG_PreSuspend(char *pObj); +EXPORTS GGSTATUS upiGG_Wakeup(char *pObj, int dc_in_before); + +/** + * @brief upiGG_DumpRegister + * + * Dump whole register value + * + * @para pBuf address of register value buffer + * @return data size + */ +EXPORTS _upi_u16_ upiGG_DumpRegister(char *pObj, _upi_u8_ *pBuf); + +/** + * @brief upiGG_DumpCellTable + * + * Dump cell NAC table + * + * @para pTable address of cell table + * @return _UPI_NULL_ + */ +EXPORTS void upiGG_DumpCellTable(char *pObj, CELL_TABLE *pTable); +EXPORTS GGSTATUS upiGG_UnInitial(char **pObj); +EXPORTS void upiGG_DumpParameter(char *pObj, CELL_PARAMETER *pTable); + +#define upiGG_PrePowerOff (upiGG_PreSuspend) + +#ifdef ENABLE_BQ27520_SW_CMD + +/** + * @brief upiGG_AccessMeasurementParameter + * + * Access measurement parameter + * + * @para read set _UPI_TRUE_ to read data from API + * @para pMeasPara pointer of GG_MEAS_PARA_TYPE + * @return GGSTATUS + */ +EXPORTS GGSTATUS upiGG_AccessMeasurementParameter(char *pObj, _upi_bool_ read, GG_MEAS_PARA_TYPE *pMeasPara); + +#define UG_STD_CMD_CNTL (0x00) + #define UG_STD_CMD_CNTL_CONTROL_STATUS (0x0000) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_DLOGEN (1<<15) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_FAS (1<<14) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_SS (1<<13) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_CSV (1<<12) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_CCA (1<<11) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_BCA (1<<10) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_OCVCMDCOMP (1<<9) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_OCVFAIL (1<<8) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_INITCOMP (1<<7) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_HIBERNATE (1<<6) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_SNOOZE (1<<5) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_SLEEP (1<<4) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_LDMD (1<<3) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_RUP_DIS (1<<2) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_VOK (1<<1) + #define UG_STD_CMD_CNTL_CONTROL_STATUS_QEN (1<<0) + #define UG_STD_CMD_CNTL_DEVICE_TYPE (0x0001) + #define UG_STD_CMD_CNTL_FW_VERSION (0x0002) + #define UG_STD_CMD_CNTL_PREV_MACWRITE (0x0007) + #define UG_STD_CMD_CNTL_CHEM_ID (0x0008) + #define UG_STD_CMD_CNTL_OCV_CMD (0x000C) ///< [AT-PM] : Not implemented ; 10/11/2012 + #define UG_STD_CMD_CNTL_BAT_INSERT (0x000D) + #define UG_STD_CMD_CNTL_BAT_REMOVE (0x000E) + #define UG_STD_CMD_CNTL_SET_HIBERNATE (0x0011) + #define UG_STD_CMD_CNTL_CLEAR_HIBERNATE (0x0012) + #define UG_STD_CMD_CNTL_SET_SLEEP_PLUS (0x0013) + #define UG_STD_CMD_CNTL_CLEAR_SLEEP_PLUS (0x0014) + #define UG_STD_CMD_CNTL_FACTORY_RESTORE (0x0015) + #define UG_STD_CMD_CNTL_ENABLE_DLOG (0x0018) + #define UG_STD_CMD_CNTL_DISABLE_DLOG (0x0019) + #define UG_STD_CMD_CNTL_DF_VERSION (0x001F) + #define UG_STD_CMD_CNTL_SEALED (0x0020) + #define UG_STD_CMD_CNTL_RESET (0x0041) +#define UG_STD_CMD_AR (0x02) +#define UG_STD_CMD_ARTTE (0x04) +#define UG_STD_CMD_TEMP (0x06) +#define UG_STD_CMD_VOLT (0x08) +#define UG_STD_CMD_FLAGS (0x0A) + #define UG_STD_CMD_FLAGS_OTC (1<<15) + #define UG_STD_CMD_FLAGS_OTD (1<<14) + #define UG_STD_CMD_FLAGS_RSVD13 (1<<13) + #define UG_STD_CMD_FLAGS_RSVD12 (1<<12) + #define UG_STD_CMD_FLAGS_CHG_INH (1<<11) + #define UG_STD_CMD_FLAGS_XCHG (1<<10) + #define UG_STD_CMD_FLAGS_FC (1<<9) + #define UG_STD_CMD_FLAGS_CHG (1<<8) + #define UG_STD_CMD_FLAGS_RSVD7 (1<<7) + #define UG_STD_CMD_FLAGS_RSVD6 (1<<6) + #define UG_STD_CMD_FLAGS_OCV_GD (1<<5) + #define UG_STD_CMD_FLAGS_WAIT_ID (1<<4) + #define UG_STD_CMD_FLAGS_BAT_DET (1<<3) + #define UG_STD_CMD_FLAGS_SOC1 (1<<2) + #define UG_STD_CMD_FLAGS_SYSDOWN (1<<1) + #define UG_STD_CMD_FLAGS_DSG (1<<0) +#define UG_STD_CMD_NAC (0x0C) +#define UG_STD_CMD_FAC (0x0E) +#define UG_STD_CMD_RM (0x10) +#define UG_STD_CMD_FCC (0x12) +#define UG_STD_CMD_AI (0x14) +#define UG_STD_CMD_TTE (0x16) +#define UG_STD_CMD_TTF (0x18) +#define UG_STD_CMD_SI (0x1A) +#define UG_STD_CMD_STTE (0x1C) +#define UG_STD_CMD_MLI (0x1E) +#define UG_STD_CMD_MLTTE (0x20) +#define UG_STD_CMD_AE (0x22) +#define UG_STD_CMD_AP (0x24) +#define UG_STD_CMD_TTECP (0x26) +#define UG_STD_CMD_SOH (0x28) + #define UG_STD_CMD_SOH_VALUE_MASK (0x00FF) + #define UG_STD_CMD_SOH_STATUS_MASK (0xFF00) + #define UG_STD_CMD_SOH_STATUS_NOT_VALID (0x0000) + #define UG_STD_CMD_SOH_STATUS_INSTANT_READY (0x0100) + #define UG_STD_CMD_SOH_STATUS_INITIAL_READY (0x0200) + #define UG_STD_CMD_SOH_STATUS_READY (0x0300) +#define UG_STD_CMD_CC (0x2A) +#define UG_STD_CMD_SOC (0x2C) +#define UG_STD_CMD_NIC (0x2E) ///< [AT-PM] : Not implemented ; 10/11/2012 +#define UG_STD_CMD_ICR (0x30) +#define UG_STD_CMD_DLI (0x32) +#define UG_STD_CMD_DLB (0x34) +#define UG_STD_CMD_ITEMP (0x36) +#define UG_STD_CMD_OPCFG (0x3A) + #define UG_STD_CMD_OPCFG_RESCAP (1<<31) + #define UG_STD_CMD_OPCFG_BATG_OVR (1<<30) + #define UG_STD_CMD_OPCFG_INT_BERM (1<<29) + #define UG_STD_CMD_OPCFG_PFC_CFG1 (1<<28) + #define UG_STD_CMD_OPCFG_PFC_CFG0 (1<<27) + #define UG_STD_CMD_OPCFG_IWAKE (1<<26) + #define UG_STD_CMD_OPCFG_RSNS1 (1<<25) + #define UG_STD_CMD_OPCFG_RSNS0 (1<<24) + #define UG_STD_CMD_OPCFG_INT_FOCV (1<<23) + #define UG_STD_CMD_OPCFG_IDSELEN (1<<22) + #define UG_STD_CMD_OPCFG_SLEEP (1<<21) + #define UG_STD_CMD_OPCFG_RMFCC (1<<20) + #define UG_STD_CMD_OPCFG_SOCI_POL (1<<19) + #define UG_STD_CMD_OPCFG_BATG_POL (1<<18) + #define UG_STD_CMD_OPCFG_BATL_POL (1<<17) + #define UG_STD_CMD_OPCFG_TEMPS (1<<16) + #define UG_STD_CMD_OPCFG_WRTEMP (1<<15) + #define UG_STD_CMD_OPCFG_BIE (1<<14) + #define UG_STD_CMD_OPCFG_BL_INT (1<<13) + #define UG_STD_CMD_OPCFG_GNDSEL (1<<12) + #define UG_STD_CMD_OPCFG_FCE (1<<11) + #define UG_STD_CMD_OPCFG_DFWRINDBL (1<<10) + #define UG_STD_CMD_OPCFG_RFACTSTEP (1<<9) + #define UG_STD_CMD_OPCFG_INDFACRES (1<<8) + #define UG_STD_CMD_OPCFG_BATGSPUEN (1<<7) + #define UG_STD_CMD_OPCFG_BATGWPUEN (1<<6) + #define UG_STD_CMD_OPCFG_BATLSPUEN (1<<5) + #define UG_STD_CMD_OPCFG_BATLWSPUEN (1<<4) + #define UG_STD_CMD_OPCFG_RSVD3 (1<<3) + #define UG_STD_CMD_OPCFG_SLPWKCHG (1<<2) + #define UG_STD_CMD_OPCFG_DELTAVOPT1 (1<<1) + #define UG_STD_CMD_OPCFG_DELTAVOPT0 (1<<0) +#define UG_EXT_CMD_DCAP (0x3C) + +/** + * @brief upiGG_FetchDataCommand + * + * Fetch bq27520 like command + * + * @para read set _UPI_TRUE_ to read data from API + * @para pMeasPara pointer of GG_MEAS_PARA_TYPE + * @return GGSTATUS + */ +EXPORTS GGSTATUS upiGG_FetchDataCommand(char *pObj, _upi_u8_ CommandCode, _upi_u16_ *pData); + +typedef struct GG_FETCH_DATA_PARA_ST { + _upi_s8_ FCSet; + _upi_s8_ FCClear; + _upi_u8_ Soc1Set; + _upi_u8_ Soc1Clear; + _upi_s8_ InitSI; + _upi_s16_ InitMaxLoadCurrent; + _upi_u16_ CCThreshold; + _upi_u32_ Opcfg; + _upi_u16_ Dcap; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) GG_FETCH_DATA_PARA_TYPE; +#else ///< else of defined(uG31xx_OS_ANDROID) +} GG_FETCH_DATA_PARA_TYPE; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief upiGG_FetchDataParameter + * + * Set the parameter for bq27520 like command + * + * @para data parameters of GG_FETCH_DATA_PARA_TYPE + * @return GGSTATUS + */ +EXPORTS GGSTATUS upiGG_FetchDataParameter(char *pObj, GG_FETCH_DATA_PARA_TYPE data); + +#endif //endif ENABLE_BQ27520_SW_CMD + +typedef struct GG_FETCH_DEBUG_DATA_ST { + /// [AT-PM] : Driver version ; 01/30/2013 + int versionMain; + int versionOtp; + int versionSub; + + /// [AT-PM] : Capacity related ; 01/30/2013 + int capStatus; + int capSelfHour; + int capSelfMin; + int capSelfSec; + int capSelfMilliSec; + int capTPTime; + int capDelta; + int capDsgCharge; + int capDsgChargeStart; + int capDsgChargeTime; + int capPreDsgCharge; + int capTableUpdateIdx; + + /// [AT-PM] : Measurement related ; 01/30/2013 + int measCodeBat1; + int measCodeCurrent; + int measCodeIT; + int measCodeET; + int measCharge; + int measCCOffset; + int measAdc1ConvertTime; + int measAdc1Gain; + int measAdc1Offset; + int measAdc2Gain; + int measAdc2Offset; + int measLastCounter; + int measLastTimeTick; + int measLastDeltaQ; + +#if defined(uG31xx_OS_ANDROID) + }__attribute__((packed)) GG_FETCH_DEBUG_DATA_TYPE; +#else ///< else of defined(uG31xx_OS_ANDROID) + } GG_FETCH_DEBUG_DATA_TYPE; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief upiGG_FetchDebugData + * + * Fetch debug information data + * + * @para pObj address of memory buffer + * @para data address of GG_FETCH_CAP_DATA_TYPE + * @return _UPI_NULL_ + */ +EXPORTS void upiGG_FetchDebugData(char *pObj, GG_FETCH_DEBUG_DATA_TYPE *data); + +/** + * @brief upiGG_DebugSwitch + * + * Enable/disable debug information to UART + * + * @para Enable set _UPI_TRUE_ to enable it + * @return NULL + */ +EXPORTS void upiGG_DebugSwitch(_upi_bool_ enable); + +#define UPI_CHECK_BACKUP_FILE_FAIL (0) +#define UPI_CHECK_BACKUP_FILE_EXIST (1) +#define UPI_CHECK_BACKUP_FILE_MISMATCH (2) + +EXPORTS _upi_u8_ upiGG_CheckBackupFile(char *pObj); + +EXPORTS void upiGG_ForceTaper(char *pObj, int charger_full, int dc_in_before, int dc_in_now); + +#endif ///< end of _UG31XXAPI_H_ + +/// =========================================== +/// End of uG31xx_API.h +/// =========================================== + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.c new file mode 100755 index 00000000..90a82633 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.c @@ -0,0 +1,601 @@ +/** + * @filename uG31xx_API_Backup.cpp + * + * Backup data on uG31xx to a file in system + * + * @author AllenTeng + */ + +#include "stdafx.h" //windows need this?? +#include "uG31xx_API.h" + +#define UG31XX_BACKUP_FILE_ENABLE + +#ifdef uG31xx_OS_WINDOWS + +typedef char mm_segment_t; +typedef char loff_t; + +typedef struct file +{ + FILE *fp; +} fileType; + +#define O_RDONLY (1<<0) +#define O_WRONLY (1<<1) +#define O_RDWR (3<<0) +#define O_CREAT (1<<2) +#define O_APPEND (1<<3) + +static struct file BackupFile; + +/** + * @brief filp_open + * + * Open file + * + * @para path address of file + * @para cntl FILE_CNTL parameter + * @para misc dummy parameter + * @return address of BackupFile + */ +struct file * filp_open(const wchar_t *path, int cntl, int misc) +{ + if(BackupFile.fp != _UPI_NULL_) + { + fclose(BackupFile.fp); + } + BackupFile.fp = _UPI_NULL_; + + switch(cntl & O_RDWR) + { + case O_RDONLY: + _wfopen_s(&BackupFile.fp, path, _T("rb, ccs=UTF-8")); + break; + case O_WRONLY: + _wfopen_s(&BackupFile.fp, path, _T("wb, ccs=UTF-8")); + break; + case O_RDWR: + _wfopen_s(&BackupFile.fp, path, _T("r+b, ccs=UTF-8")); + break; + default: + _wfopen_s(&BackupFile.fp, path, _T("rb, ccs=UTF-8")); + break; + } + return (&BackupFile); +} + +/** + * @brief filp_close + * + * Close file + * + * @para fp address of struct file + * @para misc dummy value + * @return _UPI_NULL_ + */ +void filp_close(struct file *fp, int misc) +{ + if(fp->fp != _UPI_NULL_) + { + fclose(fp->fp); + } +} + +/** + * @brief vfs_write + * + * Write data to binary file + * + * @para fp address of struct file + * @para data address of data to be written + * @para size size to be written + * @para pos start position in the file + * @return size be written + */ +size_t vfs_write(struct file *fp, char *data, int size, loff_t *pos) +{ + return (fwrite(data, sizeof(char), size, fp->fp)); +} + +/** + * @brief vfs_read + * + * Read data from binary file + * + * @para fp address of struct file + * @para data address of data to be read + * @para size size to be read + * @para pos start position in the file + * @return size be read + */ +size_t vfs_read(struct file *fp, char *data, int size, loff_t *pos) +{ + return (fread(data, sizeof(char), size, fp->fp)); +} + +/** + * @brief IS_ERR + * + * Check file is opened or not + * + * @para fp address of struct file + * @return _UPI_TRUE_ if file is opened + */ +_upi_bool_ IS_ERR(struct file *fp) +{ + return ((fp->fp == _UPI_NULL_) ? _UPI_TRUE_ : _UPI_FALSE_); +} + +/** + * @brief get_fs + * + * Dummy function + * + * @return 0 + */ +mm_segment_t get_fs(void) +{ + return (0); +} + +/** + * @brief set_fs + * + * Dummy function + * + * @para value mm_segment_t value + * @return _UPI_NULL_ + */ +void set_fs(mm_segment_t value) +{ +} + +/** + * @brief get_ds + * + * Dummy function + * + * @return 0 + */ +mm_segment_t get_ds(void) +{ + return (0); +} + +#endif ///< end of uG31xx_OS_WINDOWS + +/** + * @brief ISFileExist + * + * Check file existed or not + * + * @para data address of BackupDataType + * @return BACKUP_BOOL_TRUE if file existed + */ +_backup_bool_ ISFileExist(BackupDataType *data) +{ + struct file *fp; + + fp = filp_open(data->backupFileName, O_RDONLY, 0); + if(IS_ERR(fp)) + { + UG31_LOGI("[%s]: Backup file is not existed\n", __func__); + return (BACKUP_BOOL_FALSE); + } + UG31_LOGI("[%s]: Backup file is existed\n", __func__); + filp_close(fp, _UPI_NULL_); + return (BACKUP_BOOL_TRUE); +} + +/** + * @brief WriteFile + * + * Write data to file + * + * @para data address of BackupDataType + * @para fp address of struct fp + */ +void WriteFile(BackupDataType *data, struct file *fp) +{ + mm_segment_t oldFS; + loff_t pos; + size_t size; + + oldFS = get_fs(); + set_fs(get_ds()); + + pos = 0; + size = vfs_write(fp, (char *)data->capData->encriptTable, sizeof(data->capData->encriptTable), &pos); + UG31_LOGI("[%s]: Write table %d bytes\n", __func__, size); + size = vfs_write(fp, (char *)(&data->sysData->rmFromIC), sizeof(data->sysData->rmFromIC), &pos); + UG31_LOGI("[%s]: Write RM (%d) %d bytes\n", __func__, data->sysData->rmFromIC, size); + size = vfs_write(fp, (char *)(&data->sysData->fccFromIC), sizeof(data->sysData->fccFromIC), &pos); + UG31_LOGI("[%s]: Write FCC (%d) %d bytes\n", __func__, data->sysData->fccFromIC, size); + size = vfs_write(fp, (char *)(&data->sysData->timeTagFromIC), sizeof(data->sysData->timeTagFromIC), &pos); + UG31_LOGI("[%s]: Write Time Tag (%d) %d bytes\n", __func__, data->sysData->timeTagFromIC, size); + size = vfs_write(fp, (char *)(&data->sysData->tableUpdateIdxFromIC), sizeof(data->sysData->tableUpdateIdxFromIC), &pos); + UG31_LOGI("[%s]: Write Table Update Index (%d) %d bytes\n", __func__, data->sysData->tableUpdateIdxFromIC, size); + size = vfs_write(fp, (char *)(&data->sysData->deltaCapFromIC), sizeof(data->sysData->deltaCapFromIC), &pos); + UG31_LOGI("[%s]: Write Delta Capacity (%d) %d bytes\n", __func__, data->sysData->deltaCapFromIC, size); + size = vfs_write(fp, (char *)(&data->sysData->adc1ConvTime), sizeof(data->sysData->adc1ConvTime), &pos); + UG31_LOGI("[%s]: Write ADC1 Conversion Time (%d) %d bytes\n", __func__, data->sysData->adc1ConvTime, size); + size = vfs_write(fp, (char *)(&data->sysData->rsocFromIC), sizeof(data->sysData->rsocFromIC), &pos); + UG31_LOGI("[%s]: Write RSOC (%d) %d bytes\n", __func__, data->sysData->rsocFromIC, size); + size = vfs_write(fp, (char *)(&data->targetFileVer), sizeof(_backup_u32_), &pos); + UG31_LOGI("[%s]: Write version (%d) %d bytes\n", __func__, data->targetFileVer, size); + + set_fs(oldFS); +} + +/** + * @brief CreateBackupFile + * + * Create backup file in system + * + * @para data address of BackupDataType + * @return BACKUP_BOOL_TRUE if success + */ +_backup_bool_ CreateBackupFile(BackupDataType *data) +{ + struct file *fp; + + fp = filp_open(data->backupFileName, O_CREAT | O_RDWR, 0); + if(IS_ERR(fp)) + { + UG31_LOGI("[%s]: Create backup file fail\n", __func__); + return (BACKUP_BOOL_FALSE); + } + + /// [AT-PM] : Write data to file ; 02/21/2013 + WriteFile(data, fp); + + filp_close(fp, _UPI_NULL_); + return (BACKUP_BOOL_TRUE); +} + +/** + * @brief ReadFile + * + * Read data from file + * + * @para data address of BackupDataType + * @para fp address of struct fp + */ +void ReadFile(BackupDataType *data, struct file *fp) +{ + mm_segment_t oldFS; + loff_t pos; + size_t size; + + oldFS = get_fs(); + set_fs(get_ds()); + + pos = 0; + size = vfs_read(fp, (char *)&data->capData->encriptTable, sizeof(data->capData->encriptTable), &pos); + UG31_LOGI("[%s]: Read table %d bytes\n", __func__, size); + size = vfs_read(fp, (char *)(&data->sysData->rmFromIC), sizeof(data->sysData->rmFromIC), &pos); + UG31_LOGI("[%s]: Read RM (%d) %d bytes\n", __func__, data->sysData->rmFromIC, size); + size = vfs_read(fp, (char *)(&data->sysData->fccFromIC), sizeof(data->sysData->fccFromIC), &pos); + UG31_LOGI("[%s]: Read FCC (%d) %d bytes\n", __func__, data->sysData->fccFromIC, size); + size = vfs_read(fp, (char *)(&data->sysData->timeTagFromIC), sizeof(data->sysData->timeTagFromIC), &pos); + UG31_LOGI("[%s]: Read Time Tag (%d) %d bytes\n", __func__, data->sysData->timeTagFromIC, size); + size = vfs_read(fp, (char *)(&data->sysData->tableUpdateIdxFromIC), sizeof(data->sysData->tableUpdateIdxFromIC), &pos); + UG31_LOGI("[%s]: Read Table Update Index (%d) %d bytes\n", __func__, data->sysData->tableUpdateIdxFromIC, size); + size = vfs_read(fp, (char *)(&data->sysData->deltaCapFromIC), sizeof(data->sysData->deltaCapFromIC), &pos); + UG31_LOGI("[%s]: Read Delta Capacity (%d) %d bytes\n", __func__, data->sysData->deltaCapFromIC, size); + size = vfs_read(fp, (char *)(&data->sysData->adc1ConvTime), sizeof(data->sysData->adc1ConvTime), &pos); + UG31_LOGI("[%s]: Read ADC1 Conversion Time (%d) %d bytes\n", __func__, data->sysData->adc1ConvTime, size); + size = vfs_read(fp, (char *)(&data->sysData->rsocFromIC), sizeof(data->sysData->rsocFromIC), &pos); + UG31_LOGI("[%s]: Read RSOC (%d) %d bytes\n", __func__, data->sysData->rsocFromIC, size); + size = vfs_read(fp, (char *)(&data->backupFileVer), sizeof(_backup_u32_), &pos); + UG31_LOGI("[%s]: Read version (%d) %d bytes\n", __func__, data->backupFileVer, size); + + set_fs(oldFS); +} + +/** + * @brief CheckBackupFile + * + * Check backup file is consisted with IC or not + * + * @para data address of BackupDataType + * @return BACKUP_BOOL_TRUE if success + */ +_backup_bool_ CheckBackupFile(BackupDataType *data) +{ + struct file *fp; + CapacityDataType *bufCapData; + SystemDataType *bufSysData; + + fp = filp_open(data->backupFileName, O_RDWR, 0); + if(IS_ERR(fp)) + { + UG31_LOGI("[%s]: Open backup file fail\n", __func__); + return (BACKUP_BOOL_FALSE); + } + + /// [AT-PM] : Create buffer ; 02/21/2013 + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + bufCapData = (CapacityDataType *)malloc(sizeof(CapacityDataType)); + bufSysData = (SystemDataType *)malloc(sizeof(SystemDataType)); + #else ///< else of uG31xx_BOOT_LOADER + bufCapData = (CapacityDataType *)kmalloc(sizeof(CapacityDataType), GFP_KERNEL); + bufSysData = (SystemDataType *)kmalloc(sizeof(SystemDataType), GFP_KERNEL); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + bufCapData = (CapacityDataType *)malloc(sizeof(CapacityDataType)); + bufSysData = (SystemDataType *)malloc(sizeof(SystemDataType)); + #endif ///< end of defined(uG31xx_OS_ANDROID) + memcpy(bufCapData, data->capData, sizeof(CapacityDataType)); + memcpy(bufSysData, data->sysData, sizeof(SystemDataType)); + + /// [AT-PM] : Get data from file ; 02/21/2013 + ReadFile(data, fp); + + /// [AT-PM] : Following information is not checked ; 02/21/2013 + data->sysData->rmFromIC = bufSysData->rmFromIC; + data->sysData->timeTagFromIC = bufSysData->timeTagFromIC; + data->sysData->deltaCapFromIC = bufSysData->deltaCapFromIC; + data->sysData->adc1ConvTime = bufSysData->adc1ConvTime; + + /// [AT-PM] : Check data ; 02/21/2013 + if((memcmp(bufCapData, data->capData, sizeof(CapacityDataType)) != 0) || + (memcmp(bufSysData, data->sysData, sizeof(SystemDataType)) != 0) || + (data->backupFileVer != data->targetFileVer)) + { + UG31_LOGI("[%s]: Backup file needs to be updated\n", __func__); + /// [AT-PM] : Write data to file ; 02/21/2013 + memcpy(data->capData, bufCapData, sizeof(CapacityDataType)); + memcpy(data->sysData, bufSysData, sizeof(SystemDataType)); + WriteFile(data, fp); + } + + filp_close(fp, _UPI_NULL_); + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + free(bufCapData); + free(bufSysData); + #else ///< else of uG31xx_BOOT_LOADER + kfree(bufCapData); + kfree(bufSysData); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + free(bufCapData); + free(bufSysData); + #endif ///< end of defined(uG31xx_OS_ANDROID) + return (BACKUP_BOOL_TRUE); +} + +/** + * @brief WriteSuspendBackupData + * + * Write suspend backup data to file + * + * @para data address of BackupDataType + * @return BACKUP_BOOL_TRUE if success + */ +_backup_bool_ WriteSuspendBackupData(BackupDataType *data) +{ + struct file *fp; + _backup_u8_ idx; + mm_segment_t oldFS; + loff_t pos; + size_t size; + _backup_u8_ *buf; + + /// [AT-PM] : Check backup file content ; 10/12/2013 + fp = filp_open("/sdcard/upi_table", O_RDWR, 0); + if(!IS_ERR(fp)) + { + oldFS = get_fs(); + set_fs(get_ds()); + + idx = 0; + pos = 0; + buf = (_backup_u8_ *)kmalloc(sizeof(BackupSuspendDataType), GFP_KERNEL); + while(idx < BACKUP_MAX_LOG_SUSPEND_DATA) + { + size = vfs_read(fp, (char *)buf, sizeof(BackupSuspendDataType), &pos); + + if(memcmp((char *)buf, (char *)data->logData[idx], sizeof(BackupSuspendDataType)) != 0) + { + UG31_LOGI("[%s]: Need to write suspend data to file (%d)\n", __func__, idx); + break; + } + + idx = idx + 1; + } + kfree(buf); + + set_fs(oldFS); + + filp_close(fp, _UPI_NULL_); + + if(idx >= BACKUP_MAX_LOG_SUSPEND_DATA) + { + UG31_LOGI("[%s]: No need to update suspend data.\n", __func__, idx); + return (BACKUP_BOOL_TRUE); + } + } + + fp = filp_open("/sdcard/upi_table", O_CREAT | O_RDWR, 0); + if(IS_ERR(fp)) + { + UG31_LOGI("[%s]: Open backup file fail\n", __func__); + return (BACKUP_BOOL_FALSE); + } + + oldFS = get_fs(); + set_fs(get_ds()); + + idx = 0; + pos = 0; + while(idx < BACKUP_MAX_LOG_SUSPEND_DATA) + { + size = vfs_write(fp, (char *)data->logData[idx], sizeof(BackupSuspendDataType), &pos); + UG31_LOGI("[%s]: Write suspend data %d with %d bytes\n", __func__, idx, size); + + idx = idx + 1; + } + + set_fs(oldFS); + + filp_close(fp, _UPI_NULL_); + return (BACKUP_BOOL_TRUE); +} + +/// ============================================= +/// Extern Function Region +/// ============================================= + +#define RETRY_CHECKING_THRESHOLD (CONST_CONVERSION_COUNT_THRESHOLD) + +/** + * @brief UpiBackupData + * + * Backup data from IC to system routine + * + * @para data address of BackupDataType + * @return _UPI_NULL_ + */ +void UpiBackupData(BackupDataType *data) +{ + _backup_bool_ rtnBool; + + #ifndef UG31XX_BACKUP_FILE_ENABLE + rtnBool = _UPI_TRUE_; + data->backupFileSts = BACKUP_FILE_STS_EXIST; + #endif ///< end of UG31XX_BACKUP_FILE_ENABLE + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + data->backupFileName = (char *)malloc(strlen(BACKUP_FILE_PATH)); + #else ///< else of uG31xx_BOOT_LOADER + data->backupFileName = (char *)kmalloc(strlen(BACKUP_FILE_PATH), GFP_KERNEL); + #endif ///< end of uG31xx_BOOT_LOADER + sprintf(data->backupFileName, "%s", BACKUP_FILE_PATH); + #else ///< else of defined(uG31xx_OS_ANDROID) + data->backupFileName = data->sysData->backupFileName; + #endif ///< end of defined(uG31xx_OS_ANDROID) + + switch(data->backupFileSts) + { + case BACKUP_FILE_STS_CHECKING: + /// [AT-PM] : Check backup file existed or not ; 02/21/2013 + rtnBool = ISFileExist(data); + if(rtnBool == BACKUP_BOOL_TRUE) + { + #ifdef BACKUP_FILE_STS_NOT_EXIST + data->backupFileSts = BACKUP_FILE_STS_NOT_EXIST; + #else ///< else of BACKUP_FILE_STS_NOT_EXIST + data->backupFileSts = BACKUP_FILE_STS_EXIST; + #endif ///< end of BACKUP_FILE_STS_NOT_EXIST + } + else + { + if(data->measData->lastCounter > RETRY_CHECKING_THRESHOLD) + { + data->backupFileSts = BACKUP_FILE_STS_NOT_EXIST; + } + } + break; + case BACKUP_FILE_STS_NOT_EXIST: + /// [AT-PM] : Create backup file ; 02/21/2013 + rtnBool = CreateBackupFile(data); + if(rtnBool == BACKUP_BOOL_TRUE) + { + data->backupFileSts = BACKUP_FILE_STS_EXIST; + } + break; + case BACKUP_FILE_STS_EXIST: + rtnBool = CheckBackupFile(data); + if(rtnBool != BACKUP_BOOL_TRUE) + { + data->backupFileSts = BACKUP_FILE_STS_NOT_EXIST; + } + else + { + data->backupFileSts = BACKUP_FILE_STS_COMPARE; + } + break; + case BACKUP_FILE_STS_COMPARE: + if(data->icDataAvailable == BACKUP_BOOL_TRUE) + { + /// [AT-PM] : Check content of file is consist with IC or not ; 02/21/2013 + rtnBool = CheckBackupFile(data); + if(rtnBool != BACKUP_BOOL_TRUE) + { + data->backupFileSts = BACKUP_FILE_STS_NOT_EXIST; + } + rtnBool = WriteSuspendBackupData(data); + if(rtnBool != BACKUP_BOOL_TRUE) + { + data->backupFileSts = BACKUP_FILE_STS_NOT_EXIST; + } + } + else + { + data->backupFileSts = BACKUP_FILE_STS_CHECKING; + } + break; + default: + /// [AT-PM] : Un-known state ; 02/21/2013 + data->backupFileSts = BACKUP_FILE_STS_NOT_EXIST; + break; + } + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + free(data->backupFileName); + #else ///< else of uG31xx_BOOT_LOADER + kfree(data->backupFileName); + #endif ///< end of uG31xx_BOOT_LOADER + #endif ///< end of defined(uG31xx_OS_ANDROID) + + UG31_LOGI("[%s]: Backp file status = %d\n", __func__, data->backupFileSts); +} + +/** + * @brief UpiUpdateSuspendData + * + * Update data for suspend backup + * + * @para data address of BackupDataType + * @para is_resume UPI_TRUE if called in resume + * @return NULL + */ +void UpiUpdateSuspendData(BackupDataType *data, _backup_bool_ is_resume) +{ + if(is_resume == _UPI_TRUE_) + { + data->logData[data->backupDataIdx]->afterCapData = *(data->capData); + data->logData[data->backupDataIdx]->afterMeasData = *(data->measData); + UG31_LOGI("[%s]: Backup resume data to buffer %d\n", __func__, data->backupDataIdx); + + data->backupDataIdx = data->backupDataIdx + 1; + if(data->backupDataIdx >= BACKUP_MAX_LOG_SUSPEND_DATA) + { + data->backupDataIdx = BACKUP_MAX_LOG_SUSPEND_DATA; + } + } + else + { + if((data->backupDataIdx >= BACKUP_MAX_LOG_SUSPEND_DATA) && (is_resume == _UPI_FALSE_)) + { + data->backupDataIdx = 0; + while(data->backupDataIdx < (BACKUP_MAX_LOG_SUSPEND_DATA - 1)) + { + memcpy(data->logData[data->backupDataIdx], data->logData[data->backupDataIdx + 1], sizeof(BackupSuspendDataType)); + data->backupDataIdx = data->backupDataIdx + 1; + } + } + + data->logData[data->backupDataIdx]->beforeCapData = *(data->capData); + data->logData[data->backupDataIdx]->beforeMeasData = *(data->measData); + UG31_LOGI("[%s]: Backup suspend data to buffer %d\n", __func__, data->backupDataIdx); + } +} + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.h new file mode 100755 index 00000000..03564f3f --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Backup.h @@ -0,0 +1,79 @@ +/** + * @filename uG31xx_API_Backup.h + * + * Header of uG31xx_API_Backup.cpp + * + * @author AllenTeng + */ + +#define BACKUP_BOOL_TRUE (1) +#define BACKUP_BOOL_FALSE (0) + +#define BACKUP_FILE_PATH ("/sdcard/upi_gg") + +enum BACKUP_FILE_STS { + BACKUP_FILE_STS_CHECKING = 0, + BACKUP_FILE_STS_NOT_EXIST, + BACKUP_FILE_STS_EXIST, + BACKUP_FILE_STS_COMPARE, +}; + +typedef unsigned char _backup_bool_; +typedef unsigned char _backup_u8_; +typedef unsigned long _backup_u32_; + +typedef struct BackupSuspendDataST { + CapacityDataType beforeCapData; + MeasDataType beforeMeasData; + + CapacityDataType afterCapData; + MeasDataType afterMeasData; +} __attribute__ ((packed)) BackupSuspendDataType; + +#define BACKUP_MAX_LOG_SUSPEND_DATA (8) + +typedef struct BackupDataST { + + CapacityDataType *capData; + SystemDataType *sysData; + MeasDataType *measData; + + _backup_bool_ icDataAvailable; + _backup_u8_ backupFileSts; + _backup_u32_ backupFileVer; + _backup_u32_ targetFileVer; + + _backup_u8_ backupDataIdx; + BackupSuspendDataType *logData[BACKUP_MAX_LOG_SUSPEND_DATA]; + + #if defined (uG31xx_OS_WINDOWS) + const wchar_t* backupFileName; + #elif defined(uG31xx_OS_ANDROID) + char *backupFileName; + #endif + +#if defined(uG31xx_OS_ANDROID) + } __attribute__ ((packed)) BackupDataType; +#else ///< else of defined(uG31xx_OS_ANDROID) + } BackupDataType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief UpiBackupData + * + * Backup data from IC to system routine + * + * @para data address of BackupDataType + * @return _UPI_NULL_ + */ +extern void UpiBackupData(BackupDataType *data); + +/** + * @brief UpiUpdateSuspendData + * + * Update data for suspend backup + * + * @para data address of BackupDataType + * @return NULL + */ +extern void UpiUpdateSuspendData(BackupDataType *data, _backup_bool_ is_resume); diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.b b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.b new file mode 100755 index 00000000..52317121 Binary files /dev/null and b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.b differ diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.h new file mode 100755 index 00000000..a45ea7b4 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Capacity.h @@ -0,0 +1,143 @@ +/** + * @filename uG31xx_API_Capacity.h + * + * Header of uG31xx capacity algorithm + * + * @author AllenTeng + */ + +typedef _upi_bool_ _cap_bool_; +typedef unsigned char _cap_u8_; +typedef signed char _cap_s8_; +typedef unsigned short _cap_u16_; +typedef signed short _cap_s16_; +typedef unsigned long _cap_u32_; +typedef signed long _cap_s32_; + +#define CAP_FC_RELEASE_RSOC (99) +#define UG31XX_CAP_VERSION (36) +#define CAP_ENCRIPT_TABLE_SIZE (TEMPERATURE_NUMS*C_RATE_NUMS*(SOV_NUMS - 1)) + +typedef struct CapacityDataST { + + /// [AT-PM] : Data from GGB file ; 01/25/2013 + CELL_PARAMETER *ggbParameter; + CELL_TABLE *ggbTable; + + /// [AT-PM] : Measurement data ; 01/25/2013 + MeasDataType *measurement; + + /// [AT-PM] : Data for table backup ; 01/31/2013 + TableBackupType tableBackup[SOV_NUMS]; + _cap_u8_ encriptTable[CAP_ENCRIPT_TABLE_SIZE]; + + /// [AT-PM] : Capacity information ; 01/25/2013 + _cap_u16_ rm; + _cap_u16_ fcc; + _cap_u16_ fccBackup; + _cap_u8_ rsoc; + + /// [AT-PM] : Capacity operation variables ; 01/25/2013 + _cap_u32_ status; + + _cap_u32_ selfDsgMilliSec; + _cap_u8_ selfDsgSec; + _cap_u8_ selfDsgMin; + _cap_u8_ selfDsgHour; + _cap_u8_ selfDsgResidual; + + _cap_u8_ lastRsoc; + + _cap_u32_ tpTime; + + _cap_s32_ dsgCharge; + _cap_s32_ dsgChargeStart; + _cap_u32_ dsgChargeTime; + _cap_s32_ preDsgCharge; + + _cap_u8_ tableUpdateIdx; + _cap_u32_ tableUpdateDisqTime; + _cap_u8_ tableUpdateDelayCnt; + + _cap_s8_ parseRMResidual; + + _cap_s16_ reverseCap; + _cap_u8_ avgCRate; + + _cap_s16_ ccRecord[SOV_NUMS]; +#if defined(uG31xx_OS_ANDROID) + } __attribute__ ((packed)) CapacityDataType; +#else ///< else of defined(uG31xx_OS_ANDROID) + } CapacityDataType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief UpiInitCapacity + * + * Initial capacity algorithm + * + * @para data address of CapacityDataType + * @return _UPI_NULL_ + */ +extern void UpiInitCapacity(CapacityDataType *data); + +/** + * @brief UpiReadCapacity + * + * Read capacity information + * + * @para data address of CapacityDataType + * @return _UPI_NULL_ + */ +extern void UpiReadCapacity(CapacityDataType *data); + +/** + * @brief UpiTableCapacity + * + * Look up capacity from table + * + * @para data address of CapacityDataType + * @return _UPI_NULL_ + */ +extern void UpiTableCapacity(CapacityDataType *data); + +/** + * @brief UpiInitDsgCharge + * + * Initialize data->dsgCharge value + * + * @para data address of CapacityDataType + * @return _UPI_NULL_ + */ +extern void UpiInitDsgCharge(CapacityDataType *data); + +/** + * @brief UpiInitNacTable + * + * Initialize NAC table + * + * @para data address of CapacityDataType + * @return _UPI_NULL_ + */ +extern void UpiInitNacTable(CapacityDataType *data); + +/** + * @brief UpiSaveNacTable + * + * Save NAC table to IC + * + * @para data address of CapacityDataType + * @return _UPI_NULL_ + */ +extern void UpiSaveNacTable(CapacityDataType *data); + +/** + * @brief CalculateRsoc + * + * RSOC = RM x 100 / FCC + * + * @para rm remaining capacity + * @para fcc full charged capacity + * @return relative state of charge + */ +extern _cap_u8_ CalculateRsoc(_cap_u16_ rm, _cap_u16_ fcc); diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.c new file mode 100755 index 00000000..29f5072c --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.c @@ -0,0 +1,1389 @@ +/** + * @filename uG31xx_API_Measurement.cpp + * + * guG31xx measurement API + * + * @author AllenTeng + */ + +#include "stdafx.h" //windows need this?? +#include "uG31xx_API.h" + +//#define MEAS_FAKE_INT_TEMP +#ifdef MEAS_FAKE_INT_TEMP + #define MEAS_FAKE_INT_TEMP_OFFSET (200) +#endif ///< end of MEAS_FAKE_INT_TEMP + +typedef struct MeasDataInternalST { + + MeasDataType *info; + + _meas_s16_ adc1CodeT25V100; + _meas_s16_ adc1CodeT25V200; + _meas_s16_ adc1CodeT80V100; + _meas_s16_ adc1CodeT80V200; + + _meas_s16_ adc2CodeT25V100; + _meas_s16_ adc2CodeT25V200; + _meas_s16_ adc2CodeT80V100; + _meas_s16_ adc2CodeT80V200; + + _meas_u32_ currTime; + + _meas_u16_ codeBat1; + _meas_s16_ codeCurrent; + _meas_u16_ codeIntTemperature; + _meas_u16_ codeExtTemperature; + _meas_s16_ codeCharge; + _meas_u16_ codeCounter; + _meas_s16_ ccOffset; + +#if defined(uG31xx_OS_ANDROID) + } __attribute__ ((packed)) MeasDataInternalType; +#else ///< else of defined(uG31xx_OS_ANDROID) + } MeasDataInternalType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct AdcDeltaCodeMappingST { + _meas_s32_ Adc1V100; + _meas_s32_ Adc1V200; + _meas_s32_ Adc2V100; + _meas_s32_ Adc2V200; +#if defined(uG31xx_OS_ANDROID) +}__attribute__((packed)) AdcDeltaCodeMappingType; +#else ///< else of defined(uG31xx_OS_ANDROID) +} AdcDeltaCodeMappingType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +static AdcDeltaCodeMappingType AdcDeltaCodeMapping[] = +{ + { -12800, -25600, 1536, 0 }, ///< Index = 0 + { -12544, -25088, 1600, 128 }, ///< Index = 1 + { -13056, -26112, 1472, -128 }, ///< Index = 2 + { -12288, -24576, 1664, 256 }, ///< Index = 3 + { -13312, -26624, 1408, -256 }, ///< Index = 4 + { -12032, -24064, 1728, 384 }, ///< Index = 5 + { -13568, -27136, 1344, -384 }, ///< Index = 6 + { -11776, -23552, 1792, 512 }, ///< Index = 7 + { -13824, -27648, 1280, -512 }, ///< Index = 8 + { -11520, -23040, 1856, 640 }, ///< Index = 9 + { -14080, -28160, 1216, -640 }, ///< Index = 10 + { -11264, -22528, 1920, 768 }, ///< Index = 11 + { -14336, -28672, 1152, -768 }, ///< Index = 12 + { -11008, -22016, 1984, 896 }, ///< Index = 13 + { -14592, -29184, 1088, -896 }, ///< Index = 14 + { -10752, -21504, 2048, 1024 }, ///< Index = 15 + { -14848, -29696, 1024, -1024 }, ///< Index = 16 + { -10496, -20992, 2112, 1152 }, ///< Index = 17 + { -15104, -30208, 960, -1152 }, ///< Index = 18 + { -10240, -20480, 2176, 1280 }, ///< Index = 19 + { -15360, -30720, 896, -1280 }, ///< Index = 20 + { -9984, -19968, 2240, 1408 }, ///< Index = 21 + { -15616, -31232, 832, -1408 }, ///< Index = 22 + { -9728, -19456, 2304, 1536 }, ///< Index = 23 + { -15872, -31744, 768, -1536 }, ///< Index = 24 + { -9472, -18944, 2368, 1664 }, ///< Index = 25 + { -16128, -32256, 704, -1664 }, ///< Index = 26 + { -9216, -18432, 2432, 1792 }, ///< Index = 27 + { -16384, -32768, 640, -1792 }, ///< Index = 28 + { -8960, -17920, 2496, 1920 }, ///< Index = 29 + { -16640, -33280, 576, -1920 }, ///< Index = 30 + { 0, 0, 0, 0 }, ///< Index = 31 +}; + +#define ADC_TEMPERATURE_GAIN_CONST (1000) + +#define ADC1_CODE_100MV_NEGATIVE (0xFF00) +#define ADC1_CODE_200MV_NEGATIVE (0xFE00) +#define ADC1_CP_CODE_25_100MV (12288) +#define ADC1_CP_CODE_25_200MV (24576) +#define ADC1_DELTA_CODE_25_100MV_SIGN_BIT (1<<8) +#define ADC1_DELTA_CODE_25_200MV_SIGN_BIT (1<<9) +#define ADC1_TEMPERATURE_GAIN_100MV (869600) +#define ADC1_TEMPERATURE_GAIN_200MV (-695680) + +/** + * @brief ConvertAdc1Data + * + * Convert ADC1 data from OTP + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertAdc1Data(MeasDataInternalType *obj) +{ + _meas_u16_ tmp16; + _meas_s32_ tmp32; + + /// [AT-PM] : Get code T25 100mV ; 01/23/2013 + tmp16 = obj->info->otp->adc1DeltaCodeT25V100; + if(tmp16 & ADC1_DELTA_CODE_25_100MV_SIGN_BIT) + { + tmp16 = tmp16 & (~ADC1_DELTA_CODE_25_100MV_SIGN_BIT); + if(tmp16 != 0) + { + tmp16 = tmp16 + ADC1_CODE_100MV_NEGATIVE; + } + } + tmp16 = tmp16 + ADC1_CP_CODE_25_100MV; + tmp32 = (_meas_s32_)(_meas_s16_)tmp16; + tmp32 = tmp32 + AdcDeltaCodeMapping[obj->info->otp->indexAdc1V100T25].Adc1V100; + obj->adc1CodeT25V100 = (_meas_s16_)tmp32; + + /// [AT-PM] : Get code T25 200mV ; 01/23/2013 + tmp16 = obj->info->otp->adc1DeltaCodeT25V200; + if(tmp16 & ADC1_DELTA_CODE_25_200MV_SIGN_BIT) + { + tmp16 = tmp16 & (~ADC1_DELTA_CODE_25_200MV_SIGN_BIT); + if(tmp16 != 0) + { + tmp16 = tmp16 + ADC1_CODE_200MV_NEGATIVE; + } + } + tmp16 = tmp16 + ADC1_CP_CODE_25_200MV; + tmp32 = (_meas_s32_)(_meas_s16_)tmp16; + tmp32 = tmp32 + AdcDeltaCodeMapping[obj->info->otp->indexAdc1V200T25].Adc1V200; + obj->adc1CodeT25V200 = (_meas_s16_)tmp32; + + tmp32 = (_meas_s32_)obj->info->otp->aveIT80; + tmp32 = (tmp32 - obj->info->otp->aveIT25)*ADC_TEMPERATURE_GAIN_CONST; + + /// [AT-PM] : Get code T80 100mV ; 01/23/2013 + obj->adc1CodeT80V100 = (_meas_s16_)(tmp32/ADC1_TEMPERATURE_GAIN_100MV + obj->adc1CodeT25V100); + + /// [AT-PM] : Get code T80 200mV ; 01/23/2013 + obj->adc1CodeT80V200 = (_meas_s16_)(tmp32/ADC1_TEMPERATURE_GAIN_200MV + obj->adc1CodeT25V200); +} + +#define ADC2_CODE_100MV_NEGATIVE (0xFFC0) +#define ADC2_CODE_200MV_NEGATIVE (0xFF80) +#define ADC2_CP_CODE_25_100MV (3072) +#define ADC2_CP_CODE_25_200MV (6144) +#define ADC2_DELTA_CODE_25_100MV_SIGN_BIT (1<<6) +#define ADC2_DELTA_CODE_25_200MV_SIGN_BIT (1<<7) +#define ADC2_TEMPERATURE_GAIN_100MV (-149130) +#define ADC2_TEMPERATURE_GAIN_200MV (-136937) + +/** + * @brief ConvertAdc2Data + * + * Convert ADC2 data from OTP + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertAdc2Data(MeasDataInternalType *obj) +{ + _meas_u16_ tmp16; + _meas_s32_ tmp32; + + /// [AT-PM] : Get code T25 100mV ; 01/23/2013 + tmp16 = obj->info->otp->adc2DeltaCodeT25V100; + if(tmp16 & ADC2_DELTA_CODE_25_100MV_SIGN_BIT) + { + tmp16 = tmp16 & (~ADC2_DELTA_CODE_25_100MV_SIGN_BIT); + tmp16 = tmp16 + ADC2_CODE_100MV_NEGATIVE; + } + tmp16 = tmp16 + ADC2_CP_CODE_25_100MV; + tmp32 = (_meas_s32_)(_meas_s16_)tmp16; + tmp32 = tmp32 + AdcDeltaCodeMapping[obj->info->otp->indexAdc2V100T25].Adc2V100; + obj->adc2CodeT25V100 = (_meas_s16_)tmp32; + + /// [AT-PM] : Get code T25 200mV ; 01/23/2013 + tmp16 = obj->info->otp->adc2DeltaCodeT25V200; + if(tmp16 & ADC2_DELTA_CODE_25_200MV_SIGN_BIT) + { + tmp16 = tmp16 & (~ADC2_DELTA_CODE_25_200MV_SIGN_BIT); + tmp16 = tmp16 + ADC2_CODE_200MV_NEGATIVE; + } + tmp16 = tmp16 + ADC2_CP_CODE_25_200MV; + tmp32 = (_meas_s32_)(_meas_s16_)tmp16; + tmp32 = tmp32 + AdcDeltaCodeMapping[obj->info->otp->indexAdc2V200T25].Adc2V200; + obj->adc2CodeT25V200 = (_meas_s16_)tmp32; + + tmp32 = (_meas_s32_)obj->info->otp->aveIT80; + tmp32 = (tmp32 - obj->info->otp->aveIT25)*ADC_TEMPERATURE_GAIN_CONST; + + /// [AT-PM] : Get code T80 100mV ; 01/23/2013 + obj->adc2CodeT80V100 = (_meas_s16_)(tmp32/ADC2_TEMPERATURE_GAIN_100MV + obj->adc2CodeT25V100); + + /// [AT-PM] : Get code T80 200mV ; 01/23/2013 + obj->adc2CodeT80V200 = (_meas_s16_)(tmp32/ADC2_TEMPERATURE_GAIN_200MV + obj->adc2CodeT25V200); +} + +/** + * @brief CalAdc1Factors + * + * Calculate ADC1 gain slope and factor B + * Calculate ADC1 offset slope and factor O + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void CalAdc1Factors(MeasDataInternalType *obj) +{ + _meas_s32_ delta25; + _meas_s32_ delta80; + _meas_s64_ tmp64; + + /// [AT-PM] : Calculate gain slope and factor B ; 01/23/2013 + delta25 = (_meas_s32_)obj->adc1CodeT25V200; + delta25 = delta25 - obj->adc1CodeT25V100; + delta80 = (_meas_s32_)obj->adc1CodeT80V200; + delta80 = delta80 - obj->adc1CodeT80V100; + + obj->info->adc1GainSlope = delta80 - delta25; + obj->info->adc1GainFactorB = delta25*(obj->info->otp->aveIT80) - delta80*(obj->info->otp->aveIT25); + + /// [AT-PM] : Calculate offset slope and factor O ; 01/23/2013 + delta25 = (_meas_s32_)obj->adc1CodeT25V100; + delta25 = delta25*2 - obj->adc1CodeT25V200; + delta80 = (_meas_s32_)obj->adc1CodeT80V100; + delta80 = delta80*2 - obj->adc1CodeT80V200; + + obj->info->adc1OffsetSlope = delta80 - delta25; + obj->info->adc1OffsetFactorO = delta25*(obj->info->otp->aveIT80) - delta80*(obj->info->otp->aveIT25); + + /// [AT-PM] : Calculate current ADC1 gain ; 01/23/2013 + tmp64 = (_meas_s64_)obj->info->adc1GainSlope; + tmp64 = tmp64*(obj->codeIntTemperature) + obj->info->adc1GainFactorB; + obj->info->adc1Gain = (_meas_s32_)tmp64; + + /// [AT-PM] : Calculate current ADC1 offset ; 01/23/2013 + tmp64 = (_meas_s64_)obj->info->adc1OffsetSlope; + tmp64 = tmp64*(obj->codeIntTemperature) + obj->info->adc1OffsetFactorO; + obj->info->adc1Offset = (_meas_s32_)tmp64; +} + +/** + * @brief CalAdc2Factors + * + * Calculate ADC2 gain slope and factor B + * Calculate ADC2 offset slope and factor O + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void CalAdc2Factors(MeasDataInternalType *obj) +{ + _meas_s32_ delta25; + _meas_s32_ delta80; + _meas_s64_ tmp64; + + /// [AT-PM] : Calculate gain slope and factor B ; 01/23/2013 + delta25 = (_meas_s32_)obj->adc2CodeT25V200; + delta25 = delta25 - obj->adc2CodeT25V100; + delta80 = (_meas_s32_)obj->adc2CodeT80V200; + delta80 = delta80 - obj->adc2CodeT80V100; + + obj->info->adc2GainSlope = delta80 - delta25; + obj->info->adc2GainFactorB = delta25*(obj->info->otp->aveIT80) - delta80*(obj->info->otp->aveIT25); + + /// [AT-PM] : Calculate offset slope and factor O ; 01/23/2013 + delta25 = (_meas_s32_)obj->adc2CodeT25V100; + delta25 = delta25*2 - obj->adc2CodeT25V200; + delta80 = (_meas_s32_)obj->adc2CodeT80V100; + delta80 = delta80*2 - obj->adc2CodeT80V200; + + obj->info->adc2OffsetSlope = delta80 - delta25; + obj->info->adc2OffsetFactorO = delta25*(obj->info->otp->aveIT80) - delta80*(obj->info->otp->aveIT25); + + /// [AT-PM] : Calculate current ADC1 gain ; 01/23/2013 + tmp64 = (_meas_s64_)obj->info->adc2GainSlope; + tmp64 = tmp64*(obj->codeIntTemperature) + obj->info->adc2GainFactorB; + obj->info->adc2Gain = (_meas_s32_)tmp64; + + /// [AT-PM] : Calculate current ADC1 offset ; 01/23/2013 + tmp64 = (_meas_s64_)obj->info->adc2OffsetSlope; + tmp64 = tmp64*(obj->codeIntTemperature) + obj->info->adc2OffsetFactorO; + obj->info->adc2Offset = (_meas_s32_)tmp64; +} + +#define ADC1_IDEAL_CODE_100MV (614) +#define ADC1_IDEAL_CODE_200MV (1229) +#define ADC1_IDEAL_CODE_DELTA (ADC1_IDEAL_CODE_200MV - ADC1_IDEAL_CODE_100MV) + +/** + * @brief CalibrateAdc1Code + * + * Calibrate ADC1 code + * + * @para obj address of MeasDataInternalType + * @para code ADC1 code to be calibrated + * @return calibrated code + */ +_meas_s32_ CalibrateAdc1Code(MeasDataInternalType *obj, _meas_s32_ code) +{ + _meas_s64_ tmp64; + _meas_s32_ tmp32; + _meas_s32_ deltaIT; + _meas_s32_ gain; + _meas_s32_ offset; + + deltaIT = (_meas_s32_)obj->info->otp->aveIT80; + deltaIT = deltaIT - obj->info->otp->aveIT25; + + /// [AT-PM] : Pre-operation to avoid 64-bit division ; 01/23/2013 + gain = obj->info->adc1Gain; + offset = obj->info->adc1Offset; + while(1) + { + tmp64 = (_meas_s64_)code; + tmp64 = tmp64*deltaIT - offset; + tmp64 = tmp64*ADC1_IDEAL_CODE_DELTA; + if((tmp64 < 2147483647) && (tmp64 > -2147483647)) + { + break; + } + code = code/2; + deltaIT = deltaIT/2; + gain = gain/4; + offset = offset/4; + } + + tmp32 = (_meas_s32_)tmp64; + tmp32 = tmp32/gain; + return (tmp32); +} + +#define ADC2_IDEAL_CODE_100MV (ADC2_CP_CODE_25_100MV) +#define ADC2_IDEAL_CODE_200MV (ADC2_CP_CODE_25_200MV) +#define ADC2_IDEAL_CODE_DELTA (ADC2_IDEAL_CODE_200MV - ADC2_IDEAL_CODE_100MV) + +/** + * @brief CalibrateAdc2Code + * + * Calibrate ADC2 code + * + * @para obj address of MeasDataInternalType + * @para code ADC2 code to be calibrated + * @return calibrated code + */ +_meas_s32_ CalibrateAdc2Code(MeasDataInternalType *obj, _meas_s32_ code) +{ + _meas_s64_ tmp64; + _meas_s32_ tmp32; + _meas_s32_ deltaIT; + _meas_s32_ gain; + _meas_s32_ offset; + + deltaIT = (_meas_s32_)obj->info->otp->aveIT80; + deltaIT = deltaIT - obj->info->otp->aveIT25; + + /// [AT-PM] : Pre-operation to avoid 64-bit division ; 01/23/2013 + gain = obj->info->adc2Gain; + offset = obj->info->adc2Offset; + while(1) + { + tmp64 = (_meas_s64_)code; + tmp64 = tmp64*deltaIT - offset; + tmp64 = tmp64*ADC2_IDEAL_CODE_DELTA; + if((tmp64 < 2147483647) && (tmp64 > -2147483647)) + { + break; + } + code = code/2; + deltaIT = deltaIT/2; + gain = gain/4; + offset = offset/4; + } + + tmp32 = (_meas_s32_)tmp64; + tmp32 = tmp32/gain; + return (tmp32); +} + +#define IT_IDEAL_CODE_25 (24310) +#define IT_IDEAL_CODE_80 (28612) +#define IT_IDEAL_CODE_DELTA (IT_IDEAL_CODE_80 - IT_IDEAL_CODE_25) + +/** + * @brief CalibrateITCode + * + * Calibrate internal temperature code + * + * @para obj address of MeasDataInternalType + * @para itCode raw IT code + * @return calibrated IT code + */ +_meas_u16_ CalibrateITCode(MeasDataInternalType *obj, _meas_u16_ itCode) +{ + _meas_s32_ tmp32; + + tmp32 = (_meas_s32_)itCode; + tmp32 = tmp32 - obj->info->otp->aveIT25; + tmp32 = tmp32*IT_IDEAL_CODE_DELTA; + tmp32 = tmp32/(obj->info->otp->aveIT80 - obj->info->otp->aveIT25); + tmp32 = tmp32 + IT_IDEAL_CODE_25; + return ((_meas_u16_)tmp32); +} + +#define NORMAL_REGISTER (NORMAL) + +/** + * @brief CalibrateChargeCode + * + * Calibrate charge code + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void CalibrateChargeCode(MeasDataInternalType *obj) +{ + _meas_s32_ tmp32; + _meas_s64_ tmp64; + _meas_s32_ gain; + _meas_s32_ offset; + + UG31_LOGI("[%s]: Raw Code = %d\n", __func__, obj->codeCharge); + + /// [AT-PM] : Calibrate charge code ; 01/23/2013 + obj->info->rawCodeCharge = obj->codeCharge; + obj->info->codeCharge = CalibrateAdc1Code(obj, ((_meas_s32_)obj->codeCharge)*2); + + /// [AT-PM] : Calculate coulomb counter offset ; 01/23/2013 + tmp32 = obj->info->adc1Offset/(obj->info->otp->aveIT80 - obj->info->otp->aveIT25)*(-1); + tmp32 = tmp32 + obj->info->ccOffsetAdj; + obj->info->ccOffset = (_meas_s16_)tmp32; + + UG31_LOGI("[%s]: Calibrated Code = %d, Offset = %d (%d)\n", __func__, obj->info->codeCharge, obj->info->ccOffset, obj->info->ccOffsetAdj); + + /// [AT-PM] : Set coulomb counter offset ; 01/27/2013 + API_I2C_Write(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_ADC1_OFFSET_LOW, + REG_ADC1_OFFSET_HIGH - REG_ADC1_OFFSET_LOW + 1, + (unsigned char *)&obj->info->ccOffset); + + /// [AT-PM] : Remove the offset in calibrated charge code ; 01/23/2013 + gain = obj->info->adc1Gain; + offset = obj->info->adc1Offset; + while(1) + { + tmp64 = (_meas_s64_)offset; + tmp64 = tmp64*ADC1_IDEAL_CODE_DELTA; + if((tmp64 < 2147483647) && (tmp64 > -2147483647)) + { + break; + } + gain = gain/2; + offset = offset/2; + } + tmp32 = (_meas_s32_)tmp64; + tmp32 = tmp32/gain; + UG31_LOGI("[%s]: Compensation = %d x %d / %d\n", __func__, + obj->info->adc1Offset, ADC1_IDEAL_CODE_DELTA, obj->info->adc1Gain); + obj->info->codeCharge = obj->info->codeCharge + tmp32; + UG31_LOGI("[%s]: Charge = %d\n", __func__, obj->info->codeCharge); +} + +#define ADC2_VOLTAGE_100MV (3000) ///< [AT-PM] : Unit in mV ; 01/25/2013 +#define ADC2_VOLTAGE_200MV (4000) ///< [AT-PM] : Unit in mV ; 01/25/2013 +#define ADC2_VOLTAGE_DELTA (ADC2_VOLTAGE_200MV - ADC2_VOLTAGE_100MV) + +/** + * @brief ConvertBat1 + * + * Convert code of BAT1 + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertBat1(MeasDataInternalType *obj) +{ + _meas_s32_ tmp32; + + /// [AT-PM] : Convert from calibrated ADC code ; 01/25/2013 + tmp32 = (_meas_s32_)obj->info->codeBat1; + tmp32 = tmp32 - ADC2_IDEAL_CODE_100MV; + tmp32 = tmp32*ADC2_VOLTAGE_DELTA/ADC2_IDEAL_CODE_DELTA; + tmp32 = tmp32 + ADC2_VOLTAGE_100MV; + + /// [AT-PM] : Apply board factor ; 01/25/2013 + tmp32 = tmp32 - BOARD_FACTOR_VOLTAGE_OFFSET; + tmp32 = tmp32*BOARD_FACTOR_CONST/BOARD_FACTOR_VOLTAGE_GAIN; + + /// [AT-PM] : Apply calibration parameter ; 01/25/2013 + tmp32 = tmp32 - obj->info->sysData->ggbParameter->adc2_offset; + tmp32 = tmp32*CALIBRATION_FACTOR_CONST/obj->info->sysData->ggbParameter->adc2_gain; + obj->info->bat1Voltage = (_meas_u16_)tmp32; +} + +#define ADC1_VOLTAGE_100MV (-5000) ///< [AT-PM] : Unit in uV ; 01/25/2013 +#define ADC1_VOLTAGE_200MV (-10000) ///< [AT-PM] : Unit in uV ; 01/25/2013 +#define ADC1_VOLTAGE_DELTA (ADC1_VOLTAGE_200MV - ADC1_VOLTAGE_100MV) +/** + * @brief ConvertCurrent + * + * Convert code of Current + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertCurrent(MeasDataInternalType *obj) +{ + _meas_s32_ tmp32; + + /// [AT-PM] : Convert from calibrated ADC code ; 01/25/2013 + tmp32 = (_meas_s32_)obj->info->codeCurrent; + tmp32 = tmp32 - ADC1_IDEAL_CODE_100MV; + tmp32 = tmp32*ADC1_VOLTAGE_DELTA/ADC1_IDEAL_CODE_DELTA; + tmp32 = tmp32 + ADC1_VOLTAGE_100MV; + tmp32 = tmp32/obj->info->sysData->ggbParameter->rSense; + + /// [AT-PM] : Apply board factor ; 01/25/2013 + tmp32 = tmp32 - BOARD_FACTOR_CURR_OFFSET; + tmp32 = tmp32*BOARD_FACTOR_CONST/BOARD_FACTOR_CURR_GAIN; + + /// [AT-PM] : Apply calibration factor ; 01/25/2013 + tmp32 = tmp32 - obj->info->sysData->ggbParameter->adc1_pos_offset; + if(tmp32 > 0) + { + tmp32 = tmp32*CALIBRATION_FACTOR_CONST/obj->info->sysData->ggbParameter->adc1_pgain; + } + else + { + tmp32 = tmp32*CALIBRATION_FACTOR_CONST/obj->info->sysData->ggbParameter->adc1_ngain; + } + obj->info->curr = (_meas_s16_)tmp32; +} + +#define AMBIENT_TEMPERATURE_IN_FT (220) +#define IT_CONST (100) +#define IT_GAIN (392) +#define IT_OFFSET (11172) + +static _meas_s16_ FTAmbientMappingTable[] = +{ + AMBIENT_TEMPERATURE_IN_FT, ///< Index = 0 + AMBIENT_TEMPERATURE_IN_FT + 10, ///< Index = 1 + AMBIENT_TEMPERATURE_IN_FT - 10, ///< Index = 2 + AMBIENT_TEMPERATURE_IN_FT + 20, ///< Index = 3 + AMBIENT_TEMPERATURE_IN_FT - 20, ///< Index = 4 + AMBIENT_TEMPERATURE_IN_FT + 30, ///< Index = 5 + AMBIENT_TEMPERATURE_IN_FT - 30, ///< Index = 6 + AMBIENT_TEMPERATURE_IN_FT + 40, ///< Index = 7 + AMBIENT_TEMPERATURE_IN_FT - 40, ///< Index = 8 + AMBIENT_TEMPERATURE_IN_FT + 50, ///< Index = 9 + AMBIENT_TEMPERATURE_IN_FT - 50, ///< Index = 10 + AMBIENT_TEMPERATURE_IN_FT + 60, ///< Index = 11 + AMBIENT_TEMPERATURE_IN_FT - 60, ///< Index = 12 + AMBIENT_TEMPERATURE_IN_FT + 70, ///< Index = 13 + AMBIENT_TEMPERATURE_IN_FT - 70, ///< Index = 14 + AMBIENT_TEMPERATURE_IN_FT, ///< Index = 15 +}; + +/** + * @brief ConvertIntTemperature + * + * Convert code of internal temperature + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertIntTemperature(MeasDataInternalType *obj) +{ + _meas_s32_ tmp32; + _meas_s32_ ftIT; + + /// [AT-PM] : Convert from calibrated ADC code ; 01/25/2013 + tmp32 = (_meas_s32_)obj->info->codeIntTemperature; + tmp32 = tmp32/2; + tmp32 = tmp32 - IT_OFFSET; + tmp32 = tmp32*IT_CONST/IT_GAIN; + + /// [AT-PM] : Apply FT information ; 01/25/2013 + ftIT = (_meas_s32_)CalibrateITCode(obj, obj->info->otp->ftIT); + ftIT = ftIT/2; + ftIT = ftIT - IT_OFFSET; + ftIT = ftIT*IT_CONST/IT_GAIN; + tmp32 = tmp32 - (ftIT - FTAmbientMappingTable[obj->info->otp->deltaET]); + + /// [AT-PM] : Apply board factor ; 01/25/2013 + tmp32 = tmp32 - BOARD_FACTOR_INTT_OFFSET; + + /// [AT-PM] : Apply calibration factor ; 01/25/2013 + tmp32 = tmp32 - obj->info->sysData->ggbParameter->adc_d5; + obj->info->intTemperature = (_meas_s16_)tmp32; +} + +static _meas_s16_ ExtTemperatureTable[] = { + -100, ///< Index = 0 + -50, ///< Index = 1 + 0, ///< Index = 2 + 50, ///< Index = 3 + 100, ///< Index = 4 + 150, ///< Index = 5 + 200, ///< Index = 6 + 250, ///< Index = 7 + 300, ///< Index = 8 + 350, ///< Index = 9 + 400, ///< Index = 10 + 450, ///< Index = 11 + 500, ///< Index = 12 + 550, ///< Index = 13 + 600, ///< Index = 14 + 650, ///< Index = 15 + 700, ///< Index = 16 + 750, ///< Index = 17 + 800, ///< Index = 18 +}; + +/** + * @brief ConvertExtTemperature + * + * Convert code of external temperature + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertExtTemperature(MeasDataInternalType *obj) +{ + _meas_u8_ idx; + _meas_s32_ tmp32; + + idx = 0; + while(idx < ET_NUMS) + { + if(obj->info->codeExtTemperature >= obj->info->sysData->ggbParameter->rtTable[idx]) + { + break; + } + idx = idx + 1; + } + + if(idx == 0) + { + /// [AT-PM] : Minimum measurable temperature ; 01/25/2013 + tmp32 = (_meas_s32_)ExtTemperatureTable[0]; + } + else if(idx == ET_NUMS) + { + /// [AT-PM] : Maximum measurable temperature ; 01/25/2013 + tmp32 = (_meas_s32_)ExtTemperatureTable[ET_NUMS - 1]; + } + else + { + /// [AT-PM] : Calculate external temperature ; 01/25/2013 + tmp32 = (_meas_s32_)obj->info->codeExtTemperature; + tmp32 = tmp32 - obj->info->sysData->ggbParameter->rtTable[idx]; + tmp32 = tmp32*(ExtTemperatureTable[idx - 1] - ExtTemperatureTable[idx]); + tmp32 = tmp32/(obj->info->sysData->ggbParameter->rtTable[idx - 1] - obj->info->sysData->ggbParameter->rtTable[idx]); + tmp32 = tmp32 + ExtTemperatureTable[idx]; + } + + /// [AT-PM] : Apply board factor ; 01/25/2013 + tmp32 = tmp32 - BOARD_FACTOR_EXTT_OFFSET; + + /// [AT-PM] : Apply calibration factor ; 01/25/2013 + tmp32 = tmp32 - obj->info->sysData->ggbParameter->adc_d4; + obj->info->extTemperature = (_meas_s16_)tmp32; +} + +#define TIME_DEFAULT_ADC1_CONVERT_TIME (1253) +#define MINIMUM_ADC1_COUNTER_FOR_CONVERT_TIME (10) +#define MAXIMUM_ADC1_CONVERSION_TIME (0xf8) +#define MINIMUM_ADC1_CONVERSION_TIME (0x08) + +/** + * @brief CalculateAdc1ConvertTime + * + * Calculate ADC1 conversion time + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void CalculateAdc1ConvertTime(MeasDataInternalType *obj) +{ + _meas_u32_ tmp32; + + UG31_LOGI("[%s]: Initial conversion time = %d\n", __func__, obj->info->adc1ConvertTime); + + /// [AT-PM] : First time to calculate ADC1 conversion time ; 01/25/2013 + if(obj->info->adc1ConvertTime == 0) + { + obj->info->adc1ConvertTime = TIME_DEFAULT_ADC1_CONVERT_TIME; + obj->info->lastCounter = obj->codeCounter; + return; + } + + #ifdef uG31xx_BOOT_LOADER + /// [AT-PM] : In bootloader, ADC1 converstion time is not calculated ; 02/12/2013 + return; + #endif ///< end of uG31xx_BOOT_LOADER + + /// [AT-PM] : Check counter overflow or time overflow; 01/25/2013 + if((obj->codeCounter <= obj->info->lastCounter) || (obj->info->deltaTime == 0)) + { + obj->info->lastCounter = obj->codeCounter; + return; + } + + /// [AT-PM] : Limit the minimum counter ; 02/11/2013 + tmp32 = (_meas_u32_)obj->codeCounter; + tmp32 = tmp32 - obj->info->lastCounter; + if(tmp32 < MINIMUM_ADC1_COUNTER_FOR_CONVERT_TIME) + { + obj->info->lastCounter = obj->codeCounter; + return; + } + + /// [AT-PM] : Average ADC1 conversion time ; 01/25/2013 + tmp32 = obj->info->deltaTime; + tmp32 = tmp32*TIME_CONVERT_TIME_TO_MSEC/(obj->codeCounter - obj->info->lastCounter); + tmp32 = tmp32 + obj->info->adc1ConvertTime; + tmp32 = tmp32/2; + + /// [AT-PM] : Check conversion time is valid or not ; 02/13/2013 + if((tmp32 > (MAXIMUM_ADC1_CONVERSION_TIME*TIME_CONVERT_TIME_TO_MSEC)) || + (tmp32 < (MINIMUM_ADC1_CONVERSION_TIME*TIME_CONVERT_TIME_TO_MSEC))) + { + UG31_LOGI("[%s]: ***************************************************************************************\n", __func__); + UG31_LOGI("[%s]: ***************************************************************************************\n", __func__); + UG31_LOGI("[%s]: #### ##### ## ## #### ##### ## ## #### ## ###### ###### ## ## ######\n", __func__); + UG31_LOGI("[%s]: ## ## ## ## ### ## ## ## ## ## ### ### ## ## ## ###### ## ### ### ##\n", __func__); + UG31_LOGI("[%s]: ###### ##### ###### ## ## ##### ####### ###### ## ## ## ####### ###\n", __func__); + UG31_LOGI("[%s]: ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ##\n", __func__); + UG31_LOGI("[%s]: ## ## ##### ## ## #### ## ## ## ## ## ## ###### ## ###### ## ## ######\n", __func__); + UG31_LOGI("[%s]:\n", __func__); + UG31_LOGI("[%s]: Previous Time Tag = %d\n", __func__, obj->info->lastTimeTick - obj->info->deltaTime); + UG31_LOGI("[%s]: Current Time Tag = %d\n", __func__, obj->info->lastTimeTick); + UG31_LOGI("[%s]: Delta Time = %d\n", __func__, obj->info->deltaTime); + UG31_LOGI("[%s]: Previous ADC Count = %d\n", __func__, obj->info->lastCounter); + UG31_LOGI("[%s]: Current ADC Count = %d\n", __func__, obj->codeCounter); + UG31_LOGI("[%s]: Delta ADC Count = %d\n", __func__, obj->codeCounter - obj->info->lastCounter); + UG31_LOGI("[%s]: Old ADC Convert Time = %d\n", __func__, obj->info->adc1ConvertTime); + UG31_LOGI("[%s]: New ADC Convert Time = %d\n", __func__, tmp32); + UG31_LOGI("[%s]: ***************************************************************************************\n", __func__); + UG31_LOGI("[%s]: ***************************************************************************************\n", __func__); + tmp32 = (_meas_u32_)obj->info->adc1ConvertTime; + } + UG31_LOGI("[%s]: Conversion Time = %d ((%d - %d)/%d)\n", __func__, + tmp32, obj->codeCounter, obj->info->lastCounter, obj->info->deltaTime); + obj->info->adc1ConvertTime = (_meas_u16_)tmp32; + obj->info->lastCounter = obj->codeCounter; +} + +#define TIME_MSEC_TO_SEC (1000) +#define TIME_SEC_TO_HOUR (3600) +#define COULOMB_COUNTER_LSB (4096) + +/** + * @brief ConvertCharge + * + * Convert code of charge + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ConvertCharge(MeasDataInternalType *obj) +{ + _meas_s16_ tmp16; + _meas_s32_ tmp32; + _meas_s64_ tmp64; + + /// [AT-PM] : Convert from calibrated ADC code ; 01/25/2013 + tmp16 = ADC1_IDEAL_CODE_DELTA; + tmp32 = (_meas_s32_)obj->info->codeCharge; + tmp32 = tmp32 - ADC1_IDEAL_CODE_100MV; + while(1) + { + tmp64 = (_meas_s64_)tmp32; + tmp64 = tmp64*ADC1_VOLTAGE_DELTA; + if((tmp64 < 2147483647) && (tmp64 > -2147483647)) + { + break; + } + tmp16 = tmp16/2; + tmp32 = tmp32/2; + } + tmp32 = (_meas_s32_)tmp64; + tmp32 = tmp32/tmp16; + tmp32 = tmp32 + ADC1_VOLTAGE_100MV; + tmp32 = tmp32/obj->info->sysData->ggbParameter->rSense; + UG31_LOGI("[%s]: ((%d - %d) x %d / %d + %d) / %d = %d\n", __func__, + obj->info->codeCharge, ADC1_IDEAL_CODE_100MV, ADC1_VOLTAGE_DELTA, + ADC1_IDEAL_CODE_DELTA, ADC1_VOLTAGE_100MV, obj->info->sysData->ggbParameter->rSense, tmp32); + /// [AT-PM] : Apply board factor ; 01/25/2013 + tmp32 = tmp32 - BOARD_FACTOR_CURR_OFFSET; + tmp32 = tmp32*BOARD_FACTOR_CONST/BOARD_FACTOR_CURR_GAIN; + UG31_LOGI("[%s]: Board Factor (%d/%d) -> %d\n", __func__, + BOARD_FACTOR_CURR_GAIN, BOARD_FACTOR_CURR_OFFSET, tmp32); + + /// [AT-PM] : Apply calibration factor ; 01/25/2013 + tmp32 = tmp32 - obj->info->sysData->ggbParameter->adc1_pos_offset; + if(tmp32 > 0) + { + tmp32 = tmp32*CALIBRATION_FACTOR_CONST/obj->info->sysData->ggbParameter->adc1_pgain; + } + else + { + tmp32 = tmp32*CALIBRATION_FACTOR_CONST/obj->info->sysData->ggbParameter->adc1_ngain; + } + UG31_LOGI("[%s]: Calibration Factor (%d|%d/%d) -> %d\n", __func__, + obj->info->sysData->ggbParameter->adc1_pgain, obj->info->sysData->ggbParameter->adc1_ngain, + obj->info->sysData->ggbParameter->adc1_pos_offset, tmp32); + + /// [AT-PM] : Apply time information ; 01/25/2013 + CalculateAdc1ConvertTime(obj); + tmp32 = tmp32*(obj->info->adc1ConvertTime)/TIME_MSEC_TO_SEC*COULOMB_COUNTER_LSB/TIME_SEC_TO_HOUR; + tmp32 = tmp32/TIME_CONVERT_TIME_TO_MSEC; + + /// [AT-PM] : Update capacity information ; 01/25/2013 + obj->info->deltaCap = (_meas_s16_)tmp32; + obj->info->stepCap = obj->info->deltaCap - obj->info->lastDeltaCap; + obj->info->lastDeltaCap = obj->info->deltaCap; + UG31_LOGI("[%s]: Capacity = %d (%d)\n", __func__, obj->info->deltaCap, obj->info->stepCap); +} + +/** + * @brief TimeTick + * + * Get the time tick and calculate delta time + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void TimeTick(MeasDataInternalType *obj) +{ + obj->currTime = GetTickCount(); + + /// [AT-PM] : Prevent time tick overflow ; 01/25/2013 + if(obj->currTime <= obj->info->lastTimeTick) + { + obj->info->deltaTime = 0; + obj->info->lastTimeTick = obj->currTime; + UG31_LOGI("[%s]: OVERFLOW -> %d < %d\n", __func__, + obj->currTime, obj->info->lastTimeTick); + return; + } + + /// [AT-PM] : Calculate delta time ; 01/25/2013 + obj->info->deltaTime = obj->currTime - obj->info->lastTimeTick; + UG31_LOGI("[%s]: Delta Time = %d - %d = %d\n", __func__, + obj->currTime, obj->info->lastTimeTick, obj->info->deltaTime); + obj->info->lastTimeTick = obj->currTime; +} + +/** + * @brief ReadRegister + * + * Read measurement registers + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ReadRegister(MeasDataInternalType *obj) +{ + /// [AT-PM] : Read VBat1Ave ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_AVE_VBAT1_LOW, + REG_AVE_VBAT1_HIGH - REG_AVE_VBAT1_LOW + 1, + (unsigned char *)&obj->codeBat1); + + /// [AT-PM] : Read CurrentAve ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_AVE_CURRENT_LOW, + REG_AVE_CURRENT_HIGH - REG_AVE_CURRENT_LOW + 1, + (unsigned char *)&obj->codeCurrent); + + /// [AT-PM] : Read ITAve ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_AVE_IT_LOW, + REG_AVE_IT_HIGH - REG_AVE_IT_LOW + 1, + (unsigned char *)&obj->codeIntTemperature); + + /// [AT-PM] : Read ETAve ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_AVE_ET_LOW, + REG_AVE_ET_HIGH - REG_AVE_ET_LOW + 1, + (unsigned char *)&obj->codeExtTemperature); + + /// [AT-PM] : Read Charge ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_CHARGE_LOW, + REG_CHARGE_HIGH - REG_CHARGE_LOW + 1, + (unsigned char *)&obj->codeCharge); + + /// [AT-PM] : Read Counter ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_COUNTER_LOW, + REG_COUNTER_HIGH - REG_COUNTER_LOW + 1, + (unsigned char *)&obj->codeCounter); + + /// [AT-PM] : Read Offset ; 01/27/2013 + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_ADC1_OFFSET_LOW, + REG_ADC1_OFFSET_HIGH - REG_ADC1_OFFSET_LOW + 1, + (unsigned char *)&obj->ccOffset); +} + +/** + * @brief ResetCoulombCounter + * + * Reset coulomb counter + * + * @para obj address of MeasDataInternalType + * @return _UPI_NULL_ + */ +void ResetCoulombCounter(MeasDataInternalType *obj) +{ + _meas_u8_ tmp8; + + API_I2C_Read(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_CTRL1, + 1, + &tmp8); + tmp8 = tmp8 | CTRL1_GG_RST; + API_I2C_Write(NORMAL_REGISTER, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_CTRL1, + 1, + &tmp8); +} + +/** + * @brief RevertCalibrateAdc2Code + * + * Revert calibrated ADC2 code + * + * @para data address of MeasDataType + * @para caliCode calibrated ADC2 code + * @return raw ADC2 code + */ +_meas_s32_ RevertCalibrateAdc2Code(MeasDataType *data, _meas_s32_ caliCode) +{ + _meas_s64_ tmp64; + _meas_s32_ tmp32; + _meas_s32_ deltaIT; + _meas_s32_ gain; + _meas_s32_ offset; + _meas_s32_ constant; + + /// [AT-PM] : tmp32 = ( caliCode x gain / constant + offset ) / deltaIT ; 04/08/2013 + gain = data->adc2Gain; + offset = data->adc2Offset; + deltaIT = (_meas_s32_)data->otp->aveIT80; + deltaIT = deltaIT - data->otp->aveIT25; + constant = ADC2_IDEAL_CODE_DELTA; + while(1) + { + tmp64 = (_meas_s64_)caliCode; + tmp64 = tmp64*gain; + if((tmp64 < 2147483647) && (tmp64 > -2147483647)) + { + break; + } + caliCode = caliCode/2; + gain = gain/2; + constant = constant/4; + } + tmp32 = (_meas_s32_)tmp64; + tmp32 = tmp32/constant; + tmp32 = tmp32 + offset; + tmp32 = tmp32/deltaIT; + return (tmp32); +} + +/** + * @brief RevertBat1Code + * + * Revert VBat1 code + * + * @para data address of MeasDataType + * @para volt voltage in mV to be reverted + * @return adc2 vbat1 code + */ +_meas_u16_ RevertBat1Code(MeasDataType *data, _upi_s16_ volt) +{ + _meas_s32_ tmp32; + + tmp32 = (_meas_s32_)volt; + + /// [AT-PM] : Revert calibration parameter ; 04/08/2013 + tmp32 = tmp32*data->sysData->ggbParameter->adc2_gain/CALIBRATION_FACTOR_CONST; + tmp32 = tmp32 + data->sysData->ggbParameter->adc2_offset; + + /// [AT-PM] : Revert board factor ; 04/08/2013 + tmp32 = tmp32*BOARD_FACTOR_VOLTAGE_GAIN/BOARD_FACTOR_CONST; + tmp32 = tmp32 + BOARD_FACTOR_VOLTAGE_OFFSET; + + /// [AT-PM] : Revert to calibrated ADC code ; 04/08/2013 + tmp32 = tmp32 - ADC2_VOLTAGE_100MV; + tmp32 = tmp32*ADC2_IDEAL_CODE_DELTA/ADC2_VOLTAGE_DELTA; + tmp32 = tmp32 + ADC2_IDEAL_CODE_100MV; + + /// [AT-PM] : Revert to raw code ; 04/08/2013 + tmp32 = RevertCalibrateAdc2Code(data, tmp32); + return ((_meas_u16_)tmp32); +} + +/** + * @brief RevertETCode + * + * Revert ET code + * + * @para data address of MeasDataType + * @para et external temperature in 0.1oC to be reverted + * @return adc1 et code + */ +_meas_u16_ RevertETCode(MeasDataType *data, _upi_s16_ et) +{ + _meas_s32_ tmp32; + _meas_u8_ idx; + + tmp32 = (_meas_s32_)et; + + /// [AT-PM] : Revert calibration factor ; 04/08/2013 + tmp32 = tmp32 + data->sysData->ggbParameter->adc_d4; + + /// [AT-PM] : Revert board factor ; 04/08/2013 + tmp32 = tmp32 + BOARD_FACTOR_EXTT_OFFSET; + + /// [AT-PM] : Revert external temperature calculation ; 04/08/2013 + idx = 0; + while(idx < ET_NUMS) + { + if(tmp32 < ExtTemperatureTable[idx]) + { + break; + } + idx = idx + 1; + } + if(idx == 0) + { + tmp32 = (_meas_s32_)data->sysData->ggbParameter->rtTable[0]; + } + else if(idx >= ET_NUMS) + { + tmp32 = (_meas_s32_)data->sysData->ggbParameter->rtTable[ET_NUMS - 1]; + } + else + { + tmp32 = tmp32 - ExtTemperatureTable[idx - 1]; + tmp32 = tmp32*(data->sysData->ggbParameter->rtTable[idx] - data->sysData->ggbParameter->rtTable[idx - 1]); + tmp32 = tmp32/(ExtTemperatureTable[idx] - ExtTemperatureTable[idx - 1]); + tmp32 = tmp32 + data->sysData->ggbParameter->rtTable[idx - 1]; + } + return ((_meas_u16_)tmp32); +} + +/// ============================================= +/// [AT-PM] : Extern function region +/// ============================================= + +/** + * @brief UpiResetCoulombCounter + * + * Reset coulomb counter + * + * @para data address of MeasDataType + * @return _UPI_NULL_ + */ +void UpiResetCoulombCounter(MeasDataType *data) +{ + MeasDataInternalType *obj; + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + obj = (MeasDataInternalType *)malloc(sizeof(MeasDataInternalType)); + #else ///< else of uG31xx_BOOT_LOADER + obj = (MeasDataInternalType *)kmalloc(sizeof(MeasDataInternalType), GFP_KERNEL); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + obj = (MeasDataInternalType *)malloc(sizeof(MeasDataInternalType)); + #endif ///< end of defined(uG31xx_OS_ANDROID) + memset(obj, 0x00, sizeof(MeasDataInternalType)); + + obj->info = data; + + /// [AT-PM] : Get delta time ; 01/25/2013 + TimeTick(obj); + + /// [AT-PM] : Read ADC code ; 01/27/2013 + ReadRegister(obj); + + /// [AT-PM] : Reset coulomb counter ; 01/30/2013 + ResetCoulombCounter(obj); + + /// [AT-PM] : Convert ADC characteristic from OTP ; 01/23/2013 + ConvertAdc1Data(obj); + + /// [AT-PM] : Calculate ADC gain and offset ; 01/23/2013 + CalAdc1Factors(obj); + + /// [AT-PM] : Calibrate ADC code ; 01/23/2013 + data->codeCurrent = (_meas_s16_)CalibrateAdc1Code(obj, (_meas_s32_)obj->codeCurrent); + CalibrateChargeCode(obj); + + /// [AT-PM] : Convert into physical value ; 01/23/2013 + ConvertCurrent(obj); + ConvertCharge(obj); + data->lastDeltaCap = 0; + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + free(obj); + #else ///< else of uG31xx_BOOT_LOADER + kfree(obj); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + free(obj); + #endif ///< end of defined(uG31xx_OS_ANDROID) +} + +#define MAXIMUM_RETRY_CNT (5) +#define MINIMUM_VBAT1_CODE (ADC2_IDEAL_CODE_100MV/2) +#define MAXIMUM_CURRENT_CODE (ADC1_IDEAL_CODE_200MV*6) +#define MINIMUM_CURRENT_CODE (ADC1_IDEAL_CODE_200MV*(-6)) +#define MINIMUM_IT_CODE (IT_IDEAL_CODE_25/2) +#define MAXIMUM_IT_CODE (IT_IDEAL_CODE_80*11/10) +#define MINIMUM_ET_CODE (1000) +#define MAXIMUM_ET_CODE (28000) +#define RESET_CC_CURRENT_MAGIC_NUMBER (2) + +/** + * @brief UpiMeasurement + * + * Measurement routine + * + * @para data address of MeasDataType + * @return MEAS_RTN_CODE + */ +MEAS_RTN_CODE UpiMeasurement(MeasDataType *data) +{ + MeasDataInternalType *obj; + _meas_u8_ retry; + MEAS_RTN_CODE rtn; + _meas_s16_ standbyUpper; + _meas_s16_ standbyLower; + _meas_s16_ tmp16; + + UG31_LOGI("[%s]: Measurement version : %d\n", __func__, UG31XX_MEAS_VERSION); + + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + obj = (MeasDataInternalType *)malloc(sizeof(MeasDataInternalType)); + #else ///< else of uG31xx_BOOT_LOADER + obj = (MeasDataInternalType *)kmalloc(sizeof(MeasDataInternalType), GFP_KERNEL); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + obj = (MeasDataInternalType *)malloc(sizeof(MeasDataInternalType)); + #endif ///< end of defined(uG31xx_OS_ANDROID) + memset(obj, 0x00, sizeof(MeasDataInternalType)); + + obj->info = data; + rtn = MEAS_RTN_PASS; + + /// [AT-PM] : Get delta time ; 01/25/2013 + TimeTick(obj); + + /// [AT-PM] : Read ADC code ; 01/27/2013 + retry = 0; + while(retry < MAXIMUM_RETRY_CNT) + { + ReadRegister(obj); + + if(obj->codeBat1 < MINIMUM_VBAT1_CODE) + { + UG31_LOGE("[%s]: Voltage code %d < %d -> Retry %d\n", __func__, + obj->codeBat1, MINIMUM_VBAT1_CODE, retry); + rtn = MEAS_RTN_BATTERY_REMOVED; + } + else if(obj->codeCurrent < MINIMUM_CURRENT_CODE) + { + UG31_LOGE("[%s]: Current code %d < %d\n", __func__, + obj->codeCurrent, MINIMUM_CURRENT_CODE); + obj->codeCurrent = MINIMUM_CURRENT_CODE; + break; + } + else if(obj->codeCurrent > MAXIMUM_CURRENT_CODE) + { + UG31_LOGE("[%s]: Current code %d > %d\n", __func__, + obj->codeCurrent, MAXIMUM_CURRENT_CODE); + obj->codeCurrent = MAXIMUM_CURRENT_CODE; + break; + } + else if(obj->codeIntTemperature < MINIMUM_IT_CODE) + { + UG31_LOGE("[%s]: Internal Temperature code %d < %d -> Retry %d\n", __func__, + obj->codeIntTemperature, MINIMUM_IT_CODE, retry); + rtn = MEAS_RTN_ADC_ABNORMAL; + } + else if(obj->codeIntTemperature > MAXIMUM_IT_CODE) + { + UG31_LOGE("[%s]: Internal Temperature code %d > %d -> Retry %d\n", __func__, + obj->codeIntTemperature, MAXIMUM_IT_CODE, retry); + rtn = MEAS_RTN_ADC_ABNORMAL; + } + else if(obj->codeExtTemperature < MINIMUM_ET_CODE) + { + UG31_LOGE("[%s]: External Temperature code %d < %d -> Retry %d\n", __func__, + obj->codeExtTemperature, MINIMUM_ET_CODE, retry); + rtn = MEAS_RTN_NTC_SHORT; + #ifndef ENABLE_NTC_CHECK + break; + #endif ///< end of ENABLE_NTC_CHECK + } + else if(obj->codeExtTemperature > MAXIMUM_ET_CODE) + { + UG31_LOGE("[%s]: External Temperature code %d > %d -> Retry %d\n", __func__, + obj->codeExtTemperature, MAXIMUM_ET_CODE, retry); + rtn = MEAS_RTN_BATTERY_REMOVED; + #ifndef ENABLE_NTC_CHECK + break; + #endif ///< end of ENABLE_NTC_CHECK + } + else + { + break; + } + retry = retry + 1; + SleepMiniSecond(1000); + } + if(retry >= MAXIMUM_RETRY_CNT) + { + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + free(obj); + #else ///< else of uG31xx_BOOT_LOADER + kfree(obj); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + free(obj); + #endif ///< end of defined(uG31xx_OS_ANDROID) + return (rtn); + } + rtn = MEAS_RTN_PASS; + + /// [AT-PM] : Convert ADC characteristic from OTP ; 01/23/2013 + ConvertAdc1Data(obj); + ConvertAdc2Data(obj); + + /// [AT-PM] : Calculate ADC gain and offset ; 01/23/2013 + CalAdc1Factors(obj); + CalAdc2Factors(obj); + + /// [AT-PM] : Calibrate ADC code ; 01/23/2013 + data->codeBat1 = (_meas_u16_)CalibrateAdc2Code(obj, (_meas_s32_)obj->codeBat1); + UG31_LOGI("[%s]: VBat1 Code = %d -> %d\n", __func__, obj->codeBat1, data->codeBat1); + data->codeCurrent = (_meas_s16_)CalibrateAdc1Code(obj, (_meas_s32_)obj->codeCurrent); + UG31_LOGI("[%s]: Current Code = %d -> %d\n", __func__, obj->codeCurrent, data->codeCurrent); + CalibrateChargeCode(obj); + data->codeIntTemperature = CalibrateITCode(obj, obj->codeIntTemperature); + UG31_LOGI("[%s]: Internal Temperature Code = %d -> %d\n", __func__, + obj->codeIntTemperature, data->codeIntTemperature); + /// [AT-PM] : External temperature code ; 06/19/2013 + tmp16 = (_meas_s16_)obj->codeExtTemperature; + tmp16 = tmp16 - (obj->codeCurrent + obj->ccOffset); + if(data->codeExtTemperature != 0) + { + tmp16 = tmp16 - data->codeExtTemperature; + if(tmp16 < -200) + { + tmp16 = -200; + } + if(tmp16 > 200) + { + tmp16 = 200; + } + tmp16 = tmp16 + data->codeExtTemperature; + } + data->codeExtTemperature = (_meas_u16_)tmp16; + UG31_LOGI("[%s]: External Temperature Code = %d -> %d\n", __func__, + obj->codeExtTemperature, data->codeExtTemperature); + + /// [AT-PM] : Convert into physical value ; 01/23/2013 + ConvertBat1(obj); + ConvertCurrent(obj); + ConvertIntTemperature(obj); + ConvertExtTemperature(obj); + ConvertCharge(obj); + + /// [AT-PM] : Reset coulomb counter if necessary ; 01/27/2013 + standbyUpper = (_meas_s16_)obj->info->sysData->ggbParameter->standbyCurrent; + standbyUpper = standbyUpper/RESET_CC_CURRENT_MAGIC_NUMBER; + standbyLower = standbyUpper*(-1); + if((obj->codeCounter > COULOMB_COUNTER_RESET_THRESHOLD_COUNTER) || + (obj->codeCharge > COULOMB_COUNTER_RESET_THRESHOLD_CHARGE_CHG) || + (obj->codeCharge < COULOMB_COUNTER_RESET_THREDHOLD_CHARGE_DSG) || + ((obj->info->curr < standbyUpper) && + (obj->info->curr > standbyLower) && + (obj->codeCounter > CONST_CONVERSION_COUNT_THRESHOLD*RESET_CC_CURRENT_MAGIC_NUMBER))) + { + ResetCoulombCounter(obj); + data->lastDeltaCap = 0; + } + + #ifdef MEAS_FAKE_INT_TEMP + data->extTemperature = data->intTemperature; + data->intTemperature = MEAS_FAKE_INT_TEMP_OFFSET + data->intTemperature%100; + #endif ///< end of MEAS_FAKE_INT_TEMP + + UG31_LOGI("[%s]: %d mV / %d mA / %d 0.1oC / %d 0.1oC / %d mAh\n", __func__, + data->bat1Voltage, data->curr, data->intTemperature, data->extTemperature, data->deltaCap); + #if defined(uG31xx_OS_ANDROID) + #ifdef uG31xx_BOOT_LOADER + free(obj); + #else ///< else of uG31xx_BOOT_LOADER + kfree(obj); + #endif ///< end of uG31xx_BOOT_LOADER + #else ///< else of defined(uG31xx_OS_ANDROID) + free(obj); + #endif ///< end of defined(uG31xx_OS_ANDROID) + return (rtn); +} + +/** + * @brief UpiMeasAlarmThreshold + * + * Get alarm threshold + * + * @para data address of MeasDataType + * @return MEAS_RTN_CODE + */ +MEAS_RTN_CODE UpiMeasAlarmThreshold(MeasDataType *data) +{ + MEAS_RTN_CODE rtn; + + rtn = MEAS_RTN_PASS; + + /// [AT-PM] : Calculate UV alarm and release threshold ; 04/08/2013 + data->sysData->uvAlarm.alarmThrd = RevertBat1Code(data, data->sysData->ggbParameter->uvAlarm); + data->sysData->uvAlarm.releaseThrd = RevertBat1Code(data, data->sysData->ggbParameter->uvRelease); + UG31_LOGI("[%s]: UV Alarm -> %d / %d\n", __func__, + data->sysData->uvAlarm.alarmThrd, data->sysData->uvAlarm.releaseThrd); + + /// [AT-PM] : Calculate UET alarm and release threshold ; 04/08/2013 + data->sysData->uetAlarm.alarmThrd = RevertETCode(data, data->sysData->ggbParameter->uetAlarm); + data->sysData->uetAlarm.releaseThrd = RevertETCode(data, data->sysData->ggbParameter->uetRelease); + UG31_LOGI("[%s]: UET Alarm -> %d / %d\n", __func__, + data->sysData->uetAlarm.alarmThrd, data->sysData->uetAlarm.releaseThrd); + + /// [AT-PM] : Calculate OET alarm and release threshold ; 04/08/2013 + data->sysData->oetAlarm.alarmThrd = RevertETCode(data, data->sysData->ggbParameter->oetAlarm); + data->sysData->oetAlarm.releaseThrd = RevertETCode(data, data->sysData->ggbParameter->oetRelease); + UG31_LOGI("[%s]: OET Alarm -> %d / %d\n", __func__, + data->sysData->oetAlarm.alarmThrd, data->sysData->oetAlarm.releaseThrd); + + return (rtn); +} + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.h new file mode 100755 index 00000000..c6bcc76e --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Measurement.h @@ -0,0 +1,127 @@ +/** + * @filename uG31xx_API_Measurement.h + * + * Header for uG31xx measurement API + * + * @author AllenTeng + */ + +typedef signed char _meas_s8_; +typedef unsigned char _meas_u8_; +typedef signed short _meas_s16_; +typedef unsigned short _meas_u16_; +typedef signed long _meas_s32_; +typedef unsigned long _meas_u32_; +typedef signed long long _meas_s64_; + +#define UG31XX_MEAS_VERSION (9) + +#define BOARD_FACTOR_CONST (1000) +#define BOARD_FACTOR_VOLTAGE_GAIN (1000) ///< [AT-PM] : VBat1 board factor - gain ; 01/25/2013 +#define BOARD_FACTOR_VOLTAGE_OFFSET (0) ///< [AT-PM] : VBat1 board factor - offset ; 01/25/2013 +#define BOARD_FACTOR_CURR_GAIN (1014) ///< [AT-PM] : Current board factor - gain ; 01/25/2013 +#define BOARD_FACTOR_CURR_OFFSET (-7) ///< [AT-PM] : Current board factor - offset ; 01/25/2013 +#define BOARD_FACTOR_INTT_OFFSET (-23) ///< [AT-PM] : Internal Temperature board factor - offset ; 01/25/2013 +#define BOARD_FACTOR_EXTT_OFFSET (13) ///< [AT-PM] : External Temperature board factor - offset ; 01/25/2013 + +#define CALIBRATION_FACTOR_CONST (1000) + +#define COULOMB_COUNTER_RESET_THRESHOLD_COUNTER (10000) +#define COULOMB_COUNTER_RESET_THRESHOLD_CHARGE_CHG (30000) +#define COULOMB_COUNTER_RESET_THREDHOLD_CHARGE_DSG (-30000) + +typedef enum _MEAS_RTN_CODE { + MEAS_RTN_PASS = 0, + MEAS_RTN_BATTERY_REMOVED, + MEAS_RTN_ADC_ABNORMAL, + MEAS_RTN_NTC_SHORT, +} MEAS_RTN_CODE; + +typedef struct MeasDataST { + + /// [AT-PM] : System data ; 04/08/2013 + SystemDataType *sysData; + + /// [AT-PM] : OTP data ; 01/23/2013 + OtpDataType *otp; + + /// [AT-PM] : Physical value ; 01/23/2013 + _meas_u16_ bat1Voltage; + _meas_s16_ curr; + _meas_s16_ intTemperature; + _meas_s16_ extTemperature; + _meas_s16_ deltaCap; + _meas_s16_ stepCap; + _meas_u32_ deltaTime; + + + /// [AT-PM] : ADC code ; 01/23/2013 + _meas_u16_ codeBat1; + _meas_s16_ codeCurrent; + _meas_u16_ codeIntTemperature; + _meas_u16_ codeExtTemperature; + _meas_s32_ codeCharge; + _meas_s16_ rawCodeCharge; + + /// [AT-PM] : Coulomb counter offset ; 01/23/2013 + _meas_s16_ ccOffset; + _meas_s16_ ccOffsetAdj; + + /// [AT-PM] : ADC1 characteristic ; 01/23/2013 + _meas_u16_ adc1ConvertTime; + _meas_s32_ adc1Gain; + _meas_s32_ adc1GainSlope; + _meas_s32_ adc1GainFactorB; + _meas_s32_ adc1Offset; + _meas_s32_ adc1OffsetSlope; + _meas_s32_ adc1OffsetFactorO; + + /// [AT-PM] : ADC2 characteristic ; 01/23/2013 + _meas_s32_ adc2Gain; + _meas_s32_ adc2GainSlope; + _meas_s32_ adc2GainFactorB; + _meas_s32_ adc2Offset; + _meas_s32_ adc2OffsetSlope; + _meas_s32_ adc2OffsetFactorO; + + /// [AT-PM] : Previous information ; 01/25/2013 + _meas_u16_ lastCounter; + _meas_u32_ lastTimeTick; + _meas_s16_ lastDeltaCap; + +#if defined(uG31xx_OS_ANDROID) +} __attribute__ ((packed)) MeasDataType; +#else ///< else of defined(uG31xx_OS_ANDROID) +} MeasDataType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief UpiResetCoulombCounter + * + * Reset coulomb counter + * + * @para data address of MeasDataType + * @return _UPI_NULL_ + */ +extern void UpiResetCoulombCounter(MeasDataType *data); + +/** + * @brief UpiMeasurement + * + * Measurement routine + * + * @para data address of MeasDataType + * @return MEAS_RTN_CODE + */ +extern MEAS_RTN_CODE UpiMeasurement(MeasDataType *data); + +/** + * @brief UpiMeasAlarmThreshold + * + * Get alarm threshold + * + * @para data address of MeasDataType + * @return MEAS_RTN_CODE + */ +extern MEAS_RTN_CODE UpiMeasAlarmThreshold(MeasDataType *data); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.c new file mode 100755 index 00000000..0b1b2d1a --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.c @@ -0,0 +1,876 @@ +/** + * @filename uG31xx_API_Otp.cpp + * + * Convert OTP registers into readable value + * + * @author AllenTeng + */ + +#include "stdafx.h" //windows need this?? +#include "uG31xx_API.h" + +/// ============================================= +/// [AT-PM] : OTP register definition +/// ============================================= + +#define OTP1_OFFSET_E0 (0) + #define INDEX_ADC1_200_25_0 (1<<0) + #define INDEX_ADC1_200_25_1 (1<<1) + #define INDEX_ADC1_200_25_2 (1<<2) + #define INDEX_ADC1_200_25_3 (1<<3) + #define DELTA_VREF_0 (1<<4) + #define DELTA_VREF_1 (1<<5) + #define DELTA_VREF_2 (1<<6) + #define DELTA_VREF_3 (1<<7) + +#define OTP1_OFFSET_E1 (OTP1_OFFSET_E0 + 1) + #define INDEX_ADC1_100_25_0 (1<<0) + #define INDEX_ADC1_100_25_1 (1<<1) + #define INDEX_ADC1_100_25_2 (1<<2) + #define INDEX_ADC1_100_25_3 (1<<3) + #define FT_IT_3 (1<<4) + #define FT_IT_4 (1<<5) + #define FT_IT_5 (1<<6) + #define FT_IT_6 (1<<7) + +#define OTP1_OFFSET_E2 (OTP1_OFFSET_E1 + 1) + #define INDEX_ADC2_200_25_0 (1<<0) + #define INDEX_ADC2_200_25_1 (1<<1) + #define INDEX_ADC2_200_25_2 (1<<2) + #define INDEX_ADC2_200_25_3 (1<<3) + #define FT_IT_7 (1<<4) + #define FT_IT_8 (1<<5) + #define FT_IT_9 (1<<6) + #define FT_IT_10 (1<<7) + +#define OTP1_OFFSET_E3 (OTP1_OFFSET_E2 + 1) + #define INDEX_ADC2_100_25_0 (1<<0) + #define INDEX_ADC2_100_25_1 (1<<1) + #define INDEX_ADC2_100_25_2 (1<<2) + #define INDEX_ADC2_100_25_3 (1<<3) + #define FT_IT_11 (1<<4) + #define FT_IT_12 (1<<5) + #define FT_IT_13 (1<<6) + #define FT_IT_14 (1<<7) + +#define OTP2_OFFSET_F0 (0) + #define OTP2_OFFSET_F0_RSVD_0 (1<<0) + #define OTP2_OFFSET_F0_RSVD_1 (1<<1) + #define OTP2_OFFSET_F0_RSVD_2 (1<<2) + #define PRODUCT_TYPE_0 (1<<3) + #define PRODUCT_TYPE_1 (1<<4) + #define DELTA_ET_0 (1<<5) + #define INDEX_ADC2_100_25_4 (1<<6) + #define DELTA_ET_1 (1<<7) + +#define OTP2_OFFSET_F1 (OTP2_OFFSET_F0 + 1) + #define OTP2_OFFSET_F1_RSVD_0 (1<<0) + #define OTP2_OFFSET_F1_RSVD_1 (1<<1) + #define OTP2_OFFSET_F1_RSVD_2 (1<<2) + #define OTP2_OFFSET_F1_RSVD_3 (1<<3) + #define OTP2_OFFSET_F1_RSVD_4 (1<<4) + #define OTP2_OFFSET_F1_RSVD_5 (1<<5) + #define OTP2_OFFSET_F1_RSVD_6 (1<<6) + #define OTP2_OFFSET_F1_RSVD_7 (1<<7) + +#define OTP2_OFFSET_F2 (OTP2_OFFSET_F1 + 1) + #define OTP2_OFFSET_F2_RSVD_0 (1<<0) + #define OTP2_OFFSET_F2_RSVD_1 (1<<1) + #define OTP2_OFFSET_F2_RSVD_2 (1<<2) + #define OTP_CELL_EN_0 (1<<3) + #define OTP_CELL_EN_1 (1<<4) + #define OTP_CELL_EN_2 (1<<5) + #define OTP_CELL_EN_3 (1<<6) + #define OTP_CELL_EN_4 (1<<7) + +#define OTP2_OFFSET_F3 (OTP2_OFFSET_F2 + 1) + #define OTP2_OFFSET_F3_RSVD_0 (1<<0) + #define OTP2_OFFSET_F3_RSVD_1 (1<<1) + #define OTP2_OFFSET_F3_RSVD_2 (1<<2) + #define OTP2_OFFSET_F3_RSVD_3 (1<<3) + #define OTP2_OFFSET_F3_RSVD_4 (1<<4) + #define OTP2_OFFSET_F3_RSVD_5 (1<<5) + #define OTP2_OFFSET_F3_RSVD_6 (1<<6) + #define OTP2_OFFSET_F3_RSVD_7 (1<<7) + +#define OTP2_OFFSET_F4 (OTP2_OFFSET_F3 + 1) + #define ADC1_DELTA_CODE_25_200MV_8 (1<<0) + #define ADC1_DELTA_CODE_25_200MV_9 (1<<1) + #define DEV_ADDR_0 (1<<2) + #define DEV_ADDR_1 (1<<3) + #define DEV_ADDR_2 (1<<4) + #define DEV_ADDR_7 (1<<5) + #define DEV_ADDR_8 (1<<6) + #define DEV_ADDR_9 (1<<7) + +#define OTP2_OFFSET_F5 (OTP2_OFFSET_F4 + 1) + #define OTP2_OFFSET_F5_RSVD_0 (1<<0) + #define OTP2_OFFSET_F5_RSVD_1 (1<<1) + #define BGR_TUNE_0 (1<<2) + #define BGR_TUNE_1 (1<<3) + #define BGR_TUNE_2 (1<<4) + #define BGR_TUNE_3 (1<<5) + #define BGR_TUNE_4 (1<<6) + #define BGR_TUNE_5 (1<<7) + +#define OTP2_OFFSET_F6 (OTP2_OFFSET_F5 + 1) + #define OSC_DELTA_CODE_25_0 (1<<0) + #define OSC_DELTA_CODE_25_1 (1<<1) + #define OSC_DELTA_CODE_25_2 (1<<2) + #define OSC_DELTA_CODE_25_3 (1<<3) + #define OSC_DELTA_CODE_25_4 (1<<4) + #define OSC_DELTA_CODE_25_5 (1<<5) + #define OSC_DELTA_CODE_25_6 (1<<6) + #define OSC_DELTA_CODE_25_7 (1<<7) + +#define OTP2_OFFSET_F7 (OTP2_OFFSET_F6 + 1) + #define OSC_DELTA_CODE_80_0 (1<<0) + #define OSC_DELTA_CODE_80_1 (1<<1) + #define OSC_DELTA_CODE_80_2 (1<<2) + #define OSC_DELTA_CODE_80_3 (1<<3) + #define OSC_DELTA_CODE_80_4 (1<<4) + #define OSC_DELTA_CODE_80_5 (1<<5) + #define OSC_DELTA_CODE_80_6 (1<<6) + #define OSC_DELTA_CODE_80_7 (1<<7) + +#define OTP2_OFFSET_F8 (OTP2_OFFSET_F7 + 1) + #define ADC1_DELTA_CODE_25_200MV_0 (1<<0) + #define ADC1_DELTA_CODE_25_200MV_1 (1<<1) + #define ADC1_DELTA_CODE_25_200MV_2 (1<<2) + #define ADC1_DELTA_CODE_25_200MV_3 (1<<3) + #define ADC1_DELTA_CODE_25_200MV_4 (1<<4) + #define ADC1_DELTA_CODE_25_200MV_5 (1<<5) + #define ADC1_DELTA_CODE_25_200MV_6 (1<<6) + #define ADC1_DELTA_CODE_25_200MV_7 (1<<7) + +#define OTP2_OFFSET_F9 (OTP2_OFFSET_F8 + 1) + #define OTP2_OFFSET_F9_RSVD_0 (1<<0) + #define OTP2_OFFSET_F9_RSVD_1 (1<<1) + #define OTP2_OFFSET_F9_RSVD_2 (1<<2) + #define OTP2_OFFSET_F9_RSVD_3 (1<<3) + #define OTP2_OFFSET_F9_RSVD_4 (1<<4) + #define OTP2_OFFSET_F9_RSVD_5 (1<<5) + #define OTP2_OFFSET_F9_RSVD_6 (1<<6) + #define OTP2_OFFSET_F9_RSVD_7 (1<<7) + +#define OTP2_OFFSET_FA (OTP2_OFFSET_F9 + 1) + #define ADC1_DELTA_CODE_25_100MV_0 (1<<0) + #define ADC1_DELTA_CODE_25_100MV_1 (1<<1) + #define ADC1_DELTA_CODE_25_100MV_2 (1<<2) + #define ADC1_DELTA_CODE_25_100MV_3 (1<<3) + #define ADC1_DELTA_CODE_25_100MV_4 (1<<4) + #define ADC1_DELTA_CODE_25_100MV_5 (1<<5) + #define ADC1_DELTA_CODE_25_100MV_6 (1<<6) + #define ADC1_DELTA_CODE_25_100MV_7 (1<<7) + +#define OTP2_OFFSET_FB (OTP2_OFFSET_FA + 1) + #define OTP2_OFFSET_FB_RSVD_0 (1<<0) + #define OTP2_OFFSET_FB_RSVD_1 (1<<1) + #define OTP2_OFFSET_FB_RSVD_2 (1<<2) + #define OTP2_OFFSET_FB_RSVD_3 (1<<3) + #define OTP2_OFFSET_FB_RSVD_4 (1<<4) + #define OTP2_OFFSET_FB_RSVD_5 (1<<5) + #define OTP2_OFFSET_FB_RSVD_6 (1<<6) + #define OTP2_OFFSET_FB_RSVD_7 (1<<7) + +#define OTP2_OFFSET_FC (OTP2_OFFSET_FB + 1) + #define ADC1_DELTA_CODE_25_100MV_8 (1<<0) + #define ADC2_DELTA_CODE_25_100MV_0 (1<<1) + #define ADC2_DELTA_CODE_25_100MV_1 (1<<2) + #define ADC2_DELTA_CODE_25_100MV_2 (1<<3) + #define ADC2_DELTA_CODE_25_100MV_3 (1<<4) + #define ADC2_DELTA_CODE_25_100MV_4 (1<<5) + #define ADC2_DELTA_CODE_25_100MV_5 (1<<6) + #define ADC2_DELTA_CODE_25_100MV_6 (1<<7) + +#define OTP2_OFFSET_FD (OTP2_OFFSET_FC + 1) + #define OTP2_OFFSET_FD_RSVD_0 (1<<0) + #define OTP2_OFFSET_FD_RSVD_1 (1<<1) + #define OTP2_OFFSET_FD_RSVD_2 (1<<2) + #define OTP2_OFFSET_FD_RSVD_3 (1<<3) + #define OTP2_OFFSET_FD_RSVD_4 (1<<4) + #define OTP2_OFFSET_FD_RSVD_5 (1<<5) + #define OTP2_OFFSET_FD_RSVD_6 (1<<6) + #define OTP2_OFFSET_FD_RSVD_7 (1<<7) + +#define OTP2_OFFSET_FE (OTP2_OFFSET_FD + 1) + #define ADC2_DELTA_CODE_25_200MV_0 (1<<0) + #define ADC2_DELTA_CODE_25_200MV_1 (1<<1) + #define ADC2_DELTA_CODE_25_200MV_2 (1<<2) + #define ADC2_DELTA_CODE_25_200MV_3 (1<<3) + #define ADC2_DELTA_CODE_25_200MV_4 (1<<4) + #define ADC2_DELTA_CODE_25_200MV_5 (1<<5) + #define ADC2_DELTA_CODE_25_200MV_6 (1<<6) + #define ADC2_DELTA_CODE_25_200MV_7 (1<<7) + +#define OTP2_OFFSET_FF (OTP2_OFFSET_FE + 1) + #define OTP2_OFFSET_FF_RSVD_0 (1<<0) + #define OTP2_OFFSET_FF_RSVD_1 (1<<1) + #define OTP2_OFFSET_FF_RSVD_2 (1<<2) + #define OTP2_OFFSET_FF_RSVD_3 (1<<3) + #define OTP2_OFFSET_FF_RSVD_4 (1<<4) + #define OTP2_OFFSET_FF_RSVD_5 (1<<5) + #define OTP2_OFFSET_FF_RSVD_6 (1<<6) + #define OTP2_OFFSET_FF_RSVD_7 (1<<7) + + +#define OTP3_OFFSET_70 (0) + #define DELTA_VREF_4 (1<<0) + #define DELTA_ET_2 (1<<1) + #define DELTA_ET_3 (1<<2) + #define AVE_IT_25_3 (1<<3) + #define AVE_IT_25_4 (1<<4) + #define AVE_IT_25_5 (1<<5) + #define AVE_IT_25_6 (1<<6) + #define AVE_IT_25_7 (1<<7) + +#define OTP3_OFFSET_71 (OTP3_OFFSET_70 + 1) + #define AVE_IT_25_8 (1<<0) + #define AVE_IT_25_9 (1<<1) + #define AVE_IT_25_10 (1<<2) + #define AVE_IT_25_11 (1<<3) + #define AVE_IT_25_12 (1<<4) + #define AVE_IT_25_13 (1<<5) + #define AVE_IT_25_14 (1<<6) + #define AVE_IT_25_15 (1<<7) + +#define OTP3_OFFSET_72 (OTP3_OFFSET_71 + 1) + #define INDEX_ADC2_200_25_4 (1<<0) + #define INDEX_ADC1_100_25_4 (1<<1) + #define INDEX_ADC1_200_25_4 (1<<2) + #define AVE_IT_80_3 (1<<3) + #define AVE_IT_80_4 (1<<4) + #define AVE_IT_80_5 (1<<5) + #define AVE_IT_80_6 (1<<6) + #define AVE_IT_80_7 (1<<7) + +#define OTP3_OFFSET_73 (OTP3_OFFSET_72 + 1) + #define AVE_IT_80_8 (1<<0) + #define AVE_IT_80_9 (1<<1) + #define AVE_IT_80_10 (1<<2) + #define AVE_IT_80_11 (1<<3) + #define AVE_IT_80_12 (1<<4) + #define AVE_IT_80_13 (1<<5) + #define AVE_IT_80_14 (1<<6) + #define AVE_IT_80_15 (1<<7) + +/// ============================================= +/// [AT-PM] : OTP register conversion routine +/// ============================================= + +/** + * @brief ConvOtp1E0 + * + * Convert OTP1 0xE0 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp1E0(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp1[OTP1_OFFSET_E0]; + + obj->indexAdc1V200T25 = obj->indexAdc1V200T25 + (value & (INDEX_ADC1_200_25_0 | + INDEX_ADC1_200_25_1 | + INDEX_ADC1_200_25_2 | + INDEX_ADC1_200_25_3)); + + obj->deltaVref = obj->deltaVref + ((value & (DELTA_VREF_0| DELTA_VREF_1 | DELTA_VREF_2 | DELTA_VREF_3)) >> 4); +} + +/** + * @brief ConvOtp1E1 + * + * Convert OTP1 0xE1 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp1E1(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp1[OTP1_OFFSET_E1]; + + obj->indexAdc1V100T25 = obj->indexAdc1V100T25 + (value & (INDEX_ADC1_100_25_0 | + INDEX_ADC1_100_25_1 | + INDEX_ADC1_100_25_2 | + INDEX_ADC1_100_25_3)); + + obj->ftIT = obj->ftIT + ((value & (FT_IT_3 | FT_IT_4 | FT_IT_5 | FT_IT_6)) >> 1); +} + +/** + * @brief ConvOtp1E2 + * + * Convert OTP1 0xE2 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp1E2(OtpDataType *obj) +{ + _otp_u8_ value; + _otp_u16_ tmp; + + value = obj->otp1[OTP1_OFFSET_E2]; + + obj->indexAdc2V200T25 = obj->indexAdc2V200T25 + (value & (INDEX_ADC2_200_25_0 | + INDEX_ADC2_200_25_1 | + INDEX_ADC2_200_25_2 | + INDEX_ADC2_200_25_3)); + + tmp = (value & (FT_IT_7 | FT_IT_8 | FT_IT_9 | FT_IT_10)); + obj->ftIT = obj->ftIT + (tmp << 3); +} + +/** + * @brief ConvOtp1E3 + * + * Convert OTP1 0xE3 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp1E3(OtpDataType *obj) +{ + _otp_u8_ value; + _otp_u16_ tmp; + + value = obj->otp1[OTP1_OFFSET_E3]; + + obj->indexAdc2V100T25 = obj->indexAdc2V100T25 + (value & (INDEX_ADC2_100_25_0 | + INDEX_ADC2_100_25_1 | + INDEX_ADC2_100_25_2 | + INDEX_ADC2_100_25_3)); + + tmp = (value & (FT_IT_11 | FT_IT_12 | FT_IT_13 | FT_IT_14)); + obj->ftIT = obj->ftIT + (tmp << 7); +} + +/** + * @brief ConvOtp2F0 + * + * Convert OTP2 0xF0 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F0(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_F0]; + + obj->productType = (value & (PRODUCT_TYPE_0 | PRODUCT_TYPE_1)) >> 3; + + obj->deltaET = obj->deltaET + ((value & DELTA_ET_0) >> 5) + ((value & DELTA_ET_1) >> 6); + + obj->indexAdc2V100T25 = obj->indexAdc2V100T25 + ((value & INDEX_ADC2_100_25_4) >> 2); +} + +/** + * @brief ConvOtp2F1 + * + * Convert OTP2 0xF1 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F1(OtpDataType *obj) +{ +} + +/** + * @brief ConvOtp2F2 + * + * Convert OTP2 0xF2 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F2(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_F2]; + + obj->otpCellEN = obj->otpCellEN + ((value & (OTP_CELL_EN_0 | + OTP_CELL_EN_1 | + OTP_CELL_EN_2 | + OTP_CELL_EN_3 | + OTP_CELL_EN_4)) >> 3); +} + +/** + * @brief ConvOtp2F3 + * + * Convert OTP2 0xF3 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F3(OtpDataType *obj) +{ +} + +/** + * @brief ConvOtp2F4 + * + * Convert OTP2 0xF4 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F4(OtpDataType *obj) +{ + _otp_u8_ value; + _otp_u16_ tmp; + + value = obj->otp2[OTP2_OFFSET_F4]; + + tmp = value & (ADC1_DELTA_CODE_25_200MV_8| ADC1_DELTA_CODE_25_200MV_9); + obj->adc1DeltaCodeT25V200 = obj->adc1DeltaCodeT25V200 + (tmp << 8); + + tmp = value & (DEV_ADDR_7 | DEV_ADDR_8 | DEV_ADDR_9); + obj->devAddr = (tmp << 2) + ((value & (DEV_ADDR_0 | DEV_ADDR_1 | DEV_ADDR_2)) >> 2); +} + +/** + * @brief ConvOtp2F5 + * + * Convert OTP2 0xF5 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F5(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_F5]; + + obj->bgrTune = obj->bgrTune + ((value & (BGR_TUNE_0 | + BGR_TUNE_1 | + BGR_TUNE_2 | + BGR_TUNE_3 | + BGR_TUNE_4 | + BGR_TUNE_5)) >> 2); +} + +/** + * @brief ConvOtp2F6 + * + * Convert OTP2 0xF6 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F6(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_F6]; + + obj->oscDeltaCode25 = obj->oscDeltaCode25 + (value & (OSC_DELTA_CODE_25_0 | + OSC_DELTA_CODE_25_1 | + OSC_DELTA_CODE_25_2 | + OSC_DELTA_CODE_25_3 | + OSC_DELTA_CODE_25_4 | + OSC_DELTA_CODE_25_5 | + OSC_DELTA_CODE_25_6 | + OSC_DELTA_CODE_25_7)); +} + +/** + * @brief ConvOtp2F7 + * + * Convert OTP2 0xF7 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F7(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_F7]; + + obj->oscDeltaCode80 = obj->oscDeltaCode80 + (value & (OSC_DELTA_CODE_80_0 | + OSC_DELTA_CODE_80_1 | + OSC_DELTA_CODE_80_2 | + OSC_DELTA_CODE_80_3 | + OSC_DELTA_CODE_80_4 | + OSC_DELTA_CODE_80_5 | + OSC_DELTA_CODE_80_6 | + OSC_DELTA_CODE_80_7)); +} + +/** + * @brief ConvOtp2F8 + * + * Convert OTP2 0xF8 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F8(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_F8]; + + obj->adc1DeltaCodeT25V200 = obj->adc1DeltaCodeT25V200 + (value & (ADC1_DELTA_CODE_25_200MV_0 | + ADC1_DELTA_CODE_25_200MV_1 | + ADC1_DELTA_CODE_25_200MV_2 | + ADC1_DELTA_CODE_25_200MV_3 | + ADC1_DELTA_CODE_25_200MV_4 | + ADC1_DELTA_CODE_25_200MV_5 | + ADC1_DELTA_CODE_25_200MV_6 | + ADC1_DELTA_CODE_25_200MV_7)); +} + +/** + * @brief ConvOtp2F9 + * + * Convert OTP2 0xF9 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2F9(OtpDataType *obj) +{ +} + +/** + * @brief ConvOtp2FA + * + * Convert OTP2 0xFA + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2FA(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_FA]; + + obj->adc1DeltaCodeT25V100 = obj->adc1DeltaCodeT25V100 + (value & (ADC1_DELTA_CODE_25_100MV_0 | + ADC1_DELTA_CODE_25_100MV_1 | + ADC1_DELTA_CODE_25_100MV_2 | + ADC1_DELTA_CODE_25_100MV_3 | + ADC1_DELTA_CODE_25_100MV_4 | + ADC1_DELTA_CODE_25_100MV_5 | + ADC1_DELTA_CODE_25_100MV_6 | + ADC1_DELTA_CODE_25_100MV_7)); +} + +/** + * @brief ConvOtp2FB + * + * Convert OTP2 0xFB + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2FB(OtpDataType *obj) +{ +} + +/** + * @brief ConvOtp2FC + * + * Convert OTP2 0xFC + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2FC(OtpDataType *obj) +{ + _otp_u8_ value; + _otp_u16_ tmp; + + value = obj->otp2[OTP2_OFFSET_FC]; + + tmp = value & ADC1_DELTA_CODE_25_100MV_8; + obj->adc1DeltaCodeT25V100 = obj->adc1DeltaCodeT25V100 + (tmp << 8); + + obj->adc2DeltaCodeT25V100 = obj->adc2DeltaCodeT25V100 + ((value & (ADC2_DELTA_CODE_25_100MV_0 | + ADC2_DELTA_CODE_25_100MV_1 | + ADC2_DELTA_CODE_25_100MV_2 | + ADC2_DELTA_CODE_25_100MV_3 | + ADC2_DELTA_CODE_25_100MV_4 | + ADC2_DELTA_CODE_25_100MV_5 | + ADC2_DELTA_CODE_25_100MV_6)) >> 1); +} + +/** + * @brief ConvOtp2FD + * + * Convert OTP2 0xFD + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2FD(OtpDataType *obj) +{ +} + +/** + * @brief ConvOtp2FE + * + * Convert OTP2 0xFE + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2FE(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp2[OTP2_OFFSET_FE]; + + obj->adc2DeltaCodeT25V200 = obj->adc2DeltaCodeT25V200 + (value & (ADC2_DELTA_CODE_25_200MV_0 | + ADC2_DELTA_CODE_25_200MV_1 | + ADC2_DELTA_CODE_25_200MV_2 | + ADC2_DELTA_CODE_25_200MV_3 | + ADC2_DELTA_CODE_25_200MV_4 | + ADC2_DELTA_CODE_25_200MV_5 | + ADC2_DELTA_CODE_25_200MV_6 | + ADC2_DELTA_CODE_25_200MV_7)); +} + +/** + * @brief ConvOtp2FF + * + * Convert OTP2 0xFF + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp2FF(OtpDataType *obj) +{ +} + +/** + * @brief ConvOtp370 + * + * Convert OTP3 0x70 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp370(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp3[OTP3_OFFSET_70]; + + obj->deltaVref = obj->deltaVref + ((value & DELTA_VREF_4) << 4); + + obj->deltaET = obj->deltaET + ((value & (DELTA_ET_2 | DELTA_ET_3)) << 1); + + obj->aveIT25 = obj->aveIT25 + (value & (AVE_IT_25_3 | AVE_IT_25_4 | AVE_IT_25_5 | AVE_IT_25_6 | AVE_IT_25_7)); +} + +/** + * @brief ConvOtp371 + * + * Convert OTP3 0x71 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp371(OtpDataType *obj) +{ + _otp_u8_ value; + _otp_u16_ tmp; + + value = obj->otp3[OTP3_OFFSET_71]; + + tmp = value & (AVE_IT_25_8 | + AVE_IT_25_9 | + AVE_IT_25_10 | + AVE_IT_25_11 | + AVE_IT_25_12 | + AVE_IT_25_13 | + AVE_IT_25_14 | + AVE_IT_25_15); + obj->aveIT25 = obj->aveIT25 + (tmp << 8); +} + +/** + * @brief ConvOtp372 + * + * Convert OTP3 0x72 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp372(OtpDataType *obj) +{ + _otp_u8_ value; + + value = obj->otp3[OTP3_OFFSET_72]; + + obj->indexAdc2V200T25 = obj->indexAdc2V200T25 + ((value & INDEX_ADC2_200_25_4) << 4); + + obj->indexAdc1V100T25 = obj->indexAdc1V100T25 + ((value & INDEX_ADC1_100_25_4) << 3); + + obj->indexAdc1V200T25 = obj->indexAdc1V200T25 + ((value & INDEX_ADC1_200_25_4) << 2); + + obj->aveIT80 = obj->aveIT80 + (value & (AVE_IT_80_3 | AVE_IT_80_4 | AVE_IT_80_5 | AVE_IT_80_6 | AVE_IT_80_7)); +} + +/** + * @brief ConvOtp373 + * + * Convert OTP3 0x73 + * + * @para obj address of OtpDataType + * @return _UPI_NULL_ + */ +void ConvOtp373(OtpDataType *obj) +{ + _otp_u8_ value; + _otp_u16_ tmp; + + value = obj->otp3[OTP3_OFFSET_73]; + + tmp = value & (AVE_IT_80_8 | + AVE_IT_80_9 | + AVE_IT_80_10 | + AVE_IT_80_11 | + AVE_IT_80_12 | + AVE_IT_80_13 | + AVE_IT_80_14 | + AVE_IT_80_15); + obj->aveIT80 = obj->aveIT80 + (tmp << 8); +} + +#define CONV_FUNC_PTR_NULL (0) + +typedef void (*ConvFuncPtr)(OtpDataType *obj); + +static ConvFuncPtr ConvFuncTable[] = { + ConvOtp1E0, + ConvOtp1E1, + ConvOtp1E2, + ConvOtp1E3, + + ConvOtp2F0, + ConvOtp2F1, + ConvOtp2F2, + ConvOtp2F3, + ConvOtp2F4, + ConvOtp2F5, + ConvOtp2F6, + ConvOtp2F7, + ConvOtp2F8, + ConvOtp2F9, + ConvOtp2FA, + ConvOtp2FB, + ConvOtp2FC, + ConvOtp2FD, + ConvOtp2FE, + ConvOtp2FF, + + ConvOtp370, + ConvOtp371, + ConvOtp372, + ConvOtp373, + + CONV_FUNC_PTR_NULL, +}; + +/** + * @brief CheckOtpISEmpty + * + * Check OTP is empty or not + * + * @para data address of OtpDataType + * @return _UPI_NULL_ + */ +void CheckOtpISEmpty(OtpDataType *data) +{ + _otp_u8_ idx; + + /// [AT-PM] : Check OTP1 ; 01/25/2013 + idx = 0; + while(idx < OTP1_SIZE) + { + if(data->otp1[idx] != 0) + { + data->empty = OTP_IS_NOT_EMPTY; + return; + } + } + + /// [AT-PM] : Check OTP2 ; 01/25/2013 + idx = 0; + while(idx < OTP2_SIZE) + { + if(data->otp2[idx] != 0) + { + data->empty = OTP_IS_NOT_EMPTY; + return; + } + } + + /// [AT-PM] : Check OTP3 ; 01/25/2013 + idx = 0; + while(idx < OTP3_SIZE) + { + if(data->otp3[idx] != 0) + { + data->empty = OTP_IS_NOT_EMPTY; + return; + } + } + + /// [AT-PM] : Set OTP is empty ; 01/25/2013 + data->empty = OTP_IS_EMPTY; +} + +/// ============================================= +/// [AT-PM] : Extern function region +/// ============================================= + +/** + * @brief UpiConvertOtp + * + * Convert OTP register value to readable value + * + * @para data address of OtpDataType + * @return _UPI_NULL_ + */ +void UpiConvertOtp(OtpDataType *data) +{ + _otp_u8_ idx; + + UG31_LOGI("[%s]: OTP version : %d.%02x\n", __func__, UG31XX_OTP_VERSION_MAIN, UG31XX_OTP_VERSION_SUB); + + /// [AT-PM] : Set version ; 01/25/2013 + data->versionMain = UG31XX_OTP_VERSION_MAIN; + data->versionSub = UG31XX_OTP_VERSION_SUB; + + /// [AT-PM] : Conversion ; 01/23/2013 + idx = 0; + while(1) + { + (*ConvFuncTable[idx])(data); + + idx = idx + 1; + if(ConvFuncTable[idx] == CONV_FUNC_PTR_NULL) + { + break; + } + } + + /// [AT-PM] : Check OTP is empty ; 01/25/2013 + CheckOtpISEmpty(data); +} + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.h new file mode 100755 index 00000000..fffdc867 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_Otp.h @@ -0,0 +1,84 @@ +/** + * @filename uG31xx_API_Otp.h + * + * Header of OTP conversion module + * + * @author AllenTeng + */ + +/// [AT-PM] : Product Type definition in OTP ; 01/23/2013 +enum UG31XX_PRODUCT_TYPE { + UG31XX_PRODUCT_TYPE_0 = 0, + UG31XX_PRODUCT_TYPE_1 = 1, + UG31XX_PRODUCT_TYPE_2 = 2, + UG31XX_PRODUCT_TYPE_3 = 3, +}; + +#define UG31XX_OTP_VERSION_MAIN (0x2013) +#define UG31XX_OTP_VERSION_SUB (0x0110) + +#define OTP_IS_EMPTY (1) +#define OTP_IS_NOT_EMPTY (0) + +#define OTP1_SIZE (4) +#define OTP2_SIZE (16) +#define OTP3_SIZE (4) + +typedef unsigned char _otp_u8_; +typedef unsigned short _otp_u16_; + +typedef struct OtpDataST { + + /// [AT-PM] : Version ; 01/23/2013 + _otp_u16_ versionMain; + _otp_u16_ versionSub; + _otp_u8_ empty; + + /// [AT-PM] : Raw data ; 01/23/2013 + _otp_u8_ otp1[OTP1_SIZE]; + _otp_u8_ otp2[OTP2_SIZE]; + _otp_u8_ otp3[OTP3_SIZE]; + + /// [AT-PM] : Converted value ; 01/23/2013 + _otp_u16_ adc1DeltaCodeT25V100; + _otp_u16_ adc1DeltaCodeT25V200; + _otp_u16_ adc2DeltaCodeT25V100; + _otp_u16_ adc2DeltaCodeT25V200; + _otp_u16_ aveIT25; + _otp_u16_ aveIT80; + + _otp_u8_ bgrTune; + + _otp_u8_ deltaET; + _otp_u8_ deltaVref; + _otp_u16_ devAddr; + + _otp_u16_ ftIT; + + _otp_u8_ indexAdc1V100T25; + _otp_u8_ indexAdc1V200T25; + _otp_u8_ indexAdc2V100T25; + _otp_u8_ indexAdc2V200T25; + + _otp_u8_ oscDeltaCode25; + _otp_u8_ oscDeltaCode80; + _otp_u8_ otpCellEN; + + _otp_u8_ productType; + +#if defined(uG31xx_OS_ANDROID) +} __attribute__ ((packed)) OtpDataType; +#else ///< else of defined(uG31xx_OS_ANDROID) +} OtpDataType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief UpiConvertOtp + * + * Convert OTP register value to readable value + * + * @para data address of OtpDataType + * @return _UPI_NULL_ + */ +extern void UpiConvertOtp(OtpDataType *data); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c new file mode 100755 index 00000000..e23f858e --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.c @@ -0,0 +1,1196 @@ +/** + * @filename uG31xx_API_System.cpp + * + * uG31xx system control + * + * @author AllenTeng + */ + +#include "stdafx.h" //windows need this?? +#include "uG31xx_API.h" + +#if defined(uG31xx_OS_ANDROID) + +_upi_bool_ ReadGGBXFileToCellDataAndInitSetting(SystemDataType *obj) +{ + _sys_u8_ *p_start = _UPI_NULL_; + _sys_u8_ *p_end = _UPI_NULL_; + _sys_u16_ sum16=0; + _sys_s32_ i=0; + + /* + * check GGBX_FILE tag + */ + if(obj->ggbXBuf->ggb_tag != GGBX_FILE_TAG) + { + UG31_LOGE("[%s] GGBX file tag not correct. tag: %08X\n", __func__, obj->ggbXBuf->ggb_tag); + return (_UPI_FALSE_); + } + + /* + * check GGBX_FILE checksum + */ + p_start = (_sys_u8_ *)obj->ggbXBuf + sizeof(GGBX_FILE_HEADER); + p_end = p_start + obj->ggbXBuf->length - 1; + for (; p_start <= p_end; p_start++) + { + sum16 += *p_start; + } + + /* check done. prepare copy data */ + memset(obj->ggbCellTable, 0x00, sizeof(CELL_TABLE)); + memset(obj->ggbParameter, 0x00, sizeof(CELL_PARAMETER)); + + p_start = (_sys_u8_ *)obj->ggbXBuf + sizeof(GGBX_FILE_HEADER); + for (i=0; iggbXBuf->num_ggb; i++) + { + /* TODO: boundary checking */ + /* TODO: select right ggb content by sku */ + memcpy(obj->ggbParameter, p_start, sizeof(CELL_PARAMETER)); + memcpy(obj->ggbCellTable, p_start + sizeof(CELL_PARAMETER), sizeof(CELL_TABLE)); + p_start += (sizeof(CELL_PARAMETER) + sizeof(CELL_TABLE)); + } + return (_UPI_TRUE_); +} + +#else ///< else of defined(uG31xx_OS_ANDROID) + + _upi_bool_ ReadGGBFileToCellDataAndInitSetting(SystemDataType *obj) +{ + FILE* stream; + _wfopen_s(&stream, obj->ggbFilename, _T("rb, ccs=UTF-8")); + + memset(obj->ggbCellTable, 0x00, sizeof(CELL_TABLE)); + memset(obj->ggbParameter, 0x00, sizeof(CELL_PARAMETER)); + + if(!stream) + { + return (_UPI_FALSE_); + } + if(fread(obj->ggbParameter, sizeof(char), sizeof(CELL_PARAMETER), stream) != sizeof(CELL_PARAMETER)) + { + fclose(stream); + return (_UPI_FALSE_); + } + if(fread(obj->ggbCellTable, sizeof(char), sizeof(CELL_TABLE), stream) != sizeof(CELL_TABLE)) + { + fclose(stream); + return (_UPI_FALSE_); + } + + fclose(stream); + + return (_UPI_TRUE_); +} + +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief GetCellNum + * + * Get cell number from ggbParameter->ICType + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void GetCellNum(SystemDataType *data) +{ + _sys_u8_ cellNum[6] = {1, 1, 2, 0, 2, 3}; + + data->cellNum = cellNum[data->ggbParameter->ICType]; +} + +/** + * @brief SetupAdcChopFunction + * + * Setup ADC chop function + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void SetupAdcChopFunction(SystemDataType *data) +{ + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_FW_CTRL, + data->ggbParameter->chopCtrl); +} + +/** + * @brief SetupAdc1Queue + * + * Setup ADC1 conversion queue + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void SetupAdc1Queue(SystemDataType *data) +{ + _cap_u8_ adcQueue[4]; + + adcQueue[0] = SET_A_IT | SET_B_IT | SET_C_CURRENT | SET_D_CURRENT; + adcQueue[1] = SET_E_CURRENT | SET_F_CURRENT | SET_G_CURRENT | SET_H_CURRENT; + adcQueue[2] = SET_I_ET | SET_J_ET | SET_K_CURRENT | SET_L_CURRENT; + adcQueue[3] = SET_M_CURRENT | SET_N_CURRENT | SET_O_CURRENT | SET_P_CURRENT; + + API_I2C_Write(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_ADC_CTR_A, + 4, + &adcQueue[0]); +} + +/** + * @brief SetupAdc2Queue + * + * Set ADC2 conversion queue + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void SetupAdc2Quene(SystemDataType *data) +{ + _sys_u8_ adc2Queue[3]; + + /// [AT-PM] : Set sell type ; 01/31/2013 + if(data->cellNum == 1) + { + adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT1 | SET_V4_VBAT1; + adc2Queue[1] = SET_V5_VBAT1 | SET_V6_VBAT1 | SET_V7_VBAT1 | SET_V8_VBAT1; + adc2Queue[2] = SET_V9_VBAT1 | SET_V10_VBAT1 | SET_V11_VBAT1 | SET_V12_VBAT1; + } + else if(data->cellNum == 2) + { + adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT2 | SET_V4_VBAT2; + adc2Queue[1] = SET_V5_VBAT1 | SET_V6_VBAT1 | SET_V7_VBAT2 | SET_V8_VBAT2; + adc2Queue[2] = SET_V9_VBAT1 | SET_V10_VBAT1 | SET_V11_VBAT2 | SET_V12_VBAT2; + } + else if(data->cellNum == 3) + { + adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT2 | SET_V4_VBAT2; + adc2Queue[1] = SET_V5_VBAT3 | SET_V6_VBAT3 | SET_V7_VBAT1 | SET_V8_VBAT1; + adc2Queue[2] = SET_V9_VBAT2 | SET_V10_VBAT2 | SET_V11_VBAT3 | SET_V12_VBAT3; + } + else + { + /// [AT-PM] : 1-cell ; 01/31/2013 + adc2Queue[0] = SET_V1_VBAT1 | SET_V2_VBAT1 | SET_V3_VBAT1 | SET_V4_VBAT1; + adc2Queue[1] = SET_V5_VBAT1 | SET_V6_VBAT1 | SET_V7_VBAT1 | SET_V8_VBAT1; + adc2Queue[2] = SET_V9_VBAT1 | SET_V10_VBAT1 | SET_V11_VBAT1 | SET_V12_VBAT1; + } + API_I2C_Write(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ADC_V1, 3, &adc2Queue[0]); +} + +/** + * @brief EnableCbc + * + * Enable CBC function + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void EnableCbc(SystemDataType *data) +{ + _sys_u8_ tmp8; + + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_B, &tmp8); + tmp8 = tmp8 & (~(INTR_CTRL_B_CBC_32_EN | INTR_CTRL_B_CBC_21_EN)); + tmp8 = tmp8 | (INTR_CTRL_B_ET_EN | INTR_CTRL_B_IT_EN | INTR_CTRL_B_RID_EN); + tmp8 = tmp8 | (data->ggbParameter->cbcEnable << 4); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_B, tmp8); +} + +/** + * @brief EnableICType + * + * Enable IC type + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void EnableICType(SystemDataType *data) +{ + _sys_u8_ tmp8; + + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, &tmp8); + tmp8 = tmp8 & (~CELL_EN_APPLICATION); + tmp8 = tmp8 | (data->ggbParameter->ICType << 2); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, tmp8); +} + +/** + * @brief ConfigGpioFunction + * + * Configure GPIO1/2 function + * + * @para setting GPIO1/2 setting + * @return register value + */ +_sys_u8_ ConfigGpioFunction(_sys_u8_ setting) +{ + _sys_u8_ gpioSelData = 0; + + if(setting & FUN_GPIO) + { + gpioSelData = 0; + } + if(setting & FUN_ALARM) //select Alarm function + { + gpioSelData = 1; + } + if(setting & FUN_CBC_EN21) //cbc21 enable + { + gpioSelData = 2; + }if(setting & FUN_CBC_EN32) //cbc32 Enable + { + gpioSelData = 3; + } + if(setting & FUN_PWM) //PWM function, set PWM cycle + { + gpioSelData = 4; + } + return (gpioSelData); +} + +/** + * @brief ConfigureGpio + * + * Configure GPIO function + * + * @para data SystemDataType + * @return _UPI_NULL_ + */ +void ConfigureGpio(SystemDataType *data) +{ + _sys_u8_ tmp8; + + API_I2C_SingleRead(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_INTR_CTRL_A, + &tmp8); + tmp8 = tmp8 | (ConfigGpioFunction(data->ggbParameter->gpio1) << 2); + tmp8 = tmp8 | (ConfigGpioFunction(data->ggbParameter->gpio2) << 5); + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_INTR_CTRL_A, + tmp8); + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_INTR_CTRL_D, + data->ggbParameter->gpio34); +} + +#define ADC_FAIL_CRITERIA (10) + +/** + * @brief CheckAdcStatusFail + * + * Check ADC status is fail or not + * + * @para pUg31xx address of SystemDataType + * @return _UPI_TRUE_ if fail + */ +_upi_bool_ CheckAdcStatusFail(SystemDataType *data) +{ + API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_COUNTER_LOW, + REG_COUNTER_HIGH - REG_COUNTER_LOW + 1, + (unsigned char *)&data->adcCheckData.regCounter); + + API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_AVE_VBAT1_LOW, + REG_AVE_VBAT1_HIGH - REG_AVE_VBAT1_LOW + 1, + (unsigned char *)&data->adcCheckData.regVbat1Ave); + + /// [AT-PM] : Compare counter register ; 01/27/2013 + if(data->adcCheckData.regCounter == data->adcCheckData.lastCounter) + { + data->adcCheckData.failCounterCurrent = data->adcCheckData.failCounterCurrent + 1; + UG31_LOGI("[%s]: Counter fixed (%d) ... %d\n", __func__, + data->adcCheckData.regCounter, data->adcCheckData.failCounterCurrent); + } + else + { + data->adcCheckData.failCounterCurrent = 0; + } + data->adcCheckData.lastCounter = data->adcCheckData.regCounter; + + /// [AT-PM] : Compre VBat1 register ; 01/27/2013 + if(data->adcCheckData.regVbat1Ave == data->adcCheckData.lastVBat1Ave) + { + data->adcCheckData.failCounterVoltage = data->adcCheckData.failCounterVoltage + 1; + UG31_LOGI("[%s]: VBat1 fixed (%d) ... %d\n", __func__, + data->adcCheckData.regVbat1Ave, data->adcCheckData.failCounterVoltage); + } + else + { + data->adcCheckData.failCounterVoltage = 0; + } + data->adcCheckData.lastVBat1Ave = data->adcCheckData.regVbat1Ave; + + /// [AT-PM] : Check ADC fail criteria ; 01/27/2013 + if(data->adcCheckData.failCounterCurrent > ADC_FAIL_CRITERIA) + { + data->adcCheckData.failCounterCurrent = 0; + return (_UPI_TRUE_); + } + if(data->adcCheckData.failCounterVoltage > ADC_FAIL_CRITERIA) + { + data->adcCheckData.failCounterVoltage = 0; + return (_UPI_TRUE_); + } + return (_UPI_FALSE_); +} + +/** + * @brief DecimateRst + * + * Decimate reset filter of ADC + * + * @return _UPI_NULL_ + */ +void DecimateRst(void) +{ + _sys_u8_ tmp8; + + tmp8 = 0x00; + API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); + tmp8 = tmp8 & (~ALARM_EN_DECIMATE_RST); + API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); + tmp8 = tmp8 | ALARM_EN_DECIMATE_RST; + API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); + UG31_LOGI("[%s]: DECIMATE_RST\n", __func__); +} + +/** + * @brief AlarmEnable + * + * Enable alarm + * + * @para alarm REG_ALARM_EN bits + * @return NULL + */ +void AlarmEnable(_sys_u8_ alarm) +{ + _sys_u8_ tmp8; + + API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); + tmp8 = tmp8 | alarm; + API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); +} + +/** + * @brief AlarmDisable + * + * Disable alarm + * + * @para alarm REG_ALARM_EN bits + * @return NULL + */ +void AlarmDisable(_sys_u8_ alarm) +{ + _sys_u8_ tmp8; + + API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); + tmp8 = tmp8 & (~alarm); + API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM_EN, 1, &tmp8); +} + +#define SYS_ALARM_STS_UV1 (ALARM2_STATUS_UV1_ALARM) +#define SYS_ALARM_STS_OV1 (ALARM2_STATUS_OV1_ALARM) +#define SYS_ALARM_STS_UV2 (ALARM2_STATUS_UV2_ALARM) +#define SYS_ALARM_STS_OV2 (ALARM2_STATUS_OV2_ALARM) +#define SYS_ALARM_STS_UV3 (ALARM2_STATUS_UV3_ALARM) +#define SYS_ALARM_STS_OV3 (ALARM2_STATUS_OV3_ALARM) +#define SYS_ALARM_STS_UET (ALARM1_STATUS_UET_ALARM<<8) +#define SYS_ALARM_STS_OET (ALARM1_STATUS_OET_ALARM<<8) +#define SYS_ALARM_STS_UIT (ALARM1_STATUS_UIT_ALARM<<8) +#define SYS_ALARM_STS_OIT (ALARM1_STATUS_OIT_ALARM<<8) +#define SYS_ALARM_STS_DOC (ALARM1_STATUS_DOC_ALARM<<8) +#define SYS_ALARM_STS_COC (ALARM1_STATUS_COC_ALARM<<8) + +/** + * @brief ProcUVAlarm + * + * UV alarm function + * + * @para data address of SystemDataType + * @return NULL + */ +void ProcUVAlarm(SystemDataType *data) +{ + _sys_u8_ tmp8[4]; + + /// [AT-PM] : Check alarm is enable or not ; 04/08/2013 + if(!(data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_UV)) + { + /// [AT-PM] : Disable UV and OV alarm ; 04/08/2013 + AlarmDisable(ALARM_EN_V1_ALARM_EN); + return; + } + + if(data->uvAlarm.state == _UPI_TRUE_) + { + /// [AT-PM] : UV alarm has been set -> Wait for OV alarm ; 04/08/2013 + if(data->alarmSts & SYS_ALARM_STS_OV1) + { + data->uvAlarm.state = _UPI_FALSE_; + + /// [AT-PM] : Release UV alarm by disable ; 04/08/2013 + AlarmDisable(ALARM_EN_V1_ALARM_EN); + + /// [AT-PM] : UV release threshold reached -> set alarm threshold ; 04/08/2013 + tmp8[0] = 0xff; + tmp8[1] = 0x7f; + tmp8[2] = (_sys_u8_)(data->uvAlarm.alarmThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->uvAlarm.alarmThrd >> 8); + } + else + { + /// [AT-PM] : UV state -> set release threshold ; 04/08/2013 + tmp8[0] = (_sys_u8_)(data->uvAlarm.releaseThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->uvAlarm.releaseThrd >> 8); + tmp8[2] = 0x00; + tmp8[3] = 0x00; + } + } + else + { + /// [AT-PM] : Normal state ; 04/08/2013 + if(data->alarmSts & SYS_ALARM_STS_UV1) + { + data->uvAlarm.state = _UPI_TRUE_; + + /// [AT-PM] : Release UV alarm by disable ; 04/08/2013 + AlarmDisable(ALARM_EN_V1_ALARM_EN); + + /// [AT-PM] : UV alarm reached -> set release threshold ; 04/08/2013 + tmp8[0] = (_sys_u8_)(data->uvAlarm.releaseThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->uvAlarm.releaseThrd >> 8); + tmp8[2] = 0x00; + tmp8[3] = 0x00; + } + else + { + /// [AT-PM] : Normal state -> set alarm threshold ; 04/08/2013 + tmp8[0] = 0xff; + tmp8[1] = 0x7f; + tmp8[2] = (_sys_u8_)(data->uvAlarm.alarmThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->uvAlarm.alarmThrd >> 8); + } + } + + /// [AT-PM] : Set alarm threshold ; 04/08/2013 + API_I2C_Write(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_OV1_LOW, 4, &tmp8[0]); + + /// [AT-PM] : Enable UV and OV alarm ; 04/08/2013 + AlarmEnable(ALARM_EN_V1_ALARM_EN); +} + +/** + * @brief ProcETAlarm + * + * UET and OET alarm function + * + * @para data address of SystemDataType + * @return NULL + */ +void ProcETAlarm(SystemDataType *data) +{ + _sys_u8_ tmp8[4]; + + /// [AT-PM] : Check alarm is enable or not ; 04/08/2013 + if(!(data->ggbParameter->alarmEnable & (CELL_PARAMETER_ALARM_EN_UET | CELL_PARAMETER_ALARM_EN_OET))) + { + /// [AT-PM] : Disable UV and OV alarm ; 04/08/2013 + AlarmDisable(ALARM_EN_ET_ALARM_EN); + return; + } + + if(data->uetAlarm.state == _UPI_TRUE_) + { + /// [AT-PM] : UET alarm state -> wait for OET alarm ; 04/08/2013 + if(data->alarmSts & SYS_ALARM_STS_OET) + { + data->uetAlarm.state = _UPI_FALSE_; + + /// [AT-PM] : Release by disable ; 04/08/2013 + AlarmDisable(ALARM_EN_ET_ALARM_EN); + + /// [AT-PM] : UET release met -> set UET and OET alarm ; 04/08/2013 + tmp8[0] = (_sys_u8_)(data->oetAlarm.alarmThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->oetAlarm.alarmThrd >> 8); + tmp8[2] = (_sys_u8_)(data->uetAlarm.alarmThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->uetAlarm.alarmThrd >> 8); + } + else + { + /// [AT-PM] : Wait OET alarm ; 04/08/2013 + tmp8[0] = (_sys_u8_)(data->uetAlarm.releaseThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->uetAlarm.releaseThrd >> 8); + tmp8[2] = 0x00; + tmp8[3] = 0x00; + } + } + else if(data->oetAlarm.state == _UPI_TRUE_) + { + /// [AT-PM] : OET alarm state -> wait for UET alarm ; 04/08/2013 + if(data->alarmSts & SYS_ALARM_STS_UET) + { + data->oetAlarm.state = _UPI_FALSE_; + + /// [AT-PM] : Release by disable ; 04/08/2013 + AlarmDisable(ALARM_EN_ET_ALARM_EN); + + /// [AT-PM] : OET release met -> set UET and OET alarm ; 04/08/2013 + tmp8[0] = (_sys_u8_)(data->oetAlarm.alarmThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->oetAlarm.alarmThrd >> 8); + tmp8[2] = (_sys_u8_)(data->uetAlarm.alarmThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->uetAlarm.alarmThrd >> 8); + } + else + { + /// [AT-PM] : Wait UET alarm ; 04/08/2013 + tmp8[0] = 0xff; + tmp8[1] = 0x7f; + tmp8[2] = (_sys_u8_)(data->oetAlarm.releaseThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->oetAlarm.releaseThrd >> 8); + } + } + else + { + /// [AT-PM] : Normal state ; 04/08/2013 + if((data->alarmSts & SYS_ALARM_STS_UET) && + (data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_UET)) + { + data->uetAlarm.state = _UPI_TRUE_; + + /// [AT-PM] : Release by disable ; 04/08/2013 + AlarmDisable(ALARM_EN_ET_ALARM_EN); + + /// [AT-PM] : UET is set -> set UET release threshold ; 04/08/2013 + tmp8[0] = (_sys_u8_)(data->uetAlarm.releaseThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->uetAlarm.releaseThrd >> 8); + tmp8[2] = 0x00; + tmp8[3] = 0x00; + } + else if((data->alarmSts & SYS_ALARM_STS_OET) && + (data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_OET)) + { + data->oetAlarm.state = _UPI_TRUE_; + + /// [AT-PM] : Release by disable ; 04/08/2013 + AlarmDisable(ALARM_EN_ET_ALARM_EN); + + /// [AT-PM] : OET is set -> set OET release threshold ; 04/08/2013 + tmp8[0] = 0xff; + tmp8[1] = 0x7f; + tmp8[2] = (_sys_u8_)(data->oetAlarm.releaseThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->oetAlarm.releaseThrd >> 8); + } + else + { + /// [AT-PM] : Set OET alarm threshold ; 04/08/2013 + if(data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_OET) + { + tmp8[0] = (_sys_u8_)(data->oetAlarm.alarmThrd & 0x00ff); + tmp8[1] = (_sys_u8_)(data->oetAlarm.alarmThrd >> 8); + } + else + { + tmp8[0] = 0xff; + tmp8[1] = 0x7f; + } + /// [AT-PM] : Set UET alarm threshold ; 04/11/2013 + if(data->ggbParameter->alarmEnable & CELL_PARAMETER_ALARM_EN_UET) + { + tmp8[2] = (_sys_u8_)(data->uetAlarm.alarmThrd & 0x00ff); + tmp8[3] = (_sys_u8_)(data->uetAlarm.alarmThrd >> 8); + } + else + { + tmp8[2] = 0x00; + tmp8[3] = 0x00; + } + } + } + + /// [AT-PM] : Set alarm threshold ; 04/08/2013 + API_I2C_Write(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_EXTR_OVER_TEMP_LOW, 4, &tmp8[0]); + + /// [AT-PM] : Enable UV and OV alarm ; 04/08/2013 + AlarmEnable(ALARM_EN_ET_ALARM_EN); +} + +/** + * @brief EnableAlarm + * + * Set UV, UET, and OET alarm functions + * + * @para data address of SystemDataType + * @return NULL + */ +void EnableAlarm(SystemDataType *data) +{ + /// [AT-PM] : UV alarm ; 04/08/2013 + ProcUVAlarm(data); + + /// [AT-PM] : UET and OET alarm ; 04/08/2013 + ProcETAlarm(data); +} + +/// ============================================= +/// [AT-PM] : Extern function region +/// ============================================= + +/** + * @brief UpiInitSystemData + * + * Initialize system variables + * + * @para data address of SystemDataType + * @return SYSTEM_RTN_CODE + */ +SYSTEM_RTN_CODE UpiInitSystemData(SystemDataType *data) +{ + /// [AT-PM] : Initialize variables ; 01/30/2013 + data->preITAve = 0; + data->cellNum = 0; + + /// [AT-PM] : Load GGB file ; 01/30/2013 + UG31_LOGI("[%s]: Read GGB\n", __func__); + #if defined(uG31xx_OS_ANDROID) + if(!ReadGGBXFileToCellDataAndInitSetting(data)) + #else + if(!ReadGGBFileToCellDataAndInitSetting(data)) + #endif + { + return (SYSTEM_RTN_READ_GGB_FAIL); + } + + /// [AT-PM] : Set cell number ; 01/31/2013 + GetCellNum(data); + return (SYSTEM_RTN_PASS); +} + +/** + * @brief UpiCheckICActive + * + * Check IC is actived or not + * + * @return _UPI_TRUE_ if uG31xx is not actived + */ +_upi_bool_ UpiCheckICActive(void) +{ + _upi_u8_ tmp; + + if(!API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_MODE, 1, &tmp)) + { + UG31_LOGI("[%s]: Get GG_RUN fail.\n", __func__); + return (_UPI_TRUE_); + } + + if((tmp & MODE_GG_RUN) == GG_RUN_OPERATION_MODE) + { + UG31_LOGI("[%s]: uG31xx is actived.\n", __func__); + return (_UPI_FALSE_); + } + UG31_LOGI("[%s]: uG31xx is NOT actived.\n", __func__); + return (_UPI_TRUE_); +} + +/** + * @brief UpiActiveUg31xx + * + * Active uG31xx + * + * @return SYSTEM_RTN_CODE + */ +SYSTEM_RTN_CODE UpiActiveUg31xx(void) +{ + _sys_u8_ tmp8; + + /// [AT-PM] : Reset uG31xx ; 01/31/2013 + tmp8 = PORDET_W_SOFTRESET | IO1DATA_W_HIGH; + if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CTRL1, 1, &tmp8)) + { + return (SYSTEM_RTN_I2C_FAIL); + } + tmp8 = IO1DATA_W_HIGH; + if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CTRL1, 1, &tmp8)) + { + return (SYSTEM_RTN_I2C_FAIL); + } + + /// [AT-PM] : Active uG31xx ; 01/31/2013 + tmp8 = CTRL1_GG_RST | IO1DATA_W_HIGH; + if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CTRL1, 1, &tmp8)) + { + return (SYSTEM_RTN_I2C_FAIL); + } + tmp8 = GG_RUN_OPERATION_MODE; + if(!API_I2C_Write(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_MODE, 1, &tmp8)) + { + return (SYSTEM_RTN_I2C_FAIL); + } + + /// [AT-PM] : Delay 255mS for system stable ; 01/31/2013 + SleepMiniSecond(255); //2012/08/29/Jacky, need wait 255 ms + return (SYSTEM_RTN_PASS); +} + +/** + * @brief UpiSetupAdc + * + * Setup ADC configurations + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void UpiSetupAdc(SystemDataType *data) +{ + _sys_u8_ tmp8; + + /// [AT-PM] : Set ADC chop function ; 01/31/2013 + SetupAdcChopFunction(data); + + /// [AT-PM] : Set ADC1 queue ; 01/31/2013 + SetupAdc1Queue(data); + + /// [AT-PM] : Set ADC2 queue ; 01/31/2013 + SetupAdc2Quene(data); + + /// [AT-PM] : Enable ADC ; 01/31/2013 + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_A, &tmp8); + tmp8 = tmp8 | (INTR_CTRL_A_ADC2_EN | INTR_CTRL_A_ADC1_EN); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_INTR_CTRL_A, tmp8); + + /// [AT-PM] : Decimate reset ; 01/31/2013 + DecimateRst(); + + /// [AT-PM] : Enable CBC function ; 01/31/2013 + EnableCbc(data); +} + +/** + * @brief UpiSetupSystem + * + * Setup uG31xx system + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void UpiSetupSystem(SystemDataType *data) +{ + _sys_u8_ tmp8; + + /// [AT-PM] : Enable IC type ; 01/31/2013 + EnableICType(data); + + /// [AT-PM] : Configure GPIO ; 01/31/2013 + ConfigureGpio(data); + + /// [AT-PM] : Enable cell ; 01/31/2013 + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, &tmp8); + tmp8 = tmp8 | (CELL_EN1 | CELL_EN0); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_CELL_EN, tmp8); +} + +#define OSC_CNT_TARG 512 //oscCntTarg[9:0] + +/** + * @brief UpiCalibrationOsc + * + * OSC calibration + * oscCnt25[9:0] = oscCntTarg[9:0] + oscDeltaCode25[7:0] + * oscCnt80[9:0] = oscCntTarg[9:0] + oscDeltaCode80[7:0] + * oscCnt[9:0] = m*ITcode[15:8] + C[9:0] + * m = (oscCnt80[9:0]-oscCnt25[9:0])/(iTcode80[7:0]-iTcode25[7:0]) + * c = oscCnt25[9:0] - m*ITcode25[7:0] + * write oscCnt[9:0] to register 0x97-98 + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void UpiCalibrationOsc(SystemDataType *data) +{ + _sys_u16_ u16Temp; + + _sys_u16_ oscCnt25; + _sys_u16_ oscCnt80; //10 bits + _sys_u16_ oscDeltaCode25; + _sys_u16_ oscDeltaCode80; // + _sys_u16_ targetOscCnt; //target osc + + _sys_u16_ varM; + _sys_u16_ varC; + + _sys_u16_ aveIT; + + /// [AT-PM] : Calculate m & C ; 01/25/2013 + oscDeltaCode25 = (_sys_u16_)data->otpData->oscDeltaCode25; + oscDeltaCode80 = (_sys_u16_)data->otpData->oscDeltaCode80; + + oscCnt25 = OSC_CNT_TARG + oscDeltaCode25; + oscCnt80 = OSC_CNT_TARG + oscDeltaCode80; + + varM = (oscCnt80 - oscCnt25)/(data->otpData->aveIT80 - data->otpData->aveIT25); + varC = oscCnt25 - varM*(data->otpData->aveIT25); + + /// [AT-PM] : Read ITAve ; 01/27/2013 + API_I2C_Read(NORMAL, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_AVE_IT_LOW, + REG_AVE_IT_HIGH - REG_AVE_IT_LOW + 1, + (_sys_u8_ *)&aveIT); + + /// [AT-PM] : Calculate target OSC cnt ; 01/25/2013 + targetOscCnt = varM*(aveIT/256) + varC; + if(targetOscCnt & 0x8000) //check +/- + { + u16Temp = (_sys_u16_)(targetOscCnt & 0x1fff); + u16Temp |= 0x0200; // minus + } else{ + u16Temp = (_sys_u16_)targetOscCnt; //positive data + } + + /// [AT-PM] : Write to register 0x97-98 ; 01/25/2013 + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + OSCTUNE_CNTB, + (_sys_u8_)(u16Temp >> 8)); + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + OSCTUNE_CNTA, + (_sys_u8_)u16Temp ); +} + +/** + * @brief UpiAdcStatus + * + * Check ADC status + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void UpiAdcStatus(SystemDataType *data) +{ + if(CheckAdcStatusFail(data) == _UPI_TRUE_) //check ADC Code frozen + { + DecimateRst(); + } +} + +#define BACKUP_TIME_BYTE3 (REG_COC_LOW) +#define BACKUP_TIME_BYTE2 (REG_OTP_CTRL) +#define BACKUP_NAC_HIGH (REG_CBC21_LOW) +#define BACKUP_NAC_LOW (REG_CBC21_HIGH) +#define BACKUP_LMD_HIGH (REG_CBC32_LOW) +#define BACKUP_LMD_LOW (REG_CBC32_HIGH) +#define BACKUP_TABLE_UPDATE_IDX (REG_COC_HIGH) +#define BACKUP_DELTA_CAP_HIGH (REG_DOC_LOW) +#define BACKUP_DELTA_CAP_LOW (REG_DOC_HIGH) +#define BACKUP_ADC1_CONV_TIME (REG_COC_HIGH) + +/** + * @brief UpiLoadBatInfoFromIC + * + * Load battery information from uG31xx + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void UpiLoadBatInfoFromIC(SystemDataType *data) +{ + _sys_u8_ *u8Ptr; + _sys_u8_ u8Temp; + _sys_u8_ u8TempHigh; + _sys_u16_ u16Temp; + + //Load the time tag + u8Ptr = (_sys_u8_ *)&data->timeTagFromIC; + *u8Ptr = 0; + *(u8Ptr + 1) = 0; + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE2, &u8Temp); + *(u8Ptr + 2) = u8Temp; + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE3, &u8Temp); + *(u8Ptr + 3) = u8Temp; + + //Load the NAC + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_HIGH, &u8TempHigh); + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_LOW, &u8Temp); + data->rmFromIC = (_sys_u16_)u8TempHigh; + data->rmFromIC = data->rmFromIC*256 + u8Temp; + + // Load LMD + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_HIGH, &u8TempHigh); + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_LOW, &u8Temp); + data->fccFromIC = (_sys_u16_)u8TempHigh; + data->fccFromIC = data->fccFromIC*256 + u8Temp; + UG31_LOGE("[%s]:timeTag =%u/%x ms,NAC = %d mAh,LMD = %dmAh\n", + __func__, + data->timeTagFromIC, + data->timeTagFromIC, + data->rmFromIC, + data->fccFromIC); + + /// [AT-PM] : Load table update index ; 02/10/2013 + API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TABLE_UPDATE_IDX, &u8Temp); + data->tableUpdateIdxFromIC = u8Temp & 0x07; + UG31_LOGI("[%s]: Table Update Index From IC = %d (0x%02x)\n", __func__, data->tableUpdateIdxFromIC, u8Temp); + + /// [AT-PM] : Load delta capacity ; 02/10/2013 + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_HIGH, &u8TempHigh); + API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_LOW, &u8Temp); + data->deltaCapFromIC = (_sys_u16_)u8TempHigh; + data->deltaCapFromIC = data->deltaCapFromIC*256 + u8Temp; + UG31_LOGI("[%s]: Delta Capacity From IC = %d (0x%02x%02x)\n", __func__, data->deltaCapFromIC, u8TempHigh, u8Temp); + + /// [AT-PM] : Load ADC1 conversion time ; 02/10/2013 + API_I2C_SingleRead(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_ADC1_CONV_TIME, &u8Temp); + u16Temp = (_sys_u16_)(u8Temp & 0xf8); + data->adc1ConvTime = u16Temp*TIME_CONVERT_TIME_TO_MSEC; + UG31_LOGI("[%s]: ADC1 Conversion Time From IC = %d (0x%02x)\n", __func__, data->adc1ConvTime, u8Temp); + + /// [AT-PM] : Get RSOC ; 01/31/2013 + if(data->fccFromIC == 0) + { + data->rsocFromIC = 0; + } + else + { + data->rsocFromIC = CalculateRsoc(data->rmFromIC, data->fccFromIC); + } + + data->rmFromICBackup = data->rmFromIC; + data->fccFromICBackup = data->fccFromIC; + data->rsocFromICBackup = data->rsocFromIC; +} + +/** + * @brief UpiUpdateBatInfoFromIC + * + * Update battery information from uG31xx + * + * @para data address of SystemDataType + * @para deltaQ delta capacity from coulomb counter + * @return _UPI_NULL_ + */ +void UpiUpdateBatInfoFromIC(SystemDataType *data, _sys_s16_ deltaQ) +{ + _sys_s32_ tmp32; + _sys_u16_ oldRM; + + oldRM = data->rmFromIC; + + tmp32 = (_sys_s32_)data->rmFromIC; + tmp32 = tmp32 + deltaQ; + if(tmp32 < 0) + { + tmp32 = 0; + } + if(tmp32 > data->fccFromIC) + { + tmp32 = (_sys_s32_)data->fccFromIC; + } + UG31_LOGI("[%s]: RM = %d + %d = %d\n", __func__, + data->rmFromIC, deltaQ, tmp32); + data->rmFromIC = (_sys_u16_)tmp32; + + if(data->fccFromIC == 0) + { + data->rsocFromIC = 0; + } + else + { + data->rsocFromIC = CalculateRsoc(data->rmFromIC, data->fccFromIC); + + if(oldRM != 0) + { + /// [AT-PM] : EDVF is not reached in last log data ; 02/13/2013 + if(data->rsocFromIC == 0) + { + /// [AT-PM] : Check EDVF threshold ; 02/13/2013 + if(data->voltage < data->ggbParameter->edv1Voltage) + { + /// [AT-PM] : Set capacity to 0 when EDVF reached ; 02/13/2013 + data->rmFromIC = 0; + data->rsocFromIC = 0; + } + else + { + /// [AT-PM] : Capacity should not be 0 before EDVF ; 02/13/2013 + tmp32 = (_sys_s32_)data->fccFromIC; + tmp32 = tmp32/CONST_PERCENTAGE; + data->rmFromIC = (_sys_u16_)tmp32; + data->rsocFromIC = 1; + } + } + else + { + /// [AT-PM] : Check EDVF threshold ; 02/13/2013 + if(data->voltage < data->ggbParameter->edv1Voltage) + { + /// [AT-PM] : Set capacity to 1% when EDVF reached in initialization ; 02/13/2013 + tmp32 = (_sys_s32_)data->fccFromIC; + tmp32 = tmp32/CONST_PERCENTAGE; + data->rmFromIC = (_sys_u16_)tmp32; + data->rsocFromIC = 1; + } + } + } + } +} + +/** + * @brief UpiSaveBatInfoTOIC + * + * Save battery information from uG31xx + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +void UpiSaveBatInfoTOIC(SystemDataType *data) +{ + _sys_u8_ *u8Ptr; + _sys_u8_ u8Temp; + _sys_u8_ u8Temp1; + _sys_u16_ u16Temp; + + #if defined(uG31xx_OS_ANDROID) + data->timeTagFromIC = GetSysTickCount(); + #else ///< else of defined(uG31xx_OS_ANDROID) + data->timeTagFromIC = GetTickCount(); + #endif ///< end of defined(uG31xx_OS_ANDROID) + UG31_LOGE("[%s]:timeTag =%u/%x ms,NAC = %d maH,LMD = %d maH\n", + __func__, + data->timeTagFromIC, + data->timeTagFromIC, + data->rmFromIC, + data->fccFromIC); + + //save the time tag + u8Ptr = (_sys_u8_ *)&data->timeTagFromIC; + u8Temp = (*(u8Ptr + 2)) & 0xf8; + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE2, u8Temp); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TIME_BYTE3, *(u8Ptr + 3)); + + //save the NAC + u8Temp = (_sys_u8_)((data->rmFromIC & 0xff00)/256); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_HIGH, u8Temp); + u8Temp = (_sys_u8_)(data->rmFromIC & 0x00ff); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_NAC_LOW, u8Temp); + + // save LMD + u8Temp = (_sys_u8_)((data->fccFromIC & 0xff00)/256); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_HIGH, u8Temp); + u8Temp = (_sys_u8_)(data->fccFromIC & 0x00ff); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_LMD_LOW, u8Temp); + + /// [AT-PM] : Save table update index ; 02/10/2013 + API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TABLE_UPDATE_IDX, &u8Temp); + u8Temp = u8Temp & 0xf8; + u8Temp = u8Temp | (data->tableUpdateIdxFromIC & 0x07); + API_I2C_SingleWrite(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_TABLE_UPDATE_IDX, u8Temp); + UG31_LOGI("[%s]: Save Table Update Index = %d - 0x%02x\n", __func__, data->tableUpdateIdxFromIC, u8Temp); + + /// [AT-PM] : Save delta capacity ; 02/10/2013 + u16Temp = (_sys_u16_)data->deltaCapFromIC; + u8Temp = (_sys_u8_)(u16Temp >> 8); + API_I2C_SingleWrite(SECURITY, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_HIGH, u8Temp); + u8Temp1 = (_sys_u8_)(u16Temp & 0x00ff); + API_I2C_SingleWrite(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_DELTA_CAP_LOW, u8Temp1); + UG31_LOGI("[%s]: Save Delta Capacity = %d - 0x%02x%02x\n", __func__, data->deltaCapFromIC, u8Temp, u8Temp1); + + /// [AT-PM] : Save adc1 conversion time ; 02/10/2013 + u16Temp = data->adc1ConvTime/TIME_CONVERT_TIME_TO_MSEC; + API_I2C_SingleRead(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_ADC1_CONV_TIME, &u8Temp); + u8Temp = u8Temp & 0x07; + u8Temp = u8Temp | (u16Temp & 0xf8); + API_I2C_SingleWrite(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, BACKUP_ADC1_CONV_TIME, u8Temp); + UG31_LOGI("[%s]: Save ADC1 Conversion Time = %d - 0x%02x\n", __func__, data->adc1ConvTime, u8Temp); +} + +/** + * @brief UpiInitAlarm + * + * Initialize alarm function of uG3105 + * + * @para data address of SystemDataType + * @return NULL + */ +void UpiInitAlarm(SystemDataType *data) +{ + /// [AT-PM] : Set GPIO as alarm pin ; 04/08/2013 + ConfigureGpio(data); + + /// [AT-PM] : Set delay time ; 04/08/2013 + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_TIMER, + data->ggbParameter->alarm_timer); + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_CLK_DIVA, + data->ggbParameter->clkDivA); + API_I2C_SingleWrite(SECURITY, + UG31XX_I2C_HIGH_SPEED_MODE, + UG31XX_I2C_TEM_BITS_MODE, + REG_CLK_DIVB, + data->ggbParameter->clkDivB); + + /// [AT-PM] : Enable alarm ; 04/08/2013 + data->alarmSts = 0; + data->uvAlarm.state = _UPI_FALSE_; + data->uetAlarm.state = _UPI_FALSE_; + data->oetAlarm.state = _UPI_FALSE_; + EnableAlarm(data); +} + +/** + * @brief UpiAlarmStatus + * + * Get alarm status + * + * @para data address of SystemDataType + * @return NULL + */ +_sys_u8_ UpiAlarmStatus(SystemDataType *data) +{ + _sys_u8_ sts; + _sys_u8_ tmp8[2]; + + sts = 0; + + /// [AT-PM] : Read alarm status from uG3105 ; 04/08/2013 + API_I2C_Read(NORMAL, UG31XX_I2C_HIGH_SPEED_MODE, UG31XX_I2C_TEM_BITS_MODE, REG_ALARM1_STATUS, 2, &tmp8[0]); + data->alarmSts = (_sys_u16_)tmp8[0]; + data->alarmSts = data->alarmSts*256 + tmp8[1]; + + /// [AT-PM] : Enable alarm ; 04/08/2013 + EnableAlarm(data); + + /// [AT-PM] : Update current alarm status ; 04/08/2013 + tmp8[0] = data->uvAlarm.state == _UPI_TRUE_ ? ALARM_STATUS_UV : 0; + sts = sts | tmp8[0]; + tmp8[0] = data->uetAlarm.state == _UPI_TRUE_ ? ALARM_STATUS_UET : 0; + sts = sts | tmp8[0]; + tmp8[0] = data->oetAlarm.state == _UPI_TRUE_ ? ALARM_STATUS_OET : 0; + sts = sts | tmp8[0]; + return (sts); +} + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.h new file mode 100755 index 00000000..cb3ea775 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_API_System.h @@ -0,0 +1,211 @@ +/** + * @filename uG31xx_API_System.h + * + * Interface of ug31xx system control + * + * @author AllenTeng + */ + +#define UG31XX_SYSTEM_VERSION (6) + +typedef unsigned char _sys_u8_; +typedef signed char _sys_s8_; +typedef unsigned short _sys_u16_; +typedef signed short _sys_s16_; +typedef unsigned long _sys_u32_; +typedef signed long _sys_s32_; +typedef char _sys_bool_; + +typedef enum _SYSTEM_RTN_CODE { + SYSTEM_RTN_PASS = 0, + SYSTEM_RTN_READ_GGB_FAIL, + SYSTEM_RTN_I2C_FAIL, +} SYSTEM_RTN_CODE; + +typedef struct AlarmDataST { + _sys_u16_ alarmThrd; + _sys_u16_ releaseThrd; + _sys_bool_ state; +#if defined(uG31xx_OS_ANDROID) + } __attribute__ ((packed)) AlarmDataType; +#else ///< else of defined(uG31xx_OS_ANDROID) + } AlarmDataType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +typedef struct SystemDataST { + + #if defined (uG31xx_OS_WINDOWS) + const wchar_t* ggbFilename; + const wchar_t* otpFileName; + const wchar_t* backupFileName; + #elif defined(uG31xx_OS_ANDROID) + GGBX_FILE_HEADER *ggbXBuf; + #endif + + CELL_PARAMETER *ggbParameter; + CELL_TABLE *ggbCellTable; + OtpDataType *otpData; + + ADC_CHECK adcCheckData; //add for adc error check 20121025/jacky + + _sys_u16_ voltage; + + _sys_u16_ preITAve; + _sys_u8_ cellNum; + + _sys_u16_ rmFromIC; + _sys_u16_ fccFromIC; + _sys_u8_ rsocFromIC; + _sys_u32_ timeTagFromIC; + _sys_u8_ tableUpdateIdxFromIC; + _sys_s16_ deltaCapFromIC; + _sys_u16_ adc1ConvTime; + + _sys_u16_ rmFromICBackup; + _sys_u16_ fccFromICBackup; + _sys_u8_ rsocFromICBackup; + + AlarmDataType uvAlarm; + AlarmDataType oetAlarm; + AlarmDataType uetAlarm; + _sys_u16_ alarmSts; +#if defined(uG31xx_OS_ANDROID) + } __attribute__ ((packed)) SystemDataType; +#else ///< else of defined(uG31xx_OS_ANDROID) + } SystemDataType; +#endif ///< end of defined(uG31xx_OS_ANDROID) + +/** + * @brief UpiInitSystemData + * + * Initialize system data + * + * @para data address of BootDataType + * @return _UPI_NULL_ + */ +extern SYSTEM_RTN_CODE UpiInitSystemData(SystemDataType *data); + +/** + * @brief UpiCheckICActive + * + * Check IC is actived or not + * + * @return _UPI_TRUE_ if uG31xx is not actived + */ +extern _upi_bool_ UpiCheckICActive(void); + +/** + * @brief UpiActiveUg31xx + * + * Active uG31xx + * + * @return SYSTEM_RTN_CODE + */ +extern SYSTEM_RTN_CODE UpiActiveUg31xx(void); + +/** + * @brief UpiSetupAdc + * + * Setup ADC configurations + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +extern void UpiSetupAdc(SystemDataType *data); + +/** + * @brief UpiDecimateRst + * + * Decimate reset filter of ADC + * + * @return _UPI_NULL_ + */ +extern void UpiDecimateRst(void); + +/** + * @brief UpiSetupSystem + * + * Setup uG31xx system + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +extern void UpiSetupSystem(SystemDataType *data); + +/** + * @brief UpiCalibrationOsc + * + * OSC calibration + * oscCnt25[9:0] = oscCntTarg[9:0] + oscDeltaCode25[7:0] + * oscCnt80[9:0] = oscCntTarg[9:0] + oscDeltaCode80[7:0] + * oscCnt[9:0] = m*ITcode[15:8] + C[9:0] + * m = (oscCnt80[9:0]-oscCnt25[9:0])/(iTcode80[7:0]-iTcode25[7:0]) + * c = oscCnt25[9:0] - m*ITcode25[7:0] + * write oscCnt[9:0] to register 0x97-98 + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +extern void UpiCalibrationOsc(SystemDataType *data); + +/** + * @brief UpiAdcStatus + * + * Check ADC status + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +extern void UpiAdcStatus(SystemDataType *data); + +/** + * @brief UpiLoadBatInfoFromIC + * + * Load battery information from uG31xx + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +extern void UpiLoadBatInfoFromIC(SystemDataType *data); + +/** + * @brief UpiUpdateBatInfoFromIC + * + * Update battery information from uG31xx + * + * @para data address of SystemDataType + * @para deltaQ delta capacity from coulomb counter + * @return _UPI_NULL_ + */ +extern void UpiUpdateBatInfoFromIC(SystemDataType *data, _sys_s16_ deltaQ); + +/** + * @brief UpiSaveBatInfoTOIC + * + * Save battery information from uG31xx + * + * @para data address of SystemDataType + * @return _UPI_NULL_ + */ +extern void UpiSaveBatInfoTOIC(SystemDataType *data); + +/** + * @brief UpiInitAlarm + * + * Initialize alarm function of uG3105 + * + * @para data address of SystemDataType + * @return NULL + */ +extern void UpiInitAlarm(SystemDataType *data); + +/** + * @brief UpiAlarmStatus + * + * Get alarm status + * + * @para data address of SystemDataType + * @return NULL + */ +extern _sys_u8_ UpiAlarmStatus(SystemDataType *data); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Platform.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Platform.h new file mode 100755 index 00000000..9c1e7325 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Platform.h @@ -0,0 +1,17 @@ +/** + * @filename uG31xx_Platform.h + * + * Define the platform for uG31xx driver + * + * @author AllenTeng + */ + +//#define uG31xx_OS_WINDOWS +#define uG31xx_OS_ANDROID + +#ifdef uG31xx_OS_ANDROID + + //#define uG31xx_BOOT_LOADER + +#endif ///< end of uG31xx_OS_ANDROID + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Reg_Def.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Reg_Def.h new file mode 100755 index 00000000..4de941ae --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/uG31xx_Reg_Def.h @@ -0,0 +1,667 @@ +/** + * @filename RegDef.h + * + * uG31xx register definition + * + * @author AllenTeng + * @note register table release date 2012/11/05 + */ + +#define INTERNAL_REGISTER_GROUP_A (0x00) + #define REG_MODE (INTERNAL_REGISTER_GROUP_A + 0) ///< 0x00 + #define MODE_GG_RUN (1<<4) + #define GG_RUN_STANDBY_MODE (0<<4) + #define GG_RUN_OPERATION_MODE (1<<4) + #define REG_CTRL1 (INTERNAL_REGISTER_GROUP_A + 1) ///< 0x01 + #define CTRL1_PORDET (1<<4) + #define PORDET_R_NO_POR (0<<4) + #define PORDET_R_POR (1<<4) + #define PORDET_W_RELEASE (0<<4) + #define PORDET_W_SOFTRESET (1<<4) + #define CTRL1_VTM_EOC (1<<3) + #define CTRL1_GG_EOC (1<<2) + #define CTRL1_GG_RST (1<<1) + #define CTRL1_IO1DATA (1<<0) + #define IO1DATA_R_LOW (0<<0) + #define IO1DATA_R_HIGH (1<<0) + #define IO1DATA_W_LOW (0<<0) + #define IO1DATA_W_HIGH (1<<0) + +#define INTERNAL_REGISTER_GROUP_B (0x02) + #define REG_CHARGE_LOW (INTERNAL_REGISTER_GROUP_B + 0) ///< 0x02 + #define REG_CHARGE_HIGH (INTERNAL_REGISTER_GROUP_B + 1) ///< 0x03 + #define REG_COUNTER_LOW (INTERNAL_REGISTER_GROUP_B + 2) ///< 0x04 + #define REG_COUNTER_HIGH (INTERNAL_REGISTER_GROUP_B + 3) ///< 0x05 + #define REG_AVE_CURRENT_LOW (INTERNAL_REGISTER_GROUP_B + 4) ///< 0x06 + #define REG_AVE_CURRENT_HIGH (INTERNAL_REGISTER_GROUP_B + 5) ///< 0x07 + #define REG_AVE_VBAT1_LOW (INTERNAL_REGISTER_GROUP_B + 6) ///< 0x08 + #define REG_AVE_VBAT1_HIGH (INTERNAL_REGISTER_GROUP_B + 7) ///< 0x09 + #define REG_AVE_IT_LOW (INTERNAL_REGISTER_GROUP_B + 8) ///< 0x0A + #define REG_AVE_IT_HIGH (INTERNAL_REGISTER_GROUP_B + 9) ///< 0x0B + #define REG_AVE_OFFSET_CURRENT_LOW (INTERNAL_REGISTER_GROUP_B + 10) ///< 0x0C + #define REG_AVE_OFFSET_CURRENT_HIGH (INTERNAL_REGISTER_GROUP_B + 11) ///< 0x0D + #define REG_AVE_ET_LOW (INTERNAL_REGISTER_GROUP_B + 12) ///< 0x0E + #define REG_AVE_ET_HIGH (INTERNAL_REGISTER_GROUP_B + 13) ///< 0x0F + #define REG_AVE_RID_LOW (INTERNAL_REGISTER_GROUP_B + 14) ///< 0x10 + #define REG_AVE_RID_HIGH (INTERNAL_REGISTER_GROUP_B + 15) ///< 0x11 + #define REG_ALARM1_STATUS (INTERNAL_REGISTER_GROUP_B + 16) ///< 0x12 + #define ALARM1_STATUS_COC_ALARM (1<<5) + #define ALARM1_STATUS_DOC_ALARM (1<<4) + #define ALARM1_STATUS_OIT_ALARM (1<<3) + #define ALARM1_STATUS_UIT_ALARM (1<<2) + #define ALARM1_STATUS_OET_ALARM (1<<1) + #define ALARM1_STATUS_UET_ALARM (1<<0) + #define REG_ALARM2_STATUS (INTERNAL_REGISTER_GROUP_B + 17) ///< 0x13 + #define ALARM2_STATUS_OV3_ALARM (1<<5) + #define ALARM2_STATUS_UV3_ALARM (1<<4) + #define ALARM2_STATUS_OV2_ALARM (1<<3) + #define ALARM2_STATUS_UV2_ALARM (1<<2) + #define ALARM2_STATUS_OV1_ALARM (1<<1) + #define ALARM2_STATUS_UV1_ALARM (1<<0) + #define REG_INTR_STATUS (INTERNAL_REGISTER_GROUP_B + 18) ///< 0x14 + #define INTR_STATUS_CBC_STS32 (1<<7) + #define CBC_STS32_ENABLE (0<<7) + #define CBC_STS32_DISABLE (1<<7) + #define INTR_STATUS_CBC_STS21 (1<<6) + #define CBC_STS21_ENABLE (0<<6) + #define CBC_STS21_DISABLE (1<<6) + #define INTR_STATUS_STB_STS (1<<5) + #define INTR_STATUS_ET_STS (1<<4) + #define INTR_STATUS_IT_STS (1<<3) + #define INTR_STATUS_RID_STS (1<<2) + #define INTR_STATUS_LVD_STS (1<<1) + #define INTR_STATUS_AL_STS (1<<0) + #define REG_ALARM_EN (INTERNAL_REGISTER_GROUP_B + 19) ///< 0x15 + #define ALARM_EN_COC_ALARM_EN (1<<7) + #define ALARM_EN_DOC_ALARM_EN (1<<6) + #define ALARM_EN_IT_ALARM_EN (1<<5) + #define ALARM_EN_ET_ALARM_EN (1<<4) + #define ALARM_EN_DECIMATE_RST (1<<3) + #define ALARM_EN_V3_ALARM_EN (1<<2) + #define ALARM_EN_V2_ALARM_EN (1<<1) + #define ALARM_EN_V1_ALARM_EN (1<<0) + #define REG_CTRL2 (INTERNAL_REGISTER_GROUP_B + 20) ///< 0x16 + #define CTRL2_IO4DATA (1<<2) + #define IO4DATA_R_LOW (0<<2) + #define IO4DATA_R_HIGH (1<<2) + #define IO4DATA_W_LOW (0<<2) + #define IO4DATA_W_HIGH (1<<2) + #define CTRL2_IO3DATA (1<<1) + #define IO3DATA_R_LOW (0<<1) + #define IO3DATA_R_HIGH (1<<1) + #define IO3DATA_W_LOW (0<<1) + #define IO3DATA_W_HIGH (1<<1) + #define CTRL2_IO2DATA (1<<0) + #define IO2DATA_R_LOW (0<<0) + #define IO2DATA_R_HIGH (1<<0) + #define IO2DATA_W_LOW (0<<0) + #define IO2DATA_W_HIGH (1<<0) + +#define INTERNAL_REGISTER_GROUP_C (0x20) + #define REG_RAM0 (INTERNAL_REGISTER_GROUP_C + 0) ///< 0x20 + #define REG_RAM1 (INTERNAL_REGISTER_GROUP_C + 1) ///< 0x21 + #define REG_RAM2 (INTERNAL_REGISTER_GROUP_C + 2) ///< 0x22 + #define REG_RAM3 (INTERNAL_REGISTER_GROUP_C + 3) ///< 0x23 + #define REG_RAM4 (INTERNAL_REGISTER_GROUP_C + 4) ///< 0x24 + #define REG_RAM5 (INTERNAL_REGISTER_GROUP_C + 5) ///< 0x25 + #define REG_RAM6 (INTERNAL_REGISTER_GROUP_C + 6) ///< 0x26 + #define REG_RAM7 (INTERNAL_REGISTER_GROUP_C + 7) ///< 0x27 + #define REG_RAM8 (INTERNAL_REGISTER_GROUP_C + 8) ///< 0x28 + #define REG_RAM9 (INTERNAL_REGISTER_GROUP_C + 9) ///< 0x29 + #define REG_RAM10 (INTERNAL_REGISTER_GROUP_C + 10) ///< 0x2A + #define REG_RAM11 (INTERNAL_REGISTER_GROUP_C + 11) ///< 0x2B + #define REG_RAM12 (INTERNAL_REGISTER_GROUP_C + 12) ///< 0x2C + #define REG_RAM13 (INTERNAL_REGISTER_GROUP_C + 13) ///< 0x2D + #define REG_RAM14 (INTERNAL_REGISTER_GROUP_C + 14) ///< 0x2E + #define REG_RAM15 (INTERNAL_REGISTER_GROUP_C + 15) ///< 0x2F + #define REG_RAM16 (INTERNAL_REGISTER_GROUP_C + 16) ///< 0x30 + #define REG_RAM17 (INTERNAL_REGISTER_GROUP_C + 17) ///< 0x31 + #define REG_RAM18 (INTERNAL_REGISTER_GROUP_C + 18) ///< 0x32 + #define REG_RAM19 (INTERNAL_REGISTER_GROUP_C + 19) ///< 0x33 + #define REG_RAM20 (INTERNAL_REGISTER_GROUP_C + 20) ///< 0x34 + #define REG_RAM21 (INTERNAL_REGISTER_GROUP_C + 21) ///< 0x35 + #define REG_RAM22 (INTERNAL_REGISTER_GROUP_C + 22) ///< 0x36 + #define REG_RAM23 (INTERNAL_REGISTER_GROUP_C + 23) ///< 0x37 + #define REG_RAM24 (INTERNAL_REGISTER_GROUP_C + 24) ///< 0x38 + #define REG_RAM25 (INTERNAL_REGISTER_GROUP_C + 25) ///< 0x39 + #define REG_RAM26 (INTERNAL_REGISTER_GROUP_C + 26) ///< 0x3A + #define REG_RAM27 (INTERNAL_REGISTER_GROUP_C + 27) ///< 0x3B + #define REG_RAM28 (INTERNAL_REGISTER_GROUP_C + 28) ///< 0x3C + #define REG_RAM29 (INTERNAL_REGISTER_GROUP_C + 29) ///< 0x3D + #define REG_RAM30 (INTERNAL_REGISTER_GROUP_C + 30) ///< 0x3E + #define REG_RAM31 (INTERNAL_REGISTER_GROUP_C + 31) ///< 0x3F + +#define INTERNAL_REGISTER_GROUP_D (0x40) + #define REG_VBAT2_LOW (INTERNAL_REGISTER_GROUP_D + 0) ///< 0x40 + #define REG_VBAT2_HIGH (INTERNAL_REGISTER_GROUP_D + 1) ///< 0x41 + #define REG_VBAT3_LOW (INTERNAL_REGISTER_GROUP_D + 2) ///< 0x42 + #define REG_VBAT3_HIGH (INTERNAL_REGISTER_GROUP_D + 3) ///< 0x43 + #define REG_VBAT1_LOW (INTERNAL_REGISTER_GROUP_D + 4) ///< 0x44 + #define REG_VBAT1_HIGH (INTERNAL_REGISTER_GROUP_D + 5) ///< 0x45 + #define REG_VBAT2_AVE_LOW (INTERNAL_REGISTER_GROUP_D + 6) ///< 0x46 + #define REG_VBAT2_AVE_HIGH (INTERNAL_REGISTER_GROUP_D + 7) ///< 0x47 + #define REG_VBAT3_AVE_LOW (INTERNAL_REGISTER_GROUP_D + 8) ///< 0x48 + #define REG_VBAT3_AVE_HIGH (INTERNAL_REGISTER_GROUP_D + 9) ///< 0x49 + #define REG_V1_LOW (INTERNAL_REGISTER_GROUP_D + 10) ///< 0x4A + #define REG_V1_HIGH (INTERNAL_REGISTER_GROUP_D + 11) ///< 0x4B + #define REG_V2_LOW (INTERNAL_REGISTER_GROUP_D + 12) ///< 0x4C + #define REG_V2_HIGH (INTERNAL_REGISTER_GROUP_D + 13) ///< 0x4D + #define REG_V3_LOW (INTERNAL_REGISTER_GROUP_D + 14) ///< 0x4E + #define REG_V3_HIGH (INTERNAL_REGISTER_GROUP_D + 15) ///< 0x4F + #define REG_INTR_TEMPER_LOW (INTERNAL_REGISTER_GROUP_D + 16) ///< 0x50 + #define REG_INTR_TEMPER_HIGH (INTERNAL_REGISTER_GROUP_D + 17) ///< 0x51 + #define REG_EXTR_TEMPER_LOW (INTERNAL_REGISTER_GROUP_D + 18) ///< 0x52 + #define REG_EXTR_TEMPER_HIGH (INTERNAL_REGISTER_GROUP_D + 19) ///< 0x53 + #define REG_RID_LOW (INTERNAL_REGISTER_GROUP_D + 20) ///< 0x54 + #define REG_RID_HIGH (INTERNAL_REGISTER_GROUP_D + 21) ///< 0x55 + #define REG_CURRENT_LOW (INTERNAL_REGISTER_GROUP_D + 22) ///< 0x56 + #define REG_CURRENT_HIGH (INTERNAL_REGISTER_GROUP_D + 23) ///< 0x57 + #define REG_ADC1_OFFSET_LOW (INTERNAL_REGISTER_GROUP_D + 24) ///< 0x58 + #define REG_ADC1_OFFSET_HIGH (INTERNAL_REGISTER_GROUP_D + 25) ///< 0x59 + + #define OTP6_BYTE1 (INTERNAL_REGISTER_GROUP_D + 48) ///< 0x70 + #define AVE_IT25_7_3 (63<<3) + #define DELTA_ET_3_2 (3<<1) + #define DELTA_VREF_4 (1<<0) + #define OTP6_BYTE2 (INTERNAL_REGISTER_GROUP_D + 49) ///< 0x71 + #define AVE_IT25_15_8 (255<<0) + #define OTP6_BYTE3 (INTERNAL_REGISTER_GROUP_D + 50) ///< 0x72 + #define AVE_IT80_7_3 (63<<3) + #define INDEX_ADC1_200_25_4 (1<<2) + #define INDEX_ADC1_100_25_4 (1<<1) + #define INDEX_ADC2_200_25_4 (1<<0) + #define OTP6_BYTE4 (INTERNAL_REGISTER_GROUP_D + 51) ///< 0x73 + #define AVE_IT80_15_8 (255<<0) + +#define INTERNAL_REGISTER_GROUP_E (0x8F) + #define REG_TIMER (INTERNAL_REGISTER_GROUP_E + 0) ///< 0x8F + #define TIMER_TIMER_ITSET (3<<6) + #define TIMER_ITSET_4 (0<<6) + #define TIMER_ITSET_9 (1<<6) + #define TIMER_ITSET_14 (2<<6) + #define TIMER_ITSET_19 (3<<6) + #define TIMER_TIMER_ETSET (3<<4) + #define TIMER_ETSET_4 (0<<4) + #define TIMER_ETSET_9 (1<<4) + #define TIMER_ETSET_14 (2<<4) + #define TIMER_ETSET_19 (3<<4) + #define TIMER_TIMER_VSET (3<<2) + #define TIMER_VSET_4 (0<<2) + #define TIMER_VSET_9 (1<<2) + #define TIMER_VSET_14 (2<<2) + #define TIMER_VSET_19 (3<<2) + #define TIMER_TIMER_CSET (3<<0) + #define TIMER_CSET_4 (0<<0) + #define TIMER_CSET_9 (1<<0) + #define TIMER_CSET_14 (2<<0) + #define TIMER_CSET_19 (3<<0) + #define REG_CLK_DIVA (INTERNAL_REGISTER_GROUP_E + 1) ///< 0x90 + #define CLK_DIVA_FW_CLK_CDIV (15<<4) + #define FW_CLK_CDIV_31US (0<<4) + #define FW_CLK_CDIV_61US (1<<4) + #define FW_CLK_CDIV_122US (2<<4) + #define FW_CLK_CDIV_244US (3<<4) + #define FW_CLK_CDIV_488US (4<<4) + #define FW_CLK_CDIV_977US (5<<4) + #define FW_CLK_CDIV_2MS (6<<4) + #define FW_CLK_CDIV_4MS (7<<4) + #define FW_CLK_CDIV_8MS (8<<4) + #define FW_CLK_CDIV_16MS (9<<4) + #define FW_CLK_CDIV_31MS (10<<4) + #define FW_CLK_CDIV_62MS (11<<4) + #define FW_CLK_CDIV_125MS (12<<4) + #define FW_CLK_CDIV_250MS (13<<4) + #define FW_CLK_CDIV_500MS (14<<4) + #define FW_CLK_CDIV_1S (15<<4) + #define CLK_DIVA_FW_CLK_VDIV (15<<0) + #define FW_CLK_VDIV_31US (0<<0) + #define FW_CLK_VDIV_61US (1<<0) + #define FW_CLK_VDIV_122US (2<<0) + #define FW_CLK_VDIV_244US (3<<0) + #define FW_CLK_VDIV_488US (4<<0) + #define FW_CLK_VDIV_977US (5<<0) + #define FW_CLK_VDIV_2MS (6<<0) + #define FW_CLK_VDIV_4MS (7<<0) + #define FW_CLK_VDIV_8MS (8<<0) + #define FW_CLK_VDIV_16MS (9<<0) + #define FW_CLK_VDIV_31MS (10<<0) + #define FW_CLK_VDIV_62MS (11<<0) + #define FW_CLK_VDIV_125MS (12<<0) + #define FW_CLK_VDIV_250MS (13<<0) + #define FW_CLK_VDIV_500MS (14<<0) + #define FW_CLK_VDIV_1S (15<<0) + #define REG_CLK_DIVB (INTERNAL_REGISTER_GROUP_E + 2) ///< 0x91 + #define CLK_DIVB_FW_CLK_ETDIV (15<<4) + #define FW_CLK_ETDIV_31US (0<<4) + #define FW_CLK_ETDIV_61US (1<<4) + #define FW_CLK_ETDIV_122US (2<<4) + #define FW_CLK_ETDIV_244US (3<<4) + #define FW_CLK_ETDIV_488US (4<<4) + #define FW_CLK_ETDIV_977US (5<<4) + #define FW_CLK_ETDIV_2MS (6<<4) + #define FW_CLK_ETDIV_4MS (7<<4) + #define FW_CLK_ETDIV_8MS (8<<4) + #define FW_CLK_ETDIV_16MS (9<<4) + #define FW_CLK_ETDIV_31MS (10<<4) + #define FW_CLK_ETDIV_62MS (11<<4) + #define FW_CLK_ETDIV_125MS (12<<4) + #define FW_CLK_ETDIV_250MS (13<<4) + #define FW_CLK_ETDIV_500MS (14<<4) + #define FW_CLK_ETDIV_1S (15<<4) + #define CLK_DIVB_FW_CLK_ITDIV (15<<0) + #define FW_CLK_ITDIV_31US (0<<0) + #define FW_CLK_ITDIV_61US (1<<0) + #define FW_CLK_ITDIV_122US (2<<0) + #define FW_CLK_ITDIV_244US (3<<0) + #define FW_CLK_ITDIV_488US (4<<0) + #define FW_CLK_ITDIV_977US (5<<0) + #define FW_CLK_ITDIV_2MS (6<<0) + #define FW_CLK_ITDIV_4MS (7<<0) + #define FW_CLK_ITDIV_8MS (8<<0) + #define FW_CLK_ITDIV_16MS (9<<0) + #define FW_CLK_ITDIV_31MS (10<<0) + #define FW_CLK_ITDIV_62MS (11<<0) + #define FW_CLK_ITDIV_125MS (12<<0) + #define FW_CLK_ITDIV_250MS (13<<0) + #define FW_CLK_ITDIV_500MS (14<<0) + #define FW_CLK_ITDIV_1S (15<<0) + #define REG_INTR_CTRL_D (INTERNAL_REGISTER_GROUP_E + 3) ///< 0x92 + #define INTR_CTRL_D_GPIO4_SEL (7<<3) + #define GPIO4_SEL_GPIO1 (0<<3) + #define GPIO4_SEL_ALARM (1<<3) + #define GPIO4_SEL_CBC_EN21 (2<<3) + #define GPIO4_SEL_CBC_EN32 (3<<3) + #define GPIO4_SEL_PWM (4<<3) + #define GPIO4_SEL_ADC1_D (6<<3) + #define GPIO4_SEL_ADC2_D (7<<3) + #define INTR_CTRL_D_GPIO3_SEL (7<<0) + #define GPIO3_SEL_GPIO1 (0<<0) + #define GPIO3_SEL_ALARM (1<<0) + #define GPIO3_SEL_CBC_EN21 (2<<0) + #define GPIO3_SEL_CBC_EN32 (3<<0) + #define GPIO3_SEL_PWM (4<<0) + #define GPIO3_SEL_ADC1_D (6<<0) + #define GPIO3_SEL_ADC2_D (7<<0) + #define OSCTUNE_J1 (INTERNAL_REGISTER_GROUP_E + 4) ///< 0x93 + #define OSCTUNE_J_LOW (255<<0) + #define OSCTUNE_J2 (INTERNAL_REGISTER_GROUP_E + 5) ///< 0x94 + #define OSCTUNE_J_HIGH (3<<0) + #define OSCTUNE_K1 (INTERNAL_REGISTER_GROUP_E + 6) ///< 0x95 + #define OSCTUNE_K_LOW (255<<0) + #define OSCTUNE_K2 (INTERNAL_REGISTER_GROUP_E + 7) ///< 0x96 + #define OSCTUNE_K_HIGH (3<<0) + #define OSCTUNE_CNTA (INTERNAL_REGISTER_GROUP_E + 8) ///< 0x97 + #define OSCTUNE_CNT_LOW (255<<0) + #define OSCTUNE_CNTB (INTERNAL_REGISTER_GROUP_E + 9) ///< 0x98 + #define OSCTUNE_CNT_HIGH (3<<0) + #define ADC1_TARGET_A (INTERNAL_REGISTER_GROUP_E + 10) ///< 0x99 + #define TARGET_A_LOW (255<<0) + #define ADC1_TARGET_B (INTERNAL_REGISTER_GROUP_E + 11) ///< 0x9A + #define TARGET_A_HIGH (3<<0) + #define REG_INTR_CTRL_A (INTERNAL_REGISTER_GROUP_E + 12) ///< 0x9B + #define INTR_CTRL_A_GPIO2_SEL (7<<5) + #define GPIO2_SEL_GPIO1 (0<<5) + #define GPIO2_SEL_ALARM (1<<5) + #define GPIO2_SEL_CBC_EN21 (2<<5) + #define GPIO2_SEL_CBC_EN32 (3<<5) + #define GPIO2_SEL_PWM (4<<5) + #define INTR_CTRL_A_GPIO1_SEL (7<<2) + #define GPIO1_SEL_GPIO1 (0<<2) + #define GPIO1_SEL_ALARM (1<<2) + #define GPIO1_SEL_CBC_EN21 (2<<2) + #define GPIO1_SEL_CBC_EN32 (3<<2) + #define GPIO1_SEL_PWM (4<<2) + #define GPIO1_SEL_OSCOUT (7<<2) + #define INTR_CTRL_A_ADC2_EN (1<<1) + #define INTR_CTRL_A_ADC1_EN (1<<0) + #define REG_INTR_CTRL_B (INTERNAL_REGISTER_GROUP_E + 13) ///< 0x9C + #define INTR_CTRL_B_OSC_CNT_EN (1<<7) + #define INTR_CTRL_B_PWM_EN (1<<6) + #define INTR_CTRL_B_CBC_32_EN (1<<5) + #define INTR_CTRL_B_CBC_21_EN (1<<4) + #define INTR_CTRL_B_STB_EN (1<<3) + #define INTR_CTRL_B_ET_EN (1<<2) + #define INTR_CTRL_B_IT_EN (1<<1) + #define INTR_CTRL_B_RID_EN (1<<0) + #define REG_ITNR_CTRL_C (INTERNAL_REGISTER_GROUP_E + 14) ///< 0x9D + #define INTR_CTRL_C_BGRCAL_FINISH (1<<7) + #define INTR_CTRL_C_FW_V_DIVIDE (1<<6) + #define INTR_CTRL_C_BGRCAL_START (1<<5) + #define INTR_CTRL_C_BGR_CALEN (1<<4) + #define INTR_CTRL_C_PWM_SET (3<<2) + #define PWM_SET_32K (0<<2) + #define PWM_SET_16K (1<<2) + #define PWM_SET_8K (2<<2) + #define PWM_SET_4K (3<<2) + #define INTR_CTRL_C_TIMER_SET (3<<0) + #define TIMER_SET_OV_UV (0<<0) + #define TIMER_SET_OC_UC (1<<0) + #define TIMER_SET_OIT_UIT (2<<0) + #define TIMER_SET_OET_UET (3<<0) + #define REG_CELL_EN (INTERNAL_REGISTER_GROUP_E + 15) ///< 0x9E + #define CELL_EN_APPLICATION (7<<2) + #define APPLICATION_UG3100 (0<<2) + #define APPLICATION_UG3101 (1<<2) + #define APPLICATION_UG3102 (2<<2) + #define APPLICATION_UG3103_2 (4<<2) + #define APPLICATION_UG3103_3 (5<<2) + #define CELL_EN1 (1<<1) + #define CELL_EN0 (1<<0) + +#define INTERNAL_REGISTER_GROUP_F (0x9F) + #define REG_COC_LOW (INTERNAL_REGISTER_GROUP_F + 0) ///< 0x9F + #define REG_COC_HIGH (INTERNAL_REGISTER_GROUP_F + 1) ///< 0xA0 + #define REG_DOC_LOW (INTERNAL_REGISTER_GROUP_F + 2) ///< 0xA1 + #define REG_DOC_HIGH (INTERNAL_REGISTER_GROUP_F + 3) ///< 0xA2 + #define REG_UC_LOW (INTERNAL_REGISTER_GROUP_F + 4) ///< 0xA3 + #define REG_UC_HIGH (INTERNAL_REGISTER_GROUP_F + 5) ///< 0xA4 + #define REG_OV1_LOW (INTERNAL_REGISTER_GROUP_F + 6) ///< 0xA5 + #define REG_OV1_HIGH (INTERNAL_REGISTER_GROUP_F + 7) ///< 0xA6 + #define REG_UV1_LOW (INTERNAL_REGISTER_GROUP_F + 8) ///< 0xA7 + #define REG_UV1_HIGH (INTERNAL_REGISTER_GROUP_F + 9) ///< 0xA8 + #define REG_OV2_LOW (INTERNAL_REGISTER_GROUP_F + 10) ///< 0xA9 + #define REG_OV2_HIGH (INTERNAL_REGISTER_GROUP_F + 11) ///< 0xAA + #define REG_UV2_LOW (INTERNAL_REGISTER_GROUP_F + 12) ///< 0xAB + #define REG_UV2_HIGH (INTERNAL_REGISTER_GROUP_F + 13) ///< 0xAC + #define REG_OV3_LOW (INTERNAL_REGISTER_GROUP_F + 14) ///< 0xAD + #define REG_OV3_HIGH (INTERNAL_REGISTER_GROUP_F + 15) ///< 0xAE + #define REG_UV3_LOW (INTERNAL_REGISTER_GROUP_F + 16) ///< 0xAF + #define REG_UV3_HIGH (INTERNAL_REGISTER_GROUP_F + 17) ///< 0xB0 + #define REG_OVP_LOW (INTERNAL_REGISTER_GROUP_F + 18) ///< 0xB1 + #define REG_OVP_HIGH (INTERNAL_REGISTER_GROUP_F + 19) ///< 0xB2 + #define REG_UVP_LOW (INTERNAL_REGISTER_GROUP_F + 20) ///< 0xB3 + #define REG_UVP_HIGH (INTERNAL_REGISTER_GROUP_F + 21) ///< 0xB4 + #define REG_INTR_OVER_TEMP_LOW (INTERNAL_REGISTER_GROUP_F + 22) ///< 0xB5 + #define REG_INTR_OVER_TEMP_HIGH (INTERNAL_REGISTER_GROUP_F + 23) ///< 0xB6 + #define REG_INTR_UNDER_TEMP_LOW (INTERNAL_REGISTER_GROUP_F + 24) ///< 0xB7 + #define REG_INTR_UNDER_TEMP_HIGH (INTERNAL_REGISTER_GROUP_F + 25) ///< 0xB8 + #define REG_EXTR_OVER_TEMP_LOW (INTERNAL_REGISTER_GROUP_F + 26) ///< 0xB9 + #define REG_EXTR_OVER_TEMP_HIGH (INTERNAL_REGISTER_GROUP_F + 27) ///< 0xBA + #define REG_EXTR_UNDER_TEMP_LOW (INTERNAL_REGISTER_GROUP_F + 28) ///< 0xBB + #define REG_EXTR_UNDER_TEMP_HIGH (INTERNAL_REGISTER_GROUP_F + 29) ///< 0xBC + #define REG_CBC21_LOW (INTERNAL_REGISTER_GROUP_F + 30) ///< 0xBD + #define REG_CBC21_HIGH (INTERNAL_REGISTER_GROUP_F + 31) ///< 0xBE + #define REG_CBC32_LOW (INTERNAL_REGISTER_GROUP_F + 32) ///< 0xBF + #define REG_CBC32_HIGH (INTERNAL_REGISTER_GROUP_F + 33) ///< 0xC0 + +#define INTERNAL_REGISTER_GROUP_G (0xC1) + #define REG_FW_CTRL (INTERNAL_REGISTER_GROUP_G + 0) ///< 0xC1 + #define FW_CTRL_CHOP2_EN (1<<3) + #define FW_CTRL_CHOPPING2 (1<<2) + #define FW_CTRL_CHOP1_EN (1<<1) + #define FW_CTRL_CHOPPING1 (1<<0) + #define REG_OTP_CTRL (INTERNAL_REGISTER_GROUP_G + 1) ///< 0xC2 + #define OTP_CTRL_IT_CAL80 (1<<7) + #define OTP_CTRL_IT_CAL25 (1<<6) + #define OTP_CTRL_ADC2_200MV (1<<5) + #define OTP_CTRL_ADC2_100MV (1<<4) + #define OTP_CTRL_ADC1_200MV (1<<3) + #define OTP_CTRL_ADC1_100MV (1<<2) + #define OTP_CTRL_OTP_PTM (3<<0) + #define REG_OTP_PPROG_ON (INTERNAL_REGISTER_GROUP_G + 2) ///< 0xC3 + #define OTP_PPROG_ON_VALUE (0xDD) + #define REG_OTP_PPROG_OFF (INTERNAL_REGISTER_GROUP_G + 3) ///< 0xC4 + #define OTP_PPROG_OFF_VALUE (0xDE) + +#define INTERNAL_REGISTER_GROUP_H (0xC5) + #define REG_ADC_CTR_A (INTERNAL_REGISTER_GROUP_H + 0) ///< 0xC5 + #define ADC_CTR_A_SET_A (3<<6) + #define SET_A_CURRENT (0<<6) + #define SET_A_ET (1<<6) + #define SET_A_RID_IN (2<<6) + #define SET_A_IT (3<<6) + #define ADC_CTR_A_SET_B (3<<4) + #define SET_B_CURRENT (0<<4) + #define SET_B_ET (1<<4) + #define SET_B_RID_IN (2<<4) + #define SET_B_IT (3<<4) + #define ADC_CTR_A_SET_C (3<<2) + #define SET_C_CURRENT (0<<2) + #define SET_C_ET (1<<2) + #define SET_C_RID_IN (2<<2) + #define SET_C_IT (3<<2) + #define ADC_CTR_A_SET_D (3<<0) + #define SET_D_CURRENT (0<<0) + #define SET_D_ET (1<<0) + #define SET_D_RID_IN (2<<0) + #define SET_D_IT (3<<0) + #define REG_ADC_CTR_B (INTERNAL_REGISTER_GROUP_H + 1) ///< 0xC6 + #define ADC_CTR_B_SET_E (3<<6) + #define SET_E_CURRENT (0<<6) + #define SET_E_ET (1<<6) + #define SET_E_RID_IN (2<<6) + #define SET_E_IT (3<<6) + #define ADC_CTR_B_SET_F (3<<4) + #define SET_F_CURRENT (0<<4) + #define SET_F_ET (1<<4) + #define SET_F_RID_IN (2<<4) + #define SET_F_IT (3<<4) + #define ADC_CTR_B_SET_G (3<<2) + #define SET_G_CURRENT (0<<2) + #define SET_G_ET (1<<2) + #define SET_G_RID_IN (2<<2) + #define SET_G_IT (3<<2) + #define ADC_CTR_B_SET_H (3<<0) + #define SET_H_CURRENT (0<<0) + #define SET_H_ET (1<<0) + #define SET_H_RID_IN (2<<0) + #define SET_H_IT (3<<0) + #define REG_ADC_CTR_C (INTERNAL_REGISTER_GROUP_H + 2) ///< 0xC7 + #define ADC_CTR_C_SET_I (3<<6) + #define SET_I_CURRENT (0<<6) + #define SET_I_ET (1<<6) + #define SET_I_RID_IN (2<<6) + #define SET_I_IT (3<<6) + #define ADC_CTR_C_SET_J (3<<4) + #define SET_J_CURRENT (0<<4) + #define SET_J_ET (1<<4) + #define SET_J_RID_IN (2<<4) + #define SET_J_IT (3<<4) + #define ADC_CTR_C_SET_K (3<<2) + #define SET_K_CURRENT (0<<2) + #define SET_K_ET (1<<2) + #define SET_K_RID_IN (2<<2) + #define SET_K_IT (3<<2) + #define ADC_CTR_C_SET_L (3<<0) + #define SET_L_CURRENT (0<<0) + #define SET_L_ET (1<<0) + #define SET_L_RID_IN (2<<0) + #define SET_L_IT (3<<0) + #define REG_ADC_CTR_D (INTERNAL_REGISTER_GROUP_H + 3) ///< 0xC8 + #define ADC_CTR_D_SET_M (3<<6) + #define SET_M_CURRENT (0<<6) + #define SET_M_ET (1<<6) + #define SET_M_RID_IN (2<<6) + #define SET_M_IT (3<<6) + #define ADC_CTR_D_SET_N (3<<4) + #define SET_N_CURRENT (0<<4) + #define SET_N_ET (1<<4) + #define SET_N_RID_IN (2<<4) + #define SET_N_IT (3<<4) + #define ADC_CTR_D_SET_O (3<<2) + #define SET_O_CURRENT (0<<2) + #define SET_O_ET (1<<2) + #define SET_O_RID_IN (2<<2) + #define SET_O_IT (3<<2) + #define ADC_CTR_D_SET_P (3<<0) + #define SET_P_CURRENT (0<<0) + #define SET_P_ET (1<<0) + #define SET_P_RID_IN (2<<0) + #define SET_P_IT (3<<0) + #define REG_ADC_V1 (INTERNAL_REGISTER_GROUP_H + 4) ///< 0xC9 + #define ADC_CTR_V1_SET_V1 (3<<6) + #define SET_V1_GND (0<<6) + #define SET_V1_VBAT1 (1<<6) + #define SET_V1_VBAT2 (2<<6) + #define SET_V1_VBAT3 (3<<6) + #define ADC_CTR_V1_SET_V2 (3<<4) + #define SET_V2_GND (0<<4) + #define SET_V2_VBAT1 (1<<4) + #define SET_V2_VBAT2 (2<<4) + #define SET_V2_VBAT3 (3<<4) + #define ADC_CTR_V1_SET_V3 (3<<2) + #define SET_V3_GND (0<<2) + #define SET_V3_VBAT1 (1<<2) + #define SET_V3_VBAT2 (2<<2) + #define SET_V3_VBAT3 (3<<2) + #define ADC_CTR_V1_SET_V4 (3<<0) + #define SET_V4_GND (0<<0) + #define SET_V4_VBAT1 (1<<0) + #define SET_V4_VBAT2 (2<<0) + #define SET_V4_VBAT3 (3<<0) + #define REG_ADC_V2 (INTERNAL_REGISTER_GROUP_H + 5) ///< 0xCA + #define ADC_CTR_V2_SET_V5 (3<<6) + #define SET_V5_GND (0<<6) + #define SET_V5_VBAT1 (1<<6) + #define SET_V5_VBAT2 (2<<6) + #define SET_V5_VBAT3 (3<<6) + #define ADC_CTR_V2_SET_V6 (3<<4) + #define SET_V6_GND (0<<4) + #define SET_V6_VBAT1 (1<<4) + #define SET_V6_VBAT2 (2<<4) + #define SET_V6_VBAT3 (3<<4) + #define ADC_CTR_V2_SET_V7 (3<<2) + #define SET_V7_GND (0<<2) + #define SET_V7_VBAT1 (1<<2) + #define SET_V7_VBAT2 (2<<2) + #define SET_V7_VBAT3 (3<<2) + #define ADC_CTR_V2_SET_V8 (3<<0) + #define SET_V8_GND (0<<0) + #define SET_V8_VBAT1 (1<<0) + #define SET_V8_VBAT2 (2<<0) + #define SET_V8_VBAT3 (3<<0) + #define REG_ADC_V3 (INTERNAL_REGISTER_GROUP_H + 6) ///< 0xCB + #define ADC_CTR_V3_SET_V9 (3<<6) + #define SET_V9_GND (0<<6) + #define SET_V9_VBAT1 (1<<6) + #define SET_V9_VBAT2 (2<<6) + #define SET_V9_VBAT3 (3<<6) + #define ADC_CTR_V3_SET_V10 (3<<4) + #define SET_V10_GND (0<<4) + #define SET_V10_VBAT1 (1<<4) + #define SET_V10_VBAT2 (2<<4) + #define SET_V10_VBAT3 (3<<4) + #define ADC_CTR_V3_SET_V11 (3<<2) + #define SET_V11_GND (0<<2) + #define SET_V11_VBAT1 (1<<2) + #define SET_V11_VBAT2 (2<<2) + #define SET_V11_VBAT3 (3<<2) + #define ADC_CTR_V3_SET_V12 (3<<0) + #define SET_V12_GND (0<<0) + #define SET_V12_VBAT1 (1<<0) + #define SET_V12_VBAT2 (2<<0) + #define SET_V12_VBAT3 (3<<0) + +#define INTERNAL_REGISTER_GROUP_I (0xCC) + #define KCONFIG_D1 (INTERNAL_REGISTER_GROUP_I + 0) ///< 0xCC + #define KCONFIG_D_LOW (255<<0) + #define KCONFIG_D2 (INTERNAL_REGISTER_GROUP_I + 1) ///< 0xCD + #define KCONFIG_D_HIGH (255<<0) + +#define INTERNAL_REGISTER_GROUP_J (0xCE) + #define KCONFIG_A1 (INTERNAL_REGISTER_GROUP_J + 0) ///< 0xCE + #define KCONFIG_A1_KGG1_OSC (255<<0) + #define KCONFIG_A2 (INTERNAL_REGISTER_GROUP_J + 1) ///< 0xCF + #define KCONFIG_A2_KGG1_DSM2_L (255<<0) + #define KCONFIG_A3 (INTERNAL_REGISTER_GROUP_J + 2) ///< 0xD0 + #define KCONFIG_A3_KGG1_DSM2_M (255<<0) + #define KCONFIG_A4 (INTERNAL_REGISTER_GROUP_J + 3) ///< 0xD1 + #define KCONFIG_A4_KGG1_DSM2_H (255<<0) + #define KCONFIG_A5 (INTERNAL_REGISTER_GROUP_J + 4) ///< 0xD2 + #define KCONFIG_A5_KGG1_DSM1_L (255<<0) + #define KCONFIG_A6 (INTERNAL_REGISTER_GROUP_J + 5) ///< 0xD3 + #define KCONFIG_A6_KGG1_DSM1_M (255<<0) + #define KCONFIG_A7 (INTERNAL_REGISTER_GROUP_J + 6) ///< 0xD4 + #define KCONFIG_A7_KGG1_DSM1_H (255<<0) + #define KCONFIG_A8 (INTERNAL_REGISTER_GROUP_J + 7) ///< 0xD5 + #define KCONFIG_A8_KGG1_MBIAS_L (255<<0) + #define KCONFIG_A9 (INTERNAL_REGISTER_GROUP_J + 8) ///< 0xD6 + #define KCONFIG_A9_KGG1_MBIAS_H (3<<0) + + #define KCONFIG_H1 (INTERNAL_REGISTER_GROUP_J + 9) ///< 0xD7 + #define KCONFIG_H1_KGG1_IDO_LOW (15<<4) + #define KCONFIG_H1_KGG1_MBIAS (3<<2) + #define KCONFIG_H1_KGG1_OSC (3<<2) + #define KCONFIG_H2 (INTERNAL_REGISTER_GROUP_J + 10) ///< 0xD8 + #define KCONFIG_H2_KGG1_IDO_HIGH (255<<0) + #define KCONFIG_H3 (INTERNAL_REGISTER_GROUP_J + 11) ///< 0xD9 + #define KCONFIG_H3_KGG1_BGAP_LOW (63<<2) + #define KCONFIG_H3_KGG1_DSM2 (3<<0) + #define KCONFIG_H4 (INTERNAL_REGISTER_GROUP_J + 12) ///< 0xDA + #define KCONFIG_H3_KGG1_BGAP_HIGH (127<<0) + #define KCONFIG_H5 (INTERNAL_REGISTER_GROUP_J + 13) ///< 0xDB + #define KCONFIG_H5_WIRE_V_DIVIDE (1<<6) + #define KCONFIG_H5_KGG1_BGAP_CAL (63<<0) + +#define INTERNAL_REGISTER_GROUP_K (0xDC) + #define KCONFIG_CAL1 (INTERNAL_REGISTER_GROUP_K + 0) ///< 0xDC + #define KCONFIG_CAL1_KGG1_OSC_L (255<<0) + #define KCONFIG_CAL2 (INTERNAL_REGISTER_GROUP_K + 1) ///< 0xDD + #define KCONFIG_CAL2_KGG1_OSC_H (255<<0) + #define KCONFIG_CAL3 (INTERNAL_REGISTER_GROUP_K + 2) ///< 0xDE + #define KCONFIG_CAL3_KGG1_DSM2 (255<<0) + #define KCONFIG_CAL4 (INTERNAL_REGISTER_GROUP_K + 3) ///< 0xDF + #define KCONFIG_CAL4_KGG1_DSM1 (255<<0) + +#define INTERNAL_REGISTER_GROUP_L (0xE0) + #define OTP1_BYTE1 (INTERNAL_REGISTER_GROUP_L + 0) ///< 0xE0 + #define DELTA_VREF_3_0 (15<<4) + #define INDEX_ADC1_200_25_3_0 (15<<0) + #define OTP1_BYTE2 (INTERNAL_REGISTER_GROUP_L + 1) ///< 0xE1 + #define FT_IT_6_3 (15<<4) + #define INDEX_ADC1_100_25_3_0 (15<<0) + #define OTP1_BYTE3 (INTERNAL_REGISTER_GROUP_L + 2) ///< 0xE2 + #define FT_IT_10_7 (15<<4) + #define INDEX_ADC2_200_25_3_0 (15<<0) + #define OTP1_BYTE4 (INTERNAL_REGISTER_GROUP_L + 3) ///< 0xE3 + #define FT_IT_14_11 (15<<4) + #define INDEX_ADC2_100_25_3_0 (15<<0) + + #define OTP2_BYTE1 (INTERNAL_REGISTER_GROUP_L + 16) ///< 0xF0 + #define DELTA_ET_1 (1<<7) + #define INDEX_ADC2_100_25_4 (1<<6) + #define DELTA_ET_0 (1<<5) + #define PRODUCT_TYPE (3<<3) + #define ITDELTACODE25_10_8 (7<<0) + #define OTP2_BYTE2 (INTERNAL_REGISTER_GROUP_L + 17) ///< 0xF1 + #define ITDELTACODE25_7_0 (255<<0) + #define OTP2_BYTE3 (INTERNAL_REGISTER_GROUP_L + 18) ///< 0xF2 + #define OTP_CELL_EN (31<<3) + #define ITDELTACODE80_10_8 (7<<0) + #define OTP2_BYTE4 (INTERNAL_REGISTER_GROUP_L + 19) ///< 0xF3 + #define ITDELTACODE80_7_0 (255<<0) + + #define OTP3_BYTE1 (INTERNAL_REGISTER_GROUP_L + 20) ///< 0xF4 + #define DEVADDR_9_0 (63<<2) + #define ADC1DELTACODE25_200_9 (1<<1) + #define ADC1DELTACODE25_200_8 (1<<0) + #define OTP3_BYTE2 (INTERNAL_REGISTER_GROUP_L + 21) ///< 0xF5 + #define BGRTUNE_5_0 (63<<2) + #define ADC1DELTACODE80_200_9_8 (3<<0) + #define OTP3_BYTE3 (INTERNAL_REGISTER_GROUP_L + 22) ///< 0xF6 + #define OSCDELTACODE25 (255<<0) + #define OTP3_BYTE4 (INTERNAL_REGISTER_GROUP_L + 23) ///< 0xF7 + #define OSCDELTACODE80 (255<<0) + + #define OTP4_BYTE1 (INTERNAL_REGISTER_GROUP_L + 24) ///< 0xF8 + #define ADC1DELTACODE25_200_7_0 (255<<0) + #define OTP4_BYTE2 (INTERNAL_REGISTER_GROUP_L + 25) ///< 0xF9 + #define ADC1DELTACODE80_200_7_0 (255<<0) + #define OTP4_BYTE3 (INTERNAL_REGISTER_GROUP_L + 26) ///< 0xFA + #define ADC1DELTACODE25_100_7_0 (255<<0) + #define OTP4_BYTE4 (INTERNAL_REGISTER_GROUP_L + 27) ///< 0xFB + #define ADC1DELTACODE80_100_7_0 (255<<0) + + #define OTP5_BYTE1 (INTERNAL_REGISTER_GROUP_L + 28) ///< 0xFC + #define ADC2DELTACODE25_100_6 (1<<7) + #define ADC2DELTACODE25_100_5_0 (63<<1) + #define ADC1DELTACODE25_100_8 (1<<0) + #define OTP5_BYTE2 (INTERNAL_REGISTER_GROUP_L + 29) ///< 0xFD + #define ADC2DELTACODE80_100_6_0 (127<<1) + #define ADC1DELTACODE80_100_8 (1<<0) + #define OTP5_BYTE3 (INTERNAL_REGISTER_GROUP_L + 30) ///< 0xFE + #define ADC2DELTACODE25_200_7 (1<<7) + #define ADC2DELTACODE25_200_6_0 (127<<0) + #define OTP5_BYTE4 (INTERNAL_REGISTER_GROUP_L + 31) ///< 0xFF + #define ADC2DELTACODE80_200_7_0 (255<<0) + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.c new file mode 100755 index 00000000..433ff15c --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.c @@ -0,0 +1,782 @@ +/* + * Copyright (c) 2012, uPI Semiconductor Corp. All Rights Reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ug31xx_gauge.h" +#include "uG31xx_API.h" + +/* Functions Declaration */ +static int ug31xx_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val); +static int ug31xx_update_psp(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val); +static void ug31xx_external_power_changed(struct power_supply *psy); + +#define UG31XX_CHECK_FILE_CNT_THRD (20) + +/* Global Variables */ +static struct ug31xx_gauge *ug31 = NULL; +static char chk_backup_file_cnt = UG31XX_CHECK_FILE_CNT_THRD; +static char *pGGB = NULL; +static GG_DEVICE_INFO gauge_dev_info; +static GG_CAPACITY gauge_dev_capacity; +static struct workqueue_struct *ug31xx_gauge_wq = NULL; +static int charger_dc_in_before_suspend = 0; +static bool ug3105_in_suspend = false; +static bool ug3105_charger_enabled = true; +static unsigned char force_reset = 0; +static unsigned char enable_debug = 0; + +static __attribute__((unused)) char *chg_status[] = { + "Unknown", + "Charging", + "Discharging", + "Not charging", + "Full" +}; + +static drv_status_t drv_status = DRV_NOT_READY; + +#include "ggb/ug31xx_ggb_data_wms8309_wm8_20130820_110949.h" +#include "ggb/ug31xx_ggb_data_wms8309_c7_20130725_164935.h" +#include "ggb/ug31xx_ggb_data_wms8309_c7_20130910_130553.h" +#include "ggb/ug31xx_ggb_data_wms7320_20130718_200031.h" +#include "ggb/ug31xx_ggb_data_cw500_20130801_103638.h" +#include "ggb/ug31xx_ggb_data_mp718_20131004_070110.h" +#include "ggb/ug31xx_ggb_data_t73v_20131120_001204.h" + +enum { + UG31XX_ID_3105, + UG31XX_ID_3102, +}; + +struct ggb_info { + char *name; + uint8_t *data; +}; + +/* Extern Function */ +static struct ggb_info ggb_arrays[] = { + { + .name = "wms8309wm8", + .data = FactoryGGBXFile_wms8309_wm8, + }, { + .name = "wms7320", + .data = FactoryGGBXFile_wms7320, + }, { + .name = "wms8309c7_3900mAh", + .data = FactoryGGBXFile_wms8309_c7_3900mAh, + }, { + .name = "wms8309c7_3000mAh", + .data = FactoryGGBXFile_wms8309_c7_3000mAh, + }, { + .name = "cw500", + .data = FactoryGGBXFile_cw500, + }, { + .name = "mp718", + .data = FactoryGGBXFile_mp718, + }, { + .name = "t73v", + .data = FactoryGGBXFile_t73v, + }, +}; + +struct charger_param { + int id; + int i2c; + int et; + int temp_range[2]; + struct ggb_info *ggb; +}; + +static struct charger_param charger_param; + +static bool inline export_external_termperature(void) +{ + return !!charger_param.et; +} + +static int parse_battery_param(void) +{ + char env[] = "wmt.battery.param"; + char buf[64]; + size_t l = sizeof(buf); + int i; + + if (wmt_getsyspara(env, buf, &l)) + return -EINVAL; + + if (!prefixcmp(buf, "ug3105:")) { + charger_param.id = UG31XX_ID_3105; + } else if (!prefixcmp(buf, "ug3102:")) { + charger_param.id = UG31XX_ID_3102; + } else { + return -EINVAL; + } + + i = sscanf(buf + 7, "%d:%d:%d:%d", + &charger_param.i2c, &charger_param.et, + &charger_param.temp_range[0], + &charger_param.temp_range[1]); + if (i < 4) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ggb_arrays); i++) { + if (strstr(buf, ggb_arrays[i].name)) { + charger_param.ggb = &ggb_arrays[i]; + break; + } + } + if (i == ARRAY_SIZE(ggb_arrays)) + charger_param.ggb = &ggb_arrays[0]; + + pr_info("%s i2c%d, use %s temperature, range [%d, %d], ggb %s\n", + charger_param.id == UG31XX_ID_3105 ? "ug3105" : "ug3102", + charger_param.i2c, + charger_param.et ? "External" : "Internal", + charger_param.temp_range[0], + charger_param.temp_range[1], + charger_param.ggb->name); + + return 0; +} + +/* + * WMT MCE: Use gpio3 on ug31xx as a switch to control charger. + */ +static void hw_charging_set(bool enable) +{ + if (charger_param.id == UG31XX_ID_3105) { + API_I2C_SingleWrite(0, 0, 0, 0x16, enable ? 0x2 : 0x0); + } else if (charger_param.id == UG31XX_ID_3102) { + u8 data = 0; + API_I2C_SingleRead(0, 0, 0 ,REG_CTRL1, &data); + if (enable) + data |= CTRL1_IO1DATA; + else + data &= ~CTRL1_IO1DATA; + API_I2C_SingleWrite(0, 0, 0, REG_CTRL1, data); + } + ug3105_charger_enabled = enable; +} + +static void inline hw_charging_disable(void) +{ + hw_charging_set(false); +} + +static void inline hw_charging_enable(void) +{ + hw_charging_set(true); +} + +static bool is_charging_full(void) +{ + return (ug3105_charger_enabled == true) && charger_is_full(); +} + +static enum power_supply_property ug31xx_batt_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL, +}; + +static struct power_supply ug31xx_supply[] = { + { + .name = "battery", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = ug31xx_batt_props, + .num_properties = ARRAY_SIZE(ug31xx_batt_props), + .get_property = ug31xx_battery_get_property, + .external_power_changed = ug31xx_external_power_changed, + }, +}; + +static int ug31xx_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_HEALTH: + val->intval = POWER_SUPPLY_HEALTH_GOOD; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + case POWER_SUPPLY_PROP_STATUS: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_CURRENT_NOW: + case POWER_SUPPLY_PROP_CAPACITY: + case POWER_SUPPLY_PROP_TEMP: + case POWER_SUPPLY_PROP_CHARGE_NOW: + case POWER_SUPPLY_PROP_CHARGE_FULL: + if (ug31xx_update_psp(psy, psp, val)) + return -EINVAL; + break; + default: + return -EINVAL; + } + return ret; +} + +static int ug31xx_update_psp(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ +// int rtn; + + if (drv_status != DRV_INIT_OK) { + GAUGE_err("Gauge driver not init finish\n"); + return -EINVAL; + } + + if (psp == POWER_SUPPLY_PROP_TEMP) { + if (export_external_termperature()) + ug31->batt_temp = gauge_dev_info.ET; + else + ug31->batt_temp = gauge_dev_info.IT; + val->intval = ug31->batt_temp; + GAUGE_notice("I.Temperature=%d, E.T=%d\n", gauge_dev_info.IT, gauge_dev_info.ET); + } + + if (psp == POWER_SUPPLY_PROP_CAPACITY) { + if (ug31->batt_status == POWER_SUPPLY_STATUS_FULL) + ug31->batt_capacity = 100; + else + ug31->batt_capacity = gauge_dev_capacity.RSOC; + + val->intval = ug31->batt_capacity; + GAUGE_notice("Capacity=%d %%\n", val->intval); + } + + if (psp == POWER_SUPPLY_PROP_VOLTAGE_NOW) { + val->intval = ug31->batt_volt = gauge_dev_info.voltage_mV; + GAUGE_notice("Voltage=%d mV\n", val->intval); + } + + if (psp == POWER_SUPPLY_PROP_CURRENT_NOW) { + val->intval = ug31->batt_current = gauge_dev_info.AveCurrent_mA; + GAUGE_notice("Current=%d mA\n", val->intval); + } + + if (psp == POWER_SUPPLY_PROP_STATUS) { + int status = charger_get_status(); + if (status < 0) + return status; + + if (status == POWER_SUPPLY_STATUS_CHARGING && ug31->batt_capacity == 100) + status = POWER_SUPPLY_STATUS_FULL; + + ug31->batt_status = status; + val->intval = ug31->batt_status; + GAUGE_notice("Status=%s\n", chg_status[val->intval]); + } + + if (psp == POWER_SUPPLY_PROP_CHARGE_NOW) { + val->intval = ug31->batt_charge_now = gauge_dev_capacity.NAC; + GAUGE_notice("Charge_Now=%d mAh\n", val->intval); + } + + if (psp == POWER_SUPPLY_PROP_CHARGE_FULL) { + val->intval =ug31->batt_charge_full = gauge_dev_capacity.LMD; + GAUGE_notice("Charge_Full=%d mAh\n", val->intval); + } + +#if 0 + mutex_lock(&ug31->info_update_lock); + chk_backup_file_cnt = chk_backup_file_cnt + 1; + UG31_LOGI("chk_backup_file_cnt %d\n", chk_backup_file_cnt); + if (chk_backup_file_cnt > UG31XX_CHECK_FILE_CNT_THRD) { + rtn = upiGG_CheckBackupFile(pGGB); + if(rtn == UPI_CHECK_BACKUP_FILE_MISMATCH) + { + force_reset = 1; + UG31_LOGI("[%s]: Force reset due to version dismatched.\n", __func__); + } + else if(rtn == UPI_CHECK_BACKUP_FILE_EXIST) + { + chk_backup_file_cnt = 0; + UG31_LOGI("[%s]: Backup file existed -> no need to check frequently.\n", __func__) + } + else + { + chk_backup_file_cnt = UG31XX_CHECK_FILE_CNT_THRD; + UG31_LOGI("[%s]: Backup file not existed -> need to check frequently.\n", __func__) + } + UG31_LOGI("[%s]: Check backup file status = %d\n", __func__, rtn); + } + mutex_unlock(&ug31->info_update_lock); +#endif + return 0; +} + +static int ug31xx_powersupply_init(struct i2c_client *client) +{ + int i, ret; + for (i = 0; i < ARRAY_SIZE(ug31xx_supply); i++) { + ret = power_supply_register(&client->dev, &ug31xx_supply[i]); + if (ret) { + GAUGE_err("Failed to register power supply\n"); + while (i--) + power_supply_unregister(&ug31xx_supply[i]); + return ret; + } + } + return 0; +} + +static void ug31xx_external_power_changed(struct power_supply *psy) +{ + if (ug3105_in_suspend == false) + queue_delayed_work(ug31xx_gauge_wq, &ug31->ug31_gauge_info_work, 0*HZ); +} + +#define UG31XX_INITIAL_RETRY_CNT (3) +#define UG31XX_INITIAL_LOCK_ENABLE (1) +#define UG31XX_INITIAL_LOCK_DISABLE (0) +#define UG31XX_INITIAL_FIX_T_COUNT (30) + +static int ug31_gauge_info_reset(int enable_lock) +{ + int retry; + int gg_status; + + force_reset = 0; + + if(enable_lock == UG31XX_INITIAL_LOCK_ENABLE) + { + mutex_lock(&ug31->info_update_lock); + } + + retry = 0; + while(retry < UG31XX_INITIAL_RETRY_CNT) + { + gg_status = UG_SUCCESS; + if(pGGB != NULL) + { + gg_status = upiGG_UnInitial(&pGGB); + pGGB = NULL; + GAUGE_notice("Driver remove. gg_status=0x%02x\n", gg_status); + } + + if(gg_status == UG_SUCCESS) + { + gg_status = upiGG_Initial(&pGGB, + (GGBX_FILE_HEADER *)charger_param.ggb->data, + force_reset, UG31XX_INITIAL_FIX_T_COUNT); + + if(gg_status == UG_INIT_SUCCESS) + { + chk_backup_file_cnt = UG31XX_CHECK_FILE_CNT_THRD; + if(enable_lock == UG31XX_INITIAL_LOCK_ENABLE) + { + mutex_unlock(&ug31->info_update_lock); + } + return (0); + } + } + + retry = retry + 1; + GAUGE_err("GGB file read and init fail count = %d (%d)\n", retry, gg_status); + } + + GAUGE_err("Reset uG31xx fail.\n"); + if(pGGB != NULL) + { + gg_status = upiGG_UnInitial(&pGGB); + pGGB = NULL; + GAUGE_notice("Driver remove. gg_status=0x%02x\n", gg_status); + } + + if(enable_lock == UG31XX_INITIAL_LOCK_ENABLE) + { + mutex_unlock(&ug31->info_update_lock); + } + return (-1); +} + +static void ug31_gauge_info_work_func(struct work_struct *work) +{ + int gg_status = 0, retry = 3; + struct power_supply *psy = &ug31xx_supply[PWR_SUPPLY_BATTERY]; + int batt_status = ug31->batt_status; + struct ug31xx_gauge *ug31_dev; + + ug31_dev = container_of(work, struct ug31xx_gauge, ug31_gauge_info_work.work); + + if(enable_debug == 0) + { + upiGG_DebugSwitch(_UPI_FALSE_); + UG31_LOGI("Set upiGG_DebugSwitch to FALSE\n"); + } + else + { + upiGG_DebugSwitch(_UPI_TRUE_); + UG31_LOGI("Set upiGG_DebugSwitch to TRUE\n"); + } + + UG31_LOGI("Update gauge info!!\n"); + + mutex_lock(&ug31->info_update_lock); + while (retry-- > 0) { + gg_status = upiGG_ReadDeviceInfo(pGGB,&gauge_dev_info); + if (gg_status == UG_READ_DEVICE_INFO_SUCCESS) + goto read_dev_info_ok; + } + GAUGE_err("Read device info fail. gg_status=%d\n", gg_status); + if(gg_status == UG_MEAS_FAIL_BATTERY_REMOVED) + { + gauge_dev_capacity.NAC = 0; + gauge_dev_capacity.LMD = 0; + gauge_dev_capacity.RSOC = 0; + } + goto read_dev_info_fail; + +read_dev_info_ok: + if(gauge_dev_capacity.Ready != UG_CAP_DATA_READY) + { + if(gauge_dev_info.ET > UG31XX_MAX_TEMPERATURE_BEFORE_READY) + { + gauge_dev_info.ET = UG31XX_MAX_TEMPERATURE_BEFORE_READY; + } + if(gauge_dev_info.ET < UG31XX_MIN_TEMPERATURE_BEFORE_READY) + { + gauge_dev_info.ET = UG31XX_MIN_TEMPERATURE_BEFORE_READY; + } + } + + upiGG_ReadCapacity(pGGB,&gauge_dev_capacity); + UG31_LOGI("Gauge info updated !!\n"); + +read_dev_info_fail: + mutex_unlock(&ug31->info_update_lock); + + if(force_reset == 1) + { + UG31_LOGI("Reset whole uG31xx driver.\n"); + gg_status = ug31_gauge_info_reset(UG31XX_INITIAL_LOCK_ENABLE); + if(gg_status != 0) + { + goto set_polling_time; + } + gauge_dev_capacity.Ready = UG_CAP_DATA_READY; + } + + /* Disable charging by temperture */ + + if (charger_param.id == UG31XX_ID_3105) { + if (export_external_termperature()) { + if (gauge_dev_info.ET < charger_param.temp_range[0] || + gauge_dev_info.ET > charger_param.temp_range[1]) + hw_charging_disable(); + else + hw_charging_enable(); + } + } else if (charger_param.id == UG31XX_ID_3102) { + hw_charging_enable(); + } + + if (wmt_charger_is_dc_plugin() && power_supply_am_i_supplied(psy)) { + if (gauge_dev_capacity.RSOC == 100) + batt_status = POWER_SUPPLY_STATUS_FULL; + else if (is_charging_full() && ug31->batt_capacity >= 90) { + batt_status = POWER_SUPPLY_STATUS_FULL; + gauge_dev_capacity.RSOC = 100; + mutex_lock(&ug31->info_update_lock); + upiGG_ForceTaper(pGGB, 1, 1, 1); + mutex_unlock(&ug31->info_update_lock); + } else + batt_status = POWER_SUPPLY_STATUS_CHARGING; + } else + batt_status = POWER_SUPPLY_STATUS_DISCHARGING; + + /* Report uevent while capacity changed */ + if (ug31->batt_capacity != gauge_dev_capacity.RSOC || + ug31->batt_status != batt_status) { + GAUGE_notice("Capacity changed: %d -> %d\n", ug31->batt_capacity, gauge_dev_capacity.RSOC); + GAUGE_notice("Status changed: %d -> %d\n", ug31->batt_status, batt_status); + power_supply_changed(psy); + } + +set_polling_time: + if (gauge_dev_capacity.Ready == UG_CAP_DATA_READY) { + queue_delayed_work(ug31xx_gauge_wq, &ug31_dev->ug31_gauge_info_work, 5*HZ); + } else if(force_reset == 1) { + queue_delayed_work(ug31xx_gauge_wq, &ug31_dev->ug31_gauge_info_work, 0*HZ); + } else { + queue_delayed_work(ug31xx_gauge_wq, &ug31_dev->ug31_gauge_info_work, 1*HZ); + } +} + +static int __devinit ug31xx_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + int gg_status; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) + return -EIO; + + ug31 = kzalloc(sizeof(*ug31), GFP_KERNEL); + if (!ug31) + return -ENOMEM; + + ug31->client = client; + ug31->dev = &client->dev; + + i2c_set_clientdata(client, ug31); + ug31xx_i2c_client_set(ug31->client); + + gauge_dev_capacity.RSOC = 50; + + /* get GGB file */ + GAUGE_notice("[UPI]: Force to reset uG3105 driver (%d)\n", force_reset); + gg_status = ug31_gauge_info_reset(UG31XX_INITIAL_LOCK_DISABLE); + if(gg_status != 0) + { + goto ggb_init_fail; + } + + mutex_init(&ug31->info_update_lock); + wake_lock_init(&ug31->cable_wake_lock, WAKE_LOCK_SUSPEND, "cable_state_changed"); + + ug31xx_gauge_wq = create_singlethread_workqueue("ug31xx_gauge_work_queue"); + INIT_DELAYED_WORK(&ug31->ug31_gauge_info_work, ug31_gauge_info_work_func); + queue_delayed_work(ug31xx_gauge_wq, &ug31->ug31_gauge_info_work, 0*HZ); + + /* power supply registration */ + if (ug31xx_powersupply_init(client)) + goto pwr_supply_fail; + + force_reset = 0; + drv_status = DRV_INIT_OK; + + GAUGE_notice(" Driver %s registered done\n", client->name); + + return 0; + +pwr_supply_fail: + kfree(ug31); +ggb_init_fail: + if(!pGGB) { + upiGG_UnInitial(&pGGB); + } + force_reset = 0; + return gg_status; +} + +static int __devexit ug31xx_i2c_remove(struct i2c_client *client) +{ + struct ug31xx_gauge *ug31_dev; + int i = 0, gg_status; + + for (i = 0; i < ARRAY_SIZE(ug31xx_supply); i++) { + power_supply_unregister(&ug31xx_supply[i]); + } + + cancel_delayed_work_sync(&ug31->ug31_gauge_info_work); + destroy_workqueue(ug31xx_gauge_wq); + wake_lock_destroy(&ug31->cable_wake_lock); + + gg_status = upiGG_UnInitial(&pGGB); + GAUGE_notice("Driver remove. gg_status=0x%02x\n", gg_status); + + ug31_dev = i2c_get_clientdata(client); + if (ug31_dev) { + kfree(ug31_dev); + } + return 0; +} + +static int ug31xx_i2c_suspend(struct i2c_client *client, pm_message_t mesg) +{ + int gg_status; + + GAUGE_notice("ug31xx_i2c_suspend() start\n"); + ug3105_in_suspend = true; + + cancel_delayed_work_sync(&ug31->ug31_gauge_info_work); + flush_workqueue(ug31xx_gauge_wq); + + mutex_lock(&ug31->info_update_lock); + gg_status = upiGG_PreSuspend(pGGB); + if (gg_status != UG_READ_DEVICE_INFO_SUCCESS) { + GAUGE_err("Fail in suspend. gg_status=0x%02x\n", gg_status); + } else + GAUGE_notice("Driver suspend. gg_status=0x%02x\n", gg_status); + mutex_unlock(&ug31->info_update_lock); + + charger_dc_in_before_suspend = wmt_charger_is_dc_plugin(); + + if (charger_param.id == UG31XX_ID_3102) { + hw_charging_enable(); + } + + GAUGE_notice("ug31xx_i2c_suspend() end\n"); + return 0; +} + +static int ug31xx_i2c_resume(struct i2c_client *client) +{ + int gg_status; + + GAUGE_notice("ug31xx_i2c_resume() start\n"); + + mutex_lock(&ug31->info_update_lock); + gg_status = upiGG_Wakeup(pGGB, charger_dc_in_before_suspend); + if (gg_status != UG_READ_DEVICE_INFO_SUCCESS) { + GAUGE_err("Fail in resume. gg_status=0x%02x\n", gg_status); + if(gg_status == UG_MEAS_FAIL_BATTERY_REMOVED) + { + gauge_dev_capacity.NAC = 0; + gauge_dev_capacity.LMD = 0; + gauge_dev_capacity.RSOC = 0; + } + } else { + GAUGE_notice("Driver resume. gg_status=0x%02x\n", gg_status); + } + mutex_unlock(&ug31->info_update_lock); + + /// [AT-PM] : Check charger status ; 08/14/2013 + mutex_lock(&ug31->info_update_lock); + upiGG_ForceTaper(pGGB, is_charging_full(), charger_dc_in_before_suspend, wmt_charger_is_dc_plugin()); + mutex_unlock(&ug31->info_update_lock); + + ug3105_in_suspend = false; + + cancel_delayed_work(&ug31->ug31_gauge_info_work); + queue_delayed_work(ug31xx_gauge_wq, &ug31->ug31_gauge_info_work, 0*HZ); + + GAUGE_notice("ug31xx_i2c_resume() end\n"); + return 0; +} + +void ug31xx_i2c_shutdown(struct i2c_client *client) +{ + int gg_status; + + cancel_delayed_work(&ug31->ug31_gauge_info_work); + mutex_lock(&ug31->info_update_lock); + gg_status = upiGG_PrePowerOff(pGGB); + mutex_unlock(&ug31->info_update_lock); + GAUGE_notice("Driver shutdown. gg_status=0x%02x\n", gg_status); +} + +static const struct i2c_device_id ug31xx_i2c_id[] = { + { UG31XX_DEV_NAME, 0 }, + { }, +}; + +MODULE_DEVICE_TABLE(i2c, ug31xx_i2c_id); + +static struct i2c_driver ug31xx_i2c_driver = { + .driver = { + .name = UG31XX_DEV_NAME, + .owner = THIS_MODULE, + }, + .probe = ug31xx_i2c_probe, + .remove = __devexit_p(ug31xx_i2c_remove), + .suspend = ug31xx_i2c_suspend, + .resume = ug31xx_i2c_resume, + .shutdown = ug31xx_i2c_shutdown, + .id_table = ug31xx_i2c_id, +}; + +static struct i2c_board_info ug31xx_i2c_board_info = { + .type = "ug31xx-gauge", + .flags = 0x00, + .addr = 0x70, + .platform_data = NULL, + .archdata = NULL, + .irq = -1, +}; + +static struct i2c_client *i2c_client; +static struct i2c_adapter *i2c_adap; + +static int __init ug31xx_i2c_init(void) +{ + int ret; + + ret = parse_battery_param(); + if (ret) + return ret; + + i2c_adap = i2c_get_adapter(charger_param.i2c); + if (!i2c_adap) { + pr_err("Cannot get i2c adapter %d\n", charger_param.i2c); + ret = -ENODEV; + goto err1; + } + + i2c_client = i2c_new_device(i2c_adap, &ug31xx_i2c_board_info); + if (!i2c_client) { + pr_err("Unable to add I2C device for 0x%x\n", + ug31xx_i2c_board_info.addr); + ret = -ENODEV; + goto err2; + } + + ret = i2c_add_driver(&ug31xx_i2c_driver); + if (ret) + goto err3; + + return 0; + +err3: i2c_unregister_device(i2c_client); +err2: i2c_put_adapter(i2c_adap); +err1: + return ret; +} +module_init(ug31xx_i2c_init); + +static void __exit ug31xx_i2c_exit(void) +{ + i2c_put_adapter(i2c_adap); + i2c_del_driver(&ug31xx_i2c_driver); + i2c_unregister_device(i2c_client); +} +module_exit(ug31xx_i2c_exit); + +MODULE_DESCRIPTION("ug31xx gauge driver"); +MODULE_LICENSE("GPL"); + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) +MODULE_PARM (force_reset, "b"); +MODULE_PARM (enable_debug, "b"); +#else +module_param (force_reset, byte, 0); +module_param (enable_debug, byte, 0644); +#endif +MODULE_PARM_DESC(force_reset, "Set 1 to force reset driver as first power on."); +MODULE_PARM_DESC(enable_debug, "Set 1 to enable dumping debug message."); diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.h new file mode 100755 index 00000000..212d7e30 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_gauge.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, ASUSTek, Inc. All Rights Reserved. + */ + +#ifndef __UPI_ug31xx_GAUGE_H +#define __UPI_ug31xx_GAUGE_H + +//#define UG31XX_DYNAMIC_POLLING + +#define UG31XX_DEV_NAME "ug31xx-gauge" + +#ifdef UG31XX_DEBUG_ENABLE +#define GAUGE_notice(format, arg...) \ + printk(KERN_DEBUG "GAUGE: [%s] " format , __func__ , ## arg); +#else +#define GAUGE_notice(format, arg...) +#endif + +#define GAUGE_err(format, arg...) \ + printk(KERN_ERR "GAUGE: [%s] " format , __FUNCTION__ , ## arg); + +#define UPI_DEBUG_STRING (320) + +typedef enum { + DRV_NOT_READY = 0, + DRV_INIT_OK, +} drv_status_t; + +struct ug31xx_gauge { + struct i2c_client *client; + struct device *dev; + struct delayed_work batt_info_update_work; + struct delayed_work ug31_gauge_info_work; + struct wake_lock cable_wake_lock; + struct mutex info_update_lock; + u32 cable_status; + u32 polling_time; + u32 batt_volt; + u32 batt_capacity; + u32 batt_charge_now; + u32 batt_charge_full; + int batt_current; + int batt_temp; + int batt_status; + + /// [AT-PM] : Add for version ; 01/30/2013 + char gauge_debug[UPI_DEBUG_STRING]; + + /// [AT-PM] : Alarm status ; 04/19/2013 + u8 alarmSts; +}; + +enum { + PWR_SUPPLY_BATTERY = 0, + PWR_SUPPLY_AC, + PWR_SUPPLY_USB +}; + +enum { + NO_CABLE = 0, + USB_PC_CABLE = 1, + AC_ADAPTER_CABLE = 3 +}; + +#endif /*__UPI_ug31xx_GAUGE_H */ diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c new file mode 100755 index 00000000..6249df50 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2012, ASUSTek, Inc. All Rights Reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ug31xx_i2c.h" + +static struct i2c_client *ug31xx_client = NULL; + +void ug31xx_i2c_client_set(struct i2c_client *client) +{ + ug31xx_client = client; + dev_info(&ug31xx_client->dev, "%s: Ug31xx i2c client saved.\n", __func__); +} + +int ug31xx_read_i2c(struct i2c_client *client, + u8 reg, int *rt_value, int b_single) +{ + struct i2c_msg msg[2]; + unsigned char data[4]; + int err; + + if (!client || !client->adapter) + return -ENODEV; + + if (!rt_value) return -EINVAL; + + data[0] = reg; + //err = i2c_transfer(client->adapter, msg, 1); + + msg[0].addr = client->addr; + msg[0].flags = 0 | I2C_M_NOSTART; + msg[0].len = 1; + if (reg >= 0x80) { + data[1] = SECURITY_KEY; + msg[0].len++; + } + msg[0].buf = (unsigned char *)data; + + msg[1].addr = client->addr; + msg[1].flags = (I2C_M_RD); + msg[1].len = b_single ? 1 : 2; + msg[1].buf = (unsigned char *)data; + + err = i2c_transfer(client->adapter, msg, sizeof(msg)/sizeof(struct i2c_msg)); + + if (err < 0) return err; + + if (b_single) + *rt_value = data[0]; + else + *rt_value = get_unaligned_le16(data); + + return 0; +} + +int ug31xx_write_i2c(struct i2c_client *client, + u8 reg, int rt_value, int b_single) +{ + struct i2c_msg msg[1]; + unsigned char data[4]; + int err; + int idx; + int tmp_buf=0; + + if (!client || !client->adapter) + return -ENODEV; + + idx = 0; + data[idx++] = reg; + if (reg >= 0x80) { + data[idx++] = SECURITY_KEY; + } + data[idx++] = rt_value & 0x0FF; + data[idx++] = (rt_value & 0x0FF00)>>8; + + msg[0].addr = client->addr; + msg[0].flags = 0 | I2C_M_NOSTART; + msg[0].len = b_single ? idx-1 : idx; + msg[0].buf = (unsigned char *)data; + + err = i2c_transfer(client->adapter, msg, sizeof(msg)/sizeof(struct i2c_msg)); + + if (err >= 0) + err = ug31xx_read_i2c(client, reg, &tmp_buf, b_single); + //dev_info(&client->dev, "%s:: 0x%02X, 0x%04X, 0x%04X. %s\n", + // __func__, reg, rt_value, tmp_buf, err < 0 ? "FAIL" : "SUCCESS"); + + return err < 0 ? err : 0; +} + +bool _API_I2C_Write(u16 writeAddress, u8 writeLength, u8 *PWriteData) +{ + int i, ret; + int byte_flag=0; + + if (!PWriteData) { + dev_err(&ug31xx_client->dev, "%s: Write buffer pointer error.\n", __func__); + return false; + } + + byte_flag = ONE_BYTE; + + for (i=0; idev, "%s: Write data(0x%02X) fail. %d\n", + __func__, i, ret); + return false; + } + } + + return true; +} + +bool _API_I2C_Read(u16 readAddress, u8 readLength, u8 *pReadDataBuffer) +{ + int i, ret; + int byte_flag=0; + + if (!pReadDataBuffer) { + dev_err(&ug31xx_client->dev, "%s: Read buffer pointer error.\n", __func__); + return false; + } + + byte_flag = ONE_BYTE; + + for (i=0; idev, "%s: read data(0x%02X) fail. %d\n", + __func__, i, ret); + return false; + } + pReadDataBuffer[i] = tmp_buf; + } + + return true; +} + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.h new file mode 100755 index 00000000..630fedd6 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, ASUSTek, Inc. All Rights Reserved. + */ +#include + +#define SECURITY_KEY 0x5A //i2c read/write +#define ONE_BYTE 0x1 +#define TWO_BYTE 0x0 + +void ug31xx_i2c_client_set(struct i2c_client *client); +int ug31xx_read_i2c(struct i2c_client *client, u8 reg, int *rt_value, int b_single); +int ug31xx_write_i2c(struct i2c_client *client, u8 reg, int rt_value, int b_single); + +bool _API_I2C_Write(u16 writeAddress, u8 writeLength, u8 *PWriteData); +bool _API_I2C_Read(u16 readAddress, u8 readLength, u8 *pReadDataBuffer); + +static inline bool API_I2C_Read(bool bSecurityMode, bool bHighSpeedMode, + bool bTenBitMode ,u16 readAddress, u8 readLength, u8 *pReadDataBuffer) +{ + return _API_I2C_Read(readAddress, readLength, pReadDataBuffer); +} + +static inline bool API_I2C_Write(bool bSecurityMode, bool bHighSpeedMode, bool bTenBitMode, + u16 writeAddress, u8 writeLength, u8 *PWriteData) +{ + return _API_I2C_Write(writeAddress, writeLength, PWriteData); +} + +static inline bool API_I2C_SingleRead(bool bSecurityMode,bool bHighSpeedMode, bool bTenBitMode , + u16 readAddress, u8 *ReadData) +{ + return API_I2C_Read(bSecurityMode, bHighSpeedMode, bTenBitMode, readAddress, 1, ReadData); +} + +static inline bool API_I2C_SingleWrite(bool bSecurityMode, bool bHighSpeedMode, bool bTenBitMode , + u16 writeAddress, u8 WriteData) +{ + return API_I2C_Write(bSecurityMode, bHighSpeedMode, bTenBitMode, writeAddress, 1, &WriteData); +} +static inline bool API_I2C_Init(u32 clockRate, u16 slaveAddr) +{ + return true; +} diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/Makefile b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/Makefile new file mode 100755 index 00000000..c30df937 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/Makefile @@ -0,0 +1,5 @@ + +s_wmt_batt_vt1603-objs += vt1603.o batt_leds.o + +obj-m += s_wmt_batt_vt1603.o + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.c new file mode 100755 index 00000000..108f40f9 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.c @@ -0,0 +1,189 @@ +/* + * batt_leds.c - WonderMedia Battery LED Driver. + * + * Copyright (C) 2013 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +enum { + LED_GREEN = 0, + LED_RED, +}; + +struct batt_led_trigger { + char *name; + struct led_trigger *trigger; +}; + +#define RTC_NAME "rtc0" +static struct rtc_device *rtc_dev = NULL; +static bool battery_led_registered = false; + +static struct batt_led_trigger batt_led_triggers[] = { + [LED_GREEN] = { + .name = "bat-green", + }, + [LED_RED] = { + .name = "bat-red", + } +}; + +static struct gpio_led batt_leds[] = { + [LED_GREEN] = { + .name = "bat-green", + .default_trigger = "bat-green", + .retain_state_suspended = 1, + .active_low = 0, + }, + [LED_RED] = { + .name = "bat-red", + .default_trigger = "bat-red", + .retain_state_suspended = 1, + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data batt_leds_data = { + .leds = batt_leds, + .num_leds = ARRAY_SIZE(batt_leds), +}; + +static struct platform_device batt_leds_dev = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &batt_leds_data, + }, +}; + +static int parse_battery_led_param(void) +{ + char env[] = "wmt.charger.led"; + char s[64]; + size_t l = sizeof(s); + int id, r, g; + + if (wmt_getsyspara(env, s, &l)) + return -EINVAL; + + if (sscanf(s, "%d:%d:%d", &id, &r, &g) != 3) + return -EINVAL; + + if (id != 1 || !gpio_is_valid(r) || !gpio_is_valid(g)) + return -EINVAL; + + batt_leds[LED_GREEN].gpio = g; + batt_leds[LED_RED].gpio = r; + + pr_info("charger-led: charging (gpio%d), full (gpio%d)\n", r, g); + return 0; +} + +int batt_leds_update(int status) +{ + struct led_trigger *r = batt_led_triggers[LED_RED].trigger; + struct led_trigger *g = batt_led_triggers[LED_GREEN].trigger; + + if (battery_led_registered == false) + return 0; + + switch (status) { + case POWER_SUPPLY_STATUS_CHARGING: + led_trigger_event(r, LED_FULL); + led_trigger_event(g, LED_OFF); + gpio_direction_input(batt_leds[LED_GREEN].gpio); + break; + case POWER_SUPPLY_STATUS_FULL: + led_trigger_event(r, LED_OFF); + led_trigger_event(g, LED_FULL); + break; + case POWER_SUPPLY_STATUS_DISCHARGING: + default: + led_trigger_event(r, LED_OFF); + led_trigger_event(g, LED_OFF); + gpio_direction_input(batt_leds[LED_GREEN].gpio); + break; + } + return 0; +} + +void batt_leds_suspend_prepare(void) +{ + struct rtc_wkalrm tmp; + unsigned long time, now; + //unsigned long add = 30; /* seconds */ + unsigned long add = 120; /* seconds */ + + if (battery_led_registered == false) + return; + + if (!rtc_dev) { + rtc_dev = rtc_class_open(RTC_NAME); + if (IS_ERR_OR_NULL(rtc_dev)) { + rtc_dev = NULL; + pr_err("Cannot get RTC %s, %ld.\n", RTC_NAME, PTR_ERR(rtc_dev)); + return; + } + } + + tmp.enabled = 1; + rtc_read_time(rtc_dev, &tmp.time); + rtc_tm_to_time(&tmp.time, &now); + time = now + add; + + rtc_time_to_tm(time, &tmp.time); + rtc_set_alarm(rtc_dev, &tmp); + +} + +void batt_leds_resume_complete(void) +{ + if (rtc_dev) { + rtc_class_close(rtc_dev); + rtc_dev = NULL; + } +} + +int batt_leds_setup(void) +{ + int i; + + if (parse_battery_led_param()) + return -EINVAL; + + platform_device_register(&batt_leds_dev); + + for (i = 0; i < ARRAY_SIZE(batt_led_triggers); ++i) + led_trigger_register_simple(batt_led_triggers[i].name, + &batt_led_triggers[i].trigger); + battery_led_registered = true; + return 0; +} + +void batt_leds_cleanup(void) +{ + int i; + + if (battery_led_registered == true) { + platform_device_unregister(&batt_leds_dev); + for (i = 0; i < ARRAY_SIZE(batt_led_triggers); ++i) + led_trigger_unregister_simple(batt_led_triggers[i].trigger); + battery_led_registered = false; + } +} diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.h new file mode 100755 index 00000000..dbcaa657 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/batt_leds.h @@ -0,0 +1,12 @@ +#ifndef _BATT_LEDS_H_ +#define _BATT_LEDS_H_ + +extern int batt_leds_setup(void); +extern void batt_leds_cleanup(void); +extern void batt_leds_suspend_prepare(void); +extern void batt_leds_resume_complete(void); +extern int batt_leds_update(int status); + +#endif /* #ifndef _BATT_LEDS_H_ */ + + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.c b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.c new file mode 100755 index 00000000..e75a99e8 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.c @@ -0,0 +1,513 @@ +/* + * vt1603.c - WonderMedia VT1603 Adc Battery Driver. + * + * Copyright (C) 2013 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "vt1603.h" +#include "batt_leds.h" + +enum { + COMPENSATION_VOLUME = 0, + COMPENSATION_BRIGHTNESS, + COMPENSATION_WIFI, + COMPENSATION_VIDEO, + COMPENSATION_USB, + COMPENSATION_HDMI, + COMPENSATION_COUNT +}; + +static const char *compensation_strings[] = { + "volume", + "brightness", + "wifi", + "video", + "usb", + "hdmi" +}; + +struct vt1603_device_info { + struct vt1603 *vt1603; + struct device *dev; + struct power_supply ps_bat; + struct mutex mutex; + int compensation[COMPENSATION_COUNT]; + + int capacity; + int sleeping; + int debug; +}; + +static struct vt1603_device_info *vt1603_dev_info = NULL; + +static int vt1603_set_reg8(struct vt1603 *vt1603, u8 reg, u8 val) +{ + int ret = vt1603->reg_write(vt1603, reg, val); + if (ret) + pr_err("vt1603 battery write error, errno%d\n", ret); + return ret; +} + +static u8 vt1603_get_reg8(struct vt1603 *vt1603, u8 reg) +{ + u8 val = 0; + int ret = 0; + + ret = vt1603->reg_read(vt1603, reg, &val); + if (ret < 0){ + pr_err("vt1603 battery read error, errno%d\n", ret); + return 0; + } + + return val; +} + +static int vt1603_read8(struct vt1603 *vt1603, u8 reg, u8 *data) +{ + int ret = vt1603->reg_read(vt1603, reg, data); + if (ret) + pr_err("vt1603 battery read error, errno%d\n", ret); + return ret; +} + +static void vt1603_setbits(struct vt1603 *vt1603, u8 reg, u8 mask) +{ + u8 tmp = vt1603_get_reg8(vt1603, reg) | mask; + vt1603_set_reg8(vt1603, reg, tmp); +} + +static void vt1603_clrbits(struct vt1603 *vt1603, u8 reg, u8 mask) +{ + u8 tmp = vt1603_get_reg8(vt1603, reg) & (~mask); + vt1603_set_reg8(vt1603, reg, tmp); +} + +#define ADC_DATA(low, high) ((((high) & 0x0F) << 8) + (low)) + +static int vt1603_get_bat_data(struct vt1603 *vt1603,int *data) +{ + int ret = 0; + u8 data_l, data_h; + + ret |= vt1603_read8(vt1603, VT1603_DATL_REG, &data_l); + ret |= vt1603_read8(vt1603, VT1603_DATH_REG, &data_h); + + *data = ADC_DATA(data_l, data_h); + return ret; +} + +static void vt1603_switch_to_bat_mode(struct vt1603 *vt1603) +{ + vt1603_set_reg8(vt1603, VT1603_CR_REG, 0x00); + vt1603_set_reg8(vt1603, 0xc6, 0x00); + vt1603_set_reg8(vt1603, VT1603_AMCR_REG, BIT0); +} + +static inline void vt1603_bat_pen_manual(struct vt1603 *vt1603) +{ + vt1603_setbits(vt1603, VT1603_INTCR_REG, BIT7); +} + +static void vt1603_bat_power_up(struct vt1603 *vt1603) +{ + if (vt1603_get_reg8(vt1603, VT1603_PWC_REG) != 0x08) + vt1603_set_reg8(vt1603, VT1603_PWC_REG, 0x08); +} + +static int vt1603_read_volt(struct vt1603 *vt1603) +{ + int timeout = 2000; + int ret = 0; + int value; + + // wait for interrupt that adc converted completed. + do { + if (vt1603_get_reg8(vt1603, VT1603_INTS_REG) & BIT0) + break; + } while (timeout--); + + if (!timeout) { + pr_err("wait adc end timeout ?!\n"); + return -ETIMEDOUT; + } + + ret = vt1603_get_bat_data(vt1603, &value); + if (ret < 0) { + pr_err("vt1603 get bat adc data Failed!\n"); + return ret; + } + + return value; +} + +static int vt1603_manual_read_adc(struct vt1603 *vt1603) +{ + int i; + int ret = 0; + uint32_t sum = 0; + + /* enable sar-adc power and clock */ + vt1603_bat_power_up(vt1603); + /* enable pen down/up to avoid miss irq */ + vt1603_bat_pen_manual(vt1603); + /* switch vt1603 to battery detect mode */ + vt1603_switch_to_bat_mode(vt1603); + /* do conversion use battery manual mode */ + vt1603_setbits(vt1603, VT1603_INTS_REG, BIT0); + vt1603_set_reg8(vt1603, VT1603_CR_REG, BIT4); + + for (i = 0; i < 4; i++) { + ret = vt1603_read_volt(vt1603); + if (ret < 0) + break; + sum += ret; + + vt1603_setbits(vt1603, VT1603_INTS_REG, BIT0); + vt1603_set_reg8(vt1603, VT1603_CR_REG, BIT4); //start manual ADC mode + } + vt1603_clrbits(vt1603, VT1603_INTCR_REG, BIT7); + vt1603_setbits(vt1603, VT1603_INTS_REG, BIT0 | BIT3); + vt1603_set_reg8(vt1603, VT1603_CR_REG, BIT1); + + return (ret < 0) ? ret : (sum >> 2); +} + +static inline int volt_reg_to_mV(int value) +{ + return ((value * 1047) / 1000); +} + +static int vt1603_bat_read_voltage(struct vt1603_device_info *di, int *intval) +{ + int ret = vt1603_manual_read_adc(di->vt1603); + if (ret < 0) + return ret; + + *intval = volt_reg_to_mV(ret); + return 0; +} + +static int vt1603_bat_read_status(struct vt1603_device_info *di, int *intval) +{ + int status; + + status = charger_get_status(); + if (status < 0) + return status; + + if (status == POWER_SUPPLY_STATUS_CHARGING && di->capacity == 100) + status = POWER_SUPPLY_STATUS_FULL; + + batt_leds_update(status); + *intval = status; + return 0; +} + +static int vt1603_proc_read(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + int l = 0, i; + int ret, status, dcin, voltage, full; + struct vt1603_device_info *di = vt1603_dev_info; + + mutex_lock(&di->mutex); + + ret = vt1603_bat_read_status(di, &status); + if (ret) { + pr_err("vt1603_bat_read_status failed\n"); + goto out; + } + voltage = vt1603_manual_read_adc(di->vt1603); + if (voltage < 0) { + pr_err("vt1603_manual_read_adc failed\n"); + goto out; + } + + dcin = power_supply_is_system_supplied(); + full = charger_is_full(); + + l += sprintf(buf + l, "status : %d\n", status); + l += sprintf(buf + l, "dcin : %d\n", dcin); + l += sprintf(buf + l, "voltage : %d\n", voltage); + l += sprintf(buf + l, "full : %d\n", full); + l += sprintf(buf + l, "sleeping : %d\n", di->sleeping); + l += sprintf(buf + l, "debug : %d\n", di->debug); + + for (i = 0; i < COMPENSATION_COUNT; i++) { + l += sprintf(buf +l, "compensation %10s : %d\n", + compensation_strings[i], di->compensation[i]); + } + + /* clear after read */ + di->sleeping = 0; +out: + mutex_unlock(&di->mutex); + return l; +} + +static int vt1603_proc_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int bm, usage; + struct vt1603_device_info *di = vt1603_dev_info; + int capacity; + + if (sscanf(buffer, "capacity=%d", &capacity)) { + di->capacity = capacity; + power_supply_changed(&di->ps_bat); + return count; + } + + if (sscanf(buffer, "debug=%d", &di->debug)) + return count; + + if (sscanf(buffer, "MODULE_CHANGE:%d-%d", &bm, &usage) < 2) + return 0; + + if (bm < 0 || bm >= COMPENSATION_COUNT) { + pr_err("bm %d error, [0, %d)\n", bm, COMPENSATION_COUNT); + return 0; + } + + if (usage > 100 || usage < 0) { + pr_err("usage %d error\n", usage); + return 0; + } + + mutex_lock(&di->mutex); + di->compensation[bm] = usage; + mutex_unlock(&di->mutex); + return count; +} + +#define VT1603_PROC_NAME "battery_calibration" + +static void vt1603_proc_init(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry(VT1603_PROC_NAME, 0666, NULL); + if (entry) { + entry->read_proc = vt1603_proc_read; + entry->write_proc = vt1603_proc_write; + } +} + +static void vt1603_proc_cleanup(void) +{ + remove_proc_entry(VT1603_PROC_NAME, NULL); +} + +#define to_vt1603_device_info(x) container_of((x), \ + struct vt1603_device_info, ps_bat); + +static int vt1603_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + struct vt1603_device_info *di = to_vt1603_device_info(psy); + + mutex_lock(&di->mutex); + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + ret = vt1603_bat_read_status(di, &val->intval); + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = di->capacity; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = vt1603_bat_read_voltage(di, &val->intval); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = POWER_SUPPLY_HEALTH_GOOD; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = 250; + break; + case POWER_SUPPLY_PROP_ONLINE: + val->intval = 1; + break; + default: + ret = -EINVAL; + break; + } + mutex_unlock(&di->mutex); + return ret; +} + +static void vt1603_external_power_changed(struct power_supply *psy) +{ + power_supply_changed(psy); +} + +static enum power_supply_property vt1603_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, +}; + +static int __devinit vt1603_batt_probe(struct platform_device *pdev) +{ + struct vt1603_device_info *di; + int ret; + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) { + dev_err(&pdev->dev, "no memery\n"); + return -ENOMEM; + } + + di->dev = &pdev->dev; + di->vt1603 = dev_get_platdata(&pdev->dev); + di->capacity = 50; + + mutex_init(&di->mutex); + + di->ps_bat.name = "battery"; + di->ps_bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->ps_bat.properties = vt1603_battery_props; + di->ps_bat.num_properties = ARRAY_SIZE(vt1603_battery_props); + di->ps_bat.get_property = vt1603_battery_get_property; + di->ps_bat.external_power_changed = vt1603_external_power_changed; + + ret = power_supply_register(di->dev, &di->ps_bat); + if (ret) { + dev_err(di->dev, "failed to register battery: %d\n", ret); + kfree(di); + return ret; + } + + platform_set_drvdata(pdev, di); + vt1603_dev_info = di; + + vt1603_proc_init(); + + pr_info("VT1603 Battery Driver Installed!\n"); + return 0; +} + +static int __devexit vt1603_batt_remove(struct platform_device *pdev) +{ + struct vt1603_device_info *di = platform_get_drvdata(pdev); + vt1603_proc_cleanup(); + power_supply_unregister(&di->ps_bat); + kfree(di); + vt1603_dev_info = NULL; + pr_info("VT1603 Battery Driver Removed!\n"); + return 0; +} + +static int vt1603_batt_suspend_prepare(struct device *dev) +{ + struct vt1603_device_info *di = dev_get_drvdata(dev); + int status, ret; + + ret = vt1603_bat_read_status(di, &status); + if (ret) { + pr_err("vt1603_bat_read_status failed\n"); + return 0; + } + + if (status == POWER_SUPPLY_STATUS_CHARGING) + batt_leds_suspend_prepare(); + + return 0; +} + +static int vt1603_batt_suspend(struct device *dev) +{ + return 0; +} + +static int vt1603_batt_resume(struct device *dev) +{ + struct vt1603_device_info *di = dev_get_drvdata(dev); + di->sleeping = 1; + return 0; +} + +static void vt1603_batt_resume_complete(struct device *dev) +{ + return batt_leds_resume_complete(); +} + +static const struct dev_pm_ops vt1603_batt_manager_pm = { + .prepare = vt1603_batt_suspend_prepare, + .suspend = vt1603_batt_suspend, + .resume = vt1603_batt_resume, + .complete = vt1603_batt_resume_complete, +}; + +static struct platform_driver vt1603_batt_driver = { + .driver = { + .name = "vt1603-batt", + .owner = THIS_MODULE, + .pm = &vt1603_batt_manager_pm, + }, + .probe = vt1603_batt_probe, + .remove = __devexit_p(vt1603_batt_remove), +}; + +static int parse_battery_param(void) +{ + char env[] = "wmt.battery.param"; + char buf[64]; + size_t l = sizeof(buf); + + if (wmt_getsyspara(env, buf, &l)) + return -EINVAL; + + return prefixcmp(buf, "vt1603") ? -ENODEV : 0; +} + +static int __init vt1603_batt_init(void) +{ + if (parse_battery_param()) + return -EINVAL; + + batt_leds_setup(); + return platform_driver_register(&vt1603_batt_driver); +} + +static void __exit vt1603_batt_exit(void) +{ + platform_driver_unregister(&vt1603_batt_driver); + batt_leds_cleanup(); +} + +module_init(vt1603_batt_init); +module_exit(vt1603_batt_exit); + +MODULE_AUTHOR("WonderMedia"); +MODULE_DESCRIPTION("WonderMedia VT1603 Adc Battery Driver"); +MODULE_LICENSE("GPL"); + diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.h b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.h new file mode 100755 index 00000000..24471226 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/gauge/vt1603/vt1603.h @@ -0,0 +1,124 @@ +/*++ + Copyright (c) 2008 WonderMedia Technologies, Inc. + + This program is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software Foundation, + either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with + this program. If not, see . + + WonderMedia Technologies, Inc. + 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + +#ifndef __VT1603_BAT_H__ +#define __VT1603_BAT_H__ +#include + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 + +/* VT1603 touch panel state */ +#define TS_PENDOWN_STATE 0x00 +#define TS_PENUP_STATE 0x01 + +/* vt1603 bus type config */ +#define VT1603_MAX_SPI_CLK (20*1000*1000) +#define SPI_DEFAULT_CLK (12*1000*1000) +#define IDLE_DATA_NUM 5 +#define VT1603_SPI_FIX_CS 0x00 +#define VT1603_SPI_FAKE_CS 3 //(0x7F - 1) +#define VT1603_SPI_BUS_0 0x00 +#define VT1603_SPI_BUS_1 0x01 +#define VT1603_REG_OP_R 0x00 +#define VT1603_REG_OP_W 0x01 + + +#define VT1603_I2C_FIX_ADDR 0x1A +#define VT1603_I2C_FAKE_ADDR 0xEE +#define VT1603_I2C_WCMD 0x00 +#define VT1603_I2C_RCMD 0x01 +#define VT1603_I2C_RWCMD 0x02 +#define VT1603_I2C_BUS_0 0x00 +#define VT1603_I2C_BUS_1 0x01 + + +#define BA_WAKEUP_SRC_0 BIT0 +#define BA_WAKEUP_SRC_1 BIT1 +#define BA_WAKEUP_SRC_2 BIT2 +#define BA_WAKEUP_SRC_3 BIT3 + +#define I2C_BUS 0 +#define SPI_BUS 1 +#define VT1603_FIFO_LEN 3 + +/* VT1603 Register address */ +#define VT1603_BTHD_REG 0x78 +#define VT1603_BCLK_REG 0x88 +#define VT1603_BAEN_REG 0x04 + +#define VT1603_PWC_REG 0xC0 +#define VT1603_CR_REG 0xC1 +#define VT1603_CCCR_REG 0xC2 +#define VT1603_CDPR_REG 0xC3 +#define VT1603_TSPC_REG 0xC4 +#define VT1603_AMCR_REG 0xC7 +#define VT1603_INTCR_REG 0xC8 +#define VT1603_INTEN_REG 0xC9 +#define VT1603_INTS_REG 0xCA +#define VT1603_DCR_REG 0xCB + +#define VT1603_TODCL_REG 0xCC +#define VT1603_TODCH_REG 0xCD + +#define VT1603_DATL_REG 0xCE +#define VT1603_DATH_REG 0xCF + +#define VT1603_XPL_REG 0xD0 +#define VT1603_XPH_REG 0xD1 +#define VT1603_YPL_REG 0xD2 +#define VT1603_YPH_REG 0xD3 + +#define VT1603_BATL_REG 0xD4 +#define VT1603_BATH_REG 0xD5 + +#define VT1603_TEMPL_REG 0xD6 +#define VT1603_TEMPH_REG 0xD7 + +#define VT1603_ERR8_REG 0xD8 +#define VT1603_ERR7_REG 0xD9 +#define VT1603_ERR6_REG 0xDA +#define VT1603_ERR5_REG 0xDB +#define VT1603_ERR4_REG 0xDC +#define VT1603_ERR3_REG 0xDD +#define VT1603_ERR2_REG 0xDE +#define VT1603_ERR1_REG 0xDF + +#define VT1603_DBG8_REG 0xE0 +#define VT1603_DBG7_REG 0xE1 +#define VT1603_DBG6_REG 0xE2 +#define VT1603_DBG5_REG 0xE3 +#define VT1603_DBG4_REG 0xE4 +#define VT1603_DBG3_REG 0xE5 +#define VT1603_DBG2_REG 0xE6 +#define VT1603_DBG1_REG 0xE7 + +/* for VT1603 GPIO1 interrupt setting */ +#define VT1603_IMASK_REG27 27 +#define VT1603_IMASK_REG28 28 +#define VT1603_IMASK_REG29 29 +#define VT1603_IPOL_REG33 33 +#define VT1603_ISEL_REG36 36 + +#endif /* __VT1603_TS_H__ */ diff --git a/ANDROID_3.4.5/drivers/power/wmt_battery/wmt_battery.c b/ANDROID_3.4.5/drivers/power/wmt_battery/wmt_battery.c new file mode 100755 index 00000000..23692ee9 --- /dev/null +++ b/ANDROID_3.4.5/drivers/power/wmt_battery/wmt_battery.c @@ -0,0 +1,66 @@ +/* + * mp2625_charger.c - WonderMedia Charger Driver. + * + * Copyright (C) 2013 WonderMedia Technologies, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +extern void mp2625_pc_connected(void); +extern void g2214_pc_connected(void); + +void wmt_do_pc_connected(void) +{ + mp2625_pc_connected(); + g2214_pc_connected(); +} + +static struct { + int led_power; + int led_gpio_level; +} charger_led; + +void led_power_enable(int enable) +{ + if (gpio_is_valid(charger_led.led_power)) { + if (enable) + gpio_direction_output(charger_led.led_power, + charger_led.led_gpio_level); + else + gpio_direction_output(charger_led.led_power, + !charger_led.led_gpio_level); + } +} + +int parse_charger_led(void) +{ + static const char uboot_env[] = "wmt.charger.led"; + char buf[64]; + size_t l = sizeof(buf); + int id; + + if (wmt_getsyspara((char *)uboot_env, buf, &l) || + (sscanf(buf, "%d:%d:%d", &id, + &charger_led.led_power, &charger_led.led_gpio_level) != 3) || + id != 0 || !gpio_is_valid(charger_led.led_power) || + gpio_request(charger_led.led_power, "led power")) { + charger_led.led_power = -1; + return -EINVAL; + } + + led_power_enable(0); + return 0; +} + -- cgit