diff --git a/arch/arm/configs/htcleo_defconfig b/arch/arm/configs/htcleo_defconfig index 1aa391ba..7620dcce 100644 --- a/arch/arm/configs/htcleo_defconfig +++ b/arch/arm/configs/htcleo_defconfig @@ -237,8 +237,8 @@ CONFIG_MACH_HTCLEO=y # CONFIG_MACH_INCREDIBLE is not set # CONFIG_MACH_INCREDIBLEC is not set # CONFIG_MACH_SUPERSONIC is not set -CONFIG_HTC_BATTCHG=y # CONFIG_HTC_BATTCHG_SMEM is not set +# CONFIG_HTC_BATTCHG is not set # CONFIG_HTC_PWRSINK is not set CONFIG_HTC_SLEEP_MODE_GPIO_DUMP=y # CONFIG_HTC_POWER_COLLAPSE_MAGIC is not set @@ -1192,7 +1192,7 @@ CONFIG_POWER_SUPPLY=y # CONFIG_BATTERY_DS2760 is not set # CONFIG_BATTERY_DS2782 is not set # CONFIG_BATTERY_DS2784 is not set -CONFIG_BATTERY_DS2746=y +# CONFIG_BATTERY_DS2746 is not set # CONFIG_BATTERY_BQ27x00 is not set # CONFIG_BATTERY_MAX17040 is not set # CONFIG_HWMON is not set diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 5f3a5b58..847d9811 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -115,9 +115,9 @@ obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-wifi.o htc_awb_cal.o obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-microp.o clock.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-panel.o board-htcleo-keypad.o -obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-ts.o board-htcleo-mmc.o ieee754-df.o +obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-ts.o board-htcleo-mmc.o ieee754-df.o board-htcleo-power.o -obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-audio.o board-htcleo-acoustic.o +obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-battery.o board-htcleo-log.o board-htcleo-audio.o board-htcleo-acoustic.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-rfkill.o board-htcleo-wifi.o board-htcleo-microp.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-proximity.o board-htcleo-leds.o board-htcleo-ls.o obj-$(CONFIG_MACH_HTCLEO) += clock-wince.o diff --git a/arch/arm/mach-msm/board-htcleo-battery.c b/arch/arm/mach-msm/board-htcleo-battery.c new file mode 100644 index 00000000..20488aa9 --- /dev/null +++ b/arch/arm/mach-msm/board-htcleo-battery.c @@ -0,0 +1,728 @@ +/* arch/arm/mach-msm/board-htcleo-battery.h +* +* Copyright (C) 2010 Markinus +* Copyright (C) 2009 HTC Corporation +* Copyright (C) 2009 Google, Inc. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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. +* +*/ + +/* + +actually this file called "board-htcleo-battery.c", so it's HTC LEO specific only +most values are hard coded here really. +this driver designed for android. + +proper ds2745 driver located at "driver/i2c/chips/ds2745.c" +I don't want and have not resources to support any "proper" linux drivers coding. +("proper" for them, not for me ofcourse) + +my primary target was to make high quality battery support in Android for HTC LEO. kefir with us! + +*/ +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "gpio_chip.h" +#include "board-htcleo.h" + +static enum power_supply_property battery_properties[] = +{ + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_CHARGE_COUNTER, +}; + +static int battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val); +static void htcleo_program_alarm(struct htcleo_device_info *di, int seconds); +static void battery_ext_power_changed(struct power_supply *psy); + +#define BATTERY_LOG_MAX 1024 +#define BATTERY_LOG_MASK (BATTERY_LOG_MAX - 1) + +static DEFINE_MUTEX(battery_log_lock); +static struct battery_status battery_log[BATTERY_LOG_MAX]; +static unsigned battery_log_head; +static unsigned battery_log_tail; + +void battery_log_status(struct battery_status *s) +{ + unsigned n; + mutex_lock(&battery_log_lock); + n = battery_log_head; + memcpy(battery_log + n, s, sizeof(struct battery_status)); + n = (n + 1) & BATTERY_LOG_MASK; + if (n == battery_log_tail) + battery_log_tail = (battery_log_tail + 1) & BATTERY_LOG_MASK; + battery_log_head = n; + mutex_unlock(&battery_log_lock); +} + +static const char *battery_source[3] = { "none", " usb", " ac" }; +static const char *battery_mode[4] = { " off", "slow", "fast", "full" }; + +static int battery_log_print(struct seq_file *sf, void *private) +{ + unsigned n; + mutex_lock(&battery_log_lock); + seq_printf(sf, "timestamp mV mA avg mA uAh dC %% src mode reg full\n"); + for (n = battery_log_tail; n != battery_log_head; n = (n + 1) & BATTERY_LOG_MASK) + { + struct battery_status *s = battery_log + n; + seq_printf(sf, "%9d %5d %6d %6d %8d %4d %3d %s %s 0x%02x %d\n", + s->timestamp, s->voltage_uV / 1000, + s->current_uA / 1000, s->current_avg_uA / 1000, + s->charge_uAh, s->temp_C, + s->percentage, + battery_source[s->charge_source], + battery_mode[s->charge_mode], + s->status_reg, s->battery_full); + } + mutex_unlock(&battery_log_lock); + return 0; +} + +static int I2C_Read_Status(struct htcleo_device_info *di) +{ + uint8_t i2c_msg[1]; + uint8_t i2c_data[2]; + + i2c_msg[0] = 0x01; //status reg + + i2c_master_send(di->client, i2c_msg, 1); + i2c_master_recv(di->client, i2c_data, 2); + + dev_dbg(&di->client->dev, "I2C_Read_Status() = %08X!\n", i2c_data[0]); + di->raw_status = i2c_data[0]; + return 0; +} + +static int I2C_Read_Data(struct htcleo_device_info *di) +{ + uint8_t i2c_msg[1]; + uint8_t i2c_data[10]; + + i2c_msg[0] = 0x08; // AUX0 AUX1 VOLTAGE CURRENT ACR + + i2c_master_send(di->client, i2c_msg, 1); + i2c_master_recv(di->client, i2c_data, 10); + + dev_dbg(&di->client->dev, "I2C_Read_Data() %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X!\n", + i2c_data[0], i2c_data[1], i2c_data[2], i2c_data[3], i2c_data[4], + i2c_data[5], i2c_data[6], i2c_data[7], i2c_data[8], i2c_data[9]); + memcpy(di->raw, i2c_data, 10); + return 0; +} + +static int I2C_Write_ACR(struct htcleo_device_info *di, uint16_t val) +{ + uint8_t i2c_msg[3]; + + i2c_msg[0] = 0x10; + i2c_msg[1] = (val >> 8) & 0xFF; + i2c_msg[2] = (val >> 0) & 0xFF; + +// dev_dbg(&di->client->dev, "I2C_Write_ACR() = %04X!\n", val); + i2c_master_send(di->client, i2c_msg, 3); + return 0; +} + +////////////////////////////////////////////////////////////////////////// + +static int htcleo_charge(int on, int fast) +{ + gpio_direction_output(HTCLEO_GPIO_BATTERY_CHARGER_CURRENT, !!fast); + gpio_direction_output(HTCLEO_GPIO_BATTERY_CHARGER_ENABLE, !on); + return 0; +} + +static void htcleo_parse_data(uint32_t raw_status, u8 *raw, struct battery_status *s) +{ + short n; + uint32_t n32; + uint32_t FL, ACR, ACR_EMPTY; + + /* Get status reg */ + s->status_reg = raw_status; + + /* Get Level */ + // TODO: FL too wrong (?) + ACR = ((raw[8] << 8) | raw[9]); + FL = (LEO_BATTERY_CAPACITY * 1570) / 625; + ACR_EMPTY = (LEO_BATTERY_EMPTY * 1570) / 625; + s->percentage = (100 * (ACR - ACR_EMPTY)) / FL; + + s->charge_uAh = 1000 * (((ACR - ACR_EMPTY) * 625) / 1570); + + if (s->percentage < 0 ) s->percentage = 0; + if (s->percentage > 100 ) s->percentage = 100; + + + /* Get Voltage */ + n32 = (((raw[4] << 8) | raw[5]) / 16); + //s->voltage_uV = (n32 * 244) / 100; + s->voltage_uV = 1000 * ((n32 * 312) >> 7); // div to 128 + + /* Get Current */ + n = ((raw[6]) << 8) | raw[7]; + s->current_uA = 1000 * (((n/4) * 625) / 1570); + + printk("ACR=%d CURR=%d VOL=%d RAAC=%d\n", ACR, s->current_uA, s->voltage_uV, s->percentage); + + // average current not supported by DS2746 + s->current_avg_uA = s->current_uA; + + /* Get Temperature */ + n = ((raw[0] << 8) | (raw[1])); + n /= 16; + + // printk("temp = %x\n", n); + if (n > 2047 || n == 0) + { + s->temp_C = 250; + } + else + { + double v = 0.021277 * (300.0 / (2047.0 / n - 1.0)); + s->temp_C = 10 * (1.0 / ((log(v) * 0.000290698) + 0.003354016) - 273.15); + } + if (s->temp_C < -250) + { + s->temp_C = -250; + } +} + +static int htcleo_battery_read_status(struct htcleo_device_info *di) +{ + // read status + I2C_Read_Status(di); + I2C_Read_Data(di); + + // printk("status = %04X\n", di->raw_status); + htcleo_parse_data(di->raw_status, di->raw, &di->status); + + dev_dbg(&di->client->dev, "batt: %3d%%, %d mV, %d mA (%d avg), %d.%d C, %d mAh\n", + di->status.percentage, + di->status.voltage_uV / 1000, di->status.current_uA / 1000, + di->status.current_avg_uA / 1000, + di->status.temp_C / 10, di->status.temp_C % 10, + di->status.charge_uAh / 1000); + + return 0; +} + +////////////////////////////////////////////////////////////////////////// + +static int htcleo_set_cc(struct htcleo_device_info *di, bool enable) +{ + // not supported for DS2745, there no CE bit + return 0; +} + + +static int battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) +{ + struct htcleo_device_info *di = psy_to_dev_info(psy); + + switch (psp) + { + case POWER_SUPPLY_PROP_STATUS: + switch (di->status.charge_source) + { + case CHARGE_OFF: + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + break; + case CHARGE_FAST: + case CHARGE_SLOW: + if (di->status.battery_full) + val->intval = POWER_SUPPLY_STATUS_FULL; + else if (di->status.charge_mode == CHARGE_OFF) + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + else + val->intval = POWER_SUPPLY_STATUS_CHARGING; + break; + default: + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + break; + } + break; + case POWER_SUPPLY_PROP_HEALTH: + if (di->status.temp_C >= TEMP_HOT) + val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; + else + val->intval = POWER_SUPPLY_HEALTH_GOOD; + break; + case POWER_SUPPLY_PROP_PRESENT: + /* XXX todo */ + val->intval = 1; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + if (di->dummy) + val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; + else + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_CAPACITY: + if (di->dummy) + val->intval = 75; + else + val->intval = di->status.percentage; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = di->status.voltage_uV; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = di->status.temp_C; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = di->status.current_uA; + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + val->intval = di->status.current_avg_uA; + break; + case POWER_SUPPLY_PROP_CHARGE_COUNTER: + val->intval = di->status.charge_uAh; + break; + default: + return -EINVAL; + } + + return 0; +} + +static void htcleo_battery_update_status(struct htcleo_device_info *di) +{ + u8 last_level; + last_level = di->status.percentage; + + htcleo_battery_read_status(di); + + // CotullaTODO: add ACR = FL at top point here + + if ((last_level != di->status.percentage) || (di->status.temp_C > 450)) + { + power_supply_changed(&di->bat); + } +} + +static DEFINE_MUTEX(charge_state_lock); + +static bool check_timeout(ktime_t now, ktime_t last, int seconds) +{ + ktime_t timeout = ktime_add(last, ktime_set(seconds, 0)); + return ktime_sub(timeout, now).tv64 < 0; +} + +static int battery_adjust_charge_state(struct htcleo_device_info *di) +{ + unsigned source; + int rc = 0; + int temp, volt, curr, perc; + int ovp; + u8 charge_mode; + bool charge_timeout = false; + static int lastval=0xffff; + const int min_curr=5000; + + mutex_lock(&charge_state_lock); + + curr = di->status.current_uA; + perc = di->status.percentage; + temp = di->status.temp_C; + volt = di->status.voltage_uV / 1000; + + source = di->status.charge_source; + + /* initially our charge mode matches our source: + * NONE:OFF, USB:SLOW, AC:FAST + */ + charge_mode = source; + + // Check whether the bat is full and change the ACR to right 100% value + if(curr >=0 && curr < min_curr && lastval < min_curr && perc > 95 && source) { + uint32_t FL = (LEO_BATTERY_CAPACITY * 1570) / 625; + uint32_t ACR_EMPTY = (LEO_BATTERY_EMPTY * 1570) / 625; + I2C_Write_ACR(di, FL+ACR_EMPTY); + di->status.battery_full = 1; + di->status.percentage = 100; + charge_mode = CHARGE_OFF; + } + else { + di->status.battery_full = 0; + } + if(curr >=0) lastval=curr; + else lastval=0xffff; + + ovp = gpio_get_value(HTCLEO_GPIO_BATTERY_OVER_CHG); + if (ovp) + { + printk("Battery overpowered!\n"); + } + + if (temp >= TEMP_HOT || ovp) + { + if (temp >= TEMP_CRITICAL) + { + charge_mode = CHARGE_OFF; + } + + /* once we charge to max voltage when hot, disable + * charging until the temp drops or the voltage drops + */ + if (volt >= TEMP_HOT_MAX_MV) + { + di->status.cooldown = 1; + } + } + + /* when the battery is warm, only charge in slow charge mode */ + if ((temp >= TEMP_WARM) && (charge_mode == CHARGE_FAST)) + charge_mode = CHARGE_SLOW; + + if (di->status.cooldown) + { + if ((temp < TEMP_WARM) || (volt <= TEMP_HOT_MIN_MV)) + di->status.cooldown = 0; + else + charge_mode = CHARGE_OFF; + } + + if (di->status.current_uA > 1024) + { + di->last_charge_seen = di->last_poll; + } + else if (di->last_charge_mode != CHARGE_OFF && check_timeout(di->last_poll, di->last_charge_seen, 60 * 60)) + { + /* The charger has probably stopped charging. Turn it + * off until the next sample period. + */ + charge_timeout = true; + charge_mode = CHARGE_OFF; + } + + if (source == CHARGE_OFF) + charge_mode = CHARGE_OFF; + + + if (di->last_charge_mode == charge_mode) + goto done; + + di->last_charge_mode = charge_mode; + di->status.charge_mode = charge_mode; + + switch (charge_mode) + { + case CHARGE_OFF: + htcleo_charge(0, 0); + htcleo_set_cc(di, true); + if (temp >= TEMP_CRITICAL) + pr_info("batt: charging OFF [OVERTEMP]\n"); + else if (di->status.cooldown) + pr_info("batt: charging OFF [COOLDOWN]\n"); + else if (di->status.battery_full) + pr_info("batt: charging OFF [FULL]\n"); + else if (charge_timeout) + pr_info("batt: charging OFF [TIMEOUT]\n"); + else + pr_info("batt: charging OFF\n"); + break; + case CHARGE_SLOW: + di->last_charge_seen = di->last_poll; + htcleo_set_cc(di, true); + htcleo_charge(1, 0); + pr_info("batt: charging SLOW\n"); + break; + case CHARGE_FAST: + di->last_charge_seen = di->last_poll; + htcleo_set_cc(di, true); + htcleo_charge(1, 1); + pr_info("batt: charging FAST\n"); + break; + } + rc = 1; + done: + mutex_unlock(&charge_state_lock); + return rc; +} + + + +static void htcleo_battery_work(struct work_struct *work) +{ + struct htcleo_device_info *di = container_of(work, struct htcleo_device_info, monitor_work); + struct timespec ts; + unsigned long flags; + + htcleo_battery_update_status(di); + + di->last_poll = alarm_get_elapsed_realtime(); + + if (battery_adjust_charge_state(di)) + { + power_supply_changed(&di->bat); + } + + ts = ktime_to_timespec(di->last_poll); + di->status.timestamp = ts.tv_sec; + battery_log_status(&di->status); + + /* prevent suspend before starting the alarm */ + local_irq_save(flags); + wake_unlock(&di->work_wake_lock); + htcleo_program_alarm(di, FAST_POLL); + local_irq_restore(flags); +} + +////////////////////////////////////////////////////////////////////////// + +static void htcleo_program_alarm(struct htcleo_device_info *di, int seconds) +{ + ktime_t low_interval = ktime_set(seconds - 10, 0); + ktime_t slack = ktime_set(20, 0); + ktime_t next; + + next = ktime_add(di->last_poll, low_interval); + + alarm_start_range(&di->alarm, next, ktime_add(next, slack)); +} + +static void htcleo_battery_alarm(struct alarm *alarm) +{ + struct htcleo_device_info *di = container_of(alarm, struct htcleo_device_info, alarm); + wake_lock(&di->work_wake_lock); + queue_work(di->monitor_wqueue, &di->monitor_work); +} + +static void battery_ext_power_changed(struct power_supply *psy) +{ + struct htcleo_device_info *di; + int got_power; + + di = psy_to_dev_info(psy); + got_power = power_supply_am_i_supplied(psy); + + if (got_power) + { + if (is_ac_power_supplied()) + di->status.charge_source = SOURCE_AC; + else + di->status.charge_source = SOURCE_USB; + wake_lock(&vbus_wake_lock); + } + else + { + di->status.charge_source = SOURCE_NONE; + /* give userspace some time to see the uevent and update + * LED state or whatnot... + */ + wake_lock_timeout(&vbus_wake_lock, HZ / 2); + } + battery_adjust_charge_state(di); + power_supply_changed(psy); +} + +static int htcleo_battery_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int rc; + struct htcleo_device_info *di; + + printk("%s\n", __func__); + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) + { + return -EIO; + } + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) + { + return -ENOMEM; + } + + mydi=di; + + di->client = client; + + i2c_set_clientdata(client, di); + + gpio_request(HTCLEO_GPIO_BATTERY_CHARGER_CURRENT, "charger_current"); + gpio_request(HTCLEO_GPIO_BATTERY_CHARGER_ENABLE, "charger_enable"); + gpio_request(HTCLEO_GPIO_BATTERY_OVER_CHG, "charger_over_chg"); + + gpio_direction_output(HTCLEO_GPIO_BATTERY_CHARGER_CURRENT, 1); + gpio_direction_output(HTCLEO_GPIO_BATTERY_CHARGER_ENABLE, 1); + gpio_direction_input(HTCLEO_GPIO_BATTERY_OVER_CHG); + + + di->bat.name = "battery"; + di->bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->bat.properties = battery_properties; + di->bat.num_properties = ARRAY_SIZE(battery_properties); + di->bat.external_power_changed = battery_ext_power_changed; + di->bat.get_property = battery_get_property; + di->last_charge_mode = 0xff; + + rc = power_supply_register(&client->dev, &di->bat); + if (rc) + { + goto fail_register; + } + + INIT_WORK(&di->monitor_work, htcleo_battery_work); + di->monitor_wqueue = create_freezeable_workqueue(dev_name(&client->dev)); + + /* init to something sane */ + di->last_poll = alarm_get_elapsed_realtime(); + + if (!di->monitor_wqueue) + { + rc = -ESRCH; + goto fail_workqueue; + } + wake_lock_init(&di->work_wake_lock, WAKE_LOCK_SUSPEND, "htcleo-battery"); + printk("alarm init\n"); + alarm_init(&di->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, htcleo_battery_alarm); + wake_lock(&di->work_wake_lock); + queue_work(di->monitor_wqueue, &di->monitor_work); + printk("%s: done!\n", __func__); + return 0; + + fail_workqueue: + power_supply_unregister(&di->bat); + fail_register: + + + gpio_free(HTCLEO_GPIO_BATTERY_CHARGER_CURRENT); + gpio_free(HTCLEO_GPIO_BATTERY_CHARGER_ENABLE); + gpio_free(HTCLEO_GPIO_BATTERY_OVER_CHG); + + kfree(di); + return rc; +} + +static int htcleo_suspend(struct device *dev) +{ + struct htcleo_device_info *di = dev_get_drvdata(dev); + + /* If we are on battery, reduce our update rate until + * we next resume. + */ + if (di->status.charge_source == SOURCE_NONE) + { + htcleo_program_alarm(di, SLOW_POLL); + di->slow_poll = 1; + } + return 0; +} + +static int htcleo_resume(struct device *dev) +{ + struct htcleo_device_info *di = dev_get_drvdata(dev); + + /* We might be on a slow sample cycle. If we're + * resuming we should resample the battery state + * if it's been over a minute since we last did + * so, and move back to sampling every minute until + * we suspend again. + */ + if (di->slow_poll) + { + htcleo_program_alarm(di, FAST_POLL); + di->slow_poll = 0; + } + return 0; +} + +static struct dev_pm_ops htcleo_pm_ops = +{ + .suspend = htcleo_suspend, + .resume = htcleo_resume, +}; + + +static const struct i2c_device_id htcleo_battery_id[] = +{ + { "htcleo-battery", 0 }, + { } +}; + + +static struct i2c_driver htcleo_battery_driver = +{ + .driver = + { + .name = "htcleo-battery", + .owner = THIS_MODULE, + .pm = &htcleo_pm_ops, + }, + .id_table = htcleo_battery_id, + .probe = htcleo_battery_probe, +#ifndef CONFIG_HAS_EARLYSUSPEND + /* .suspend = htcleo_suspend, + .resume = htcleo_resume,*/ +#endif +}; + +static int battery_log_open(struct inode *inode, struct file *file) +{ + return single_open(file, battery_log_print, NULL); +} + +static struct file_operations battery_log_fops = +{ + .open = battery_log_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init htcleo_battery_init(void) +{ + debugfs_create_file("battery_log", 0444, NULL, NULL, &battery_log_fops); + wake_lock_init(&vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present"); + return i2c_add_driver(&htcleo_battery_driver); +} + +//module_init(htcleo_battery_init); +late_initcall(htcleo_battery_init); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Cotulla"); +MODULE_DESCRIPTION("htcleo battery driver"); +// END OF FILE diff --git a/arch/arm/mach-msm/board-htcleo-power.c b/arch/arm/mach-msm/board-htcleo-power.c new file mode 100644 index 00000000..fcb9d8da --- /dev/null +++ b/arch/arm/mach-msm/board-htcleo-power.c @@ -0,0 +1,214 @@ +/* arch/arm/mach-msm/board-htcleo-power.c +* +* Copyright (C) 2010 Cotulla +* Copyright (C) 2008 HTC Corporation. +* Copyright (C) 2008 Google, Inc. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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. +* +*/ + +// +// calls seq: +// +// notify_vbus_change_intr -> vbus_work_func -> msm_hsusb_set_vbus_state -> USB -> notify_usb_connected +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "board-htcleo.h" + +static char *supply_list[] = +{ + "battery", +}; + +static int inited; +static int vbus_present; +static int usb_status; +static struct work_struct vbus_work; + +#ifdef CONFIG_USB_ANDROID +void notify_usb_connected(int status); +static struct t_usb_status_notifier usb_status_notifier = { + .name = "htc_battery", + .func = notify_usb_connected, +}; +#endif + +static int power_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + if (psp != POWER_SUPPLY_PROP_ONLINE) + return -EINVAL; + + if (psy->type == POWER_SUPPLY_TYPE_MAINS) + { + val->intval = (usb_status == 2); + } + else + { + val->intval = vbus_present; + } + return 0; +} + +static enum power_supply_property power_properties[] = +{ + POWER_SUPPLY_PROP_ONLINE, +}; + +static struct power_supply ac_supply = +{ + .name = "ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .supplied_to = supply_list, + .num_supplicants = ARRAY_SIZE(supply_list), + .properties = power_properties, + .num_properties = ARRAY_SIZE(power_properties), + .get_property = power_get_property, +}; + +static struct power_supply usb_supply = +{ + .name = "usb", + .type = POWER_SUPPLY_TYPE_USB, + .supplied_to = supply_list, + .num_supplicants = ARRAY_SIZE(supply_list), + .properties = power_properties, + .num_properties = ARRAY_SIZE(power_properties), + .get_property = power_get_property, +}; + +static int get_vbus_state(void) +{ + if (readl(MSM_SHARED_RAM_BASE + 0xEF20C)) + return 1; + else + return 0; +} + +void notify_cable_status(int status) +{ + pr_info("### notify_cable_status(%d) ###\n", status); + vbus_present = status; + msm_hsusb_set_vbus_state(vbus_present); + power_supply_changed(&ac_supply); + power_supply_changed(&usb_supply); + if(mydi) + power_supply_changed(&mydi->bat); +} + +// called from USB driver +void notify_usb_connected(int status) +{ + if (!inited) return; + pr_info("### notify_usb_connected(%d) ###\n", status); + usb_status = status; + power_supply_changed(&ac_supply); + power_supply_changed(&usb_supply); + if(mydi) + power_supply_changed(&mydi->bat); +} + +// called from DEX intrrupt +void notify_vbus_change_intr(void) +{ + if (!inited) return; + schedule_work(&vbus_work); +} + +// used by battery driver +int is_ac_power_supplied(void) +{ + return (usb_status == 2); +} + +static void vbus_work_func(struct work_struct *work) +{ + int vbus = get_vbus_state(); + printk(" new vbus = %d\n", vbus); + #ifdef CONFIG_USB_EHCI_HCD + if (vbus) + return 0; + else + return 0; + #else + if (vbus) + gpio_set_value(HTCLEO_GPIO_POWER_USB, 0); + else + gpio_set_value(HTCLEO_GPIO_POWER_USB, 1); + #endif + notify_cable_status(vbus); +} + + +static int htcleo_power_probe(struct platform_device *pdev) +{ + printk("$$$ htcleo_power_probe $$$\n"); + + INIT_WORK(&vbus_work, vbus_work_func); + + gpio_request(HTCLEO_GPIO_POWER_USB, "power_usb"); + gpio_direction_output(HTCLEO_GPIO_POWER_USB, 0); + + power_supply_register(&pdev->dev, &ac_supply); + power_supply_register(&pdev->dev, &usb_supply); + + inited = 1; + // init VBUS state + notify_vbus_change_intr(); + return 0; +} + +//#define APP_BATT_PDEV_NAME "rs30100001:00000000" +#define APP_BATT_PDEV_NAME "htcleo_power" + +static struct platform_driver htcleo_power_driver = +{ + .probe = htcleo_power_probe, + .driver = + { + .name = APP_BATT_PDEV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init htcleo_power_init(void) +{ + printk("htcleo_power_init\n"); + platform_driver_register(&htcleo_power_driver); + #ifdef CONFIG_USB_ANDROID + usb_register_notifier(&usb_status_notifier); + #endif + return 0; +} + +//module_init(htcleo_power_init); +late_initcall(htcleo_power_init); +MODULE_DESCRIPTION("HTCLEO Power Driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index 8cfdc3ec..47632913 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -34,7 +34,6 @@ #endif #include #include <../../../drivers/staging/android/timed_gpio.h> -#include #include #include @@ -232,6 +231,9 @@ static struct microp_i2c_platform_data microp_data = { static struct i2c_board_info base_i2c_devices[] = { + { + I2C_BOARD_INFO("htcleo-battery", 0x26), + }, { I2C_BOARD_INFO(LEO_TOUCH_DRV_NAME, 0), }, @@ -714,46 +716,11 @@ static struct platform_device ram_console_device = { // Power/Battery /////////////////////////////////////////////////////////////////////// -static struct htc_battery_platform_data htc_battery_pdev_data = { - .func_show_batt_attr = htc_battery_show_attr, - .gpio_mbat_in = -1, - .gpio_mchg_en_n = HTCLEO_GPIO_BATTERY_CHARGER_ENABLE, - .gpio_iset = HTCLEO_GPIO_BATTERY_CHARGER_CURRENT, - .gpio_power = HTCLEO_GPIO_POWER_USB, - .guage_driver = GUAGE_DS2746, - .charger = LINEAR_CHARGER, - .m2a_cable_detect = 0, - .force_no_rpc = 1, - .int_data = { - .chg_int = HTCLEO_GPIO_BATTERY_OVER_CHG, - }, -}; - -static struct platform_device htc_battery_pdev = { - .name = "htc_battery", - .id = -1, - .dev = { - .platform_data = &htc_battery_pdev_data, - }, -}; - -static int get_thermal_id(void) +static struct platform_device htcleo_power = { - return THERMAL_300; -} - -static struct ds2746_platform_data ds2746_pdev_data = { - .func_get_thermal_id = get_thermal_id, -}; - -static struct platform_device ds2746_battery_pdev = { - .name = "ds2746-battery", + .name = "htcleo_power", .id = -1, - .dev = { - .platform_data = &ds2746_pdev_data, - }, }; - /////////////////////////////////////////////////////////////////////// // Real Time Clock /////////////////////////////////////////////////////////////////////// @@ -784,11 +751,10 @@ static struct platform_device *devices[] __initdata = &android_pmem_adsp_device, &android_pmem_venc_device, &msm_device_i2c, - &ds2746_battery_pdev, - &htc_battery_pdev, &msm_kgsl_device, &msm_camera_sensor_s5k3e2fx, &htcleo_flashlight_device, + &htcleo_power, &qsd_device_spi, &htc_headset_mgr, &htc_headset_gpio, @@ -939,6 +905,10 @@ static void __init htcleo_init(void) platform_device_register(&htcleo_timed_gpios); +#ifdef CONFIG_USB_ANDROID + msm_hsusb_set_vbus_state(htcleo_get_vbus_state()); +#endif + /* Blink the camera LED shortly to show that we're alive! */ #ifdef CONFIG_HTCLEO_BLINK_AT_BOOT bank6_in = (unsigned int*)(MSM_GPIO1_BASE + 0x0864); diff --git a/arch/arm/mach-msm/htc_battery.c b/arch/arm/mach-msm/htc_battery.c index 3519d568..fbb717a8 100644 --- a/arch/arm/mach-msm/htc_battery.c +++ b/arch/arm/mach-msm/htc_battery.c @@ -30,23 +30,21 @@ #include /* Jay, to register display notifier */ #include #include -#include -#include #ifdef CONFIG_HTC_BATTCHG_SMEM #include "smd_private.h" #endif -#include -#include #if defined(CONFIG_TROUT_BATTCHG_DOCK) #include #endif #ifdef CONFIG_BATTERY_DS2784 #include -#elif defined(CONFIG_BATTERY_DS2746) +#elif CONFIG_BATTERY_DS2746 #include #endif +#include + static struct wake_lock vbus_wake_lock; enum { @@ -117,7 +115,6 @@ struct htc_battery_info { int gpio_power; int guage_driver; int m2a_cable_detect; - int force_no_rpc; int charger; }; @@ -208,37 +205,6 @@ int unregister_notifier_cable_status(struct notifier_block *nb) return blocking_notifier_chain_unregister(&cable_status_notifier_list, nb); } -/* -------------------------------------------------------------------------- */ -/* HTCLeo Dex Functions. */ -#if defined(CONFIG_MACH_HTCLEO) - -static int get_vbus_state(void) -{ - if (readl(MSM_SHARED_RAM_BASE + 0xEF20C)) - return 1; - else - return 0; -} - -void notify_cable_status(int status) -{ - pr_info("notify_cable_status(%d)\n", status); - msm_hsusb_set_vbus_state(status); - power_supply_changed(&htc_power_supplies[CHARGER_USB]); - power_supply_changed(&htc_power_supplies[CHARGER_AC]); - power_supply_changed(&htc_power_supplies[CHARGER_BATTERY]); -} - -// called from DEX intrrupt -void notify_vbus_change_intr(void) -{ - int vbus; - if (!htc_battery_initial) return; - vbus = get_vbus_state(); - notify_cable_status(vbus); -} - -#endif /* -------------------------------------------------------------------------- */ /* For sleep charging screen. */ static int zcharge_enabled; @@ -363,6 +329,7 @@ device_initcall(batt_debug_init); static int init_batt_gpio(void) { + if (htc_batt_info.gpio_mbat_in > 0 && gpio_request(htc_batt_info.gpio_mbat_in, "batt_detect") < 0) goto gpio_failed; @@ -399,6 +366,7 @@ int battery_charging_ctrl(enum batt_ctl_t ctl) { int result = 0; if (!htc_battery_initial) return 0; + switch (ctl) { case DISABLE: BATT_LOG("charger OFF"); @@ -655,13 +623,9 @@ static void usb_status_notifier_func(int online) blocking_notifier_call_chain(&cable_status_notifier_list, htc_batt_info.rep.charging_source, NULL); - if (htc_battery_initial) { - power_supply_changed(&htc_power_supplies[CHARGER_AC]); - power_supply_changed(&htc_power_supplies[CHARGER_USB]); - power_supply_changed(&htc_power_supplies[CHARGER_BATTERY]); - } else { - pr_err("\n\n ### htc_battery_code is not inited yet! ###\n\n"); - } + power_supply_changed(&htc_power_supplies[CHARGER_AC]); + power_supply_changed(&htc_power_supplies[CHARGER_USB]); + power_supply_changed(&htc_power_supplies[CHARGER_BATTERY]); update_wake_lock(htc_batt_info.rep.charging_source); #else mutex_lock(&htc_batt_info.lock); @@ -1029,17 +993,13 @@ static int htc_battery_get_charging_status(void) break; case CHARGER_USB: case CHARGER_AC: -#if !defined(CONFIG_BATTERY_DS2746) if ((htc_charge_full) && (htc_batt_info.rep.full_level == 100)) { htc_batt_info.rep.level = 100; } -#endif + level = htc_batt_info.rep.level; if (level == 100){ htc_charge_full = 1;} - else - htc_charge_full = 0; - if (htc_charge_full) ret = POWER_SUPPLY_STATUS_FULL; else if (htc_batt_info.rep.charging_enabled != 0) @@ -1066,20 +1026,12 @@ static int htc_battery_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_HEALTH: val->intval = POWER_SUPPLY_HEALTH_GOOD; - if (machine_is_paradise()) { - if (htc_batt_info.rep.batt_temp >= 500 || - htc_batt_info.rep.batt_temp <= 0) - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - } else if (machine_is_spade()) { - if (htc_batt_info.rep.batt_temp >= 450 || - htc_batt_info.rep.batt_temp <= 0) - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - } else { - if (htc_batt_info.rep.batt_temp >= 480 || - htc_batt_info.rep.batt_temp <= 0) - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - } - + if (machine_is_paradise() && (htc_batt_info.rep.batt_temp >= 500 || + htc_batt_info.rep.batt_temp <= 0)) + val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; + else if (!machine_is_paradise() && (htc_batt_info.rep.batt_temp >= 480 || + htc_batt_info.rep.batt_temp <= 0)) + val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; if (htc_batt_debug_mask & HTC_BATT_DEBUG_USER_QUERY) BATT_LOG("%s: %s: health=%d", __func__, psy->name, val->intval); break; @@ -1130,8 +1082,9 @@ static struct device_attribute htc_battery_attrs[] = { #ifdef CONFIG_HTC_BATTCHG_SMEM __ATTR(smem_raw, S_IRUGO, htc_battery_show_smem, NULL), __ATTR(smem_text, S_IRUGO, htc_battery_show_smem, NULL), -#endif +#else __ATTR(batt_attr_text, S_IRUGO, htc_battery_show_batt_attr, NULL), +#endif }; enum { @@ -1253,6 +1206,7 @@ static ssize_t htc_battery_set_full_level(struct device *dev, { int rc = 0; unsigned long percent = 100; + unsigned long param = 0; percent = simple_strtoul(buf, NULL, 10); @@ -1272,8 +1226,9 @@ static ssize_t htc_battery_set_full_level(struct device *dev, mutex_lock(&htc_batt_info.lock); htc_full_level_flag = 1; htc_batt_info.rep.full_level = percent; + param = percent; blocking_notifier_call_chain(&cable_status_notifier_list, - 0xff, (void *) &htc_batt_info.rep.full_level); + 0xff, (void *) ¶m); mutex_unlock(&htc_batt_info.lock); } rc = 0; @@ -1345,7 +1300,7 @@ static int update_batt_info(void) ret = -1; } break; -#elif defined(CONFIG_BATTERY_DS2746) +#elif CONFIG_BATTERY_DS2746 case GUAGE_DS2746: if (ds2746_get_battery_info(&htc_batt_info.rep)) { BATT_ERR("%s: ds2746 read failed!!!", __func__); @@ -1435,93 +1390,10 @@ dont_need_update: return i; } -static irqreturn_t tps65200_int_detection(int irq, void *data) -{ - struct htc_battery_tps65200_int *ip = data; - - BATT_LOG("%s: over voltage is detected.", __func__); - - disable_irq_nosync(ip->chg_int); - - ip->tps65200_reg = 0; - - schedule_delayed_work(&ip->int_work, msecs_to_jiffies(200)); - - return IRQ_HANDLED; -} - -static void htc_battery_tps65200_int_func(struct work_struct *work) -{ - struct htc_battery_tps65200_int *ip; - int fault_bit; - ip = container_of(work, struct htc_battery_tps65200_int, - int_work.work); - - switch (ip->tps65200_reg) { - case CHECK_INT1: - /* read twice. First read to trigger TPS65200 clear fault bit - on INT1. Second read to make sure that fault bit is cleared - and call off ovp function.*/ - fault_bit = tps_set_charger_ctrl(CHECK_INT1); - BATT_LOG("INT1 value: %d", fault_bit); - fault_bit = tps_set_charger_ctrl(CHECK_INT1); - - if (fault_bit) { -#ifdef CONFIG_HTC_BATTCHG_SMEM - smem_batt_info->over_vchg = 1; -#else - htc_batt_info.rep.over_vchg = 1; -#endif - power_supply_changed(&htc_power_supplies[CHARGER_BATTERY]); - schedule_delayed_work(&ip->int_work, - msecs_to_jiffies(5000)); - BATT_LOG("OVER_VOLTAGE: " - "over voltage fault bit on TPS65200 is raised:" - " %d", fault_bit); - } else { -#ifdef CONFIG_HTC_BATTCHG_SMEM - smem_batt_info->over_vchg = 0; -#else - htc_batt_info.rep.over_vchg = 0; -#endif - cancel_delayed_work(&ip->int_work); - enable_irq(ip->chg_int); - } - break; - default: - fault_bit = tps_set_charger_ctrl(CHECK_INT2); - BATT_LOG("Read TPS65200 INT2 register value: %x", fault_bit); - if (fault_bit) { - fault_bit = tps_set_charger_ctrl(CHECK_INT2); - BATT_LOG("Read TPS65200 INT2 register value: %x" - , fault_bit); - fault_bit = tps_set_charger_ctrl(CHECK_INT2); - BATT_LOG("Read TPS65200 INT2 register value: %x" - , fault_bit); - fault_bit = tps_set_charger_ctrl(CHECK_CONTROL); -#ifdef CONFIG_HTC_BATTCHG_SMEM - smem_batt_info->reserve4 = 1; -#endif - cancel_delayed_work(&ip->int_work); - enable_irq(ip->chg_int); - } else { - fault_bit = tps_set_charger_ctrl(CHECK_INT1); - BATT_LOG("Read TPS65200 INT1 register value: %x" - , fault_bit); - if (fault_bit) { - ip->tps65200_reg = CHECK_INT1; - schedule_delayed_work(&ip->int_work, - msecs_to_jiffies(200)); - } - } - break; - } -} - static int htc_battery_core_probe(struct platform_device *pdev) { int i, rc; - pr_info("%s\n", __func__); + /* init battery gpio */ if (htc_batt_info.charger == LINEAR_CHARGER) { if ((rc = init_batt_gpio()) < 0) { @@ -1537,14 +1409,12 @@ static int htc_battery_core_probe(struct platform_device *pdev) */ htc_batt_info.present = 1; - if(!htc_batt_info.force_no_rpc) { - /* init rpc */ - endpoint = msm_rpc_connect(APP_BATT_PROG, APP_BATT_VER, 0); - if (IS_ERR(endpoint)) { - BATT_ERR("%s: init rpc failed! rc = %ld", - __func__, PTR_ERR(endpoint)); - return -EINVAL; - } + /* init rpc */ + endpoint = msm_rpc_connect(APP_BATT_PROG, APP_BATT_VER, 0); + if (IS_ERR(endpoint)) { + BATT_ERR("%s: init rpc failed! rc = %ld", + __func__, PTR_ERR(endpoint)); + return -EINVAL; } /* init power supplier framework */ @@ -1561,21 +1431,16 @@ static int htc_battery_core_probe(struct platform_device *pdev) * the battery status in case of we lost some info */ htc_battery_initial = 1; - - if(htc_batt_info.force_no_rpc) { - update_batt_info(); - } - else { - mutex_lock(&htc_batt_info.rpc_lock); - htc_batt_info.rep.charging_source = CHARGER_BATTERY; - if (htc_get_batt_info(&htc_batt_info.rep) < 0) - BATT_ERR("%s: get info failed", __func__); - if (htc_rpc_set_delta(1) < 0) - BATT_ERR("%s: set delta failed", __func__); - htc_batt_info.update_time = jiffies; - mutex_unlock(&htc_batt_info.rpc_lock); - } + mutex_lock(&htc_batt_info.rpc_lock); + htc_batt_info.rep.charging_source = CHARGER_BATTERY; + if (htc_get_batt_info(&htc_batt_info.rep) < 0) + BATT_ERR("%s: get info failed", __func__); + + if (htc_rpc_set_delta(1) < 0) + BATT_ERR("%s: set delta failed", __func__); + htc_batt_info.update_time = jiffies; + mutex_unlock(&htc_batt_info.rpc_lock); return 0; } @@ -1673,6 +1538,7 @@ static int ds2784_notifier_func(struct notifier_block *nfb, unsigned long action, void *param) { u8 arg = 0; + if (param) arg = *(u8 *)param; @@ -1706,7 +1572,6 @@ static struct notifier_block ds2784_notifier = { static int htc_battery_probe(struct platform_device *pdev) { - int rc = 0; struct htc_battery_platform_data *pdata = pdev->dev.platform_data; htc_batt_info.device_id = pdev->id; @@ -1714,7 +1579,6 @@ static int htc_battery_probe(struct platform_device *pdev) htc_batt_info.gpio_power = pdata->gpio_power; htc_batt_info.guage_driver = pdata->guage_driver; htc_batt_info.m2a_cable_detect = pdata->m2a_cable_detect; - htc_batt_info.force_no_rpc = pdata->force_no_rpc; htc_batt_info.func_show_batt_attr = pdata->func_show_batt_attr; htc_batt_info.charger = pdata->charger; htc_batt_info.rep.full_level = 100; @@ -1731,35 +1595,11 @@ static int htc_battery_probe(struct platform_device *pdev) #ifdef CONFIG_BATTERY_DS2784 if (pdata->guage_driver == GUAGE_DS2784) ds2784_register_notifier(&ds2784_notifier); -#elif defined(CONFIG_BATTERY_DS2746) +#elif CONFIG_BATTERY_DS2746 if (pdata->guage_driver == GUAGE_DS2746) ds2746_register_notifier(&ds2784_notifier); #endif - if (system_rev >= 1 || machine_is_htcleo()) { - if (pdata->int_data.chg_int) { - BATT_LOG("init over voltage interrupt detection."); - INIT_DELAYED_WORK(&pdata->int_data.int_work, - htc_battery_tps65200_int_func); - - rc = request_irq(pdata->int_data.chg_int, - tps65200_int_detection, - IRQF_TRIGGER_LOW, - "over_voltage_interrupt", - &pdata->int_data); - - if (rc) { - BATT_LOG("request irq failed"); - return rc; - } - } - } -#if defined(CONFIG_MACH_HTCLEO) - if(pdata->force_no_rpc) { - htc_battery_core_probe(pdev); - htc_cable_status_update(get_vbus_state()); - } -#endif return 0; } diff --git a/arch/arm/mach-msm/include/mach/htc_battery.h b/arch/arm/mach-msm/include/mach/htc_battery.h index a820efc4..7a7edc5f 100644 --- a/arch/arm/mach-msm/include/mach/htc_battery.h +++ b/arch/arm/mach-msm/include/mach/htc_battery.h @@ -22,10 +22,7 @@ #define SET_ICL500 0X65 #define SET_ICL100 0X66 #define CHECK_INT2 0X67 -#define OVERTEMP_VREG_4060 0XC8 -#define NORMALTEMP_VREG_4200 0XC9 -#define CHECK_INT1 0XCA -#define CHECK_CONTROL 0xCB + /* information about the system we're running on */ extern unsigned int system_rev; @@ -70,13 +67,6 @@ struct battery_info_reply { u32 over_vchg; /* 0:normal, 1:over voltage charger */ s32 eval_current; /* System loading current from ADC */ }; - -struct htc_battery_tps65200_int { - int chg_int; - int tps65200_reg; - struct delayed_work int_work; -}; - struct htc_battery_platform_data { int (*func_show_batt_attr)(struct device_attribute *attr, char *buf); @@ -88,8 +78,6 @@ struct htc_battery_platform_data { int guage_driver; int m2a_cable_detect; int charger; - struct htc_battery_tps65200_int int_data; - int force_no_rpc; }; #if CONFIG_HTC_BATTCHG diff --git a/drivers/power/ds2746_battery.c b/drivers/power/ds2746_battery.c deleted file mode 100644 index 56fbcc66..00000000 --- a/drivers/power/ds2746_battery.c +++ /dev/null @@ -1,1248 +0,0 @@ -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Copyright (c) 2010 High Tech Computer Corporation - -Module Name: - - ds2746_battery.c - -Abstract: - - This module implements the power algorithm, including below concepts: - 1. Charging function control. - 2. Charging full condition. - 3. Recharge control. - 4. Battery capacity maintainance. - 5. Battery full capacity calibration. - -Original Auther: - - Andy.YS Wang June-01-2010 ----------------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/*#include */ -#include -#include -#include -#include -#include "../../arch/arm/mach-msm/proc_comm.h" -#include /* for i2c_adapter, i2c_client define*/ -/*#include "../w1/w1.h"*/ -/*#include "../w1/slaves/w1_ds2784.h"*/ -#include -#include - -struct ds2746_device_info { - - struct device *dev; - struct device *w1_dev; - struct workqueue_struct *monitor_wqueue; - struct work_struct monitor_work; - /* lock to protect the battery info */ - struct mutex lock; - /* DS2784 data, valid after calling ds2784_battery_read_status() */ - unsigned long update_time; /* jiffies when data read */ - struct alarm alarm; - struct wake_lock work_wake_lock; - u8 slow_poll; - ktime_t last_poll; -}; -static struct wake_lock vbus_wake_lock; - -/*======================================================================================== - -HTC power algorithm helper member and functions - -========================================================================================*/ - -static struct poweralg_type poweralg = {0}; -static struct poweralg_config_type config = {0}; -static struct poweralg_config_type debug_config = {0}; - -#define FAST_POLL (1 * 60) -#define SLOW_POLL (10 * 60) -#define PREDIC_POLL 20 - -#define SOURCE_NONE 0 -#define SOURCE_USB 1 -#define SOURCE_AC 2 - -#define CHARGE_OFF 0 -#define CHARGE_SLOW 1 -#define CHARGE_FAST 2 - -#define BATTERY_ID_UNKNOWN 0 -#define HTC_BATTERY_DS2746_DEBUG_ENABLE 0 - -/* DS2746 I2C BUS*/ -#define DS2746_I2C_BUS_ID 0 -#define DS2746_I2C_SLAVE_ADDR 0x26 - -/*======================================================================================== - -IC dependent defines - -========================================================================================*/ - -/* DS2746 I2C register address*/ -#define DS2746_STATUS_REG 0x01 -#define DS2746_AUX0_MSB 0x08 -#define DS2746_AUX0_LSB 0x09 -#define DS2746_AUX1_MSB 0x0A -#define DS2746_AUX1_LSB 0x0B -#define DS2746_VOLT_MSB 0x0C -#define DS2746_VOLT_LSB 0x0D -#define DS2746_CURRENT_MSB 0x0E -#define DS2746_CURRENT_LSB 0x0F -#define DS2746_ACR_MSB 0x10 -#define DS2746_ACR_LSB 0x11 - -/* DS2746 I2C I/O*/ -static struct i2c_adapter *i2c2 = NULL; -static struct i2c_client *ds2746_i2c = NULL; -static int htc_battery_initial = 0; - -int ds2746_i2c_write_u8(u8 value, u8 reg) -{ - int ret; - u8 buf[2]; - struct i2c_msg *msg; - struct i2c_msg xfer_msg[1]; - - /* [MSG1] fill the register address data and fill the data Tx buffer */ - msg = &xfer_msg[0]; - msg->addr = ds2746_i2c->addr; - msg->len = 2; - msg->flags = 0; /* Read the register value */ - msg->buf = buf; - - buf[0] = reg; - buf[1] = value; - - ret = i2c_transfer(ds2746_i2c->adapter, xfer_msg, 1); - if (ret <= 0){ - printk(DRIVER_ZONE "[%s] fail.\n", __func__); - } - -#if HTC_BATTERY_DS2746_DEBUG_ENABLE - printk(DRIVER_ZONE "[%s] ds2746[0x%x]<-0x%x.\n", __func__, reg, value); -#endif - - return ret; -} - -int ds2746_i2c_read_u8(u8 *value, u8 reg) -{ - int ret; - struct i2c_msg *msg; - struct i2c_msg xfer_msg[2]; - - /* [MSG1] fill the register address data */ - msg = &xfer_msg[0]; - msg->addr = ds2746_i2c->addr; - msg->len = 1; - msg->flags = 0; /* Read the register value */ - msg->buf = ® - /* [MSG2] fill the data rx buffer */ - msg = &xfer_msg[1]; - msg->addr = ds2746_i2c->addr; - msg->len = 1; - msg->flags = I2C_M_RD; /* Read the register value */ - msg->buf = value; - - ret = i2c_transfer(ds2746_i2c->adapter, xfer_msg, 2); - if (ret <= 0){ - printk(DRIVER_ZONE "[%s] fail.\n", __func__); - } - -#if HTC_BATTERY_DS2746_DEBUG_ENABLE - printk(DRIVER_ZONE "[%s] ds2746[0x%x]=0x%x.\n", __func__, reg, *value); -#endif - - return ret; -} - -static void ds2746_i2c_exit(void) -{ - if (ds2746_i2c != NULL){ - kfree(ds2746_i2c); - ds2746_i2c = NULL; - } - - if (i2c2 != NULL){ - i2c_put_adapter(i2c2); - i2c2 = NULL; - } -} - -static int ds2746_i2c_init(void) -{ - i2c2 = i2c_get_adapter(DS2746_I2C_BUS_ID); - ds2746_i2c = kzalloc(sizeof(*ds2746_i2c), GFP_KERNEL); - - if (i2c2 == NULL || ds2746_i2c == NULL){ - printk(DRIVER_ZONE "[%s] fail (0x%x, 0x%x).\n", - __func__, - (int) i2c2, - (int) ds2746_i2c); - ds2746_i2c_exit(); - return -ENOMEM; - } - - ds2746_i2c->adapter = i2c2; - ds2746_i2c->addr = DS2746_I2C_SLAVE_ADDR; - - return 0; -} - -/*======================================================================================== - - HTC supporting MFG testing member and functions - -=========================================================================================*/ - -static BOOL b_is_charge_off_by_bounding = FALSE; -static void bounding_fullly_charged_level(int upperbd) -{ - static int pingpong = 1; - int lowerbd; - int current_level; - b_is_charge_off_by_bounding = FALSE; - if (upperbd <= 0) - return; /* doesn't activated this function */ - lowerbd = upperbd - 5; /* 5% range */ - - if (lowerbd < 0) - lowerbd = 0; - current_level = CEILING(poweralg.capacity_01p, 10); - - if (pingpong == 1 && upperbd <= current_level) { - printk(DRIVER_ZONE "MFG: lowerbd=%d, upperbd=%d, current=%d, pingpong:1->0 turn off\n", lowerbd, upperbd, current_level); - b_is_charge_off_by_bounding = TRUE; - pingpong = 0; - } else if (pingpong == 0 && lowerbd < current_level) { - printk(DRIVER_ZONE "MFG: lowerbd=%d, upperbd=%d, current=%d, toward 0, turn off\n", lowerbd, upperbd, current_level); - b_is_charge_off_by_bounding = TRUE; - } else if (pingpong == 0 && current_level <= lowerbd) { - printk(DRIVER_ZONE "MFG: lowerbd=%d, upperbd=%d, current=%d, pingpong:0->1 turn on\n", lowerbd, upperbd, current_level); - pingpong = 1; - } else { - printk(DRIVER_ZONE "MFG: lowerbd=%d, upperbd=%d, current=%d, toward %d, turn on\n", lowerbd, upperbd, current_level, pingpong); - } - -} - -static BOOL is_charge_off_by_bounding_condition(void) -{ - return b_is_charge_off_by_bounding; -} - -void calibrate_id_ohm(struct battery_type *battery) -{ - if (!poweralg.charging_source || !poweralg.charging_enable){ - battery->id_ohm += 500; /* If device is in discharge mode, Rid=Rid_1 + 0.5Kohm*/ - } - else if (poweralg.charging_source == 2 && battery->current_mA >= 400 && battery->id_ohm >= 1500){ - battery->id_ohm -= 1500; /* If device is in charge mode and ISET=1 (charge current is <800mA), Rid=Rid_1 - 1.5Kohm*/ - } - else if (battery->id_ohm >= 700){ - battery->id_ohm -= 700; /* If device is in charge mode and ISET=0 (charge current is <400mA), Rid=Rid_1 - 0.7Kohm*/ - } -} - -static BOOL is_charging_avaiable(void) -{ - if (poweralg.is_software_charger_timeout) return FALSE; - if (!poweralg.protect_flags.is_charging_enable_available)return FALSE; - if (!poweralg.is_cable_in) return FALSE; - if (poweralg.charge_state == CHARGE_STATE_PENDING) return FALSE; - if (poweralg.charge_state == CHARGE_STATE_FULL_PENDING) return FALSE; - if (poweralg.charge_state == CHARGE_STATE_PREDICTION) return FALSE; - if (is_charge_off_by_bounding_condition()) return FALSE; - return TRUE; /* CHARGE_STATE_UNKNOWN, SET_LED_BATTERY_CHARGING is available to be charged by default*/ -} - -static BOOL is_high_current_charging_avaialable(void) -{ - if (!poweralg.protect_flags.is_charging_high_current_avaialble) return FALSE; - if (!poweralg.is_china_ac_in) return FALSE; - if (poweralg.charge_state == CHARGE_STATE_UNKNOWN) return FALSE; - return TRUE; -} - -static void update_next_charge_state(void) -{ - static UINT32 count_charging_full_condition; - static UINT32 count_charge_over_load; - int next_charge_state; - int i; - - /* unknown -> prediction -> unknown -> discharge/charging/pending - charging -> full-wait-stable -> full-charging -> full-pending - full-pending -> full-charging -> charging - *(cable in group) -> discharge, charge-pending, dead - *(cable out group), full-wait-stable, charge-pending, dead -> charging*/ - - for (i = 0; i < 25; i++) /* maximun 25 times state transition to prevent from busy loop; ideally the transition time shall be less than 5 times.*/ - { - next_charge_state = poweralg.charge_state; - - /* 0. enter prediction state or not*/ - if (poweralg.charge_state == CHARGE_STATE_UNKNOWN){ - if (poweralg.battery.is_power_on_reset || config.debug_always_predict){ - if (poweralg.protect_flags.is_battery_dead){ - /* keep poweralg.charge_state unchanged, set capacity to 0% directly*/ - printk(DRIVER_ZONE " dead battery, \ - p=0%%\n"); - poweralg.capacity_01p = 0; - battery_capacity_update(&poweralg.battery, poweralg.capacity_01p); - - poweralg.fst_discharge_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_acr_mAh = poweralg.battery.charge_counter_mAh; - } - else{ - /* battery replaced, recalculate capacity based on battery voltage*/ - printk(DRIVER_ZONE " start predict discharge...\n"); - next_charge_state = CHARGE_STATE_PREDICTION; - } - - config.debug_always_predict = FALSE; - } - } - - if (next_charge_state == poweralg.charge_state){ - /*---------------------------------------------------------------------------------------------------*/ - /* 1. cable in group*/ - if (poweralg.charge_state == CHARGE_STATE_UNKNOWN || - poweralg.charge_state == CHARGE_STATE_CHARGING || - poweralg.charge_state == CHARGE_STATE_PENDING || - poweralg.charge_state == CHARGE_STATE_FULL_WAIT_STABLE || - poweralg.charge_state == CHARGE_STATE_FULL_CHARGING || - poweralg.charge_state == CHARGE_STATE_FULL_PENDING){ - if (!poweralg.is_cable_in){ - next_charge_state = CHARGE_STATE_DISCHARGE; - } - else if (!poweralg.protect_flags.is_charging_enable_available){ - next_charge_state = CHARGE_STATE_PENDING; - } - } - - /*---------------------------------------------------------------------------------------------------*/ - /* 2. cable out group*/ - if (poweralg.charge_state == CHARGE_STATE_UNKNOWN || - poweralg.charge_state == CHARGE_STATE_DISCHARGE){ - if (poweralg.is_cable_in){ - next_charge_state = CHARGE_STATE_CHARGING; - } - } - } - - /*---------------------------------------------------------------------------------------------------*/ - /* 3. state handler/transition, if the charge state is not changed due to cable/protect flags*/ - if (next_charge_state == poweralg.charge_state){ - switch (poweralg.charge_state){ - case CHARGE_STATE_PREDICTION: - { - UINT32 end_time_ms = BAHW_MyGetMSecs(); - - if (end_time_ms - poweralg.state_start_time_ms >= - config.predict_timeout_sec * 1000){ - - printk(DRIVER_ZONE "predict done [%d->%d]\n", poweralg.state_start_time_ms, - end_time_ms); - next_charge_state = CHARGE_STATE_UNKNOWN; - } - } - break; - case CHARGE_STATE_CHARGING: - if (!poweralg.battery.is_power_on_reset){ - /* -> full-charging, pending, dead*/ - if (poweralg.capacity_01p > 990){ - /* only ever charge-full, the capacity can be larger than 99.0%*/ - next_charge_state = CHARGE_STATE_FULL_CHARGING; - } - else if (poweralg.battery.voltage_mV >= config.full_charging_mv && - poweralg.battery.current_mA >= 0 && - poweralg.battery.current_mA <= config.full_charging_ma){ - /* meet charge full terminate condition, check again*/ - next_charge_state = CHARGE_STATE_FULL_WAIT_STABLE; - } - } - - if (poweralg.battery.current_mA <= 0){ - /* count_charge_over_load is 5 as max*/ - if (count_charge_over_load < 5) - count_charge_over_load++; - else - poweralg.is_charge_over_load = TRUE; - } - else{ - count_charge_over_load = 0; - poweralg.is_charge_over_load = FALSE; - } - - /* is_software_charger_timeout: only triggered when AC adapter in*/ - if (config.software_charger_timeout_sec && poweralg.is_china_ac_in){ - /* software charger timer is enabled; for AC charge only*/ - UINT32 end_time_ms = BAHW_MyGetMSecs(); - - if (end_time_ms - poweralg.state_start_time_ms >= - config.software_charger_timeout_sec * 1000){ - - printk(DRIVER_ZONE "software charger timer timeout [%d->%d]\n", - poweralg.state_start_time_ms, - end_time_ms); - poweralg.is_software_charger_timeout = TRUE; - } - } - break; - case CHARGE_STATE_FULL_WAIT_STABLE: - { - /* -> full-charging, pending, dead*/ - if (poweralg.battery.voltage_mV >= config.full_charging_mv && - poweralg.battery.current_mA >= 0 && - poweralg.battery.current_mA <= config.full_charging_ma){ - - count_charging_full_condition++; - } - else{ - count_charging_full_condition = 0; - next_charge_state = CHARGE_STATE_CHARGING; - } - - if (count_charging_full_condition >= 3){ - - poweralg.capacity_01p = 1000; - battery_capacity_update(&poweralg.battery, poweralg.capacity_01p); - - next_charge_state = CHARGE_STATE_FULL_CHARGING; - } - } - break; - case CHARGE_STATE_FULL_CHARGING: - { - /* -> full-pending, charging*/ - UINT32 end_time_ms = BAHW_MyGetMSecs(); - - if (poweralg.battery.voltage_mV < config.voltage_exit_full_mv){ - if (poweralg.capacity_01p > 990) - poweralg.capacity_01p = 990; - next_charge_state = CHARGE_STATE_CHARGING; - } - else if (config.full_pending_ma != 0 && - poweralg.battery.current_mA >= 0 && - poweralg.battery.current_mA <= config.full_pending_ma){ - - printk(DRIVER_ZONE " charge-full pending(%dmA)(%d:%d)\n", - poweralg.battery.current_mA, - poweralg.state_start_time_ms, - end_time_ms); - - next_charge_state = CHARGE_STATE_FULL_PENDING; - } - else if (end_time_ms - poweralg.state_start_time_ms >= - config.full_charging_timeout_sec * 1000){ - - printk(DRIVER_ZONE " charge-full (expect:%dsec)(%d:%d)\n", - config.full_charging_timeout_sec, - poweralg.state_start_time_ms, - end_time_ms); - next_charge_state = CHARGE_STATE_FULL_PENDING; - } - } - break; - case CHARGE_STATE_FULL_PENDING: - if ((poweralg.battery.voltage_mV >= 0 && - poweralg.battery.voltage_mV < config.voltage_recharge_mv) || - (poweralg.battery.RARC_01p >= 0 && - poweralg.battery.RARC_01p <= config.capacity_recharge_p * 10)){ - /* -> full-charging*/ - next_charge_state = CHARGE_STATE_FULL_CHARGING; - } - break; - case CHARGE_STATE_PENDING: - case CHARGE_STATE_DISCHARGE: - { - UINT32 end_time_ms = BAHW_MyGetMSecs(); - - if (!poweralg.is_voltage_stable){ - if (end_time_ms - poweralg.state_start_time_ms >= - config.wait_votlage_statble_sec * 1000){ - - printk(DRIVER_ZONE " voltage stable\n"); - poweralg.is_voltage_stable = TRUE; - } - } - } - - if (poweralg.is_cable_in && - poweralg.protect_flags.is_charging_enable_available){ - /* -> charging*/ - next_charge_state = CHARGE_STATE_CHARGING; - } - break; - } - } - - /*---------------------------------------------------------------------------------------------------*/ - /* 4. state transition*/ - if (next_charge_state != poweralg.charge_state){ - /* state exit*/ - switch (poweralg.charge_state){ - case CHARGE_STATE_UNKNOWN: - poweralg.capacity_01p = poweralg.battery.RARC_01p; - if (poweralg.capacity_01p > 990) - poweralg.capacity_01p = 990; - if (poweralg.capacity_01p < 0) - poweralg.capacity_01p = 0; - - poweralg.fst_discharge_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_acr_mAh = poweralg.battery.charge_counter_mAh; - break; - case CHARGE_STATE_PREDICTION: - battery_param_update(&poweralg.battery, - &poweralg.protect_flags); - - poweralg.capacity_01p = poweralg.battery.KADC_01p; - if (poweralg.capacity_01p > 990) - poweralg.capacity_01p = 990; - if (poweralg.capacity_01p < 0) - poweralg.capacity_01p = 0; - battery_capacity_update(&poweralg.battery, - poweralg.capacity_01p); - - poweralg.fst_discharge_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_acr_mAh = poweralg.battery.charge_counter_mAh; - break; - } - - /* state init*/ - poweralg.state_start_time_ms = BAHW_MyGetMSecs(); - - switch (next_charge_state){ - case CHARGE_STATE_DISCHARGE: - case CHARGE_STATE_PENDING: - /*! star_lee 20100426 - always set ACR=FULL when discharge starts and ACR>FULL*/ - if (poweralg.battery.RARC_01p > 1000) - battery_capacity_update(&poweralg.battery, 1000); - - poweralg.is_need_calibrate_at_49p = TRUE; - poweralg.is_need_calibrate_at_14p = TRUE; - poweralg.fst_discharge_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_acr_mAh = poweralg.battery.charge_counter_mAh; - poweralg.is_voltage_stable = FALSE; - - break; - case CHARGE_STATE_CHARGING: - poweralg.is_software_charger_timeout = FALSE; /* reset software charger timer every time when charging re-starts*/ - poweralg.is_charge_over_load = FALSE; - count_charge_over_load = 0; - poweralg.battery.charge_full_real_mAh = poweralg.battery.charge_full_design_mAh; - battery_capacity_update(&poweralg.battery, poweralg.capacity_01p); - break; - case CHARGE_STATE_FULL_WAIT_STABLE: - /* set to 0 first; the cournter will be add to 1 soon in CHARGE_STATE_FULL_WAIT_STABLE state handler*/ - count_charging_full_condition = 0; - break; - } - - printk(DRIVER_ZONE " state change(%d->%d), full count=%d, over load count=%d [%d]\n", - poweralg.charge_state, - next_charge_state, - count_charging_full_condition, - count_charge_over_load, - poweralg.state_start_time_ms); - - poweralg.charge_state = next_charge_state; - continue; - } - - break; - } -} - -static void __update_capacity(void) -{ - INT32 next_capacity_01p; - - pr_info("ds2746_batt:__update_capacity start\n"); - if (poweralg.charge_state == CHARGE_STATE_PREDICTION || - poweralg.charge_state == CHARGE_STATE_UNKNOWN){ - - /*! star_lee 20100429 - return 99%~25% when in prediction mode*/ - poweralg.capacity_01p = max(min(990, poweralg.battery.KADC_01p), 250); - printk(DRIVER_ZONE "fake percentage (%d) during prediction.\n", - poweralg.capacity_01p); - } - else if (poweralg.charge_state == CHARGE_STATE_FULL_CHARGING || - poweralg.charge_state == CHARGE_STATE_FULL_PENDING){ - - poweralg.capacity_01p = 1000; - } - else if (!is_charging_avaiable() && poweralg.is_voltage_stable){ - /* DISCHARGE ALG: capacity is based on KADC/RARC; only do this after cable in 3 minutes later*/ - if (poweralg.battery.KADC_01p <= 0){ - if (poweralg.capacity_01p > 0) - poweralg.capacity_01p -= 10; - if (poweralg.capacity_01p > 0){ - /* capacity is still not 0 when KADC is 0; record capacity for next boot time*/ - battery_capacity_update(&poweralg.battery, poweralg.capacity_01p); - } - } - else{ - if ((config.enable_weight_percentage) && (poweralg.capacity_01p <150 || - poweralg.battery.RARC_01p> poweralg.battery.KADC_01p)){ - -#define Padc 200 -#define Pw 5 -/* 500= 1000) - next_capacity_01p = 1000; - if (next_capacity_01p < 0) - next_capacity_01p = 0; - - if (next_capacity_01p < poweralg.capacity_01p){ - poweralg.capacity_01p -= min(10, poweralg.capacity_01p-next_capacity_01p); - } - } - - if (config.enable_full_calibration){ - if (poweralg.is_need_calibrate_at_49p && - poweralg.capacity_01p <= 500 && - poweralg.fst_discharge_capacity_01p >= 600){ - - poweralg.battery.charge_full_real_mAh = (poweralg.fst_discharge_acr_mAh-poweralg.battery.charge_counter_mAh)*1000/ - (poweralg.fst_discharge_capacity_01p-poweralg.capacity_01p); - - battery_capacity_update(&poweralg.battery, poweralg.capacity_01p); - - poweralg.is_need_calibrate_at_49p = FALSE; - poweralg.fst_discharge_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_acr_mAh = poweralg.battery.charge_counter_mAh; - - printk(DRIVER_ZONE " 1.full calibrate: full=%d\n", - poweralg.battery.charge_full_real_mAh); - } - else if (poweralg.is_need_calibrate_at_14p && - poweralg.capacity_01p <= 150 && - poweralg.fst_discharge_capacity_01p >= 250){ - poweralg.battery.charge_full_real_mAh = (poweralg.fst_discharge_acr_mAh-poweralg.battery.charge_counter_mAh)*1000/ - (poweralg.fst_discharge_capacity_01p - poweralg.capacity_01p); - - battery_capacity_update(&poweralg.battery, poweralg.capacity_01p); - - poweralg.is_need_calibrate_at_14p = FALSE; - poweralg.fst_discharge_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_acr_mAh = poweralg.battery.charge_counter_mAh; - - printk(DRIVER_ZONE " 2.full calibrate: full=%d\n", - poweralg.battery.charge_full_real_mAh); - } - } - } - else{ - /* CHARGE ALG: capacity is always based on ACR - 1. plus 1% as max when charge, if the orignal capacity is <= 99%, the result is no more than 99% - 2. minus 1% as max when discharge, not less than 0%*/ - next_capacity_01p = poweralg.battery.RARC_01p; - - if (next_capacity_01p > 1000) - next_capacity_01p = 1000; - if (next_capacity_01p < 0) - next_capacity_01p = 0; - - if (next_capacity_01p > poweralg.capacity_01p){ - /* charge case*/ - next_capacity_01p = poweralg.capacity_01p + min(next_capacity_01p - poweralg.capacity_01p, 10); - if (poweralg.capacity_01p > 990) - poweralg.capacity_01p = next_capacity_01p; - else - poweralg.capacity_01p = min(next_capacity_01p, 990); - } - else if (next_capacity_01p < poweralg.capacity_01p){ - /* discharge case*/ - poweralg.capacity_01p -= min(poweralg.capacity_01p - next_capacity_01p, 10); - if (poweralg.capacity_01p < 0) - poweralg.capacity_01p = 0; - } - } -} - -/*======================================================================================== - -HTC power algorithm implemetation - -========================================================================================*/ - -int get_state_check_interval_min_sec(void) -{ - /*the minimal check interval of each states in seconds - reserve for change polling rate - UINT32 elapse_time_ms = BAHW_MyGetMSecs() - poweralg.state_start_time_ms; - switch (poweralg.charge_state) - { - case CHARGE_STATE_FULL_WAIT_STABLE: - //! star_lee 20100429 - takes 30 seconds(10 seconds*3 times) to confirm charge full condition - return 10; - case CHARGE_STATE_PREDICTION: - return min(config.predict_timeout_sec, max((INT32)(config.predict_timeout_sec - elapse_time_ms/1000), (INT32)1)); - default: - if ( BAHW_IsChargeSourceIn() ) return config.polling_time_in_charging_sec; - else return config.polling_time_in_discharging_sec; - } - */ - return 0; -} - -BOOL do_power_alg(BOOL is_event_triggered) -{ - /* is_event_triggered - TRUE: handle event only, do not update capacity; FALSE; always update capacity*/ - static BOOL s_bFirstEntry = TRUE; - static UINT32 s_pre_time_ms; - static INT32 s_level; - - UINT32 now_time_ms = BAHW_MyGetMSecs(); - - /*------------------------------------------------------ - 1 get battery data and update charge state*/ - if (!battery_param_update(&poweralg.battery, &poweralg.protect_flags)){ - printk(DRIVER_ZONE "battery_param_update fail, please retry next time.\n"); - return FALSE; - } - - update_next_charge_state(); - - /*----------------------------------------------------- - 2 calculate battery capacity (predict if necessary)*/ - if (s_bFirstEntry || now_time_ms - s_pre_time_ms > 10000 || !is_event_triggered){ - /* DO not update capacity when plug/unplug cable less than 10 seconds*/ - __update_capacity(); - - s_bFirstEntry = FALSE; - s_pre_time_ms = now_time_ms; - } - - if (config.debug_disable_shutdown){ - if (poweralg.capacity_01p <= 0){ - poweralg.capacity_01p = 1; - } - } - - s_level = CEILING(poweralg.capacity_01p, 10); - if (CEILING(poweralg.last_capacity_01p, 10) != s_level || - poweralg.battery.last_temp_01c != poweralg.battery.temp_01c) { - - poweralg.battery.last_temp_01c = poweralg.battery.temp_01c; - poweralg.last_capacity_01p = poweralg.capacity_01p; - ds2746_blocking_notify(DS2784_LEVEL_UPDATE, &s_level); - } - - bounding_fullly_charged_level(config.full_level); - - /*------------------------------------------------------ - 3 charging function change*/ - if (is_charging_avaiable()){ - if (is_high_current_charging_avaialable()){ - ds2746_charger_control(CHARGE_FAST); - } - else{ - ds2746_charger_control(CHARGE_SLOW); - } - } - else{ - ds2746_charger_control(CHARGE_OFF); - } - - if (config.debug_disable_hw_timer && poweralg.is_charge_over_load){ - ds2746_charger_control(CHARGE_OFF); - printk(DRIVER_ZONE "Toggle charger due to HW disable charger.\n"); - } - - /*------------------------------------------------------ - 4 debug messages and update os battery status*/ - - /*powerlog_to_file(&poweralg); - update_os_batt_status(&poweralg);*/ - - printk(DRIVER_ZONE "[%d] P=%d cable=%d%d flags=%d%d%d debug=%d%d%d%d fst_discharge=%d/%d [%u]\n", - poweralg.charge_state, - poweralg.capacity_01p, - poweralg.is_cable_in, - poweralg.is_china_ac_in, - poweralg.protect_flags.is_charging_enable_available, - poweralg.protect_flags.is_charging_high_current_avaialble, - poweralg.protect_flags.is_battery_dead, - config.debug_disable_shutdown, - config.debug_fake_room_temp, - config.debug_disable_hw_timer, - config.debug_always_predict, - poweralg.fst_discharge_capacity_01p, - poweralg.fst_discharge_acr_mAh, - BAHW_MyGetMSecs()); - - return TRUE; -} - -void power_alg_init(struct poweralg_config_type *debug_config) -{ - /*------------------------------------------------------------- - 1. setup default poweralg data*/ - poweralg.charge_state = CHARGE_STATE_UNKNOWN; - poweralg.capacity_01p = 990; - poweralg.last_capacity_01p = poweralg.capacity_01p; - poweralg.fst_discharge_capacity_01p = 0; - poweralg.fst_discharge_acr_mAh = 0; - poweralg.is_need_calibrate_at_49p = TRUE; - poweralg.is_need_calibrate_at_14p = TRUE; - poweralg.is_charge_over_load = FALSE; - poweralg.is_china_ac_in = FALSE; - poweralg.is_cable_in = FALSE; - poweralg.is_voltage_stable = FALSE; - poweralg.is_software_charger_timeout = FALSE; - poweralg.state_start_time_ms = 0; - - if(get_cable_status() == SOURCE_USB) - { - poweralg.is_cable_in = TRUE; - poweralg.charging_source = SOURCE_USB; - ds2746_charger_control(CHARGE_SLOW); - } - else if (get_cable_status() == SOURCE_AC) - { - poweralg.is_cable_in = TRUE; - poweralg.is_china_ac_in = TRUE; - poweralg.charging_source = SOURCE_AC; - ds2746_charger_control(CHARGE_FAST); - } else{ - poweralg.charging_source = SOURCE_NONE; - } - /*------------------------------------------------------------- - 2. setup default config flags (board dependent)*/ - poweralg_config_init(&config); - - if (debug_config){ - config.debug_disable_shutdown = debug_config->debug_disable_shutdown; - config.debug_fake_room_temp = debug_config->debug_fake_room_temp; - config.debug_disable_hw_timer = debug_config->debug_disable_hw_timer; - config.debug_always_predict = debug_config->debug_always_predict; - } - - /* if ( BAHW_IsTestMode() ) - { - config.debug_disable_shutdown = TRUE; - config.debug_fake_room_temp = TRUE; - config.debug_disable_hw_timer = TRUE; - }*/ - - /*------------------------------------------------------------- - 3. setup default protect flags*/ - poweralg.protect_flags.is_charging_enable_available = TRUE; - poweralg.protect_flags.is_battery_dead = FALSE; - poweralg.protect_flags.is_charging_high_current_avaialble = FALSE; - poweralg.protect_flags.is_fake_room_temp = config.debug_fake_room_temp; - - /*------------------------------------------------------------- - 4. setup default battery structure*/ - battery_param_init(&poweralg.battery); - - /*pr_info("power alg inited with board name <%s>\n", HTC_BATT_BOARD_NAME);*/ -} - -void power_alg_preinit(void) -{ - /* make sure cable and battery is in when off mode charging*/ -} - -static BLOCKING_NOTIFIER_HEAD(ds2746_notifier_list); -int ds2746_register_notifier(struct notifier_block *nb) -{ - pr_info("%s\n", __func__); - return blocking_notifier_chain_register(&ds2746_notifier_list, nb); -} - -int ds2746_unregister_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&ds2746_notifier_list, nb); -} - - -int ds2746_blocking_notify(unsigned long val, void *v) -{ - int chg_ctl; - pr_info("%s\n", __func__); - - if (val == DS2784_CHARGING_CONTROL){ - chg_ctl = *(int *) v; - if (machine_is_passionc()){ - pr_info("[ds2746_batt] Switch charging %d\n", chg_ctl); - if (chg_ctl <= 2){ - gpio_direction_output(22, !(!!chg_ctl));/*PNC*/ - set_charger_ctrl(chg_ctl); - } - return 0; - } - else if (poweralg.battery.id_index != BATTERY_ID_UNKNOWN){ - /* only notify at changes */ - if (poweralg.charging_enable == chg_ctl) - return 0; - else - poweralg.charging_enable = chg_ctl; - } - else{ - /* poweralg.charging_enable = DISABLE; - v = DISABLE; - pr_info("[HTC_BATT] Unknow battery\n");*/ - if (poweralg.charging_enable == chg_ctl) - return 0; - else - poweralg.charging_enable = chg_ctl; - } - } - return blocking_notifier_call_chain(&ds2746_notifier_list, val, v); -} - - -int ds2746_get_battery_info(struct battery_info_reply *batt_info) -{ - batt_info->batt_id = poweralg.battery.id_index; /*Mbat ID*/ - batt_info->batt_vol = poweralg.battery.voltage_mV; /*VMbat*/ - batt_info->batt_temp = poweralg.battery.temp_01c; /*Temperature*/ - batt_info->batt_current = poweralg.battery.current_mA; /*Current*/ - batt_info->level = CEILING(poweralg.capacity_01p, 10); /*last_show%*/ - batt_info->charging_source = poweralg.charging_source; - batt_info->charging_enabled = poweralg.charging_enable; - batt_info->full_bat = poweralg.battery.charge_full_real_mAh; - return 0; -} -ssize_t htc_battery_show_attr(struct device_attribute *attr, char *buf) -{ - int len = 0; - pr_info("%s\n", __func__); - if (!strcmp(attr->attr.name, "batt_attr_text")){ - len += scnprintf(buf + - len, - PAGE_SIZE - - len, - "Percentage(%%): %d;\n" - "KADC(%%): %d;\n" - "RARC(%%): %d;\n" - "V_MBAT(mV): %d;\n" - "Main_battery_ID(Kohm): %d;\n" - "pd_M: %d;\n" - "Current(mA): %d;\n" - "Temp: %d;\n" - "Charging_source: %d;\n" - "ACR(mAh): %d;\n" - "FULL(mAh): %d;\n" - "1st_dis_percentage(%%): %d;\n" - "1st_dis_ACR: %d;\n", - CEILING(poweralg.capacity_01p, 10), - CEILING(poweralg.battery.KADC_01p, 10), - CEILING(poweralg.battery.RARC_01p, 10), - poweralg.battery.voltage_mV, - poweralg.battery.id_ohm, - poweralg.battery.pd_m, - poweralg.battery.current_mA, - CEILING(poweralg.battery.temp_01c, 10), - poweralg.charging_source, - poweralg.battery.charge_counter_mAh, - poweralg.battery.charge_full_real_mAh, - CEILING(poweralg.fst_discharge_capacity_01p, 10), - poweralg.fst_discharge_acr_mAh - ); - } - return len; -} - - -static int cable_status_handler_func(struct notifier_block *nfb, - unsigned long action, void *param) -{ - u32 cable_type = (u32) action; - pr_info("[ds2746_batt] cable change to %d\n", cable_type); - /* When the cable plug out, reset all the related flag, - Let algorithm machine to judge latest state */ - if (cable_type == 0){ - poweralg.is_cable_in = 0; - poweralg.is_china_ac_in = 0; - /*htc_batt_info.rep.OTP_Flag = 0; - htc_batt_info.rep.charging_sts_flag = 0; - htc_batt_info.full_charge_count = 0;*/ - } - else if (cable_type == 1){ - poweralg.is_cable_in = 1; - poweralg.is_china_ac_in = 0; - } - else if (cable_type == 2){ - poweralg.is_cable_in = 1; - poweralg.is_china_ac_in = 1; - } - else if (cable_type == 0xff){ - if (param) - config.full_level = *(INT32 *)param; - pr_info("[ds2746_batt] Set the full level to %d\n", config.full_level); - return NOTIFY_OK; - } - else if (cable_type == 0x10){ - poweralg.protect_flags.is_fake_room_temp = TRUE; - pr_info("[ds2746_batt] enable fake temp mode\n"); - return NOTIFY_OK; - } - - if (cable_type <= 2){ - poweralg.charging_source = cable_type; - ds2746_blocking_notify(DS2784_CHARGING_CONTROL, - &poweralg.charging_source); - } - return NOTIFY_OK; -} - -static struct notifier_block cable_status_handler = -{ - .notifier_call = cable_status_handler_func, -}; - -void ds2746_charger_control(int type) -{ - int chg_ctl = DISABLE; - int charge_type = type; - - switch (charge_type){ - case CHARGE_OFF: - /* CHARGER_EN is active low. Set to 1 to disable. */ - chg_ctl = DISABLE; - ds2746_blocking_notify(DS2784_CHARGING_CONTROL, &chg_ctl); - /*if (temp >= TEMP_CRITICAL) - pr_info("batt: charging OFF [OVERTEMP]\n"); - else if (htc_batt_info.rep.cooldown) - pr_info("batt: charging OFF [COOLDOWN]\n"); - else if (htc_batt_info.rep.battery_full) - pr_info("batt: charging OFF [FULL]\n"); - else*/ - pr_info("batt: charging OFF\n"); - break; - case CHARGE_SLOW: - chg_ctl = ENABLE_SLOW_CHG; - ds2746_blocking_notify(DS2784_CHARGING_CONTROL, &chg_ctl); - pr_info("batt: charging SLOW\n"); - break; - case CHARGE_FAST: - chg_ctl = ENABLE_FAST_CHG; - ds2746_blocking_notify(DS2784_CHARGING_CONTROL, &chg_ctl); - pr_info("batt: charging FAST\n"); - break; - } -} - -static void ds2746_program_alarm(struct ds2746_device_info *di, int seconds) -{ - ktime_t low_interval = ktime_set(seconds - 10, 0); - ktime_t slack = ktime_set(20, 0); - ktime_t next; - - next = ktime_add(di->last_poll, low_interval); - - alarm_start_range(&di->alarm, next, ktime_add(next, slack)); -} - -static void ds2746_battery_work(struct work_struct *work) -{ - if (!htc_battery_initial) return; - struct ds2746_device_info *di = container_of(work, - struct ds2746_device_info, monitor_work); - unsigned long flags; - - pr_info("[ds2746_batt] ds2746_battery_work*\n"); - do_power_alg(0); - get_state_check_interval_min_sec(); - di->last_poll = alarm_get_elapsed_realtime(); - - /* prevent suspend before starting the alarm */ - local_irq_save(flags); - - wake_unlock(&di->work_wake_lock); - if (poweralg.battery.is_power_on_reset) - ds2746_program_alarm(di, PREDIC_POLL); - else - ds2746_program_alarm(di, FAST_POLL); - - local_irq_restore(flags); -} - -static void ds2746_battery_alarm(struct alarm *alarm) -{ - if (!htc_battery_initial) return; - struct ds2746_device_info *di = container_of(alarm, struct ds2746_device_info, alarm); - wake_lock(&di->work_wake_lock); - queue_work(di->monitor_wqueue, &di->monitor_work); -} - -static int ds2746_battery_probe(struct platform_device *pdev) -{ - int rc; - struct ds2746_device_info *di; - struct ds2746_platform_data *pdata = pdev->dev.platform_data; - - pr_info("[ds2746_batt] ds2746_battery_prob\n"); - - poweralg.battery.thermal_id = pdata->func_get_thermal_id(); - - power_alg_preinit(); - power_alg_init(&debug_config); - - di = kzalloc(sizeof(*di), GFP_KERNEL); - if (!di){ - rc = -ENOMEM; - goto fail_register; - } - - di->update_time = jiffies; - platform_set_drvdata(pdev, di); - - di->dev = &pdev->dev; - - INIT_WORK(&di->monitor_work, ds2746_battery_work); - di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); - - /* init to something sane */ - di->last_poll = alarm_get_elapsed_realtime(); - - if (!di->monitor_wqueue){ - rc = -ESRCH; - goto fail_workqueue; - } - wake_lock_init(&di->work_wake_lock, WAKE_LOCK_SUSPEND, "ds2746-battery"); - alarm_init(&di->alarm, - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, - ds2746_battery_alarm); - wake_lock(&di->work_wake_lock); - queue_work(di->monitor_wqueue, &di->monitor_work); - htc_battery_initial = 1; - return 0; - - fail_workqueue : fail_register : kfree(di); - return rc; -} - - -static int ds2746_battery_remove(struct platform_device *pdev) -{ - struct ds2746_device_info *di = platform_get_drvdata(pdev); - - cancel_work_sync(&di->monitor_work); - destroy_workqueue(di->monitor_wqueue); - - return 0; -} - -/* FIXME: power down DQ master when not in use. */ -static int ds2746_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct ds2746_device_info *di = platform_get_drvdata(pdev); - unsigned long flags; - pr_info("ds2746_batt:ds2746_suspend\n"); - /* If we are on battery, reduce our update rate until - * we next resume.*/ - if (poweralg.charging_source == SOURCE_NONE){ - local_irq_save(flags); - ds2746_program_alarm(di, SLOW_POLL); - di->slow_poll = 1; - local_irq_restore(flags); - } - /*gpio_direction_output(87, 0);*/ - return 0; -} -static void ds2746_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct ds2746_device_info *di = platform_get_drvdata(pdev); - unsigned long flags; - - /* We might be on a slow sample cycle. If we're - * resuming we should resample the battery state - * if it's been over a minute since we last did - * so, and move back to sampling every minute until - * we suspend again.*/ - /*gpio_direction_output(87, 1);*/ - ndelay(100 * 1000); - pr_info("ds2746_batt:ds2746_resume\n"); - if (di->slow_poll){ - local_irq_save(flags); - ds2746_program_alarm(di, FAST_POLL); - di->slow_poll = 0; - local_irq_restore(flags); - } -} - -static struct dev_pm_ops ds2746_pm_ops = { - .prepare = ds2746_suspend, - .complete = ds2746_resume, -}; - -MODULE_ALIAS("platform:ds2746-battery"); -static struct platform_driver ds2746_battery_driver = -{ - .driver = { - .name = "ds2746-battery", - .pm = &ds2746_pm_ops, - }, - .probe = ds2746_battery_probe, - .remove = ds2746_battery_remove, -}; - -static int __init ds2746_battery_init(void) -{ - int ret; - - pr_info("[ds2746_batt]ds2746_battery_init"); - wake_lock_init(&vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present"); - register_notifier_cable_status(&cable_status_handler); - - ret = ds2746_i2c_init(); - if (ret < 0){ - return ret; - } - - /*mutex_init(&htc_batt_info.lock);*/ - return platform_driver_register(&ds2746_battery_driver); -} - -static void __exit ds2746_battery_exit(void) -{ - ds2746_i2c_exit(); - platform_driver_unregister(&ds2746_battery_driver); -} - -module_init(ds2746_battery_init); -module_exit(ds2746_battery_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Andy.YS Wang "); -MODULE_DESCRIPTION("ds2746 battery driver"); - diff --git a/drivers/power/ds2746_param.c b/drivers/power/ds2746_param.c deleted file mode 100644 index db462c66..00000000 --- a/drivers/power/ds2746_param.c +++ /dev/null @@ -1,852 +0,0 @@ -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Copyright (c) 2010 High Tech Computer Corporation - -Module Name: - - ds2784_param.c - -Abstract: - - This module implements the battery formula based on power spec, including below concepts: - 1. adc converter - 2. voltage mapping to capacity - 3. over temperature algorithm - 4. id range algorithm - 5. ACR maintainance - - Add from TPE PMA: - 1. temperature index - 2. pd_m_coef_boot - 3. preserved_capacity_by_temp - Remove from TAO PMA: - 1. pd_temp - - To adapt different PMA/projects, we need to modify below tables: - 1. ID_RANGE: which battery is used in the project? - 2. FL_25: the full capacity in temp 25C. - 3. pd_m_bias_mA: the discharge current threshold to calculating pd_m - 4. M_PARAMTER_TABLE: the voltage-capacity mapping table - 5. TEMP_RANGE: how many temp condition we need to consider - 6. PD_M_COEF_TABLE(BOOT)/PD_M_RESL_TABLE(BOOT): voltage compensation based on current - 7. PD_T_COEF: voltage compensation based on temp - 8. CAPACITY_DEDUCTION_01p: the capacity deduction due to low temperature - -Original Auther: - - Andy.ys Wang June-01-2010 - ----------------------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include -#include - -/*======================================================================================== - -build flags - -========================================================================================*/ - -#define HTC_ENABLE_POWER_DEBUG 0 -#define HTC_ENABLE_DUMMY_BATTERY 0 - -/*======================================================================================== - -battery common parameter defines (independent on battery id yet...) - -========================================================================================*/ - -#define BATTERY_VOLTAGE_MIN 2000 -#define BATTERY_VOLTAGE_MAX 20000 - -/*======================================================================================== - -battery parameter helper functions - -========================================================================================*/ - -static INT32 get_id_index(struct battery_type *battery) -{ - int i; - - for (i = 0; i < BATTERY_ID_NUM - 1; i++) { - /* minus 1, unknown battery is not in ID_RANGE - [min, max)*/ - UINT32 resister_min = ID_RANGE[i*2]; - UINT32 resister_max = ID_RANGE[i*2 + 1]; - - if (resister_min <= battery->id_ohm && resister_max > battery->id_ohm) { - return i + 1; - } - } - - return BATTERY_ID_UNKNOWN; -} - -static INT32 get_temp_index(struct battery_type *battery) -{ - int i; - - for (i = 0; i < 255; i++) { - /* the table size shall not be greater then 255, to ensure no infinite looping - [min, max)*/ - INT32 temp = TEMP_RANGE[i]; - if (battery->temp_01c >= temp) - return i; - } - - printk(DRIVER_ZONE " invalid batt_temp (%d) or temp range mapping.\n", battery->temp_01c); - return -1; -} - -/*======================================================================================== - -temperature formula definitions - -========================================================================================*/ - -static INT32 get_temp_01c(struct battery_type *battery) -{ - int current_index = battery->temp_check_index; - int search_direction = 0; - - if (battery->last_temp_adc > battery->temp_adc) { - search_direction = -1; - } else { - search_direction = 1; - } - - while (current_index >= 0 && current_index < TEMP_NUM-1) { - - UINT32 temp_min = TEMP_MAP[current_index]; - UINT32 temp_max = TEMP_MAP[current_index + 1]; - - if (temp_max > battery->temp_adc && temp_min <= battery->temp_adc) { - battery->temp_check_index = current_index; - battery->last_temp_adc = battery->temp_adc; - return (TEMP_MAX-current_index)*10; - } - current_index += search_direction; - } - - return (TEMP_MIN-1)*10; -} - -/*======================================================================================== - -over temperature protection - -========================================================================================*/ - -static BOOL is_over_temp(struct battery_type *battery) -{ - /* stop charging*/ - if (battery->temp_01c < over_low_temp_lock_01c || battery->temp_01c >= over_high_temp_lock_01c) { - return TRUE; - } - - return FALSE; -} - -static BOOL is_not_over_temp(struct battery_type *battery) -{ - /* start charging*/ - if (battery->temp_01c >= over_low_temp_release_01c && - battery->temp_01c < over_high_temp_release_01c) { - return TRUE; - } - - return FALSE; -} - -static void __protect_flags_update(struct battery_type *battery, - struct protect_flags_type *flags) -{ - /* Flags: - is_charging_enable_available - Over temperature, need to stop charging - is_charging_high_current_avaialble - Temperature is too high so that we have to slow charge*/ - - if (is_over_temp(battery)) { - /* Ex: T<0 or T>45 */ - flags->is_charging_enable_available = FALSE; - flags->is_charging_high_current_avaialble = FALSE; -#if 0 - flags->is_battery_overtemp = TRUE; -#endif - } else if (is_not_over_temp(battery)) { - /* Ex: T<42 or T>3*/ - flags->is_charging_enable_available = TRUE; - flags->is_charging_high_current_avaialble = TRUE; -#if 0 - flags->is_battery_overtemp = FALSE; -#endif - } - - /* Flags: - is_battery_dead - If battery is dead, show special indicator for it*/ - if (battery->voltage_mV < BATTERY_DEAD_VOLTAGE_LEVEL) { - flags->is_battery_dead = TRUE; - } - else if (battery->voltage_mV > BATTERY_DEAD_VOLTAGE_RELEASE) { - flags->is_battery_dead = FALSE; - } -} - -/*======================================================================================== - -Voltage-Percentage mapping - -========================================================================================*/ - -/*------------------------------------------------------------------------ - Example: - p0 = (4200, 10000); 4.2V for 100% - p1 = (3900, 8000); 3.9V for 80% - p2 = (3700, 2000); 3.7V for 20% - p3 = (3300, 0); 3.3V for 0% - - if V = 4000, (3900<4000<4200) - P = (4000-3900) * (10000-8000)/(4200-3900) + 8000 = 8666*/ - -#define NUM_SAMPLED_POINTS_MAX 12 - -struct sampled_point_type { - - DWORD voltage; - DWORD capacity; -}; - -struct voltage_curve_translator { - - DWORD voltage_min; - DWORD voltage_max; - DWORD capacity_min; - DWORD capacity_max; - int sampled_point_count; - struct sampled_point_type sampled_points[NUM_SAMPLED_POINTS_MAX]; -}; - -static void voltage_curve_translator_init(struct voltage_curve_translator *t) -{ - memset(t, 0, sizeof(*t)); -} - -static void voltage_curve_translator_add(struct voltage_curve_translator *t, DWORD voltage, DWORD capacity) -{ - struct sampled_point_type *pt; - - if (t->sampled_point_count >= NUM_SAMPLED_POINTS_MAX) { - return; - } - - t->sampled_points[t->sampled_point_count].voltage = voltage; - t->sampled_points[t->sampled_point_count].capacity = capacity; - pt = &t->sampled_points[t->sampled_point_count]; - - t->sampled_point_count++; - - if (pt->voltage > t->voltage_max) - t->voltage_max = pt->voltage; - if (pt->voltage < t->voltage_min) - t->voltage_min = pt->voltage; - if (pt->capacity > t->capacity_max) - t->capacity_max = pt->capacity; - if (pt->capacity < t->capacity_min) - t->capacity_min = pt->capacity; - -#if HTC_ENABLE_POWER_DEBUG - printk(DRIVER_ZONE " kadc t: capacity=%d voltage=%d\n", capacity, voltage); -#endif /* HTC_ENABLE_POWER_DEBUG*/ -} - -static INT32 voltage_curve_translator_get(struct voltage_curve_translator *t, DWORD voltage) -{ - struct sampled_point_type *p0, *p1; - INT32 capacity; - int i; - - if (voltage > t->voltage_max) - voltage = t->voltage_max; - if (voltage < t->voltage_min) - voltage = t->voltage_min; - - p0 = &t->sampled_points[0]; - p1 = p0 + 1; - for (i = 0; i < t->sampled_point_count - 1 && voltage < p1->voltage; i++) { - p0++; - p1++; - } - - /* DIV ZERO check*/ - if (p0->voltage - p1->voltage == 0) { - return 0; - } - - /* INT32 overflow check: mv(4200) * capacity(10000), shall be no problem at all...*/ - capacity = (voltage - p1->voltage) * (p0->capacity - p1->capacity) / (p0->voltage - p1->voltage) + p1->capacity; - if (capacity > t->capacity_max) { - capacity = t->capacity_max; - } - if (capacity < t->capacity_min) { - capacity = t->capacity_min; - } - return capacity; -} - -/*======================================================================================== - -KADC mapping functions - -========================================================================================*/ - -static struct voltage_curve_translator __get_kadc_t; - -static INT32 get_kadc_001p(struct battery_type *battery) -{ - INT32 pd_m = 0; - INT32 pd_temp = 0; - - INT32 temp_01c = battery->temp_01c; - INT32 current_mA = battery->current_mA; - - UINT32 *m_paramtable; - - INT32 pd_m_coef; - INT32 pd_m_resl; - - INT32 capacity_deduction_01p = CAPACITY_DEDUCTION_01p[battery->temp_index]; - INT32 capacity_predict_001p; - /* 1. INT32 overflow check: assert abs(iChgCurrent_ma) <= 3000, iBattTemp_01c>-250, pd_t_coef <= 1000 - when calculating pd_temp: 0x7FFFFFFF / (500 * 3000 * 1000) =:= 1.4*/ - - if (battery->current_mA > 3000) - current_mA = 3000; - else if (battery->current_mA < -3000) - current_mA = -3000; - if (battery->temp_01c <= -250) - temp_01c = -250; - - /* 2. calculate pd_m and pd_temp*/ - - if (battery->is_power_on_reset) { - pd_m_coef = PD_M_COEF_TABLE_BOOT[battery->temp_index][battery->id_index]; - pd_m_resl = PD_M_RESL_TABLE_BOOT[battery->temp_index][battery->id_index]; - } - else{ - pd_m_coef = PD_M_COEF_TABLE[battery->temp_index][battery->id_index]; - pd_m_resl = PD_M_RESL_TABLE[battery->temp_index][battery->id_index]; - } - - if (battery->current_mA < -pd_m_bias_mA) { - /* ex: -150mA < -130mA*/ - pd_m = (abs(battery->current_mA) - pd_m_bias_mA) * pd_m_coef /pd_m_resl; - } - - if (battery->temp_01c < 250) { - pd_temp = ((250 - battery->temp_01c) * (abs(battery->current_mA) * PD_T_COEF[battery->id_index])) / (10 * 10000); - } - battery->pd_m = pd_m; - - /* 3. calculate KADC using M_PARAMTER_TABLE*/ - - m_paramtable = M_PARAMTER_TABLE[battery->id_index]; - if (m_paramtable) { - int i = 0; /* assume that m_paramtable has at least 2 items...the last capacity item must be 0 to end the loop...*/ - - voltage_curve_translator_init(&__get_kadc_t); - - while (1) { - INT32 capacity = m_paramtable[i]; - INT32 voltage = m_paramtable[i + 1]; - if (capacity == 10000) { - /* full capacity, no need to fix voltage level*/ - voltage_curve_translator_add(&__get_kadc_t, voltage, capacity); - } - else { - voltage_curve_translator_add(&__get_kadc_t, voltage - pd_temp, capacity); - } - - if (capacity == 0) - break; - - i += 2; - } - -#if HTC_ENABLE_POWER_DEBUG - printk(DRIVER_ZONE " pd_m=%d, pd_temp=%d\n", pd_m, pd_temp); -#endif /* HTC_ENABLE_POWER_DEBUG*/ - - capacity_predict_001p = voltage_curve_translator_get(&__get_kadc_t, battery->voltage_mV + pd_m); - } - else{ - capacity_predict_001p = (battery->voltage_mV - 3400) * 10000 / (4200 - 3400); - } - - return (capacity_predict_001p - capacity_deduction_01p * 10) * 10000 / (10000 - capacity_deduction_01p * 10); -} - -/*======================================================================================== - -coulomb counter+curve tracer - -========================================================================================*/ - -static INT32 get_software_acr_revise(struct battery_type *battery, UINT32 ms) -{ - INT32 kadc_01p = battery->KADC_01p; - INT32 ccbi_01p = battery->RARC_01p; - INT32 delta_01p = kadc_01p - ccbi_01p; - - DWORD C = 5; /* KADC = 15%~100%*/ - if (kadc_01p <= 150) { - C = 5; - } /* KADC = 0%~15%*/ - - if (delta_01p < 0) { - /* if KADC is less than RARC, p shall be lower*/ - return -(INT32) (C * ms * delta_01p * delta_01p) / 1000; - } - else{ - /* if KADC is larger than RARC, p shall be higher*/ - return (INT32) (C * ms * delta_01p * delta_01p) / 1000; - } -} - -/*======================================================================================== - -ds2746 gauge ic functions, to access ds2746 registers and convert ADC to battery param - -========================================================================================*/ - -static void __ds2746_clear_porf(void) -{ - UINT8 reg_data; - if (!ds2746_i2c_read_u8(®_data, 0x01)) { - printk(DRIVER_ZONE " clear porf error in read.\n"); - return; - } - - if (!ds2746_i2c_write_u8((reg_data & (~DS2746_STATUS_PORF)), 0x01)) { - printk(DRIVER_ZONE " clear porf error in write.\n"); - return; - } -} - -static void __ds2746_acr_update(struct battery_type *battery, int capacity_01p) -{ - printk(DRIVER_ZONE " acr update: P=%d, C=%d.\n", - capacity_01p, - battery->charge_counter_adc); - - ds2746_i2c_write_u8((battery->charge_counter_adc & 0xFF00) >> 8, 0x10); - ds2746_i2c_write_u8((battery->charge_counter_adc & 0x00FF), 0x11); - - if (battery->is_power_on_reset) { - __ds2746_clear_porf(); - } -} - -static void __ds2746_init_config(struct battery_type *battery) -{ - UINT8 reg_data; - - if (!ds2746_i2c_read_u8(®_data, 0x01)) { - printk(DRIVER_ZONE " init config error in read.\n"); - return; - } - - /* Erase SMOD and NBEN value in DS2746 status/config register*/ - reg_data &= ~(DS2746_STATUS_SMOD | DS2746_STATUS_NBEN); - if (!ds2746_i2c_write_u8(reg_data, 0x01)) { - printk(DRIVER_ZONE " init config error in write.\n"); - return; - } -} - -static BOOL __ds2746_get_reg_data(UINT8 *reg) -{ - memset(reg, 0, 12); - - if (!ds2746_i2c_read_u8(®[0], 0x01)) - return FALSE; - if (!ds2746_i2c_read_u8(®[2], 0x08)) - return FALSE; - if (!ds2746_i2c_read_u8(®[3], 0x09)) - return FALSE; - if (!ds2746_i2c_read_u8(®[4], 0x0a)) - return FALSE; - if (!ds2746_i2c_read_u8(®[5], 0x0b)) - return FALSE; - if (!ds2746_i2c_read_u8(®[6], 0x0c)) - return FALSE; - if (!ds2746_i2c_read_u8(®[7], 0x0d)) - return FALSE; - if (!ds2746_i2c_read_u8(®[8], 0x0e)) - return FALSE; - if (!ds2746_i2c_read_u8(®[9], 0x0f)) - return FALSE; - if (!ds2746_i2c_read_u8(®[10], 0x10)) - return FALSE; - if (!ds2746_i2c_read_u8(®[11], 0x11)) - return FALSE; - - return TRUE; -} - -static BOOL __ds2746_battery_adc_udpate(struct battery_type *battery) -{ - UINT8 reg[12]; - - if (!__ds2746_get_reg_data((UINT8 *) ®)) { - printk(DRIVER_ZONE " get ds2746 data failed...\n"); - return FALSE; - } - - printk(DRIVER_ZONE " [x0]%x [x8]%x %x %x %x %x %x %x %x %x %x\n", - reg[0], - reg[2], - reg[3], - reg[4], - reg[5], - reg[6], - reg[7], - reg[8], - reg[9], - reg[10], - reg[11]); - - if (!(reg[0] & DS2746_STATUS_AIN0) || !(reg[0] & DS2746_STATUS_AIN1)) { - printk(DRIVER_ZONE " AIN not ready...\n"); - return FALSE; - } - - if (reg[0] & DS2746_STATUS_PORF) { - battery->is_power_on_reset = TRUE; - } - else{ - battery->is_power_on_reset = FALSE; - } - - /* adc register value*/ - battery->voltage_adc = MAKEWORD(reg[7], reg[6]) >> 4; - battery->current_adc = MAKEWORD(reg[9], reg[8]); - if (battery->current_adc & 0x8000) { - battery->current_adc = -(0x10000 - battery->current_adc); - } - battery->current_adc /= 4; - battery->charge_counter_adc = MAKEWORD(reg[11], reg[10]); - if (battery->charge_counter_adc & 0x8000) { - battery->charge_counter_adc = -(0x10000 - battery->charge_counter_adc); - } - battery->id_adc = MAKEWORD(reg[5], reg[4]) >> 4; - battery->temp_adc = MAKEWORD(reg[3], reg[2]) >> 4; - if (support_ds2746_gauge_ic) { - /* we preserve 500mAh for capacity lower than 0%, however the 500mAh is still drained out...we need to do predict for correct ACR*/ - if ((battery->charge_counter_adc & 0xFFFF) >= 0xF000){ - printk(DRIVER_ZONE " ACR out of range (x%x)...\n", - battery->charge_counter_adc); - battery->is_power_on_reset = TRUE; - } - } - - return TRUE; -} - -/*======================================================================================== - -softwar acr functions, to accumulate ACR by software and revise by battery parameter - -========================================================================================*/ - -static void __software_charge_counter_update(struct battery_type *battery, UINT32 ms) -{ - /* if the charge counter is maintained by sw, batt_alg shall use this routine to update charge counter and related parameters*/ - INT32 capacity_deduction_01p = CAPACITY_DEDUCTION_01p[battery->temp_index]; - /* AEL(mAh): A low temp unusable battery capacity, calculated in runtime*/ - INT32 ael_mAh = capacity_deduction_01p *battery->charge_full_real_mAh / 1000; -#if HTC_ENABLE_POWER_DEBUG - printk(DRIVER_ZONE "chgctr update: I=%d ms=%d.\n", battery->current_mA, ms); -#endif /* HTC_ENABLE_POWER_DEBUG*/ - - /* ACRt(mAh): The total capacity battery owns, stored in battery->charge_counter_mAh*/ - battery->software_charge_counter_mAms += (INT32) (battery->current_mA * ms); - battery->charge_counter_mAh += (battery->software_charge_counter_mAms / 3600000); - battery->software_charge_counter_mAms -= (battery->software_charge_counter_mAms / 3600000) * 3600000; - - /* CCBI(0.1%): A software RARC*/ - battery->RARC_01p = (battery->charge_counter_mAh - ael_mAh) * 1000 / (battery->charge_full_real_mAh - ael_mAh); - /* store back the battery->charge_counter_mAh to battery->charge_counter_adc*/ - battery->charge_counter_adc = (battery->charge_counter_mAh + charge_counter_zero_base_mAh) * acr_adc_to_mv_coef / acr_adc_to_mv_resl; -} - -static void __software_charge_counter_revise(struct battery_type *battery, UINT32 ms) -{ - if (battery->current_mA < 0) { -#if HTC_ENABLE_POWER_DEBUG - printk(DRIVER_ZONE "chgctr revise: delta=%d.\n", get_software_acr_revise(battery, ms)); -#endif /* HTC_ENABLE_POWER_DEBUG*/ - - /* revise software charge counter by coulomb counter+curve tracer*/ - battery->software_charge_counter_mAms += get_software_acr_revise(battery, ms); - battery->charge_counter_mAh += (battery->software_charge_counter_mAms / 3600000); - battery->software_charge_counter_mAms -= (battery->software_charge_counter_mAms / 3600000) * 3600000; - /* store back the battery->charge_counter_mAh to battery->charge_counter_adc*/ - battery->charge_counter_adc = (battery->charge_counter_mAh + charge_counter_zero_base_mAh) * acr_adc_to_mv_coef / acr_adc_to_mv_resl; - } -} - -static void __software_acr_update(struct battery_type *battery) -{ - static BOOL s_bFirstEntry = TRUE; - static DWORD last_time_ms; - DWORD now_time_ms = BAHW_MyGetMSecs(); - - if (s_bFirstEntry) { - s_bFirstEntry = FALSE; - last_time_ms = now_time_ms; - } - -#if HTC_ENABLE_POWER_DEBUG - printk(DRIVER_ZONE "+acr update: adc=%d C=%d mams=%d.\n", - battery->charge_counter_adc, - battery->charge_counter_mAh, - battery->software_charge_counter_mAms); -#endif /* HTC_ENABLE_POWER_DEBUG*/ - - __software_charge_counter_update(battery, now_time_ms - last_time_ms); - __software_charge_counter_revise(battery, now_time_ms - last_time_ms); - -#if HTC_ENABLE_POWER_DEBUG - printk(DRIVER_ZONE "-acr update: adc=%d C=%d mams=%d.\n", - battery->charge_counter_adc, - battery->charge_counter_mAh, - battery->software_charge_counter_mAms); -#endif /* HTC_ENABLE_POWER_DEBUG*/ - - last_time_ms = now_time_ms; -} - -/*======================================================================================== - -battery param update, the coef are referenced from power spec - -========================================================================================*/ - -static BOOL __battery_param_udpate(struct battery_type *battery) -{ - static int batt_id_stable_counter = 0; - INT32 batt_id_index; - INT32 temp_01c; - - if (support_ds2746_gauge_ic) { - /* adc register value are read from __ds2746_battery_adc_udpate()*/ - if (!__ds2746_battery_adc_udpate(battery)) - return FALSE; - } - else{ - /* adc register value are read from BAHW_get_batt_info_all() - if ( !BAHW_get_batt_info_all(battery) ) return FALSE;*/ - } - - /*real physical value*/ - battery->voltage_mV = (battery->voltage_adc * voltage_adc_to_mv_coef / voltage_adc_to_mv_resl); - battery->current_mA = (battery->current_adc * current_adc_to_mv_coef / current_adc_to_mv_resl); - battery->discharge_mA = (battery->discharge_adc * discharge_adc_to_mv_coef / discharge_adc_to_mv_resl); - battery->charge_counter_mAh = (battery->charge_counter_adc * acr_adc_to_mv_coef / acr_adc_to_mv_resl) - charge_counter_zero_base_mAh; - battery->current_mA = battery->current_mA - battery->discharge_mA; - /* prevent from adc out of range*/ - if (battery->id_adc >= id_adc_resl) { - battery->id_adc = id_adc_resl - 1; - } - if (battery->id_adc <= 0) { - battery->id_adc = 1; - } - if (battery->temp_adc >= temp_adc_resl) { - battery->temp_adc = temp_adc_resl - 1; - } - if (battery->temp_adc <= 0) { - battery->temp_adc = 1; - } - - /* battery ID shall be ready first for temp/kadc calculation*/ - // if ( id_conversion ) battery->id_ohm = ((float)id_R_kohm / ((float)id_adc_resl/battery->id_adc - 1)) * 1000; // kohm -> ohm - // else battery->id_ohm = battery->id_adc; - battery->id_ohm = battery->id_adc; - calibrate_id_ohm(battery); - - batt_id_index = get_id_index(battery); - - if (is_allow_batt_id_change) { - /*! TODO: batt_id changes immediately; may need to modify in future*/ - if (batt_id_stable_counter >= 3 && batt_id_index != battery->id_index){ - /* if batt_id is stable but is different from previous one*/ - batt_id_stable_counter = 0; /* reset stable counter and set batt_id to new one*/ - } - } - - if (batt_id_stable_counter < 3) { - if (batt_id_stable_counter == 0) { - /* first time to get the batt id*/ - battery->id_index = batt_id_index; - battery->charge_full_design_mAh = FL_25[battery->id_index]; - battery->charge_full_real_mAh = battery->charge_full_design_mAh; - batt_id_stable_counter = 1; - } - else{ - /* 2nd and further time to get the batt id*/ - if (batt_id_index == battery->id_index) - batt_id_stable_counter++; - else - batt_id_stable_counter = 0; - } - } - - /* calculate temperature*/ - // battery->temp_01c = get_temp_c((float)temp_R_kohm / ((float)temp_adc_resl/battery->temp_adc - 1))*10; - temp_01c = get_temp_01c(battery); - if (temp_01c >= TEMP_MIN*10) - battery->temp_01c = temp_01c; - else - printk(DRIVER_ZONE " get temp_01c(%d) failed...\n", temp_01c); - battery->temp_index = get_temp_index(battery); - - /* calculate KADC and RARC*/ - battery->KADC_01p = CEILING(get_kadc_001p(battery), 10); - battery->RARC_01p = CEILING(10000 * battery->charge_counter_mAh / battery->charge_full_real_mAh, 10); - if (!support_ds2746_gauge_ic) { - __software_acr_update(battery); - } - - if (battery->voltage_mV voltage_mV> BATTERY_VOLTAGE_MAX) { - printk(DRIVER_ZONE " invalid V(%d).\n", battery->voltage_mV); - return FALSE; - } - - /*! star_lee 20100426 - minimum RARC is 0%*/ - if (battery->RARC_01p <= 0) { - battery->RARC_01p = 0; - } - - printk(DRIVER_ZONE " V=%d(%x) I=%d(%x) C=%d.%d/%d(%x) id=%d(%x) T=%d(%x) KADC=%d\n", - battery->voltage_mV, - battery->voltage_adc, - battery->current_mA, - battery->current_adc, - battery->charge_counter_mAh, - battery->software_charge_counter_mAms, - battery->charge_full_real_mAh, - battery->charge_counter_adc, - battery->id_index, - battery->id_adc, - battery->temp_01c, - battery->temp_adc, - battery->KADC_01p); - - return TRUE; -} - -/*======================================================================================== - -time functions - -========================================================================================*/ - -DWORD BAHW_MyGetMSecs(void) -{ - struct timespec now; - getnstimeofday(&now); - /*struct timespec t; - t.tv_sec = t.tv_nsec = 0; - clock_gettime(CLOCK_MONOTONIC, &t);*/ - return now.tv_sec * 1000 + now.tv_nsec / 1000000; -} - -/*======================================================================================== - -battery param public function - -========================================================================================*/ - -void battery_capacity_update(struct battery_type *battery, int capacity_01p) -{ - - /* ACR 500~500+FULL mapping to capacity 0~FULL*/ - battery->charge_counter_mAh = capacity_01p * battery->charge_full_real_mAh / 1000; - battery->charge_counter_adc = (battery->charge_counter_mAh + charge_counter_zero_base_mAh) * acr_adc_to_mv_resl / acr_adc_to_mv_coef; - battery->RARC_01p = capacity_01p; - if (support_ds2746_gauge_ic) { - __ds2746_acr_update(battery, capacity_01p); - } - - printk(DRIVER_ZONE "new RARC=%d C=%dmAh adc=%d.\n", - battery->RARC_01p, - battery->charge_counter_mAh, - battery->charge_counter_adc); - battery->is_power_on_reset = FALSE; -} - -BOOL battery_param_update(struct battery_type *battery, struct protect_flags_type *flags) -{ - if (!__battery_param_udpate(battery)) { - return FALSE; - } - - if (flags->is_fake_room_temp) { - battery->temp_01c = 250; - printk(DRIVER_ZONE "fake temp=%d(%x)\n", - battery->temp_01c, - battery->temp_adc); - } - __protect_flags_update(battery, flags); - -#if ! HTC_ENABLE_DUMMY_BATTERY - if (battery->id_index == BATTERY_ID_UNKNOWN) { - flags->is_charging_enable_available = FALSE; - } -#else /* HTC_ENABLE_DUMMY_BATTERY*/ - /* do not disable charging for debug stage*/ - flags->is_charging_enable_available = TRUE; -#endif /* HTC_ENABLE_DUMMY_BATTERY*/ - - return TRUE; -} - -void battery_param_init(struct battery_type *battery) -{ - /* set battery id to unknown to get battery id and related characters*/ - battery->id_index = BATTERY_ID_UNKNOWN; - - /* default to 25C unless we can get valid battery temp from adc*/ - battery->temp_01c = 250; - battery->last_temp_01c = battery->temp_01c; - battery->temp_check_index = 0; - battery->last_temp_adc = 0; - - battery->voltage_mV = 3800; - - /* this is used when accumulate current by software; initial it as 0mAs*/ - battery->software_charge_counter_mAms = 0; - - /* set POR at first by software; gauge ic will has correct value*/ - battery->is_power_on_reset = TRUE; - - if (support_ds2746_gauge_ic) { - __ds2746_init_config(battery); - } - - if (battery->thermal_id == THERMAL_1000) { - TEMP_MAP = TEMP_MAP_1000K; - printk(DRIVER_ZONE "Use 1000 Kohm thermal resistance"); - } else { - printk(DRIVER_ZONE "Use default(300 Kohm) thermal resistance"); - } - - /*printk(DRIVER_ZONE "battery param inited with board name <%s>\n", HTC_BATT_BOARD_NAME);*/ -} - diff --git a/include/linux/ds2746_battery.h b/include/linux/ds2746_battery.h deleted file mode 100644 index d8930f52..00000000 --- a/include/linux/ds2746_battery.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2007 HTC Incorporated - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - */ -#ifndef _DS2746_BATTERY_H_ -#define _DS2746_BATTERY_H_ -#include -#include -#include -#include - -enum ds2784_notify_evt_t { - DS2784_CHARGING_CONTROL = 0, - DS2784_LEVEL_UPDATE, - DS2784_BATTERY_FAULT, - DS2784_OVER_TEMP, - DS2784_NUM_EVENTS, -}; - -/* battery charging state*/ - -enum { - CHARGE_STATE_UNKNOWN, /* before anything is ready, we are in this state. shall default low current charge and show charging LED*/ - CHARGE_STATE_PREDICTION, /* in normal case, we need to enter prediction for 10 seconds for 1st KADC*/ - CHARGE_STATE_DISCHARGE, /* cable out state*/ - CHARGE_STATE_CHARGING, /* charging state*/ - CHARGE_STATE_PENDING, /* charging state but no good*/ - CHARGE_STATE_FULL_WAIT_STABLE, /* charging state but going full*/ - CHARGE_STATE_FULL_CHARGING, /* charging full, keep charging*/ - CHARGE_STATE_FULL_PENDING, /* charging full, stop charging*/ -}; - -enum { - THERMAL_300, - THERMAL_600, - THERMAL_1000, -}; - -/* power algorithm data structure and config data structure*/ - -struct poweralg_type -{ - int charge_state; - int capacity_01p; - int last_capacity_01p; - int fst_discharge_capacity_01p; - int fst_discharge_acr_mAh; - int charging_source; - int charging_enable; - BOOL is_need_calibrate_at_49p; - BOOL is_need_calibrate_at_14p; - BOOL is_charge_over_load; - struct battery_type battery; - struct protect_flags_type protect_flags; - BOOL is_china_ac_in; - BOOL is_cable_in; - BOOL is_voltage_stable; - BOOL is_software_charger_timeout; - UINT32 state_start_time_ms; -}; - -struct poweralg_config_type -{ - INT32 full_charging_mv; - INT32 full_charging_ma; - INT32 full_pending_ma; /* 0 to disable*/ - INT32 full_charging_timeout_sec; /* 0 to disable*/ - INT32 voltage_recharge_mv; /* 0 to disable*/ - INT32 capacity_recharge_p; /* 0 to disable*/ - INT32 voltage_exit_full_mv; /* 0 to disable*/ - INT32 wait_votlage_statble_sec; - INT32 predict_timeout_sec; - INT32 polling_time_in_charging_sec; - INT32 polling_time_in_discharging_sec; - - BOOL enable_full_calibration; - BOOL enable_weight_percentage; - INT32 software_charger_timeout_sec; /* 0 to disable*/ - - BOOL debug_disable_shutdown; - BOOL debug_fake_room_temp; - BOOL debug_disable_hw_timer; - BOOL debug_always_predict; - INT32 full_level; /* 0 to disable*/ -}; - -struct ds2746_platform_data { - int (*func_get_thermal_id)(void); -}; - -/* battery behavior constant*/ - -#define BATTERY_PERCENTAGE_UNKNOWN 0xFF -#define BATTERY_LOW_PERCENTAGE 10 /* in 1%*/ -#define BATTERY_CRITICAL_PERCENTAGE 5 /* in 1%*/ -#define BATTERY_EMPTY_PERCENTAGE 0 /* in 1%*/ - -/* battery algorithm public functions*/ - -int get_state_check_interval_min_sec( void); -BOOL do_power_alg( BOOL is_event_triggered); -void power_alg_init( struct poweralg_config_type *debug_config); -void power_alg_preinit( void); -int ds2746_blocking_notify( unsigned long val, void *v); -void ds2746_charger_control( int type); -int ds2746_i2c_write_u8( u8 value, u8 reg); -int ds2746_i2c_read_u8( u8* value, u8 reg); -void calibrate_id_ohm( struct battery_type *battery); -/* external function implemented by upper layer*/ - -/*extern void powerlog_to_file(struct poweralg_type* poweralg);*/ -/*extern void update_os_batt_status(struct poweralg_type* poweralg);*/ - -#ifdef CONFIG_BATTERY_DS2746 -extern int ds2746_register_notifier( struct notifier_block *nb); -extern int ds2746_unregister_notifier( struct notifier_block *nb); -extern int ds2746_get_battery_info( struct battery_info_reply *batt_info); -extern ssize_t htc_battery_show_attr( struct device_attribute *attr, char *buf); -#else -static int ds2746_register_notifier( struct notifier_block *nb) { - - return 0; -} -static int ds2746_unregister_notifier( struct notifier_block *nb) { - - return 0; -} -static int ds2746_get_battery_info( struct battery_info_reply *batt_info) { - - batt_info->level = 10; - return 0; -} -extern ssize_t htc_battery_show_attr( struct device_attribute *attr, char *buf) { - - return 0; -} - -#endif - -#endif diff --git a/include/linux/ds2746_battery_config.h b/include/linux/ds2746_battery_config.h deleted file mode 100644 index 2195d450..00000000 --- a/include/linux/ds2746_battery_config.h +++ /dev/null @@ -1,44 +0,0 @@ -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Copyright (c) 2010 High Tech Computer Corporation - -Module Name: - - batt_alg_config.c -Abstract: - - This module tells batt_alg.c module how to config power alg. - -Original Auther: - - Star Lee (star_lee) Apr-12-2010 - ----------------------------------------------------------------------------------*/ - -#define HTC_BATT_BOARD_NAME "ACE" - -static void poweralg_config_init(struct poweralg_config_type *config) -{ - config->full_charging_mv = 4110; - config->full_charging_ma = 50; - config->full_pending_ma = 0; /* disabled*/ - config->full_charging_timeout_sec = 60 * 60; - config->voltage_recharge_mv = 4150; - config->capacity_recharge_p = 0; /* disabled*/ - config->voltage_exit_full_mv = 4100; - config->wait_votlage_statble_sec = 1 * 60; - config->predict_timeout_sec = 10; - config->polling_time_in_charging_sec = 30; - config->polling_time_in_discharging_sec = 30; - - config->enable_full_calibration = TRUE; - config->enable_weight_percentage = TRUE; - config->software_charger_timeout_sec = 0; /* disabled*/ - - config->debug_disable_shutdown = FALSE; - config->debug_fake_room_temp = FALSE; - config->debug_disable_hw_timer = FALSE; - config->debug_always_predict = FALSE; - config->full_level = 0; -} - diff --git a/include/linux/ds2746_param.h b/include/linux/ds2746_param.h deleted file mode 100644 index 49733165..00000000 --- a/include/linux/ds2746_param.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef __BATT_PARAM_H__ -#define __BATT_PARAM_H__ - -/* battery status and charging information*/ - -struct battery_type{ - - BOOL is_power_on_reset; - - INT32 voltage_mV; - INT32 current_mA; - INT32 discharge_mA; - INT32 charge_counter_mAh; - INT32 temp_01c; - INT32 last_temp_01c; - INT32 id_ohm; - INT32 vref_mv; - - INT32 voltage_adc; - INT32 current_adc; - INT32 discharge_adc; - INT32 charge_counter_adc; - INT32 temp_adc; - INT32 last_temp_adc; - INT32 id_adc; - INT32 vref_adc; - - INT32 id_index; - INT32 charge_full_design_mAh; - INT32 charge_full_real_mAh; - - INT32 temp_index; - INT32 temp_check_index; - - INT32 KADC_01p; - INT32 RARC_01p; - INT32 pd_m; - - INT32 software_charge_counter_mAms; - INT32 thermal_id; -}; - -struct protect_flags_type{ - - BOOL is_charging_enable_available; - BOOL is_charging_high_current_avaialble; - BOOL is_charging_indicator_available; - BOOL is_battery_dead; -#if 0 - BOOL is_battery_overtemp; -#endif - BOOL is_fake_room_temp; -}; - -/* ds2746 register definition*/ - -#define DS2746_STATUS_PORF (1 << 6) /* write to 0 as power-up sequence ready*/ -#define DS2746_STATUS_SMOD (1 << 5) /* write to 0 to disable DS2746 sleep mode*/ -#define DS2746_STATUS_NBEN (1 << 4) /* write to 0 to disable blanking of negative currents*/ -#define DS2746_STATUS_AIN0 (1 << 0) -#define DS2746_STATUS_AIN1 (1 << 1) - -/* function prototypes*/ - -void battery_capacity_update(struct battery_type *battery, int capacity_01p); -BOOL battery_param_update(struct battery_type *battery, struct protect_flags_type *flags); -DWORD BAHW_MyGetMSecs(void); -void battery_param_init(struct battery_type *battery); - -#endif /* __BATT_PARAM_H__*/ diff --git a/include/linux/ds2746_param_config.h b/include/linux/ds2746_param_config.h deleted file mode 100644 index ff77356e..00000000 --- a/include/linux/ds2746_param_config.h +++ /dev/null @@ -1,274 +0,0 @@ -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Copyright (c) 2010 High Tech Computer Corporation - -Module Name: - - ds2746_param_config.c - -Abstract: - - This module tells batt_param.c module what the battery characteristic is. - And also which charger/gauge component hardware uses, to decide if software/hardware function is available. - -Original Auther: - - Andy.ys Wang June-01-2010 - ----------------------------------------------------------------------------------*/ - - -#ifndef __BATT_PARAM_CONFIG_H__ -#define __BATT_PARAM_CONFIG_H__ -#define HTC_BATT_BOARD_NAME "ACE" - -/*======================================================================================== - -battery parameter defines (depend on board design) - -========================================================================================*/ - -static BOOL support_ds2746_gauge_ic = TRUE; - -enum BATTERY_ID_ENUM { - BATTERY_ID_UNKNOWN = 0, - BATTERY_ID_SONY_1300MAH_FORMOSA, - BATTERY_ID_SONY_1300MAH_HTE, - BATTERY_ID_SANYO_1300MAH_HTE, - BATTERY_ID_SANYO_1300MAH_TWS, - BATTERY_ID_NUM /* include unknown battery*/ -}; - -UINT32 ID_RANGE[] = -{ - /* id resister range = [min, max)*/ - 7150, 15500, /* Sony 1300mAh (Formosa) */ /* 7.1k~15k */ - 27500, 49500, /* Sony 1300mAh (HTE) */ /* 28k~49.5k */ - 15500, 27500, /* Sanyo 1300mAh (HTE) */ /* 16k~27k */ - 0, 7150, /* Samsung 1230mAh */ /* 0k~7k */ -}; - -/*This table is calculated according to temp formula for temp mapping. -If temp_adc is located on 0-95, then the temp_01c is 700. - 96-99, then the temp_01c is 690. - 100-102, then the temp_01c is 680. - ... - 1117777777-1145, then the temp_01c is 0. - 1146-1175, then the temp_01c is -1. - ... - 1433-2046, then the temp_01c is -11. -*/ -UINT32 TEMP_MAP_300K[] = -{ -0, 96, 100, 103, 107, 111, 115, 119, 123, 127, -133, 137, 143, 148, 154, 159, 165, 172, 178, 185, -192, 199, 207, 215, 223, 232, 241, 250, 260, 270, -280, 291, 301, 314, 326, 339, 352, 366, 380, 394, -410, 425, 442, 458, 476, 494, 512, 531, 551, 571, -592, 614, 636, 659, 682, 706, 730, 755, 780, 806, -833, 860, 887, 942, 943, 971, 1000, 1028, 1058, 1087, -1117, 1146, 1176, 1205, 1234, 1264, 1293, 1321, 1350, 1378, -1406, 1433, 2047, -}; - -UINT32 TEMP_MAP_1000K[] = -{ -0, 30, 31, 32, 34, 35, 36, 38, 39, 40, -42, 44, 45, 47, 49, 51, 53, 55, 57, 60, -62, 64, 67, 70, 73, 76, 79, 82, 86, 89, -93, 97, 101, 106, 111, 115, 120, 126, 131, 137, -143, 150, 156, 163, 171, 178, 187, 195, 204, 213, -223, 233, 244, 255, 267, 279, 292, 306, 320, 334, -350, 365, 382, 399, 418, 436, 456, 476, 497, 519, -542, 566, 590, 615, 641, 668, 695, 723, 752, 782, -812, 843, 2047, -}; - -UINT32 *TEMP_MAP = TEMP_MAP_300K; - -UINT32 FL_25[] = -{ - 1280, /* Unknown battery */ - 1280, /* Sony 1300mAh (Formosa) */ - 1280, /* Sony 1300mAh (HTE) */ - 1250, /* Sanyo 1300mAh (HTE) */ - 1230, /* Samsung 1230mAh */ -}; - -UINT32 PD_M_COEF[] = -{ - /* for TAO PMA, this is defined as PD_M; for TPE PMA, this is defined as FT or t*/ - 24, /* Unknown battery */ - 24, /* Sony 1300mAh (Formosa) */ - 24, /* Sony 1300mAh (HTE) */ - 27, /* Sanyo 1300mAh (HTE) */ - 30, /* Samsung 1230mAh */ -}; - -UINT32 PD_M_RESL[] = -{ - /* for TAO PMA, this is defined as PD_M; for TPE PMA, this is defined as FT or t*/ - 100, /* Unknown battery */ - 100, /* Sony 1300mAh (Formosa) */ - 100, /* Sony 1300mAh (HTE) */ - 100, /* Sanyo 1300mAh (HTE) */ - 100, /* Samsung 1230mAh */ -}; - -UINT32 PD_T_COEF[] = -{ - /* Ex: 140 -> 0.014, 156 -> 0.0156*/ - 140, /* Unknown battery */ - 140, /* Sony 1300mAh (Formosa) */ - 140, /* Sony 1300mAh (HTE) */ - 156, /* Sanyo 1300mAh (HTE) */ - 250, /* Samsung 1230mAh */ -}; - -/*! star_lee 20100426 - update KADC discharge parameter */ -UINT32 M_PARAMETER_SONY_1300MAH_FORMOSA[] = -{ - /* capacity (in 0.01%) -> voltage (in mV)*/ - 10000, 4100, 5500, 3839, 2400, 3759, 400, 3667, 0, 3397, -}; - -UINT32 M_PARAMETER_Samsung_1230MAH_FORMOSA[] = -{ - /* capacity (in 0.01%) -> voltage (in mV)*/ - 10000, 4135, 7500, 3960, 4700, 3800, 1700, 3727, 900, 3674, 300, 3640, 0, 3420, -}; - -UINT32 *M_PARAMTER_TABLE[] = -{ - /* Unknown battery */ - (UINT32 *) (M_PARAMETER_SONY_1300MAH_FORMOSA), - /* same as Sony 1300mAh (Formosa) currently... */ - /* Sony 1300mAh (Formosa) */ - (UINT32 *) (M_PARAMETER_SONY_1300MAH_FORMOSA), - /* Sony 1300mAh (HTE) */ - (UINT32 *) (M_PARAMETER_SONY_1300MAH_FORMOSA), - /* same as Sony 1300mAh (Formosa) currently... */ - /* Sanyo 1300mAh (HTE) */ - (UINT32 *) (M_PARAMETER_SONY_1300MAH_FORMOSA), - /* same as Sony 1300mAh (Formosa) currently... */ - /* Samsung 1230mAh */ - (UINT32 *) (M_PARAMETER_Samsung_1230MAH_FORMOSA), - /* same as Sony 1300mAh (Formosa) currently... */ -}; - -INT32 TEMP_RANGE[] = -{ - /* mapping temp to temp_index*/ - 200, /* ~20C */ - 100, /* 20~10C */ - 50, /* 10~5C */ - 0, /* 5~0C */ -5, /* 0~-5C */ -10, /* -5~-10C */ -3000, - /* -10C~ */ -}; - -UINT32 *PD_M_COEF_TABLE_BOOT[] = -{ - /* mapping current to pd_m_coef table when booting*/ - (UINT32 *) (PD_M_COEF), /* ~20C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 20~10C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 10~5C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 5~0C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 0~-5C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* -5~-10C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* -10C~, using PD_M_COEF */ -}; - -UINT32 *PD_M_COEF_TABLE[] = -{ - /* mapping current to pd_m_coef table*/ - (UINT32 *) (PD_M_COEF), /* ~20C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 20~10C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 10~5C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 5~0C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* 0~-5C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* -5~-10C, using PD_M_COEF */ - (UINT32 *) (PD_M_COEF), /* -10C~, using PD_M_COEF */ -}; - -UINT32 *PD_M_RESL_TABLE_BOOT[] = -{ - /* mapping current to pd_m_coef table when booting*/ - (UINT32 *) (PD_M_RESL), /* ~20C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 20~10C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 10~5C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 5~0C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 0~-5C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* -5~-10C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* -10C~, using PD_M_RESL */ -}; - -UINT32 *PD_M_RESL_TABLE[] = -{ - /* mapping current to pd_m_coef table*/ - (UINT32 *) (PD_M_RESL), /* ~20C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 20~10C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 10~5C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 5~0C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* 0~-5C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* -5~-10C, using PD_M_RESL */ - (UINT32 *) (PD_M_RESL), /* -10C~, using PD_M_RESL */ -}; - -UINT32 CAPACITY_DEDUCTION_01p[] = -{ - 0, /* ~20C, upper capacity 100 is usable */ - 0, /* 20~10C, upper capacity 95 is usable */ - 0, /* 10~5C, upper capacity 92 is usable */ - 0, /* 5~0C, upper capacity 90 is usable */ - 0, /* 0~-5C, upper capacity 87 is usable */ - 0, /* -5~-10C, upper capacity 85 is usable */ - 0, /* -10C~, upper capacity 85 is usable */ -}; - -/*======================================================================================== - -battery formula coef definition, can be re-programable - -========================================================================================*/ - -/* adc converter*/ - -static INT32 voltage_adc_to_mv_coef = 244; -static INT32 voltage_adc_to_mv_resl = 100; -static INT32 current_adc_to_mv_coef = 625; -static INT32 current_adc_to_mv_resl = 1580; -static INT32 discharge_adc_to_mv_coef = 625; -static INT32 discharge_adc_to_mv_resl = 1580; -static INT32 acr_adc_to_mv_coef = 625; -static INT32 acr_adc_to_mv_resl = 1580; -static INT32 charge_counter_zero_base_mAh = 500; - -static INT32 id_adc_resl = 2047; -static INT32 temp_adc_resl = 2047; - -/* kadc parameter*/ - -static INT32 pd_m_bias_mA; /* the bias current when calculating pd_m*/ - -/* over temperature algorithm*/ - -static INT32 over_high_temp_lock_01c = 450; -static INT32 over_high_temp_release_01c = 420; -static INT32 over_low_temp_lock_01c; /*over_low_temp_lock_01c = 0*/ -static INT32 over_low_temp_release_01c = 30; - -/* function config*/ - -static BOOL is_allow_batt_id_change = FALSE; - -/*boot up voltage*/ - -/*dead battery is voltage < M_0*/ -#define BATTERY_DEAD_VOLTAGE_LEVEL 3420 -#define BATTERY_DEAD_VOLTAGE_RELEASE 3450 - -#define TEMP_MAX 70 -#define TEMP_MIN -11 -#define TEMP_NUM 83 - -#endif diff --git a/include/linux/tps65200.h b/include/linux/tps65200.h deleted file mode 100644 index 6048cecb..00000000 --- a/include/linux/tps65200.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2007 HTC Incorporated - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - */ -#ifndef _TPS65200_H_ -#define _TPS65200_H_ -#include -#include - -#ifdef CONFIG_TPS65200 -extern int tps_set_charger_ctrl(u32 ctl); -#else -static int tps_set_charger_ctrl(u32 ctl) {return 0 ; } -#endif -#endif diff --git a/include/linux/wrapper_types.h b/include/linux/wrapper_types.h deleted file mode 100644 index 742755fe..00000000 --- a/include/linux/wrapper_types.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef __WRAPPER_TYPES_H_ -#define __WRAPPER_TYPES_H_ - -#define DRIVER_ZONE "[D:BATT]" -#define DRIVER_BATTERY (1<<9) - -/* The left side of these typedefs are machine and compiler dependent */ -typedef signed char INT8; -typedef unsigned char UINT8; -typedef signed short INT16; -typedef unsigned short UINT16; -typedef signed int INT32; -typedef unsigned int UINT32; -typedef struct _INT64{ - - UINT32 u0, u1, u2; INT32 u3; -} INT64; -typedef struct _UINT64{ - - UINT32 u0, u1, u2, u3; -} UINT64; -typedef struct _INT128{ - - UINT32 u0, u1, u2; INT32 u3; -} INT128; -typedef struct _UINT128{ - - UINT32 u0, u1, u2, u3; -} UINT128; - -typedef INT8 * PINT8; -typedef UINT8 *PUINT8; -typedef INT16 * PINT16; -typedef UINT16 * PUINT16; -typedef INT32 *PINT32; -typedef UINT32 *PUINT32; -typedef INT64 * PINT64; -typedef UINT64 * PUINT64; -typedef INT128 * PINT128; -typedef UINT128 * PUINT128; -typedef const void *PCVOID; -typedef void **PPVOID; -/*typedef unsigned char uchar;*/ -typedef void (*PFNVOID)( void); -typedef char CHAR; -typedef UINT8 BYTE; -typedef UINT8 UCHAR; -typedef UINT32 ULONG; -typedef INT32 LONG; -typedef UINT32 DWORD; -typedef UINT32 UINT; -typedef UINT32 BOOL; -typedef UINT16 WORD; -typedef UINT16 USHORT; -typedef INT32 INT; -typedef void *LPVOID; -typedef void *PVOID; -typedef void VOID; -typedef void *HLOCAL; -typedef CHAR * LPCHAR; -typedef CHAR * PBYTE; -typedef INT16 * LPCWSTR; -typedef UINT8 *LPTSTR; -typedef UINT8 *LPCSTR; -typedef UINT8 *LPCTSTR; -typedef BYTE * LPBYTE; -typedef DWORD *LPDWORD; -typedef DWORD *PDWORD; -typedef CHAR TCHAR; -typedef UINT32 HINSTANCE; -typedef UINT32 HKEY; -typedef UINT32 HMODULE; -typedef UINT32 FARPROC; -typedef UINT32 HRESULT; -typedef UINT32 HREGNOTIFY; -typedef UINT32 LPSTARTUPINFO; -typedef UINT32 LPPROCESS_INFORMATION; -typedef UINT32 REGISTRYNOTIFYCALLBACK; -typedef UINT32 NOTIFICATIONCONDITION; -typedef UINT32 REGSAM; -typedef UINT32 PHKEY; - -#define FALSE 0 -#define TRUE 1 -#define INFINITE 0x7fffffffffffffffL - -#define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) -#define LOBYTE(w) ((BYTE)(w)) -#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) -#define CEILING(n, precision) ((n+precision-1)/precision) /* ex: CEILING(989, 10)=99, means 98.9 mapping to 99*/ - -#endif