···117117118118config BATTERY_BQ27x00119119 tristate "BQ27x00 battery driver"120120+ help121121+ Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips.122122+123123+config BATTERY_BQ27X00_I2C124124+ bool "BQ27200/BQ27500 support"125125+ depends on BATTERY_BQ27x00120126 depends on I2C127127+ default y121128 help122129 Say Y here to enable support for batteries with BQ27x00 (I2C) chips.130130+131131+config BATTERY_BQ27X00_PLATFORM132132+ bool "BQ27000 support"133133+ depends on BATTERY_BQ27x00134134+ default y135135+ help136136+ Say Y here to enable support for batteries with BQ27000 (HDQ) chips.123137124138config BATTERY_DA9030125139 tristate "DA9030 battery driver"
+596-207
drivers/power/bq27x00_battery.c
···33 *44 * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>55 * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>66+ * Copyright (C) 2010-2011 Lars-Peter Clausen <lars@metafoo.de>67 *78 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.89 *···1615 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.1716 *1817 */1818+1919+/*2020+ * Datasheets:2121+ * http://focus.ti.com/docs/prod/folders/print/bq27000.html2222+ * http://focus.ti.com/docs/prod/folders/print/bq27500.html2323+ */2424+1925#include <linux/module.h>2026#include <linux/param.h>2127#include <linux/jiffies.h>···3527#include <linux/slab.h>3628#include <asm/unaligned.h>37293838-#define DRIVER_VERSION "1.1.0"3030+#include <linux/power/bq27x00_battery.h>3131+3232+#define DRIVER_VERSION "1.2.0"39334034#define BQ27x00_REG_TEMP 0x064135#define BQ27x00_REG_VOLT 0x08···4636#define BQ27x00_REG_TTE 0x164737#define BQ27x00_REG_TTF 0x184838#define BQ27x00_REG_TTECP 0x263939+#define BQ27x00_REG_NAC 0x0C /* Nominal available capaciy */4040+#define BQ27x00_REG_LMD 0x12 /* Last measured discharge */4141+#define BQ27x00_REG_CYCT 0x2A /* Cycle count total */4242+#define BQ27x00_REG_AE 0x22 /* Available enery */49435044#define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */4545+#define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */5146#define BQ27000_FLAG_CHGS BIT(7)4747+#define BQ27000_FLAG_FC BIT(5)52485353-#define BQ27500_REG_SOC 0x2c4949+#define BQ27500_REG_SOC 0x2C5050+#define BQ27500_REG_DCAP 0x3C /* Design capacity */5451#define BQ27500_FLAG_DSC BIT(0)5552#define BQ27500_FLAG_FC BIT(9)56535757-/* If the system has several batteries we need a different name for each5858- * of them...5959- */6060-static DEFINE_IDR(battery_id);6161-static DEFINE_MUTEX(battery_mutex);5454+#define BQ27000_RS 20 /* Resistor sense */62556356struct bq27x00_device_info;6457struct bq27x00_access_methods {6565- int (*read)(u8 reg, int *rt_value, int b_single,6666- struct bq27x00_device_info *di);5858+ int (*read)(struct bq27x00_device_info *di, u8 reg, bool single);6759};68606961enum bq27x00_chip { BQ27000, BQ27500 };70626363+struct bq27x00_reg_cache {6464+ int temperature;6565+ int time_to_empty;6666+ int time_to_empty_avg;6767+ int time_to_full;6868+ int charge_full;6969+ int charge_counter;7070+ int capacity;7171+ int flags;7272+7373+ int current_now;7474+};7575+7176struct bq27x00_device_info {7277 struct device *dev;7378 int id;7474- struct bq27x00_access_methods *bus;7575- struct power_supply bat;7679 enum bq27x00_chip chip;77807878- struct i2c_client *client;8181+ struct bq27x00_reg_cache cache;8282+ int charge_design_full;8383+8484+ unsigned long last_update;8585+ struct delayed_work work;8686+8787+ struct power_supply bat;8888+8989+ struct bq27x00_access_methods bus;9090+9191+ struct mutex lock;7992};80938194static enum power_supply_property bq27x00_battery_props[] = {···11178 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,11279 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,11380 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,8181+ POWER_SUPPLY_PROP_TECHNOLOGY,8282+ POWER_SUPPLY_PROP_CHARGE_FULL,8383+ POWER_SUPPLY_PROP_CHARGE_NOW,8484+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,8585+ POWER_SUPPLY_PROP_CHARGE_COUNTER,8686+ POWER_SUPPLY_PROP_ENERGY_NOW,11487};8888+8989+static unsigned int poll_interval = 360;9090+module_param(poll_interval, uint, 0644);9191+MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \9292+ "0 disables polling");1159311694/*11795 * Common code for BQ27x00 devices11896 */11997120120-static int bq27x00_read(u8 reg, int *rt_value, int b_single,121121- struct bq27x00_device_info *di)9898+static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,9999+ bool single)122100{123123- return di->bus->read(reg, rt_value, b_single, di);124124-}125125-126126-/*127127- * Return the battery temperature in tenths of degree Celsius128128- * Or < 0 if something fails.129129- */130130-static int bq27x00_battery_temperature(struct bq27x00_device_info *di)131131-{132132- int ret;133133- int temp = 0;134134-135135- ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di);136136- if (ret) {137137- dev_err(di->dev, "error reading temperature\n");138138- return ret;139139- }140140-141141- if (di->chip == BQ27500)142142- return temp - 2731;143143- else144144- return ((temp >> 2) - 273) * 10;145145-}146146-147147-/*148148- * Return the battery Voltage in milivolts149149- * Or < 0 if something fails.150150- */151151-static int bq27x00_battery_voltage(struct bq27x00_device_info *di)152152-{153153- int ret;154154- int volt = 0;155155-156156- ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di);157157- if (ret) {158158- dev_err(di->dev, "error reading voltage\n");159159- return ret;160160- }161161-162162- return volt * 1000;163163-}164164-165165-/*166166- * Return the battery average current167167- * Note that current can be negative signed as well168168- * Or 0 if something fails.169169- */170170-static int bq27x00_battery_current(struct bq27x00_device_info *di)171171-{172172- int ret;173173- int curr = 0;174174- int flags = 0;175175-176176- ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di);177177- if (ret) {178178- dev_err(di->dev, "error reading current\n");179179- return 0;180180- }181181-182182- if (di->chip == BQ27500) {183183- /* bq27500 returns signed value */184184- curr = (int)(s16)curr;185185- } else {186186- ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);187187- if (ret < 0) {188188- dev_err(di->dev, "error reading flags\n");189189- return 0;190190- }191191- if (flags & BQ27000_FLAG_CHGS) {192192- dev_dbg(di->dev, "negative current!\n");193193- curr = -curr;194194- }195195- }196196-197197- return curr * 1000;101101+ return di->bus.read(di, reg, single);198102}199103200104/*201105 * Return the battery Relative State-of-Charge202106 * Or < 0 if something fails.203107 */204204-static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)108108+static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)205109{206206- int ret;207207- int rsoc = 0;110110+ int rsoc;208111209112 if (di->chip == BQ27500)210210- ret = bq27x00_read(BQ27500_REG_SOC, &rsoc, 0, di);113113+ rsoc = bq27x00_read(di, BQ27500_REG_SOC, false);211114 else212212- ret = bq27x00_read(BQ27000_REG_RSOC, &rsoc, 1, di);213213- if (ret) {115115+ rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);116116+117117+ if (rsoc < 0)214118 dev_err(di->dev, "error reading relative State-of-Charge\n");215215- return ret;216216- }217119218120 return rsoc;219121}220122221221-static int bq27x00_battery_status(struct bq27x00_device_info *di,222222- union power_supply_propval *val)123123+/*124124+ * Return a battery charge value in µAh125125+ * Or < 0 if something fails.126126+ */127127+static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)223128{224224- int flags = 0;225225- int status;226226- int ret;129129+ int charge;227130228228- ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);229229- if (ret < 0) {230230- dev_err(di->dev, "error reading flags\n");231231- return ret;131131+ charge = bq27x00_read(di, reg, false);132132+ if (charge < 0) {133133+ dev_err(di->dev, "error reading nominal available capacity\n");134134+ return charge;232135 }233136234234- if (di->chip == BQ27500) {235235- if (flags & BQ27500_FLAG_FC)236236- status = POWER_SUPPLY_STATUS_FULL;237237- else if (flags & BQ27500_FLAG_DSC)238238- status = POWER_SUPPLY_STATUS_DISCHARGING;239239- else240240- status = POWER_SUPPLY_STATUS_CHARGING;241241- } else {242242- if (flags & BQ27000_FLAG_CHGS)243243- status = POWER_SUPPLY_STATUS_CHARGING;244244- else245245- status = POWER_SUPPLY_STATUS_DISCHARGING;137137+ if (di->chip == BQ27500)138138+ charge *= 1000;139139+ else140140+ charge = charge * 3570 / BQ27000_RS;141141+142142+ return charge;143143+}144144+145145+/*146146+ * Return the battery Nominal available capaciy in µAh147147+ * Or < 0 if something fails.148148+ */149149+static inline int bq27x00_battery_read_nac(struct bq27x00_device_info *di)150150+{151151+ return bq27x00_battery_read_charge(di, BQ27x00_REG_NAC);152152+}153153+154154+/*155155+ * Return the battery Last measured discharge in µAh156156+ * Or < 0 if something fails.157157+ */158158+static inline int bq27x00_battery_read_lmd(struct bq27x00_device_info *di)159159+{160160+ return bq27x00_battery_read_charge(di, BQ27x00_REG_LMD);161161+}162162+163163+/*164164+ * Return the battery Initial last measured discharge in µAh165165+ * Or < 0 if something fails.166166+ */167167+static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)168168+{169169+ int ilmd;170170+171171+ if (di->chip == BQ27500)172172+ ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false);173173+ else174174+ ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);175175+176176+ if (ilmd < 0) {177177+ dev_err(di->dev, "error reading initial last measured discharge\n");178178+ return ilmd;246179 }247180248248- val->intval = status;249249- return 0;181181+ if (di->chip == BQ27500)182182+ ilmd *= 1000;183183+ else184184+ ilmd = ilmd * 256 * 3570 / BQ27000_RS;185185+186186+ return ilmd;187187+}188188+189189+/*190190+ * Return the battery Cycle count total191191+ * Or < 0 if something fails.192192+ */193193+static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di)194194+{195195+ int cyct;196196+197197+ cyct = bq27x00_read(di, BQ27x00_REG_CYCT, false);198198+ if (cyct < 0)199199+ dev_err(di->dev, "error reading cycle count total\n");200200+201201+ return cyct;250202}251203252204/*253205 * Read a time register.254206 * Return < 0 if something fails.255207 */256256-static int bq27x00_battery_time(struct bq27x00_device_info *di, int reg,257257- union power_supply_propval *val)208208+static int bq27x00_battery_read_time(struct bq27x00_device_info *di, u8 reg)258209{259259- int tval = 0;260260- int ret;210210+ int tval;261211262262- ret = bq27x00_read(reg, &tval, 0, di);263263- if (ret) {264264- dev_err(di->dev, "error reading register %02x\n", reg);265265- return ret;212212+ tval = bq27x00_read(di, reg, false);213213+ if (tval < 0) {214214+ dev_err(di->dev, "error reading register %02x: %d\n", reg, tval);215215+ return tval;266216 }267217268218 if (tval == 65535)269219 return -ENODATA;270220271271- val->intval = tval * 60;221221+ return tval * 60;222222+}223223+224224+static void bq27x00_update(struct bq27x00_device_info *di)225225+{226226+ struct bq27x00_reg_cache cache = {0, };227227+ bool is_bq27500 = di->chip == BQ27500;228228+229229+ cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500);230230+ if (cache.flags >= 0) {231231+ cache.capacity = bq27x00_battery_read_rsoc(di);232232+ cache.temperature = bq27x00_read(di, BQ27x00_REG_TEMP, false);233233+ cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE);234234+ cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);235235+ cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);236236+ cache.charge_full = bq27x00_battery_read_lmd(di);237237+ cache.charge_counter = bq27x00_battery_read_cyct(di);238238+239239+ if (!is_bq27500)240240+ cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false);241241+242242+ /* We only have to read charge design full once */243243+ if (di->charge_design_full <= 0)244244+ di->charge_design_full = bq27x00_battery_read_ilmd(di);245245+ }246246+247247+ /* Ignore current_now which is a snapshot of the current battery state248248+ * and is likely to be different even between two consecutive reads */249249+ if (memcmp(&di->cache, &cache, sizeof(cache) - sizeof(int)) != 0) {250250+ di->cache = cache;251251+ power_supply_changed(&di->bat);252252+ }253253+254254+ di->last_update = jiffies;255255+}256256+257257+static void bq27x00_battery_poll(struct work_struct *work)258258+{259259+ struct bq27x00_device_info *di =260260+ container_of(work, struct bq27x00_device_info, work.work);261261+262262+ bq27x00_update(di);263263+264264+ if (poll_interval > 0) {265265+ /* The timer does not have to be accurate. */266266+ set_timer_slack(&di->work.timer, poll_interval * HZ / 4);267267+ schedule_delayed_work(&di->work, poll_interval * HZ);268268+ }269269+}270270+271271+272272+/*273273+ * Return the battery temperature in tenths of degree Celsius274274+ * Or < 0 if something fails.275275+ */276276+static int bq27x00_battery_temperature(struct bq27x00_device_info *di,277277+ union power_supply_propval *val)278278+{279279+ if (di->cache.temperature < 0)280280+ return di->cache.temperature;281281+282282+ if (di->chip == BQ27500)283283+ val->intval = di->cache.temperature - 2731;284284+ else285285+ val->intval = ((di->cache.temperature * 5) - 5463) / 2;286286+287287+ return 0;288288+}289289+290290+/*291291+ * Return the battery average current in µA292292+ * Note that current can be negative signed as well293293+ * Or 0 if something fails.294294+ */295295+static int bq27x00_battery_current(struct bq27x00_device_info *di,296296+ union power_supply_propval *val)297297+{298298+ int curr;299299+300300+ if (di->chip == BQ27500)301301+ curr = bq27x00_read(di, BQ27x00_REG_AI, false);302302+ else303303+ curr = di->cache.current_now;304304+305305+ if (curr < 0)306306+ return curr;307307+308308+ if (di->chip == BQ27500) {309309+ /* bq27500 returns signed value */310310+ val->intval = (int)((s16)curr) * 1000;311311+ } else {312312+ if (di->cache.flags & BQ27000_FLAG_CHGS) {313313+ dev_dbg(di->dev, "negative current!\n");314314+ curr = -curr;315315+ }316316+317317+ val->intval = curr * 3570 / BQ27000_RS;318318+ }319319+320320+ return 0;321321+}322322+323323+static int bq27x00_battery_status(struct bq27x00_device_info *di,324324+ union power_supply_propval *val)325325+{326326+ int status;327327+328328+ if (di->chip == BQ27500) {329329+ if (di->cache.flags & BQ27500_FLAG_FC)330330+ status = POWER_SUPPLY_STATUS_FULL;331331+ else if (di->cache.flags & BQ27500_FLAG_DSC)332332+ status = POWER_SUPPLY_STATUS_DISCHARGING;333333+ else334334+ status = POWER_SUPPLY_STATUS_CHARGING;335335+ } else {336336+ if (di->cache.flags & BQ27000_FLAG_FC)337337+ status = POWER_SUPPLY_STATUS_FULL;338338+ else if (di->cache.flags & BQ27000_FLAG_CHGS)339339+ status = POWER_SUPPLY_STATUS_CHARGING;340340+ else if (power_supply_am_i_supplied(&di->bat))341341+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;342342+ else343343+ status = POWER_SUPPLY_STATUS_DISCHARGING;344344+ }345345+346346+ val->intval = status;347347+348348+ return 0;349349+}350350+351351+/*352352+ * Return the battery Voltage in milivolts353353+ * Or < 0 if something fails.354354+ */355355+static int bq27x00_battery_voltage(struct bq27x00_device_info *di,356356+ union power_supply_propval *val)357357+{358358+ int volt;359359+360360+ volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);361361+ if (volt < 0)362362+ return volt;363363+364364+ val->intval = volt * 1000;365365+366366+ return 0;367367+}368368+369369+/*370370+ * Return the battery Available energy in µWh371371+ * Or < 0 if something fails.372372+ */373373+static int bq27x00_battery_energy(struct bq27x00_device_info *di,374374+ union power_supply_propval *val)375375+{376376+ int ae;377377+378378+ ae = bq27x00_read(di, BQ27x00_REG_AE, false);379379+ if (ae < 0) {380380+ dev_err(di->dev, "error reading available energy\n");381381+ return ae;382382+ }383383+384384+ if (di->chip == BQ27500)385385+ ae *= 1000;386386+ else387387+ ae = ae * 29200 / BQ27000_RS;388388+389389+ val->intval = ae;390390+391391+ return 0;392392+}393393+394394+395395+static int bq27x00_simple_value(int value,396396+ union power_supply_propval *val)397397+{398398+ if (value < 0)399399+ return value;400400+401401+ val->intval = value;402402+272403 return 0;273404}274405···446249 int ret = 0;447250 struct bq27x00_device_info *di = to_bq27x00_device_info(psy);448251252252+ mutex_lock(&di->lock);253253+ if (time_is_before_jiffies(di->last_update + 5 * HZ)) {254254+ cancel_delayed_work_sync(&di->work);255255+ bq27x00_battery_poll(&di->work.work);256256+ }257257+ mutex_unlock(&di->lock);258258+259259+ if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)260260+ return -ENODEV;261261+449262 switch (psp) {450263 case POWER_SUPPLY_PROP_STATUS:451264 ret = bq27x00_battery_status(di, val);452265 break;453266 case POWER_SUPPLY_PROP_VOLTAGE_NOW:267267+ ret = bq27x00_battery_voltage(di, val);268268+ break;454269 case POWER_SUPPLY_PROP_PRESENT:455455- val->intval = bq27x00_battery_voltage(di);456456- if (psp == POWER_SUPPLY_PROP_PRESENT)457457- val->intval = val->intval <= 0 ? 0 : 1;270270+ val->intval = di->cache.flags < 0 ? 0 : 1;458271 break;459272 case POWER_SUPPLY_PROP_CURRENT_NOW:460460- val->intval = bq27x00_battery_current(di);273273+ ret = bq27x00_battery_current(di, val);461274 break;462275 case POWER_SUPPLY_PROP_CAPACITY:463463- val->intval = bq27x00_battery_rsoc(di);276276+ ret = bq27x00_simple_value(di->cache.capacity, val);464277 break;465278 case POWER_SUPPLY_PROP_TEMP:466466- val->intval = bq27x00_battery_temperature(di);279279+ ret = bq27x00_battery_temperature(di, val);467280 break;468281 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:469469- ret = bq27x00_battery_time(di, BQ27x00_REG_TTE, val);282282+ ret = bq27x00_simple_value(di->cache.time_to_empty, val);470283 break;471284 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:472472- ret = bq27x00_battery_time(di, BQ27x00_REG_TTECP, val);285285+ ret = bq27x00_simple_value(di->cache.time_to_empty_avg, val);473286 break;474287 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:475475- ret = bq27x00_battery_time(di, BQ27x00_REG_TTF, val);288288+ ret = bq27x00_simple_value(di->cache.time_to_full, val);289289+ break;290290+ case POWER_SUPPLY_PROP_TECHNOLOGY:291291+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;292292+ break;293293+ case POWER_SUPPLY_PROP_CHARGE_NOW:294294+ ret = bq27x00_simple_value(bq27x00_battery_read_nac(di), val);295295+ break;296296+ case POWER_SUPPLY_PROP_CHARGE_FULL:297297+ ret = bq27x00_simple_value(di->cache.charge_full, val);298298+ break;299299+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:300300+ ret = bq27x00_simple_value(di->charge_design_full, val);301301+ break;302302+ case POWER_SUPPLY_PROP_CHARGE_COUNTER:303303+ ret = bq27x00_simple_value(di->cache.charge_counter, val);304304+ break;305305+ case POWER_SUPPLY_PROP_ENERGY_NOW:306306+ ret = bq27x00_battery_energy(di, val);476307 break;477308 default:478309 return -EINVAL;···509284 return ret;510285}511286512512-static void bq27x00_powersupply_init(struct bq27x00_device_info *di)287287+static void bq27x00_external_power_changed(struct power_supply *psy)513288{289289+ struct bq27x00_device_info *di = to_bq27x00_device_info(psy);290290+291291+ cancel_delayed_work_sync(&di->work);292292+ schedule_delayed_work(&di->work, 0);293293+}294294+295295+static int bq27x00_powersupply_init(struct bq27x00_device_info *di)296296+{297297+ int ret;298298+514299 di->bat.type = POWER_SUPPLY_TYPE_BATTERY;515300 di->bat.properties = bq27x00_battery_props;516301 di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);517302 di->bat.get_property = bq27x00_battery_get_property;518518- di->bat.external_power_changed = NULL;303303+ di->bat.external_power_changed = bq27x00_external_power_changed;304304+305305+ INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll);306306+ mutex_init(&di->lock);307307+308308+ ret = power_supply_register(di->dev, &di->bat);309309+ if (ret) {310310+ dev_err(di->dev, "failed to register battery: %d\n", ret);311311+ return ret;312312+ }313313+314314+ dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);315315+316316+ bq27x00_update(di);317317+318318+ return 0;519319}520320521521-/*522522- * i2c specific code523523- */524524-525525-static int bq27x00_read_i2c(u8 reg, int *rt_value, int b_single,526526- struct bq27x00_device_info *di)321321+static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di)527322{528528- struct i2c_client *client = di->client;529529- struct i2c_msg msg[1];323323+ cancel_delayed_work_sync(&di->work);324324+325325+ power_supply_unregister(&di->bat);326326+327327+ mutex_destroy(&di->lock);328328+}329329+330330+331331+/* i2c specific code */332332+#ifdef CONFIG_BATTERY_BQ27X00_I2C333333+334334+/* If the system has several batteries we need a different name for each335335+ * of them...336336+ */337337+static DEFINE_IDR(battery_id);338338+static DEFINE_MUTEX(battery_mutex);339339+340340+static int bq27x00_read_i2c(struct bq27x00_device_info *di, u8 reg, bool single)341341+{342342+ struct i2c_client *client = to_i2c_client(di->dev);343343+ struct i2c_msg msg[2];530344 unsigned char data[2];531531- int err;345345+ int ret;532346533347 if (!client->adapter)534348 return -ENODEV;535349536536- msg->addr = client->addr;537537- msg->flags = 0;538538- msg->len = 1;539539- msg->buf = data;350350+ msg[0].addr = client->addr;351351+ msg[0].flags = 0;352352+ msg[0].buf = ®353353+ msg[0].len = sizeof(reg);354354+ msg[1].addr = client->addr;355355+ msg[1].flags = I2C_M_RD;356356+ msg[1].buf = data;357357+ if (single)358358+ msg[1].len = 1;359359+ else360360+ msg[1].len = 2;540361541541- data[0] = reg;542542- err = i2c_transfer(client->adapter, msg, 1);362362+ ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));363363+ if (ret < 0)364364+ return ret;543365544544- if (err >= 0) {545545- if (!b_single)546546- msg->len = 2;547547- else548548- msg->len = 1;366366+ if (!single)367367+ ret = get_unaligned_le16(data);368368+ else369369+ ret = data[0];549370550550- msg->flags = I2C_M_RD;551551- err = i2c_transfer(client->adapter, msg, 1);552552- if (err >= 0) {553553- if (!b_single)554554- *rt_value = get_unaligned_le16(data);555555- else556556- *rt_value = data[0];557557-558558- return 0;559559- }560560- }561561- return err;371371+ return ret;562372}563373564374static int bq27x00_battery_probe(struct i2c_client *client,···601341{602342 char *name;603343 struct bq27x00_device_info *di;604604- struct bq27x00_access_methods *bus;605344 int num;606345 int retval = 0;607346···627368 retval = -ENOMEM;628369 goto batt_failed_2;629370 }630630- di->id = num;631631- di->chip = id->driver_data;632371633633- bus = kzalloc(sizeof(*bus), GFP_KERNEL);634634- if (!bus) {635635- dev_err(&client->dev, "failed to allocate access method "636636- "data\n");637637- retval = -ENOMEM;372372+ di->id = num;373373+ di->dev = &client->dev;374374+ di->chip = id->driver_data;375375+ di->bat.name = name;376376+ di->bus.read = &bq27x00_read_i2c;377377+378378+ if (bq27x00_powersupply_init(di))638379 goto batt_failed_3;639639- }640380641381 i2c_set_clientdata(client, di);642642- di->dev = &client->dev;643643- di->bat.name = name;644644- bus->read = &bq27x00_read_i2c;645645- di->bus = bus;646646- di->client = client;647647-648648- bq27x00_powersupply_init(di);649649-650650- retval = power_supply_register(&client->dev, &di->bat);651651- if (retval) {652652- dev_err(&client->dev, "failed to register battery\n");653653- goto batt_failed_4;654654- }655655-656656- dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);657382658383 return 0;659384660660-batt_failed_4:661661- kfree(bus);662385batt_failed_3:663386 kfree(di);664387batt_failed_2:···657416{658417 struct bq27x00_device_info *di = i2c_get_clientdata(client);659418660660- power_supply_unregister(&di->bat);419419+ bq27x00_powersupply_unregister(di);661420662662- kfree(di->bus);663421 kfree(di->bat.name);664422665423 mutex_lock(&battery_mutex);···670430 return 0;671431}672432673673-/*674674- * Module stuff675675- */676676-677433static const struct i2c_device_id bq27x00_id[] = {678434 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */679435 { "bq27500", BQ27500 },680436 {},681437};438438+MODULE_DEVICE_TABLE(i2c, bq27x00_id);682439683440static struct i2c_driver bq27x00_battery_driver = {684441 .driver = {···686449 .id_table = bq27x00_id,687450};688451452452+static inline int bq27x00_battery_i2c_init(void)453453+{454454+ int ret = i2c_add_driver(&bq27x00_battery_driver);455455+ if (ret)456456+ printk(KERN_ERR "Unable to register BQ27x00 i2c driver\n");457457+458458+ return ret;459459+}460460+461461+static inline void bq27x00_battery_i2c_exit(void)462462+{463463+ i2c_del_driver(&bq27x00_battery_driver);464464+}465465+466466+#else467467+468468+static inline int bq27x00_battery_i2c_init(void) { return 0; }469469+static inline void bq27x00_battery_i2c_exit(void) {};470470+471471+#endif472472+473473+/* platform specific code */474474+#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM475475+476476+static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg,477477+ bool single)478478+{479479+ struct device *dev = di->dev;480480+ struct bq27000_platform_data *pdata = dev->platform_data;481481+ unsigned int timeout = 3;482482+ int upper, lower;483483+ int temp;484484+485485+ if (!single) {486486+ /* Make sure the value has not changed in between reading the487487+ * lower and the upper part */488488+ upper = pdata->read(dev, reg + 1);489489+ do {490490+ temp = upper;491491+ if (upper < 0)492492+ return upper;493493+494494+ lower = pdata->read(dev, reg);495495+ if (lower < 0)496496+ return lower;497497+498498+ upper = pdata->read(dev, reg + 1);499499+ } while (temp != upper && --timeout);500500+501501+ if (timeout == 0)502502+ return -EIO;503503+504504+ return (upper << 8) | lower;505505+ }506506+507507+ return pdata->read(dev, reg);508508+}509509+510510+static int __devinit bq27000_battery_probe(struct platform_device *pdev)511511+{512512+ struct bq27x00_device_info *di;513513+ struct bq27000_platform_data *pdata = pdev->dev.platform_data;514514+ int ret;515515+516516+ if (!pdata) {517517+ dev_err(&pdev->dev, "no platform_data supplied\n");518518+ return -EINVAL;519519+ }520520+521521+ if (!pdata->read) {522522+ dev_err(&pdev->dev, "no hdq read callback supplied\n");523523+ return -EINVAL;524524+ }525525+526526+ di = kzalloc(sizeof(*di), GFP_KERNEL);527527+ if (!di) {528528+ dev_err(&pdev->dev, "failed to allocate device info data\n");529529+ return -ENOMEM;530530+ }531531+532532+ platform_set_drvdata(pdev, di);533533+534534+ di->dev = &pdev->dev;535535+ di->chip = BQ27000;536536+537537+ di->bat.name = pdata->name ?: dev_name(&pdev->dev);538538+ di->bus.read = &bq27000_read_platform;539539+540540+ ret = bq27x00_powersupply_init(di);541541+ if (ret)542542+ goto err_free;543543+544544+ return 0;545545+546546+err_free:547547+ platform_set_drvdata(pdev, NULL);548548+ kfree(di);549549+550550+ return ret;551551+}552552+553553+static int __devexit bq27000_battery_remove(struct platform_device *pdev)554554+{555555+ struct bq27x00_device_info *di = platform_get_drvdata(pdev);556556+557557+ bq27x00_powersupply_unregister(di);558558+559559+ platform_set_drvdata(pdev, NULL);560560+ kfree(di);561561+562562+ return 0;563563+}564564+565565+static struct platform_driver bq27000_battery_driver = {566566+ .probe = bq27000_battery_probe,567567+ .remove = __devexit_p(bq27000_battery_remove),568568+ .driver = {569569+ .name = "bq27000-battery",570570+ .owner = THIS_MODULE,571571+ },572572+};573573+574574+static inline int bq27x00_battery_platform_init(void)575575+{576576+ int ret = platform_driver_register(&bq27000_battery_driver);577577+ if (ret)578578+ printk(KERN_ERR "Unable to register BQ27000 platform driver\n");579579+580580+ return ret;581581+}582582+583583+static inline void bq27x00_battery_platform_exit(void)584584+{585585+ platform_driver_unregister(&bq27000_battery_driver);586586+}587587+588588+#else589589+590590+static inline int bq27x00_battery_platform_init(void) { return 0; }591591+static inline void bq27x00_battery_platform_exit(void) {};592592+593593+#endif594594+595595+/*596596+ * Module stuff597597+ */598598+689599static int __init bq27x00_battery_init(void)690600{691601 int ret;692602693693- ret = i2c_add_driver(&bq27x00_battery_driver);603603+ ret = bq27x00_battery_i2c_init();694604 if (ret)695695- printk(KERN_ERR "Unable to register BQ27x00 driver\n");605605+ return ret;606606+607607+ ret = bq27x00_battery_platform_init();608608+ if (ret)609609+ bq27x00_battery_i2c_exit();696610697611 return ret;698612}···851463852464static void __exit bq27x00_battery_exit(void)853465{854854- i2c_del_driver(&bq27x00_battery_driver);466466+ bq27x00_battery_platform_exit();467467+ bq27x00_battery_i2c_exit();855468}856469module_exit(bq27x00_battery_exit);857470
···270270 attr = &power_supply_attrs[psy->properties[j]];271271272272 ret = power_supply_show_property(dev, attr, prop_buf);273273- if (ret == -ENODEV) {273273+ if (ret == -ENODEV || ret == -ENODATA) {274274 /* When a battery is absent, we expect -ENODEV. Don't abort;275275 send the uevent with at least the the PRESENT=0 property */276276 ret = 0;
+19
include/linux/power/bq27x00_battery.h
···11+#ifndef __LINUX_BQ27X00_BATTERY_H__22+#define __LINUX_BQ27X00_BATTERY_H__33+44+/**55+ * struct bq27000_plaform_data - Platform data for bq27000 devices66+ * @name: Name of the battery. If NULL the driver will fallback to "bq27000".77+ * @read: HDQ read callback.88+ * This function should provide access to the HDQ bus the battery is99+ * connected to.1010+ * The first parameter is a pointer to the battery device, the second the1111+ * register to be read. The return value should either be the content of1212+ * the passed register or an error value.1313+ */1414+struct bq27000_platform_data {1515+ const char *name;1616+ int (*read)(struct device *dev, unsigned int);1717+};1818+1919+#endif