diff options
author | Puthikorn Voravootivat <puthik@chromium.org> | 2014-09-09 15:20:35 -0400 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2014-09-24 19:33:03 -0400 |
commit | 628ef02c56e515430dd8d8439126dd0ecb8ce8bb (patch) | |
tree | 635cf93d74bf21b19de64f82498bad3ca87dcbd9 /drivers/power/bq27x00_battery.c | |
parent | a4b7aef6b066bda215566cf4af3455a6e36c381d (diff) |
bq27x00_battery: Add support to bq27742
Add support to bq27742 in bq27x00 driver. bq27742 register
addresses are mostly mostly the same as bq27500 addresses
with minor differences.
Signed-off-by: Puthikorn Voravootivat <puthik@chromium.org>
Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-by: Rhyland Klein <rklein@nvidia.com>
Reviewed-by: Benson Leung <bleung@chromium.org>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Diffstat (limited to 'drivers/power/bq27x00_battery.c')
-rw-r--r-- | drivers/power/bq27x00_battery.c | 52 |
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 | ||
86 | enum bq27x00_chip { BQ27000, BQ27500, BQ27425}; | 89 | enum bq27x00_chip { BQ27000, BQ27500, BQ27425, BQ27742}; |
87 | 90 | ||
88 | struct bq27x00_reg_cache { | 91 | struct 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 | ||
158 | static 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 | |||
155 | static unsigned int poll_interval = 360; | 176 | static unsigned int poll_interval = 360; |
156 | module_param(poll_interval, uint, 0644); | 177 | module_param(poll_interval, uint, 0644); |
157 | MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ | 178 | MODULE_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 | */ |
177 | static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di) | 198 | static 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 | }; |
863 | MODULE_DEVICE_TABLE(i2c, bq27x00_id); | 901 | MODULE_DEVICE_TABLE(i2c, bq27x00_id); |