aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq27x00_battery.c84
1 files changed, 69 insertions, 15 deletions
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 5657990b7ace..181ddece5181 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -22,6 +22,7 @@
22 * Datasheets: 22 * Datasheets:
23 * http://focus.ti.com/docs/prod/folders/print/bq27000.html 23 * http://focus.ti.com/docs/prod/folders/print/bq27000.html
24 * http://focus.ti.com/docs/prod/folders/print/bq27500.html 24 * http://focus.ti.com/docs/prod/folders/print/bq27500.html
25 * http://www.ti.com/product/bq27425-g1
25 */ 26 */
26 27
27#include <linux/module.h> 28#include <linux/module.h>
@@ -69,6 +70,10 @@
69#define BQ27500_FLAG_FC BIT(9) 70#define BQ27500_FLAG_FC BIT(9)
70#define BQ27500_FLAG_OTC BIT(15) 71#define BQ27500_FLAG_OTC BIT(15)
71 72
73/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
74#define BQ27425_REG_OFFSET 0x04
75#define BQ27425_REG_SOC 0x18 /* Register address plus offset */
76
72#define BQ27000_RS 20 /* Resistor sense */ 77#define BQ27000_RS 20 /* Resistor sense */
73#define BQ27x00_POWER_CONSTANT (256 * 29200 / 1000) 78#define BQ27x00_POWER_CONSTANT (256 * 29200 / 1000)
74 79
@@ -77,7 +82,7 @@ struct bq27x00_access_methods {
77 int (*read)(struct bq27x00_device_info *di, u8 reg, bool single); 82 int (*read)(struct bq27x00_device_info *di, u8 reg, bool single);
78}; 83};
79 84
80enum bq27x00_chip { BQ27000, BQ27500 }; 85enum bq27x00_chip { BQ27000, BQ27500, BQ27425};
81 86
82struct bq27x00_reg_cache { 87struct bq27x00_reg_cache {
83 int temperature; 88 int temperature;
@@ -132,6 +137,20 @@ static enum power_supply_property bq27x00_battery_props[] = {
132 POWER_SUPPLY_PROP_HEALTH, 137 POWER_SUPPLY_PROP_HEALTH,
133}; 138};
134 139
140static enum power_supply_property bq27425_battery_props[] = {
141 POWER_SUPPLY_PROP_STATUS,
142 POWER_SUPPLY_PROP_PRESENT,
143 POWER_SUPPLY_PROP_VOLTAGE_NOW,
144 POWER_SUPPLY_PROP_CURRENT_NOW,
145 POWER_SUPPLY_PROP_CAPACITY,
146 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
147 POWER_SUPPLY_PROP_TEMP,
148 POWER_SUPPLY_PROP_TECHNOLOGY,
149 POWER_SUPPLY_PROP_CHARGE_FULL,
150 POWER_SUPPLY_PROP_CHARGE_NOW,
151 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
152};
153
135static unsigned int poll_interval = 360; 154static unsigned int poll_interval = 360;
136module_param(poll_interval, uint, 0644); 155module_param(poll_interval, uint, 0644);
137MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ 156MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \
@@ -144,10 +163,24 @@ MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \
144static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg, 163static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
145 bool single) 164 bool single)
146{ 165{
166 if (di->chip == BQ27425)
167 return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
147 return di->bus.read(di, reg, single); 168 return di->bus.read(di, reg, single);
148} 169}
149 170
150/* 171/*
172 * Higher versions of the chip like BQ27425 and BQ27500
173 * differ from BQ27000 and BQ27200 in calculation of certain
174 * parameters. Hence we need to check for the chip type.
175 */
176static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
177{
178 if (di->chip == BQ27425 || di->chip == BQ27500)
179 return true;
180 return false;
181}
182
183/*
151 * Return the battery Relative State-of-Charge 184 * Return the battery Relative State-of-Charge
152 * Or < 0 if something fails. 185 * Or < 0 if something fails.
153 */ 186 */
@@ -157,6 +190,8 @@ static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
157 190
158 if (di->chip == BQ27500) 191 if (di->chip == BQ27500)
159 rsoc = bq27x00_read(di, BQ27500_REG_SOC, false); 192 rsoc = bq27x00_read(di, BQ27500_REG_SOC, false);
193 else if (di->chip == BQ27425)
194 rsoc = bq27x00_read(di, BQ27425_REG_SOC, false);
160 else 195 else
161 rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true); 196 rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);
162 197
@@ -181,7 +216,7 @@ static int bq27x00_battery_read_charge(struct bq27x00_device_info *di, u8 reg)
181 return charge; 216 return charge;
182 } 217 }
183 218
184 if (di->chip == BQ27500) 219 if (bq27xxx_is_chip_version_higher(di))
185 charge *= 1000; 220 charge *= 1000;
186 else 221 else
187 charge = charge * 3570 / BQ27000_RS; 222 charge = charge * 3570 / BQ27000_RS;
@@ -215,7 +250,7 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
215{ 250{
216 int ilmd; 251 int ilmd;
217 252
218 if (di->chip == BQ27500) 253 if (bq27xxx_is_chip_version_higher(di))
219 ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); 254 ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false);
220 else 255 else
221 ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true); 256 ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
@@ -225,7 +260,7 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di)
225 return ilmd; 260 return ilmd;
226 } 261 }
227 262
228 if (di->chip == BQ27500) 263 if (bq27xxx_is_chip_version_higher(di))
229 ilmd *= 1000; 264 ilmd *= 1000;
230 else 265 else
231 ilmd = ilmd * 256 * 3570 / BQ27000_RS; 266 ilmd = ilmd * 256 * 3570 / BQ27000_RS;
@@ -269,7 +304,7 @@ static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
269 return temp; 304 return temp;
270 } 305 }
271 306
272 if (di->chip == BQ27500) 307 if (bq27xxx_is_chip_version_higher(di))
273 temp -= 2731; 308 temp -= 2731;
274 else 309 else
275 temp = ((temp * 5) - 5463) / 2; 310 temp = ((temp * 5) - 5463) / 2;
@@ -371,10 +406,12 @@ static void bq27x00_update(struct bq27x00_device_info *di)
371{ 406{
372 struct bq27x00_reg_cache cache = {0, }; 407 struct bq27x00_reg_cache cache = {0, };
373 bool is_bq27500 = di->chip == BQ27500; 408 bool is_bq27500 = di->chip == BQ27500;
409 bool is_bq27425 = di->chip == BQ27425;
374 410
375 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); 411 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
376 if (cache.flags >= 0) { 412 if (cache.flags >= 0) {
377 if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) { 413 if (!is_bq27500 && !is_bq27425
414 && (cache.flags & BQ27000_FLAG_CI)) {
378 dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n"); 415 dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
379 cache.capacity = -ENODATA; 416 cache.capacity = -ENODATA;
380 cache.energy = -ENODATA; 417 cache.energy = -ENODATA;
@@ -385,14 +422,24 @@ static void bq27x00_update(struct bq27x00_device_info *di)
385 cache.health = -ENODATA; 422 cache.health = -ENODATA;
386 } else { 423 } else {
387 cache.capacity = bq27x00_battery_read_rsoc(di); 424 cache.capacity = bq27x00_battery_read_rsoc(di);
388 cache.energy = bq27x00_battery_read_energy(di); 425 if (!is_bq27425) {
389 cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE); 426 cache.energy = bq27x00_battery_read_energy(di);
390 cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP); 427 cache.time_to_empty =
391 cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF); 428 bq27x00_battery_read_time(di,
429 BQ27x00_REG_TTE);
430 cache.time_to_empty_avg =
431 bq27x00_battery_read_time(di,
432 BQ27x00_REG_TTECP);
433 cache.time_to_full =
434 bq27x00_battery_read_time(di,
435 BQ27x00_REG_TTF);
436 }
392 cache.charge_full = bq27x00_battery_read_lmd(di); 437 cache.charge_full = bq27x00_battery_read_lmd(di);
393 cache.health = bq27x00_battery_read_health(di); 438 cache.health = bq27x00_battery_read_health(di);
394 } 439 }
395 cache.temperature = bq27x00_battery_read_temperature(di); 440 cache.temperature = bq27x00_battery_read_temperature(di);
441 if (!is_bq27425)
442 cache.cycle_count = bq27x00_battery_read_cyct(di);
396 cache.cycle_count = bq27x00_battery_read_cyct(di); 443 cache.cycle_count = bq27x00_battery_read_cyct(di);
397 cache.power_avg = 444 cache.power_avg =
398 bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG); 445 bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG);
@@ -441,7 +488,7 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di,
441 return curr; 488 return curr;
442 } 489 }
443 490
444 if (di->chip == BQ27500) { 491 if (bq27xxx_is_chip_version_higher(di)) {
445 /* bq27500 returns signed value */ 492 /* bq27500 returns signed value */
446 val->intval = (int)((s16)curr) * 1000; 493 val->intval = (int)((s16)curr) * 1000;
447 } else { 494 } else {
@@ -462,7 +509,7 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di,
462{ 509{
463 int status; 510 int status;
464 511
465 if (di->chip == BQ27500) { 512 if (bq27xxx_is_chip_version_higher(di)) {
466 if (di->cache.flags & BQ27500_FLAG_FC) 513 if (di->cache.flags & BQ27500_FLAG_FC)
467 status = POWER_SUPPLY_STATUS_FULL; 514 status = POWER_SUPPLY_STATUS_FULL;
468 else if (di->cache.flags & BQ27500_FLAG_DSC) 515 else if (di->cache.flags & BQ27500_FLAG_DSC)
@@ -490,7 +537,7 @@ static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
490{ 537{
491 int level; 538 int level;
492 539
493 if (di->chip == BQ27500) { 540 if (bq27xxx_is_chip_version_higher(di)) {
494 if (di->cache.flags & BQ27500_FLAG_FC) 541 if (di->cache.flags & BQ27500_FLAG_FC)
495 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; 542 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
496 else if (di->cache.flags & BQ27500_FLAG_SOC1) 543 else if (di->cache.flags & BQ27500_FLAG_SOC1)
@@ -641,8 +688,14 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di)
641 int ret; 688 int ret;
642 689
643 di->bat.type = POWER_SUPPLY_TYPE_BATTERY; 690 di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
644 di->bat.properties = bq27x00_battery_props; 691 di->chip = BQ27425;
645 di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props); 692 if (di->chip == BQ27425) {
693 di->bat.properties = bq27425_battery_props;
694 di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
695 } else {
696 di->bat.properties = bq27x00_battery_props;
697 di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
698 }
646 di->bat.get_property = bq27x00_battery_get_property; 699 di->bat.get_property = bq27x00_battery_get_property;
647 di->bat.external_power_changed = bq27x00_external_power_changed; 700 di->bat.external_power_changed = bq27x00_external_power_changed;
648 701
@@ -800,6 +853,7 @@ static int bq27x00_battery_remove(struct i2c_client *client)
800static const struct i2c_device_id bq27x00_id[] = { 853static const struct i2c_device_id bq27x00_id[] = {
801 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */ 854 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */
802 { "bq27500", BQ27500 }, 855 { "bq27500", BQ27500 },
856 { "bq27425", BQ27425 },
803 {}, 857 {},
804}; 858};
805MODULE_DEVICE_TABLE(i2c, bq27x00_id); 859MODULE_DEVICE_TABLE(i2c, bq27x00_id);