Skip to content

Commit

Permalink
power_supply: bq27x00: add status and time properties
Browse files Browse the repository at this point in the history
The BQ27x00 series of chips can report time-to-empty and
time-to-full, so let's add corresponding properties.
Also report charge status based on status flag register.

Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
  • Loading branch information
Grazvydas Ignotas authored and Anton Vorontsov committed Feb 27, 2010
1 parent e20908d commit 4e924a8
Showing 1 changed file with 79 additions and 2 deletions.
81 changes: 79 additions & 2 deletions drivers/power/bq27x00_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,16 @@
#define BQ27x00_REG_VOLT 0x08
#define BQ27x00_REG_AI 0x14
#define BQ27x00_REG_FLAGS 0x0A
#define BQ27x00_REG_TTE 0x16
#define BQ27x00_REG_TTF 0x18
#define BQ27x00_REG_TTECP 0x26

#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
#define BQ27000_FLAG_CHGS BIT(7)

#define BQ27500_REG_SOC 0x2c
#define BQ27500_FLAG_DSC BIT(0)
#define BQ27500_FLAG_FC BIT(9)

/* If the system has several batteries we need a different name for each
* of them...
Expand All @@ -62,11 +68,15 @@ struct bq27x00_device_info {
};

static enum power_supply_property bq27x00_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
};

/*
Expand Down Expand Up @@ -144,7 +154,7 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di)
dev_err(di->dev, "error reading flags\n");
return 0;
}
if ((flags & (1 << 7)) != 0) {
if (flags & BQ27000_FLAG_CHGS) {
dev_dbg(di->dev, "negative current!\n");
return -curr;
}
Expand Down Expand Up @@ -174,16 +184,74 @@ static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)
return rsoc;
}

static int bq27x00_battery_status(struct bq27x00_device_info *di,
union power_supply_propval *val)
{
int flags = 0;
int status;
int ret;

ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
if (ret < 0) {
dev_err(di->dev, "error reading flags\n");
return ret;
}

if (di->chip == BQ27500) {
if (flags & BQ27500_FLAG_FC)
status = POWER_SUPPLY_STATUS_FULL;
else if (flags & BQ27500_FLAG_DSC)
status = POWER_SUPPLY_STATUS_DISCHARGING;
else
status = POWER_SUPPLY_STATUS_CHARGING;
} else {
if (flags & BQ27000_FLAG_CHGS)
status = POWER_SUPPLY_STATUS_CHARGING;
else
status = POWER_SUPPLY_STATUS_DISCHARGING;
}

val->intval = status;
return 0;
}

/*
* Read a time register.
* Return < 0 if something fails.
*/
static int bq27x00_battery_time(struct bq27x00_device_info *di, int reg,
union power_supply_propval *val)
{
int tval = 0;
int ret;

ret = bq27x00_read(reg, &tval, 0, di);
if (ret) {
dev_err(di->dev, "error reading register %02x\n", reg);
return ret;
}

if (tval == 65535)
return -ENODATA;

val->intval = tval * 60;
return 0;
}

#define to_bq27x00_device_info(x) container_of((x), \
struct bq27x00_device_info, bat);

static int bq27x00_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int ret = 0;
struct bq27x00_device_info *di = to_bq27x00_device_info(psy);

switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
ret = bq27x00_battery_status(di, val);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
case POWER_SUPPLY_PROP_PRESENT:
val->intval = bq27x00_battery_voltage(di);
Expand All @@ -199,11 +267,20 @@ static int bq27x00_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_TEMP:
val->intval = bq27x00_battery_temperature(di);
break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
ret = bq27x00_battery_time(di, BQ27x00_REG_TTE, val);
break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
ret = bq27x00_battery_time(di, BQ27x00_REG_TTECP, val);
break;
case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
ret = bq27x00_battery_time(di, BQ27x00_REG_TTF, val);
break;
default:
return -EINVAL;
}

return 0;
return ret;
}

static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
Expand Down

0 comments on commit 4e924a8

Please sign in to comment.