aboutsummaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorAndy Green <andy@openmoko.com>2008-11-19 17:09:57 +0000
committerAndy Green <agreen@pads.home.warmcat.com>2008-11-19 17:09:57 +0000
commit1a79e3eedd41508187b310ea71328af7522ce10f (patch)
treef2afed15f9aef3b75205b6ae8e5aa6fb6d40fd04 /drivers/power
parent93a92d72b7b77c8238116316ef24dfb740beae91 (diff)
fix-bq27000-charger-state-tracking.patch
Charger trigger stuff goes and asks for POWER_SUPPLY_PROP_STATUS to figure out what the charger state is. But until now, we only reported there what we found out from HDQ, and the HDQ registers are not updated very often in the coulomb counter, it can be 4 or more second lag before it tells us about what it experiences. When we react to USB insertion and only after 500ms debounce tell power_supply stuff that something changed, it most times will see old pre-USB-insertion state from bq27000 over HDQ at that time and will report it ain't charging, buggering up the LED trigger tracking. This patch maintains distance between bq27000 and pcf50633 by having platform callbacks in bq27000 that it can use to ask about definitive charger "online" presence and "activity", whether the charger says it is charging. If these callbacks are implemented (and we implement them in this patch up in mach_gta02.c) then this information is used in preference to what is found from HDQ. Result is if you set the LED trigger like this: echo bat-charging > /sys/devices/platform/gta02-led.0/leds/gta02-aux:red/trigger then it lights up properly on USB insertion now, goes away on removal properly, as as far as I saw, when charging stops too. Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq27000_battery.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/drivers/power/bq27000_battery.c b/drivers/power/bq27000_battery.c
index 5598568933d..7020608e6e9 100644
--- a/drivers/power/bq27000_battery.c
+++ b/drivers/power/bq27000_battery.c
@@ -113,12 +113,7 @@ enum bq27000_status_flags {
struct bq27000_device_info {
struct device *dev;
struct power_supply bat;
-
- int rsense_mohms; /* from platform */
-
- int (*hdq_initialized)(void); /* from platform */
- int (*hdq_read)(int); /* from platform */
- int (*hdq_write)(int, u8); /* from platform */
+ struct bq27000_platform_data *pdata;
};
/*
@@ -136,16 +131,16 @@ static int hdq_read16(struct bq27000_device_info *di, int address)
while (retries--) {
- high = (di->hdq_read)(address + 1); /* high part */
+ high = (di->pdata->hdq_read)(address + 1); /* high part */
if (high < 0)
return high;
- acc = (di->hdq_read)(address);
+ acc = (di->pdata->hdq_read)(address);
if (acc < 0)
return acc;
/* confirm high didn't change between reading it and low */
- if (high == (di->hdq_read)(address + 1))
+ if (high == (di->pdata->hdq_read)(address + 1))
return (high << 8) | acc;
}
@@ -170,12 +165,36 @@ static int bq27000_battery_get_property(struct power_supply *psy,
int v, n;
struct bq27000_device_info *di = to_bq27000_device_info(psy);
- if (!(di->hdq_initialized)())
+ if (!(di->pdata->hdq_initialized)())
return -EINVAL;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+
+ if (!di->pdata->get_charger_online_status)
+ goto use_bat;
+ if ((di->pdata->get_charger_online_status)()) {
+ /*
+ * charger is definitively present
+ * we report our state in terms of what it says it
+ * is doing
+ */
+ if (!di->pdata->get_charger_active_status)
+ goto use_bat;
+ if ((di->pdata->get_charger_active_status)())
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ }
+use_bat:
+ /*
+ * either the charger is not connected, or the
+ * platform doesn't give info about charger, use battery state
+ * but... battery state can be out of date by 4 seconds or
+ * so... use the platform callbacks if possible.
+ */
v = hdq_read16(di, BQ27000_AI_L);
if (v < 0)
return v;
@@ -189,7 +208,7 @@ static int bq27000_battery_get_property(struct power_supply *psy,
break;
}
/* power is actually going in or out... */
- v = (di->hdq_read)(BQ27000_FLAGS);
+ v = (di->pdata->hdq_read)(BQ27000_FLAGS);
if (v < 0)
return v;
if (v & BQ27000_STATUS_CHGS)
@@ -205,7 +224,7 @@ static int bq27000_battery_get_property(struct power_supply *psy,
val->intval = v * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- v = (di->hdq_read)(BQ27000_FLAGS);
+ v = (di->pdata->hdq_read)(BQ27000_FLAGS);
if (v < 0)
return v;
if (v & BQ27000_STATUS_CHGS)
@@ -215,13 +234,13 @@ static int bq27000_battery_get_property(struct power_supply *psy,
v = hdq_read16(di, BQ27000_AI_L);
if (v < 0)
return v;
- val->intval = (v * n) / di->rsense_mohms;
+ val->intval = (v * n) / di->pdata->rsense_mohms;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
v = hdq_read16(di, BQ27000_LMD_L);
if (v < 0)
return v;
- val->intval = (v * 3570) / di->rsense_mohms;
+ val->intval = (v * 3570) / di->pdata->rsense_mohms;
break;
case POWER_SUPPLY_PROP_TEMP:
v = hdq_read16(di, BQ27000_TEMP_L);
@@ -235,12 +254,12 @@ static int bq27000_battery_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = (di->hdq_read)(BQ27000_RSOC);
+ val->intval = (di->pdata->hdq_read)(BQ27000_RSOC);
if (val->intval < 0)
return val->intval;
break;
case POWER_SUPPLY_PROP_PRESENT:
- v = (di->hdq_read)(BQ27000_RSOC);
+ v = (di->pdata->hdq_read)(BQ27000_RSOC);
val->intval = !(v < 0);
break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
@@ -255,6 +274,12 @@ static int bq27000_battery_get_property(struct power_supply *psy,
return v;
val->intval = 60 * v;
break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ if (di->pdata->get_charger_online_status)
+ val->intval = (di->pdata->get_charger_online_status)();
+ else
+ return -EINVAL;
+ break;
default:
return -EINVAL;
}
@@ -272,7 +297,8 @@ static enum power_supply_property bq27000_battery_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
- POWER_SUPPLY_PROP_CAPACITY
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_ONLINE
};
static int bq27000_battery_probe(struct platform_device *pdev)
@@ -301,10 +327,8 @@ static int bq27000_battery_probe(struct platform_device *pdev)
di->bat.get_property = bq27000_battery_get_property;
di->bat.external_power_changed =
bq27000_battery_external_power_changed;
- di->hdq_read = pdata->hdq_read;
- di->hdq_write = pdata->hdq_write;
- di->rsense_mohms = pdata->rsense_mohms;
- di->hdq_initialized = pdata->hdq_initialized;
+ di->bat.use_for_apm = 1;
+ di->pdata = pdata;
retval = power_supply_register(&pdev->dev, &di->bat);
if (retval) {