aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/olpc_battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/olpc_battery.c')
-rw-r--r--drivers/power/olpc_battery.c114
1 files changed, 111 insertions, 3 deletions
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index 5bc1dcf7785e..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
204static 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
252static 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,6 +333,7 @@ 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;
@@ -274,6 +341,7 @@ static int olpc_bat_get_property(struct power_supply *psy,
274 val->intval = (s16)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;
@@ -294,6 +362,16 @@ 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)
@@ -331,16 +409,20 @@ static int olpc_bat_get_property(struct power_supply *psy,
331 return ret; 409 return ret;
332} 410}
333 411
334static enum power_supply_property olpc_bat_props[] = { 412static 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 */
434static 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 = {
419static struct platform_device *bat_pdev; 522static struct platform_device *bat_pdev;
420 523
421static struct power_supply olpc_bat = { 524static 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)