diff options
Diffstat (limited to 'drivers/power/supply/sbs-battery.c')
-rw-r--r-- | drivers/power/supply/sbs-battery.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index 048d205d7074..6acd242eed48 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -5,6 +5,7 @@ * Copyright (c) 2010, NVIDIA Corporation. */ +#include <linux/bits.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/gpio/consumer.h> @@ -46,10 +47,10 @@ enum { /* Battery Mode defines */ #define BATTERY_MODE_OFFSET 0x03 -#define BATTERY_MODE_MASK 0x8000 -enum sbs_battery_mode { - BATTERY_MODE_AMPS = 0, - BATTERY_MODE_WATTS = 0x8000 +#define BATTERY_MODE_CAPACITY_MASK BIT(15) +enum sbs_capacity_mode { + CAPACITY_MODE_AMPS = 0, + CAPACITY_MODE_WATTS = BATTERY_MODE_CAPACITY_MASK }; /* manufacturer access defines */ @@ -314,17 +315,22 @@ static int sbs_get_battery_presence_and_health( { int ret; - if (psp == POWER_SUPPLY_PROP_PRESENT) { - /* Dummy command; if it succeeds, battery is present. */ - ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); - if (ret < 0) - val->intval = 0; /* battery disconnected */ - else - val->intval = 1; /* battery present */ - } else { /* POWER_SUPPLY_PROP_HEALTH */ + /* Dummy command; if it succeeds, battery is present. */ + ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); + + if (ret < 0) { /* battery not present*/ + if (psp == POWER_SUPPLY_PROP_PRESENT) { + val->intval = 0; + return 0; + } + return ret; + } + + if (psp == POWER_SUPPLY_PROP_PRESENT) + val->intval = 1; /* battery present */ + else /* POWER_SUPPLY_PROP_HEALTH */ /* SBS spec doesn't have a general health command. */ val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; - } return 0; } @@ -513,8 +519,8 @@ static void sbs_unit_adjustment(struct i2c_client *client, } } -static enum sbs_battery_mode sbs_set_battery_mode(struct i2c_client *client, - enum sbs_battery_mode mode) +static enum sbs_capacity_mode sbs_set_capacity_mode(struct i2c_client *client, + enum sbs_capacity_mode mode) { int ret, original_val; @@ -522,13 +528,13 @@ static enum sbs_battery_mode sbs_set_battery_mode(struct i2c_client *client, if (original_val < 0) return original_val; - if ((original_val & BATTERY_MODE_MASK) == mode) + if ((original_val & BATTERY_MODE_CAPACITY_MASK) == mode) return mode; - if (mode == BATTERY_MODE_AMPS) - ret = original_val & ~BATTERY_MODE_MASK; + if (mode == CAPACITY_MODE_AMPS) + ret = original_val & ~BATTERY_MODE_CAPACITY_MASK; else - ret = original_val | BATTERY_MODE_MASK; + ret = original_val | BATTERY_MODE_CAPACITY_MASK; ret = sbs_write_word_data(client, BATTERY_MODE_OFFSET, ret); if (ret < 0) @@ -536,7 +542,7 @@ static enum sbs_battery_mode sbs_set_battery_mode(struct i2c_client *client, usleep_range(1000, 2000); - return original_val & BATTERY_MODE_MASK; + return original_val & BATTERY_MODE_CAPACITY_MASK; } static int sbs_get_battery_capacity(struct i2c_client *client, @@ -544,13 +550,13 @@ static int sbs_get_battery_capacity(struct i2c_client *client, union power_supply_propval *val) { s32 ret; - enum sbs_battery_mode mode = BATTERY_MODE_WATTS; + enum sbs_capacity_mode mode = CAPACITY_MODE_WATTS; if (power_supply_is_amp_property(psp)) - mode = BATTERY_MODE_AMPS; + mode = CAPACITY_MODE_AMPS; - mode = sbs_set_battery_mode(client, mode); - if (mode < 0) + mode = sbs_set_capacity_mode(client, mode); + if ((int)mode < 0) return mode; ret = sbs_read_word_data(client, sbs_data[reg_offset].addr); @@ -559,7 +565,7 @@ static int sbs_get_battery_capacity(struct i2c_client *client, val->intval = ret; - ret = sbs_set_battery_mode(client, mode); + ret = sbs_set_capacity_mode(client, mode); if (ret < 0) return ret; @@ -620,12 +626,14 @@ static int sbs_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_PRESENT: case POWER_SUPPLY_PROP_HEALTH: - if (client->flags & SBS_FLAGS_TI_BQ20Z75) + if (chip->flags & SBS_FLAGS_TI_BQ20Z75) ret = sbs_get_ti_battery_presence_and_health(client, psp, val); else ret = sbs_get_battery_presence_and_health(client, psp, val); + + /* this can only be true if no gpio is used */ if (psp == POWER_SUPPLY_PROP_PRESENT) return 0; break; @@ -994,6 +1002,6 @@ module_i2c_driver(sbs_battery_driver); MODULE_DESCRIPTION("SBS battery monitor driver"); MODULE_LICENSE("GPL"); -module_param(force_load, bool, S_IRUSR | S_IRGRP | S_IROTH); +module_param(force_load, bool, 0444); MODULE_PARM_DESC(force_load, "Attempt to load the driver even if no battery is connected"); |