diff options
-rw-r--r-- | drivers/power/supply/bq27xxx_battery.c | 37 | ||||
-rw-r--r-- | include/linux/power/bq27xxx_battery.h | 1 |
2 files changed, 38 insertions, 0 deletions
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 90a5bccfc6b9..abc6d9329776 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -124,6 +124,7 @@ enum bq27xxx_reg_index { BQ27XXX_DM_DATA, /* Block Data */ BQ27XXX_DM_CKSUM, /* Block Data Checksum */ BQ27XXX_REG_SEDVF, /* End-of-discharge Voltage */ + BQ27XXX_REG_PKCFG, /* Pack Configuration */ BQ27XXX_REG_MAX, /* sentinel */ }; @@ -161,6 +162,7 @@ static u8 [BQ27XXX_DM_DATA] = INVALID_REG_ADDR, [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR, [BQ27XXX_REG_SEDVF] = 0x77, + [BQ27XXX_REG_PKCFG] = 0x7C, }, bq27010_regs[BQ27XXX_REG_MAX] = { [BQ27XXX_REG_CTRL] = 0x00, @@ -187,6 +189,7 @@ static u8 [BQ27XXX_DM_DATA] = INVALID_REG_ADDR, [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR, [BQ27XXX_REG_SEDVF] = 0x77, + [BQ27XXX_REG_PKCFG] = 0x7C, }, bq2750x_regs[BQ27XXX_REG_MAX] = { [BQ27XXX_REG_CTRL] = 0x00, @@ -583,6 +586,7 @@ static enum power_supply_property bq27000_props[] = { POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, }; static enum power_supply_property bq27010_props[] = { @@ -604,6 +608,7 @@ static enum power_supply_property bq27010_props[] = { POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, }; #define bq2750x_props bq27510g3_props @@ -2045,6 +2050,35 @@ static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di, } /* + * Return the design maximum battery Voltage in microvolts, or < 0 if something + * fails. The programmed value of the maximum battery voltage is determined by + * QV0 and QV1 (bits 5 and 6) in the Pack Configuration register. + */ +static int bq27xxx_battery_read_dmax_volt(struct bq27xxx_device_info *di, + union power_supply_propval *val) +{ + int reg_val, qv; + + if (di->voltage_max_design > 0) { + val->intval = di->voltage_max_design; + return 0; + } + + reg_val = bq27xxx_read(di, BQ27XXX_REG_PKCFG, true); + if (reg_val < 0) { + dev_err(di->dev, "error reading design max voltage\n"); + return reg_val; + } + + qv = (reg_val >> 5) & 0x3; + val->intval = 3968000 + 48000 * qv; + + di->voltage_max_design = val->intval; + + return 0; +} + +/* * Return the design minimum battery Voltage in microvolts * Or < 0 if something fails. */ @@ -2158,6 +2192,9 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: ret = bq27xxx_battery_read_dmin_volt(di, val); break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + ret = bq27xxx_battery_read_dmax_volt(di, val); + break; case POWER_SUPPLY_PROP_CYCLE_COUNT: ret = bq27xxx_battery_read_cyct(di, val); break; diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index 6b190639b08e..d56e1276aafe 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -62,6 +62,7 @@ struct bq27xxx_device_info { struct bq27xxx_reg_cache cache; int charge_design_full; int voltage_min_design; + int voltage_max_design; bool removed; unsigned long last_update; union power_supply_propval last_status; |