aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorRhyland Klein <rklein@nvidia.com>2011-01-25 14:10:06 -0500
committerAnton Vorontsov <cbouatmailru@gmail.com>2011-01-31 08:18:33 -0500
commit51d07566045787b99219d809639c8724506fc78a (patch)
tree7102c9c7d0855a8cbd8c2111ae878dc72847f5c1 /drivers/power
parent1bae4ce27c9c90344f23c65ea6966c50ffeae2f5 (diff)
bq20z75: Add support for charge properties
Adding support for charge properties for gas gauge. Also ensuring that battery mode is correct now for energy as well as charge properties by setting it on the fly. I also added 2 functions to power_supply.h to help identify the units for specific properties more easily by power supplies. Signed-off-by: Rhyland Klein <rklein@nvidia.com> Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq20z75.c98
1 files changed, 87 insertions, 11 deletions
diff --git a/drivers/power/bq20z75.c b/drivers/power/bq20z75.c
index 492da27e1a47..4141775e5ff6 100644
--- a/drivers/power/bq20z75.c
+++ b/drivers/power/bq20z75.c
@@ -38,11 +38,22 @@ enum {
38 REG_CYCLE_COUNT, 38 REG_CYCLE_COUNT,
39 REG_SERIAL_NUMBER, 39 REG_SERIAL_NUMBER,
40 REG_REMAINING_CAPACITY, 40 REG_REMAINING_CAPACITY,
41 REG_REMAINING_CAPACITY_CHARGE,
41 REG_FULL_CHARGE_CAPACITY, 42 REG_FULL_CHARGE_CAPACITY,
43 REG_FULL_CHARGE_CAPACITY_CHARGE,
42 REG_DESIGN_CAPACITY, 44 REG_DESIGN_CAPACITY,
45 REG_DESIGN_CAPACITY_CHARGE,
43 REG_DESIGN_VOLTAGE, 46 REG_DESIGN_VOLTAGE,
44}; 47};
45 48
49/* Battery Mode defines */
50#define BATTERY_MODE_OFFSET 0x03
51#define BATTERY_MODE_MASK 0x8000
52enum bq20z75_battery_mode {
53 BATTERY_MODE_AMPS,
54 BATTERY_MODE_WATTS
55};
56
46/* manufacturer access defines */ 57/* manufacturer access defines */
47#define MANUFACTURER_ACCESS_STATUS 0x0006 58#define MANUFACTURER_ACCESS_STATUS 0x0006
48#define MANUFACTURER_ACCESS_SLEEP 0x0011 59#define MANUFACTURER_ACCESS_SLEEP 0x0011
@@ -78,8 +89,12 @@ static const struct bq20z75_device_data {
78 BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100), 89 BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
79 [REG_REMAINING_CAPACITY] = 90 [REG_REMAINING_CAPACITY] =
80 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535), 91 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
92 [REG_REMAINING_CAPACITY_CHARGE] =
93 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
81 [REG_FULL_CHARGE_CAPACITY] = 94 [REG_FULL_CHARGE_CAPACITY] =
82 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535), 95 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
96 [REG_FULL_CHARGE_CAPACITY_CHARGE] =
97 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
83 [REG_TIME_TO_EMPTY] = 98 [REG_TIME_TO_EMPTY] =
84 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 99 BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0,
85 65535), 100 65535),
@@ -93,6 +108,9 @@ static const struct bq20z75_device_data {
93 [REG_DESIGN_CAPACITY] = 108 [REG_DESIGN_CAPACITY] =
94 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0, 109 BQ20Z75_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0,
95 65535), 110 65535),
111 [REG_DESIGN_CAPACITY_CHARGE] =
112 BQ20Z75_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0,
113 65535),
96 [REG_DESIGN_VOLTAGE] = 114 [REG_DESIGN_VOLTAGE] =
97 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0, 115 BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0,
98 65535), 116 65535),
@@ -117,6 +135,9 @@ static enum power_supply_property bq20z75_properties[] = {
117 POWER_SUPPLY_PROP_ENERGY_NOW, 135 POWER_SUPPLY_PROP_ENERGY_NOW,
118 POWER_SUPPLY_PROP_ENERGY_FULL, 136 POWER_SUPPLY_PROP_ENERGY_FULL,
119 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 137 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
138 POWER_SUPPLY_PROP_CHARGE_NOW,
139 POWER_SUPPLY_PROP_CHARGE_FULL,
140 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
120}; 141};
121 142
122struct bq20z75_info { 143struct bq20z75_info {
@@ -260,6 +281,9 @@ static void bq20z75_unit_adjustment(struct i2c_client *client,
260 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 281 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
261 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 282 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
262 case POWER_SUPPLY_PROP_CURRENT_NOW: 283 case POWER_SUPPLY_PROP_CURRENT_NOW:
284 case POWER_SUPPLY_PROP_CHARGE_NOW:
285 case POWER_SUPPLY_PROP_CHARGE_FULL:
286 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
263 val->intval *= BASE_UNIT_CONVERSION; 287 val->intval *= BASE_UNIT_CONVERSION;
264 break; 288 break;
265 289
@@ -281,11 +305,44 @@ static void bq20z75_unit_adjustment(struct i2c_client *client,
281 } 305 }
282} 306}
283 307
308static enum bq20z75_battery_mode
309bq20z75_set_battery_mode(struct i2c_client *client,
310 enum bq20z75_battery_mode mode)
311{
312 int ret, original_val;
313
314 original_val = bq20z75_read_word_data(client, BATTERY_MODE_OFFSET);
315 if (original_val < 0)
316 return original_val;
317
318 if ((original_val & BATTERY_MODE_MASK) == mode)
319 return mode;
320
321 if (mode == BATTERY_MODE_AMPS)
322 ret = original_val & ~BATTERY_MODE_MASK;
323 else
324 ret = original_val | BATTERY_MODE_MASK;
325
326 ret = bq20z75_write_word_data(client, BATTERY_MODE_OFFSET, ret);
327 if (ret < 0)
328 return ret;
329
330 return original_val & BATTERY_MODE_MASK;
331}
332
284static int bq20z75_get_battery_capacity(struct i2c_client *client, 333static int bq20z75_get_battery_capacity(struct i2c_client *client,
285 int reg_offset, enum power_supply_property psp, 334 int reg_offset, enum power_supply_property psp,
286 union power_supply_propval *val) 335 union power_supply_propval *val)
287{ 336{
288 s32 ret; 337 s32 ret;
338 enum bq20z75_battery_mode mode = BATTERY_MODE_WATTS;
339
340 if (power_supply_is_amp_property(psp))
341 mode = BATTERY_MODE_AMPS;
342
343 mode = bq20z75_set_battery_mode(client, mode);
344 if (mode < 0)
345 return mode;
289 346
290 ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr); 347 ret = bq20z75_read_word_data(client, bq20z75_data[reg_offset].addr);
291 if (ret < 0) 348 if (ret < 0)
@@ -298,6 +355,10 @@ static int bq20z75_get_battery_capacity(struct i2c_client *client,
298 } else 355 } else
299 val->intval = ret; 356 val->intval = ret;
300 357
358 ret = bq20z75_set_battery_mode(client, mode);
359 if (ret < 0)
360 return ret;
361
301 return 0; 362 return 0;
302} 363}
303 364
@@ -318,11 +379,25 @@ static int bq20z75_get_battery_serial_number(struct i2c_client *client,
318 return 0; 379 return 0;
319} 380}
320 381
382static int bq20z75_get_property_index(struct i2c_client *client,
383 enum power_supply_property psp)
384{
385 int count;
386 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++)
387 if (psp == bq20z75_data[count].psp)
388 return count;
389
390 dev_warn(&client->dev,
391 "%s: Invalid Property - %d\n", __func__, psp);
392
393 return -EINVAL;
394}
395
321static int bq20z75_get_property(struct power_supply *psy, 396static int bq20z75_get_property(struct power_supply *psy,
322 enum power_supply_property psp, 397 enum power_supply_property psp,
323 union power_supply_propval *val) 398 union power_supply_propval *val)
324{ 399{
325 int count; 400 int ps_index;
326 int ret; 401 int ret;
327 struct bq20z75_info *bq20z75_device = container_of(psy, 402 struct bq20z75_info *bq20z75_device = container_of(psy,
328 struct bq20z75_info, power_supply); 403 struct bq20z75_info, power_supply);
@@ -343,13 +418,15 @@ static int bq20z75_get_property(struct power_supply *psy,
343 case POWER_SUPPLY_PROP_ENERGY_NOW: 418 case POWER_SUPPLY_PROP_ENERGY_NOW:
344 case POWER_SUPPLY_PROP_ENERGY_FULL: 419 case POWER_SUPPLY_PROP_ENERGY_FULL:
345 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 420 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
421 case POWER_SUPPLY_PROP_CHARGE_NOW:
422 case POWER_SUPPLY_PROP_CHARGE_FULL:
423 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
346 case POWER_SUPPLY_PROP_CAPACITY: 424 case POWER_SUPPLY_PROP_CAPACITY:
347 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++) { 425 ps_index = bq20z75_get_property_index(client, psp);
348 if (psp == bq20z75_data[count].psp) 426 if (ps_index < 0)
349 break; 427 return ps_index;
350 }
351 428
352 ret = bq20z75_get_battery_capacity(client, count, psp, val); 429 ret = bq20z75_get_battery_capacity(client, ps_index, psp, val);
353 if (ret) 430 if (ret)
354 return ret; 431 return ret;
355 432
@@ -369,12 +446,11 @@ static int bq20z75_get_property(struct power_supply *psy,
369 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 446 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
370 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG: 447 case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
371 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 448 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
372 for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++) { 449 ps_index = bq20z75_get_property_index(client, psp);
373 if (psp == bq20z75_data[count].psp) 450 if (ps_index < 0)
374 break; 451 return ps_index;
375 }
376 452
377 ret = bq20z75_get_battery_property(client, count, psp, val); 453 ret = bq20z75_get_battery_property(client, ps_index, psp, val);
378 if (ret) 454 if (ret)
379 return ret; 455 return ret;
380 456