/* * Return the battery Initial last measured discharge in µAh * Or < 0 if something fails. */ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di) { int ilmd; if (bq27xxx_is_chip_version_higher(di)) { if (di->chip == BQ27425) ilmd = bq27x00_read(di, BQ27425_REG_DCAP, false); else if (di->chip == BQ27510) ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false); else ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); } else { ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true); } if (ilmd < 0) { dev_dbg(di->dev, "error reading initial last measured discharge\n"); return ilmd; } if (bq27xxx_is_chip_version_higher(di)) ilmd *= 1000; else ilmd = ilmd * 256 * 3570 / BQ27000_RS; return ilmd; }
static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di, union power_supply_propval *val) { int level; if (bq27xxx_is_chip_version_higher(di)) { if (di->cache.flags & BQ27500_FLAG_FC) level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; else if (di->cache.flags & BQ27500_FLAG_SOC1) level = POWER_SUPPLY_CAPACITY_LEVEL_LOW; else if (di->cache.flags & BQ27500_FLAG_SOCF) level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; else level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; } else { if (di->cache.flags & BQ27000_FLAG_FC) level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; else if (di->cache.flags & BQ27000_FLAG_EDV1) level = POWER_SUPPLY_CAPACITY_LEVEL_LOW; else if (di->cache.flags & BQ27000_FLAG_EDVF) level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; else level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; } val->intval = level; return 0; }
static int bq27x00_battery_status(struct bq27x00_device_info *di, union power_supply_propval *val) { int status; if (bq27xxx_is_chip_version_higher(di)) { if (di->cache.flags & BQ27500_FLAG_FC) status = POWER_SUPPLY_STATUS_FULL; else if (di->cache.flags & BQ27500_FLAG_DSC) status = POWER_SUPPLY_STATUS_DISCHARGING; else status = POWER_SUPPLY_STATUS_CHARGING; } else { if (di->cache.flags & BQ27000_FLAG_FC) status = POWER_SUPPLY_STATUS_FULL; else if (di->cache.flags & BQ27000_FLAG_CHGS) status = POWER_SUPPLY_STATUS_CHARGING; else if (power_supply_am_i_supplied(di->bat)) status = POWER_SUPPLY_STATUS_NOT_CHARGING; else status = POWER_SUPPLY_STATUS_DISCHARGING; } val->intval = status; return 0; }
/* * Return the battery average current in µA * Note that current can be negative signed as well * Or 0 if something fails. */ static int bq27x00_battery_current(struct bq27x00_device_info *di, union power_supply_propval *val) { int curr; int flags; curr = bq27x00_read(di, BQ27x00_REG_AI, false); if (curr < 0) { dev_err(di->dev, "error reading current\n"); return curr; } if (bq27xxx_is_chip_version_higher(di)) { /* bq27500 returns signed value */ val->intval = (int)((s16)curr) * 1000; } else { flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false); if (flags & BQ27000_FLAG_CHGS) { dev_dbg(di->dev, "negative current!\n"); curr = -curr; } val->intval = curr * 3570 / BQ27000_RS; } return 0; }
/* * Return the battery Nominal available capaciy in µAh * Or < 0 if something fails. */ static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di) { int flags; bool is_bq27500 = di->chip == BQ27500; bool is_higher = bq27xxx_is_chip_version_higher(di); flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI)) return -ENODATA; return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC); }
/* * Return the battery temperature in tenths of degree Kelvin * Or < 0 if something fails. */ static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di) { int temp; temp = bq27x00_read(di, BQ27x00_REG_TEMP, false); if (temp < 0) { dev_err(di->dev, "error reading temperature\n"); return temp; } if (!bq27xxx_is_chip_version_higher(di)) temp = 5 * temp / 2; return temp; }
/* * Return a battery charge value in µAh * Or < 0 if something fails. */ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg) { int charge; charge = bq27x00_read(di, reg, false); if (charge < 0) { dev_dbg(di->dev, "error reading charge register %02x: %d\n", reg, charge); return charge; } if (bq27xxx_is_chip_version_higher(di)) charge *= 1000; else charge = charge * 3570 / BQ27000_RS; return charge; }