aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/bq27x00_battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/bq27x00_battery.c')
-rw-r--r--drivers/power/bq27x00_battery.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index e10763e3a1d5..5b9f0eacb20a 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -23,6 +23,7 @@
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 * http://www.ti.com/product/bq27425-g1
26 * http://www.ti.com/product/BQ27742-G1
26 */ 27 */
27 28
28#include <linux/device.h> 29#include <linux/device.h>
@@ -71,6 +72,8 @@
71#define BQ27500_FLAG_FC BIT(9) 72#define BQ27500_FLAG_FC BIT(9)
72#define BQ27500_FLAG_OTC BIT(15) 73#define BQ27500_FLAG_OTC BIT(15)
73 74
75#define BQ27742_POWER_AVG 0x76
76
74/* bq27425 register addresses are same as bq27x00 addresses minus 4 */ 77/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
75#define BQ27425_REG_OFFSET 0x04 78#define BQ27425_REG_OFFSET 0x04
76#define BQ27425_REG_SOC 0x18 /* Register address plus offset */ 79#define BQ27425_REG_SOC 0x18 /* Register address plus offset */
@@ -83,7 +86,7 @@ struct bq27x00_access_methods {
83 int (*read)(struct bq27x00_device_info *di, u8 reg, bool single); 86 int (*read)(struct bq27x00_device_info *di, u8 reg, bool single);
84}; 87};
85 88
86enum bq27x00_chip { BQ27000, BQ27500, BQ27425}; 89enum bq27x00_chip { BQ27000, BQ27500, BQ27425, BQ27742};
87 90
88struct bq27x00_reg_cache { 91struct bq27x00_reg_cache {
89 int temperature; 92 int temperature;
@@ -152,6 +155,24 @@ static enum power_supply_property bq27425_battery_props[] = {
152 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 155 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
153}; 156};
154 157
158static enum power_supply_property bq27742_battery_props[] = {
159 POWER_SUPPLY_PROP_STATUS,
160 POWER_SUPPLY_PROP_PRESENT,
161 POWER_SUPPLY_PROP_VOLTAGE_NOW,
162 POWER_SUPPLY_PROP_CURRENT_NOW,
163 POWER_SUPPLY_PROP_CAPACITY,
164 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
165 POWER_SUPPLY_PROP_TEMP,
166 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
167 POWER_SUPPLY_PROP_TECHNOLOGY,
168 POWER_SUPPLY_PROP_CHARGE_FULL,
169 POWER_SUPPLY_PROP_CHARGE_NOW,
170 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
171 POWER_SUPPLY_PROP_CYCLE_COUNT,
172 POWER_SUPPLY_PROP_POWER_AVG,
173 POWER_SUPPLY_PROP_HEALTH,
174};
175
155static unsigned int poll_interval = 360; 176static unsigned int poll_interval = 360;
156module_param(poll_interval, uint, 0644); 177module_param(poll_interval, uint, 0644);
157MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ 178MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \
@@ -176,7 +197,7 @@ static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
176 */ 197 */
177static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di) 198static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
178{ 199{
179 if (di->chip == BQ27425 || di->chip == BQ27500) 200 if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742)
180 return true; 201 return true;
181 return false; 202 return false;
182} 203}
@@ -189,7 +210,7 @@ static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di)
189{ 210{
190 int rsoc; 211 int rsoc;
191 212
192 if (di->chip == BQ27500) 213 if (di->chip == BQ27500 || di->chip == BQ27742)
193 rsoc = bq27x00_read(di, BQ27500_REG_SOC, false); 214 rsoc = bq27x00_read(di, BQ27500_REG_SOC, false);
194 else if (di->chip == BQ27425) 215 else if (di->chip == BQ27425)
195 rsoc = bq27x00_read(di, BQ27425_REG_SOC, false); 216 rsoc = bq27x00_read(di, BQ27425_REG_SOC, false);
@@ -414,6 +435,7 @@ static void bq27x00_update(struct bq27x00_device_info *di)
414 struct bq27x00_reg_cache cache = {0, }; 435 struct bq27x00_reg_cache cache = {0, };
415 bool is_bq27500 = di->chip == BQ27500; 436 bool is_bq27500 = di->chip == BQ27500;
416 bool is_bq27425 = di->chip == BQ27425; 437 bool is_bq27425 = di->chip == BQ27425;
438 bool is_bq27742 = di->chip == BQ27742;
417 439
418 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); 440 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
419 if ((cache.flags & 0xff) == 0xff) 441 if ((cache.flags & 0xff) == 0xff)
@@ -432,7 +454,11 @@ static void bq27x00_update(struct bq27x00_device_info *di)
432 cache.health = -ENODATA; 454 cache.health = -ENODATA;
433 } else { 455 } else {
434 cache.capacity = bq27x00_battery_read_rsoc(di); 456 cache.capacity = bq27x00_battery_read_rsoc(di);
435 if (!is_bq27425) { 457 if (is_bq27742)
458 cache.time_to_empty =
459 bq27x00_battery_read_time(di,
460 BQ27x00_REG_TTE);
461 else if (!is_bq27425) {
436 cache.energy = bq27x00_battery_read_energy(di); 462 cache.energy = bq27x00_battery_read_energy(di);
437 cache.time_to_empty = 463 cache.time_to_empty =
438 bq27x00_battery_read_time(di, 464 bq27x00_battery_read_time(di,
@@ -444,14 +470,22 @@ static void bq27x00_update(struct bq27x00_device_info *di)
444 bq27x00_battery_read_time(di, 470 bq27x00_battery_read_time(di,
445 BQ27x00_REG_TTF); 471 BQ27x00_REG_TTF);
446 } 472 }
447 cache.charge_full = bq27x00_battery_read_lmd(di); 473 if (!is_bq27742)
474 cache.charge_full =
475 bq27x00_battery_read_lmd(di);
448 cache.health = bq27x00_battery_read_health(di); 476 cache.health = bq27x00_battery_read_health(di);
449 } 477 }
450 cache.temperature = bq27x00_battery_read_temperature(di); 478 cache.temperature = bq27x00_battery_read_temperature(di);
451 if (!is_bq27425) 479 if (!is_bq27425)
452 cache.cycle_count = bq27x00_battery_read_cyct(di); 480 cache.cycle_count = bq27x00_battery_read_cyct(di);
453 cache.power_avg = 481 if (is_bq27742)
454 bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG); 482 cache.power_avg =
483 bq27x00_battery_read_pwr_avg(di,
484 BQ27742_POWER_AVG);
485 else
486 cache.power_avg =
487 bq27x00_battery_read_pwr_avg(di,
488 BQ27x00_POWER_AVG);
455 489
456 /* We only have to read charge design full once */ 490 /* We only have to read charge design full once */
457 if (di->charge_design_full <= 0) 491 if (di->charge_design_full <= 0)
@@ -702,6 +736,9 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di)
702 if (di->chip == BQ27425) { 736 if (di->chip == BQ27425) {
703 di->bat.properties = bq27425_battery_props; 737 di->bat.properties = bq27425_battery_props;
704 di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props); 738 di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
739 } else if (di->chip == BQ27742) {
740 di->bat.properties = bq27742_battery_props;
741 di->bat.num_properties = ARRAY_SIZE(bq27742_battery_props);
705 } else { 742 } else {
706 di->bat.properties = bq27x00_battery_props; 743 di->bat.properties = bq27x00_battery_props;
707 di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props); 744 di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
@@ -858,6 +895,7 @@ static const struct i2c_device_id bq27x00_id[] = {
858 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */ 895 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */
859 { "bq27500", BQ27500 }, 896 { "bq27500", BQ27500 },
860 { "bq27425", BQ27425 }, 897 { "bq27425", BQ27425 },
898 { "bq27742", BQ27742 },
861 {}, 899 {},
862}; 900};
863MODULE_DEVICE_TABLE(i2c, bq27x00_id); 901MODULE_DEVICE_TABLE(i2c, bq27x00_id);