diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/power/olpc_battery.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/power/olpc_battery.c')
-rw-r--r-- | drivers/power/olpc_battery.c | 122 |
1 files changed, 115 insertions, 7 deletions
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index aafc1c506eda..0b0ff3a936a6 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c | |||
@@ -201,6 +201,72 @@ static int olpc_bat_get_tech(union power_supply_propval *val) | |||
201 | return ret; | 201 | return ret; |
202 | } | 202 | } |
203 | 203 | ||
204 | static int olpc_bat_get_charge_full_design(union power_supply_propval *val) | ||
205 | { | ||
206 | uint8_t ec_byte; | ||
207 | union power_supply_propval tech; | ||
208 | int ret, mfr; | ||
209 | |||
210 | ret = olpc_bat_get_tech(&tech); | ||
211 | if (ret) | ||
212 | return ret; | ||
213 | |||
214 | ec_byte = BAT_ADDR_MFR_TYPE; | ||
215 | ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1); | ||
216 | if (ret) | ||
217 | return ret; | ||
218 | |||
219 | mfr = ec_byte >> 4; | ||
220 | |||
221 | switch (tech.intval) { | ||
222 | case POWER_SUPPLY_TECHNOLOGY_NiMH: | ||
223 | switch (mfr) { | ||
224 | case 1: /* Gold Peak */ | ||
225 | val->intval = 3000000*.8; | ||
226 | break; | ||
227 | default: | ||
228 | return -EIO; | ||
229 | } | ||
230 | break; | ||
231 | |||
232 | case POWER_SUPPLY_TECHNOLOGY_LiFe: | ||
233 | switch (mfr) { | ||
234 | case 1: /* Gold Peak */ | ||
235 | val->intval = 2800000; | ||
236 | break; | ||
237 | case 2: /* BYD */ | ||
238 | val->intval = 3100000; | ||
239 | break; | ||
240 | default: | ||
241 | return -EIO; | ||
242 | } | ||
243 | break; | ||
244 | |||
245 | default: | ||
246 | return -EIO; | ||
247 | } | ||
248 | |||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | static int olpc_bat_get_charge_now(union power_supply_propval *val) | ||
253 | { | ||
254 | uint8_t soc; | ||
255 | union power_supply_propval full; | ||
256 | int ret; | ||
257 | |||
258 | ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &soc, 1); | ||
259 | if (ret) | ||
260 | return ret; | ||
261 | |||
262 | ret = olpc_bat_get_charge_full_design(&full); | ||
263 | if (ret) | ||
264 | return ret; | ||
265 | |||
266 | val->intval = soc * (full.intval / 100); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
204 | /********************************************************************* | 270 | /********************************************************************* |
205 | * Battery properties | 271 | * Battery properties |
206 | *********************************************************************/ | 272 | *********************************************************************/ |
@@ -267,18 +333,20 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
267 | return ret; | 333 | return ret; |
268 | break; | 334 | break; |
269 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | 335 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: |
336 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
270 | ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); | 337 | ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); |
271 | if (ret) | 338 | if (ret) |
272 | return ret; | 339 | return ret; |
273 | 340 | ||
274 | val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32; | 341 | val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32; |
275 | break; | 342 | break; |
276 | case POWER_SUPPLY_PROP_CURRENT_AVG: | 343 | case POWER_SUPPLY_PROP_CURRENT_AVG: |
344 | case POWER_SUPPLY_PROP_CURRENT_NOW: | ||
277 | ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); | 345 | ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); |
278 | if (ret) | 346 | if (ret) |
279 | return ret; | 347 | return ret; |
280 | 348 | ||
281 | val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120; | 349 | val->intval = (s16)be16_to_cpu(ec_word) * 15625L / 120; |
282 | break; | 350 | break; |
283 | case POWER_SUPPLY_PROP_CAPACITY: | 351 | case POWER_SUPPLY_PROP_CAPACITY: |
284 | ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); | 352 | ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); |
@@ -294,12 +362,22 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
294 | else | 362 | else |
295 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; | 363 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; |
296 | break; | 364 | break; |
365 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | ||
366 | ret = olpc_bat_get_charge_full_design(val); | ||
367 | if (ret) | ||
368 | return ret; | ||
369 | break; | ||
370 | case POWER_SUPPLY_PROP_CHARGE_NOW: | ||
371 | ret = olpc_bat_get_charge_now(val); | ||
372 | if (ret) | ||
373 | return ret; | ||
374 | break; | ||
297 | case POWER_SUPPLY_PROP_TEMP: | 375 | case POWER_SUPPLY_PROP_TEMP: |
298 | ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); | 376 | ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); |
299 | if (ret) | 377 | if (ret) |
300 | return ret; | 378 | return ret; |
301 | 379 | ||
302 | val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; | 380 | val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256; |
303 | break; | 381 | break; |
304 | case POWER_SUPPLY_PROP_TEMP_AMBIENT: | 382 | case POWER_SUPPLY_PROP_TEMP_AMBIENT: |
305 | ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); | 383 | ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); |
@@ -313,7 +391,7 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
313 | if (ret) | 391 | if (ret) |
314 | return ret; | 392 | return ret; |
315 | 393 | ||
316 | val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15; | 394 | val->intval = (s16)be16_to_cpu(ec_word) * 6250 / 15; |
317 | break; | 395 | break; |
318 | case POWER_SUPPLY_PROP_SERIAL_NUMBER: | 396 | case POWER_SUPPLY_PROP_SERIAL_NUMBER: |
319 | ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8); | 397 | ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8); |
@@ -331,16 +409,20 @@ static int olpc_bat_get_property(struct power_supply *psy, | |||
331 | return ret; | 409 | return ret; |
332 | } | 410 | } |
333 | 411 | ||
334 | static enum power_supply_property olpc_bat_props[] = { | 412 | static enum power_supply_property olpc_xo1_bat_props[] = { |
335 | POWER_SUPPLY_PROP_STATUS, | 413 | POWER_SUPPLY_PROP_STATUS, |
336 | POWER_SUPPLY_PROP_CHARGE_TYPE, | 414 | POWER_SUPPLY_PROP_CHARGE_TYPE, |
337 | POWER_SUPPLY_PROP_PRESENT, | 415 | POWER_SUPPLY_PROP_PRESENT, |
338 | POWER_SUPPLY_PROP_HEALTH, | 416 | POWER_SUPPLY_PROP_HEALTH, |
339 | POWER_SUPPLY_PROP_TECHNOLOGY, | 417 | POWER_SUPPLY_PROP_TECHNOLOGY, |
340 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | 418 | POWER_SUPPLY_PROP_VOLTAGE_AVG, |
419 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
341 | POWER_SUPPLY_PROP_CURRENT_AVG, | 420 | POWER_SUPPLY_PROP_CURRENT_AVG, |
421 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
342 | POWER_SUPPLY_PROP_CAPACITY, | 422 | POWER_SUPPLY_PROP_CAPACITY, |
343 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | 423 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, |
424 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | ||
425 | POWER_SUPPLY_PROP_CHARGE_NOW, | ||
344 | POWER_SUPPLY_PROP_TEMP, | 426 | POWER_SUPPLY_PROP_TEMP, |
345 | POWER_SUPPLY_PROP_TEMP_AMBIENT, | 427 | POWER_SUPPLY_PROP_TEMP_AMBIENT, |
346 | POWER_SUPPLY_PROP_MANUFACTURER, | 428 | POWER_SUPPLY_PROP_MANUFACTURER, |
@@ -348,6 +430,27 @@ static enum power_supply_property olpc_bat_props[] = { | |||
348 | POWER_SUPPLY_PROP_CHARGE_COUNTER, | 430 | POWER_SUPPLY_PROP_CHARGE_COUNTER, |
349 | }; | 431 | }; |
350 | 432 | ||
433 | /* XO-1.5 does not have ambient temperature property */ | ||
434 | static enum power_supply_property olpc_xo15_bat_props[] = { | ||
435 | POWER_SUPPLY_PROP_STATUS, | ||
436 | POWER_SUPPLY_PROP_CHARGE_TYPE, | ||
437 | POWER_SUPPLY_PROP_PRESENT, | ||
438 | POWER_SUPPLY_PROP_HEALTH, | ||
439 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
440 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | ||
441 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
442 | POWER_SUPPLY_PROP_CURRENT_AVG, | ||
443 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
444 | POWER_SUPPLY_PROP_CAPACITY, | ||
445 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | ||
446 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | ||
447 | POWER_SUPPLY_PROP_CHARGE_NOW, | ||
448 | POWER_SUPPLY_PROP_TEMP, | ||
449 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
450 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | ||
451 | POWER_SUPPLY_PROP_CHARGE_COUNTER, | ||
452 | }; | ||
453 | |||
351 | /* EEPROM reading goes completely around the power_supply API, sadly */ | 454 | /* EEPROM reading goes completely around the power_supply API, sadly */ |
352 | 455 | ||
353 | #define EEPROM_START 0x20 | 456 | #define EEPROM_START 0x20 |
@@ -419,8 +522,6 @@ static struct device_attribute olpc_bat_error = { | |||
419 | static struct platform_device *bat_pdev; | 522 | static struct platform_device *bat_pdev; |
420 | 523 | ||
421 | static struct power_supply olpc_bat = { | 524 | static struct power_supply olpc_bat = { |
422 | .properties = olpc_bat_props, | ||
423 | .num_properties = ARRAY_SIZE(olpc_bat_props), | ||
424 | .get_property = olpc_bat_get_property, | 525 | .get_property = olpc_bat_get_property, |
425 | .use_for_apm = 1, | 526 | .use_for_apm = 1, |
426 | }; | 527 | }; |
@@ -466,6 +567,13 @@ static int __init olpc_bat_init(void) | |||
466 | goto ac_failed; | 567 | goto ac_failed; |
467 | 568 | ||
468 | olpc_bat.name = bat_pdev->name; | 569 | olpc_bat.name = bat_pdev->name; |
570 | if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ | ||
571 | olpc_bat.properties = olpc_xo15_bat_props; | ||
572 | olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); | ||
573 | } else { /* XO-1 */ | ||
574 | olpc_bat.properties = olpc_xo1_bat_props; | ||
575 | olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); | ||
576 | } | ||
469 | 577 | ||
470 | ret = power_supply_register(&bat_pdev->dev, &olpc_bat); | 578 | ret = power_supply_register(&bat_pdev->dev, &olpc_bat); |
471 | if (ret) | 579 | if (ret) |