diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-16 04:50:40 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-16 04:50:40 +0300 |
commit | 8649efb2f8750dcabff018a27784bab4ecb9f88f (patch) | |
tree | 4351aa7377c2042be5963d0f8b5600a1eb221a59 /drivers/power/supply/cpcap-battery.c | |
parent | 5fd09ba68297c967f5ba6bea9c3b444d34f80ee5 (diff) | |
parent | baf5964ecfe19a0109fe2e497e72840ce0f488e6 (diff) | |
download | linux-8649efb2f8750dcabff018a27784bab4ecb9f88f.tar.xz |
Merge tag 'for-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel:
"Core:
- Add over-current health state
- Add standard, adaptive and custom charge types
- Add new properties for start/end charge threshold
New Drivers / Hardware:
- UCS1002 Programmable USB Port Power Controller
- Ingenic JZ47xx Battery Fuel Gauge
- AXP20x USB Power: Add AXP813 support
- AT91 poweroff: Add SAM9X60 support
- OLPC battery: Add XO-1.5 and XO-1.75 support
Misc Changes:
- syscon-reboot: support mask property
- AXP288 fuel gauge: Blacklist ACEPC T8/T11. Looks like some vendor
thought it's a good idea to build a desktop system with a fuel
gauge, that slowly "discharges"...
- cpcap-battery: Fix calculation errors
- misc fixes"
* tag 'for-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (54 commits)
power: supply: olpc_battery: force the le/be casts
power: supply: ucs1002: Fix build error without CONFIG_REGULATOR
power: supply: ucs1002: Fix wrong return value checking
power: supply: Add driver for Microchip UCS1002
dt-bindings: power: supply: Add bindings for Microchip UCS1002
power: supply: core: Add POWER_SUPPLY_HEALTH_OVERCURRENT constant
power: supply: core: fix clang -Wunsequenced
power: supply: core: Add missing documentation for CHARGE_CONTROL_* properties
power: supply: core: Add CHARGE_CONTROL_{START_THRESHOLD,END_THRESHOLD} properties
power: supply: core: Add Standard, Adaptive, and Custom charge types
power: supply: axp288_fuel_gauge: Add ACEPC T8 and T11 mini PCs to the blacklist
power: supply: bq27xxx_battery: Notify also about status changes
power: supply: olpc_battery: Have the framework register sysfs files for us
power: supply: olpc_battery: Add OLPC XO 1.75 support
power: supply: olpc_battery: Avoid using platform_info
power: supply: olpc_battery: Use devm_power_supply_register()
power: supply: olpc_battery: Move priv data to a struct
power: supply: olpc_battery: Use DT to get battery version
x86/platform/olpc: Use a correct version when making up a battery node
x86/platform/olpc: Trivial code move in DT fixup
...
Diffstat (limited to 'drivers/power/supply/cpcap-battery.c')
-rw-r--r-- | drivers/power/supply/cpcap-battery.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c index 6887870ba32c..61d6447d1966 100644 --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -82,9 +82,9 @@ struct cpcap_battery_config { }; struct cpcap_coulomb_counter_data { - s32 sample; /* 24-bits */ + s32 sample; /* 24 or 32 bits */ s32 accumulator; - s16 offset; /* 10-bits */ + s16 offset; /* 9 bits */ }; enum cpcap_battery_state { @@ -213,7 +213,7 @@ static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata) * TI or ST coulomb counter in the PMIC. */ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata, - u32 sample, s32 accumulator, + s32 sample, s32 accumulator, s16 offset, u32 divider) { s64 acc; @@ -224,9 +224,6 @@ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata, if (!divider) return 0; - sample &= 0xffffff; /* 24-bits, unsigned */ - offset &= 0x7ff; /* 10-bits, signed */ - switch (ddata->vendor) { case CPCAP_VENDOR_ST: cc_lsb = 95374; /* μAms per LSB */ @@ -259,7 +256,7 @@ static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata, /* 3600000μAms = 1μAh */ static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata, - u32 sample, s32 accumulator, + s32 sample, s32 accumulator, s16 offset) { return cpcap_battery_cc_raw_div(ddata, sample, @@ -268,7 +265,7 @@ static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata, } static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata, - u32 sample, s32 accumulator, + s32 sample, s32 accumulator, s16 offset) { return cpcap_battery_cc_raw_div(ddata, sample, @@ -312,17 +309,19 @@ cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata, /* Sample value CPCAP_REG_CCS1 & 2 */ ccd->sample = (buf[1] & 0x0fff) << 16; ccd->sample |= buf[0]; + if (ddata->vendor == CPCAP_VENDOR_TI) + ccd->sample = sign_extend32(24, ccd->sample); /* Accumulator value CPCAP_REG_CCA1 & 2 */ ccd->accumulator = ((s16)buf[3]) << 16; ccd->accumulator |= buf[2]; - /* Offset value CPCAP_REG_CCO */ - ccd->offset = buf[5]; - - /* Adjust offset based on mode value CPCAP_REG_CCM? */ - if (buf[4] >= 0x200) - ccd->offset |= 0xfc00; + /* + * Coulomb counter calibration offset is CPCAP_REG_CCM, + * REG_CCO seems unused + */ + ccd->offset = buf[4]; + ccd->offset = sign_extend32(ccd->offset, 9); return cpcap_battery_cc_to_uah(ddata, ccd->sample, @@ -477,11 +476,11 @@ static int cpcap_battery_get_property(struct power_supply *psy, val->intval = ddata->config.info.voltage_min_design; break; case POWER_SUPPLY_PROP_CURRENT_AVG: - if (cached) { + sample = latest->cc.sample - previous->cc.sample; + if (!sample) { val->intval = cpcap_battery_cc_get_avg_current(ddata); break; } - sample = latest->cc.sample - previous->cc.sample; accumulator = latest->cc.accumulator - previous->cc.accumulator; val->intval = cpcap_battery_cc_to_ua(ddata, sample, accumulator, @@ -498,13 +497,13 @@ static int cpcap_battery_get_property(struct power_supply *psy, val->intval = div64_s64(tmp, 100); break; case POWER_SUPPLY_PROP_POWER_AVG: - if (cached) { + sample = latest->cc.sample - previous->cc.sample; + if (!sample) { tmp = cpcap_battery_cc_get_avg_current(ddata); tmp *= (latest->voltage / 10000); val->intval = div64_s64(tmp, 100); break; } - sample = latest->cc.sample - previous->cc.sample; accumulator = latest->cc.accumulator - previous->cc.accumulator; tmp = cpcap_battery_cc_to_ua(ddata, sample, accumulator, latest->cc.offset); @@ -562,11 +561,11 @@ static irqreturn_t cpcap_battery_irq_thread(int irq, void *data) switch (d->action) { case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW: - if (latest->counter_uah >= 0) + if (latest->current_ua >= 0) dev_warn(ddata->dev, "Battery low at 3.3V!\n"); break; case CPCAP_BATTERY_IRQ_ACTION_POWEROFF: - if (latest->counter_uah >= 0) { + if (latest->current_ua >= 0) { dev_emerg(ddata->dev, "Battery empty at 3.1V, powering off\n"); orderly_poweroff(true); @@ -670,8 +669,9 @@ static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata) return 0; out_err: - dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n", - error); + if (error != -EPROBE_DEFER) + dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n", + error); return error; } |