diff options
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 32 | ||||
-rw-r--r-- | drivers/power/bq27000_battery.c | 66 | ||||
-rw-r--r-- | include/linux/bq27000_battery.h | 2 |
3 files changed, 73 insertions, 27 deletions
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index f30abb6ebe7..1fcd3fd2844 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -96,6 +96,9 @@ struct resume_dependency resume_dep_jbt_glamo; struct resume_dependency resume_dep_glamo_mci_pcf; +static int gta02_charger_online_status; +static int gta02_charger_active_status; + /* define FIQ IPC struct */ /* * contains stuff FIQ ISR modifies and normal kernel code can see and use @@ -457,12 +460,25 @@ static struct s3c2410_uartcfg gta02_uartcfgs[] = { /* BQ27000 Battery */ +static int gta02_get_charger_online_status(void) +{ + return gta02_charger_online_status; +} + +static int gta02_get_charger_active_status(void) +{ + return gta02_charger_active_status; +} + + struct bq27000_platform_data bq27000_pdata = { .name = "bat", .rsense_mohms = 20, .hdq_read = gta02hdq_read, .hdq_write = gta02hdq_write, .hdq_initialized = gta02hdq_initialized, + .get_charger_online_status = gta02_get_charger_online_status, + .get_charger_active_status = gta02_get_charger_active_status }; struct platform_device bq27000_battery_device = { @@ -481,16 +497,20 @@ static int pmu_callback(struct device *dev, unsigned int feature, switch (feature) { case PCF50633_FEAT_MBC: switch (event) { - case PMU_EVT_INSERT: + case PMU_EVT_CHARGER_IDLE: + gta02_charger_active_status = 0; + break; + case PMU_EVT_CHARGER_ACTIVE: + gta02_charger_active_status = 1; + break; case PMU_EVT_USB_INSERT: - pcf50633_charge_enable(pcf50633_global, 1); + gta02_charger_online_status = 1; break; - case PMU_EVT_REMOVE: case PMU_EVT_USB_REMOVE: - pcf50633_charge_enable(pcf50633_global, 0); + gta02_charger_online_status = 0; break; - case PMU_EVT_CHARGER_IDLE: - case PMU_EVT_CHARGER_ACTIVE: + case PMU_EVT_INSERT: /* adapter is unsused */ + case PMU_EVT_REMOVE: /* adapter is unused */ break; default: break; 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) { diff --git a/include/linux/bq27000_battery.h b/include/linux/bq27000_battery.h index fed4287d756..a617466a517 100644 --- a/include/linux/bq27000_battery.h +++ b/include/linux/bq27000_battery.h @@ -9,6 +9,8 @@ struct bq27000_platform_data { int (*hdq_read)(int); int (*hdq_write)(int, u8); int (*hdq_initialized)(void); + int (*get_charger_online_status)(void); + int (*get_charger_active_status)(void); }; #endif |