htcleo: cleanups and fixes for battery and power

- Correct cable detection on boot with cable in
- Removed battery disabling code, this isn't working with our device
- Add Full Battery Calibration, if Battery > 95% and charging <5mA we set it to 100% (fix for nand 100% problems)
- Removed some not used code
Importand: It's in this step for standard battery only, support in next step.
This commit is contained in:
Markinus 2010-10-25 01:16:35 +02:00
parent dc353d939b
commit 26386dbf81
3 changed files with 642 additions and 721 deletions

File diff suppressed because it is too large Load Diff

View File

@ -37,12 +37,13 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/switch.h>
#include <mach/board-htcleo-battery.h>
#include "board-htcleo.h"
static char *supply_list[] =
{
"battery",
"battery",
};
static int inited;
@ -51,7 +52,7 @@ static int usb_status;
static struct work_struct vbus_work;
#ifdef CONFIG_USB_ANDROID
extern void notify_usb_connected(int status);
void notify_usb_connected(int status);
static struct t_usb_status_notifier usb_status_notifier = {
.name = "htc_battery",
.func = notify_usb_connected,
@ -62,122 +63,126 @@ 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 (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;
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,
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,
.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,
.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;
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);
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 (!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);
if (!inited) return;
schedule_work(&vbus_work);
}
// used by battery driver
int is_ac_power_supplied(void)
{
return (usb_status == 2);
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);
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");
printk("$$$ htcleo_power_probe $$$\n");
INIT_WORK(&vbus_work, vbus_work_func);
INIT_WORK(&vbus_work, vbus_work_func);
gpio_request(HTCLEO_GPIO_POWER_USB, "power_usb");
gpio_direction_output(HTCLEO_GPIO_POWER_USB, 0);
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);
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;
inited = 1;
// init VBUS state
notify_vbus_change_intr();
return 0;
}
//#define APP_BATT_PDEV_NAME "rs30100001:00000000"
@ -185,25 +190,25 @@ static int htcleo_power_probe(struct platform_device *pdev)
static struct platform_driver htcleo_power_driver =
{
.probe = htcleo_power_probe,
.driver =
{
.name = APP_BATT_PDEV_NAME,
.owner = THIS_MODULE,
},
.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;
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);
//later_init(htcleo_power_init);
//module_init(htcleo_power_init);
late_initcall(htcleo_power_init);
MODULE_DESCRIPTION("HTCLEO Power Driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,102 @@
#ifndef __LEO_BATTERY__
#define __LEO_BATTERY__
#include <linux/android_alarm.h>
#define LEO_BATTERY_CAPACITY 1230
#define LEO_BATTERY_EMPTY 500
// from board-htcleo-power.c
extern int is_ac_power_supplied(void);
// from board-htcleo-log.c
extern double log(double x);
#define RAW_DATA_SIZE 10
struct battery_status
{
int timestamp;
int voltage_uV; /* units of uV */
int current_uA; /* units of uA */
int current_avg_uA;
int charge_uAh;
s16 temp_C; /* units of 0.1 C */
u8 percentage; /* battery percentage */
u8 charge_source;
u8 status_reg;
u8 battery_full; /* battery full (don't charge) */
u8 cooldown; /* was overtemp */
u8 charge_mode;
} __attribute__((packed));
#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 TEMP_CRITICAL 600 /* no charging at all */
#define TEMP_HOT 500 /* no fast charge, no charge > 4.1v */
#define TEMP_WARM 450 /* no fast charge above this */
#define TEMP_HOT_MAX_MV 4100 /* stop charging here when hot */
#define TEMP_HOT_MIN_MV 3800 /* resume charging here when hot */
#define CE_DISABLE_MIN_MV 4100
/* When we're awake or running on wall power, sample the battery
* gauge every FAST_POLL seconds. If we're asleep and on battery
* power, sample every SLOW_POLL seconds
*/
#define FAST_POLL (1 * 60)
#define SLOW_POLL (10 * 60)
struct htcleo_device_info
{
struct device *dev;
/* DS2784 data, valid after calling htcleo_battery_read_status() */
char raw[RAW_DATA_SIZE]; /* raw HTCLEO data */
uint32_t raw_status;
struct battery_status status;
struct power_supply bat;
struct workqueue_struct *monitor_wqueue;
struct work_struct monitor_work;
struct alarm alarm;
struct wake_lock work_wake_lock;
// int (*charge)(int on, int fast);
// struct w1_slave *w1_slave;
struct i2c_client *client;
u8 dummy; /* dummy battery flag */
u8 last_charge_mode; /* previous charger state */
u8 slow_poll;
ktime_t last_poll;
ktime_t last_charge_seen;
};
static struct htcleo_device_info * mydi = NULL;
#define psy_to_dev_info(x) container_of((x), struct htcleo_device_info, bat)
static struct wake_lock vbus_wake_lock;
#define to_htcleo_device_info(x) container_of((x), struct htcleo_device_info, bat);
#endif