diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 18:08:25 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 18:08:25 -0700 |
commit | 4b24ff71108164e047cf2c95990b77651163e315 (patch) | |
tree | 4b478906379adf22ff259fc1f2cce0da796df415 /drivers/power/smb347-charger.c | |
parent | bca1a5c0eabe0f17081760c61e8d08e73dd6b6a6 (diff) | |
parent | 4b1bf5871f7d59de6484cc887e205d6d2f1e6fbd (diff) | |
download | op-kernel-dev-4b24ff71108164e047cf2c95990b77651163e315.zip op-kernel-dev-4b24ff71108164e047cf2c95990b77651163e315.tar.gz |
Merge tag 'for-v3.6' of git://git.infradead.org/battery-2.6
Pull battery updates from Anton Vorontsov:
"The tag contains just a few battery-related changes for v3.6. It's is
all pretty straightforward, except one thing.
One of our patches added thermal support for power supply class, but
thermal/ subsystem changed under our feet. We (well, Stephen, that
is) caught the issue and it was decided[1] that I'd just delay the
battery pull request, and then will fix it up by merging upstream back
into battery tree at the specific commit.
That's not all though: another[2] small fixup for thermal subsystem
was needed to get rid of a warning in power supply subsystem (the
warning was not drivers/power's "fault", the thermal registration
function just needed a proper const annotation, which is also done by
a small commit on top of the merge.
So, to sum this up:
- The 'master' branch of the battery tree was in the -next tree for
weeks, was never rebased, altered etc. It should be all OK;
- Although, for-v3.6 tag contains the 'master' branch + merge + the
warning fix.
[1] http://lkml.org/lkml/2012/6/19/23
[2] http://lkml.org/lkml/2012/6/18/28"
* tag 'for-v3.6' of git://git.infradead.org/battery-2.6: (23 commits)
thermal: Constify 'type' argument for the registration routine
olpc-battery: update CHARGE_FULL_DESIGN property for BYD LiFe batteries
olpc-battery: Add VOLTAGE_MAX_DESIGN property
charger-manager: Fix build break related to EXTCON
lp8727_charger: Move header file into platform_data directory
power_supply: Add min/max alert properties for CAPACITY, TEMP, TEMP_AMBIENT
bq27x00_battery: Add support for BQ27425 chip
charger-manager: Set current limit of regulator for over current protection
charger-manager: Use EXTCON Subsystem to detect charger cables for charging
test_power: Add VOLTAGE_NOW and BATTERY_TEMP properties
test_power: Add support for USB AC source
gpio-charger: Use cansleep version of gpio_set_value
bq27x00_battery: Add support for power average and health properties
sbs-battery: Don't trigger false supply_changed event
twl4030_charger: Allow charger to control the regulator that feeds it
twl4030_charger: Add backup-battery charging
twl4030_charger: Fix some typos
max17042_battery: Support CHARGE_COUNTER power supply attribute
smb347-charger: Add constant charge and current properties
power_supply: Add constant charge_current and charge_voltage properties
...
Diffstat (limited to 'drivers/power/smb347-charger.c')
-rw-r--r-- | drivers/power/smb347-charger.c | 123 |
1 files changed, 117 insertions, 6 deletions
diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c index f8eedd8..332dd01 100644 --- a/drivers/power/smb347-charger.c +++ b/drivers/power/smb347-charger.c @@ -196,6 +196,14 @@ static const unsigned int ccc_tbl[] = { 1200000, }; +/* Convert register value to current using lookup table */ +static int hw_to_current(const unsigned int *tbl, size_t size, unsigned int val) +{ + if (val >= size) + return -EINVAL; + return tbl[val]; +} + /* Convert current to register value using lookup table */ static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val) { @@ -841,22 +849,101 @@ fail: return ret; } +/* + * Returns the constant charge current programmed + * into the charger in uA. + */ +static int get_const_charge_current(struct smb347_charger *smb) +{ + int ret, intval; + unsigned int v; + + if (!smb347_is_ps_online(smb)) + return -ENODATA; + + ret = regmap_read(smb->regmap, STAT_B, &v); + if (ret < 0) + return ret; + + /* + * The current value is composition of FCC and PCC values + * and we can detect which table to use from bit 5. + */ + if (v & 0x20) { + intval = hw_to_current(fcc_tbl, ARRAY_SIZE(fcc_tbl), v & 7); + } else { + v >>= 3; + intval = hw_to_current(pcc_tbl, ARRAY_SIZE(pcc_tbl), v & 7); + } + + return intval; +} + +/* + * Returns the constant charge voltage programmed + * into the charger in uV. + */ +static int get_const_charge_voltage(struct smb347_charger *smb) +{ + int ret, intval; + unsigned int v; + + if (!smb347_is_ps_online(smb)) + return -ENODATA; + + ret = regmap_read(smb->regmap, STAT_A, &v); + if (ret < 0) + return ret; + + v &= STAT_A_FLOAT_VOLTAGE_MASK; + if (v > 0x3d) + v = 0x3d; + + intval = 3500000 + v * 20000; + + return intval; +} + static int smb347_mains_get_property(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) { struct smb347_charger *smb = container_of(psy, struct smb347_charger, mains); + int ret; - if (prop == POWER_SUPPLY_PROP_ONLINE) { + switch (prop) { + case POWER_SUPPLY_PROP_ONLINE: val->intval = smb->mains_online; - return 0; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + ret = get_const_charge_voltage(smb); + if (ret < 0) + return ret; + else + val->intval = ret; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + ret = get_const_charge_current(smb); + if (ret < 0) + return ret; + else + val->intval = ret; + break; + + default: + return -EINVAL; } - return -EINVAL; + + return 0; } static enum power_supply_property smb347_mains_properties[] = { POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, }; static int smb347_usb_get_property(struct power_supply *psy, @@ -865,16 +952,40 @@ static int smb347_usb_get_property(struct power_supply *psy, { struct smb347_charger *smb = container_of(psy, struct smb347_charger, usb); + int ret; - if (prop == POWER_SUPPLY_PROP_ONLINE) { + switch (prop) { + case POWER_SUPPLY_PROP_ONLINE: val->intval = smb->usb_online; - return 0; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + ret = get_const_charge_voltage(smb); + if (ret < 0) + return ret; + else + val->intval = ret; + break; + + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + ret = get_const_charge_current(smb); + if (ret < 0) + return ret; + else + val->intval = ret; + break; + + default: + return -EINVAL; } - return -EINVAL; + + return 0; } static enum power_supply_property smb347_usb_properties[] = { POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, }; static int smb347_battery_get_property(struct power_supply *psy, |