diff options
-rw-r--r-- | drivers/power/olpc_battery.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 7524a63a54cb..f8dc2b18bb49 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c | |||
@@ -274,6 +274,48 @@ static enum power_supply_property olpc_bat_props[] = { | |||
274 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 274 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
275 | }; | 275 | }; |
276 | 276 | ||
277 | /* EEPROM reading goes completely around the power_supply API, sadly */ | ||
278 | |||
279 | #define EEPROM_START 0x20 | ||
280 | #define EEPROM_END 0x80 | ||
281 | #define EEPROM_SIZE (EEPROM_END - EEPROM_START) | ||
282 | |||
283 | static ssize_t olpc_bat_eeprom_read(struct kobject *kobj, | ||
284 | struct bin_attribute *attr, char *buf, loff_t off, size_t count) | ||
285 | { | ||
286 | uint8_t ec_byte; | ||
287 | int ret, end; | ||
288 | |||
289 | if (off >= EEPROM_SIZE) | ||
290 | return 0; | ||
291 | if (off + count > EEPROM_SIZE) | ||
292 | count = EEPROM_SIZE - off; | ||
293 | |||
294 | end = EEPROM_START + off + count; | ||
295 | for (ec_byte = EEPROM_START + off; ec_byte < end; ec_byte++) { | ||
296 | ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, | ||
297 | &buf[ec_byte - EEPROM_START], 1); | ||
298 | if (ret) { | ||
299 | printk(KERN_ERR "olpc-battery: EC command " | ||
300 | "EC_BAT_EEPROM @ 0x%x failed -" | ||
301 | " %d!\n", ec_byte, ret); | ||
302 | return -EIO; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | return count; | ||
307 | } | ||
308 | |||
309 | static struct bin_attribute olpc_bat_eeprom = { | ||
310 | .attr = { | ||
311 | .name = "eeprom", | ||
312 | .mode = S_IRUGO, | ||
313 | .owner = THIS_MODULE, | ||
314 | }, | ||
315 | .size = 0, | ||
316 | .read = olpc_bat_eeprom_read, | ||
317 | }; | ||
318 | |||
277 | /********************************************************************* | 319 | /********************************************************************* |
278 | * Initialisation | 320 | * Initialisation |
279 | *********************************************************************/ | 321 | *********************************************************************/ |
@@ -327,8 +369,14 @@ static int __init olpc_bat_init(void) | |||
327 | if (ret) | 369 | if (ret) |
328 | goto battery_failed; | 370 | goto battery_failed; |
329 | 371 | ||
372 | ret = device_create_bin_file(olpc_bat.dev, &olpc_bat_eeprom); | ||
373 | if (ret) | ||
374 | goto eeprom_failed; | ||
375 | |||
330 | goto success; | 376 | goto success; |
331 | 377 | ||
378 | eeprom_failed: | ||
379 | power_supply_unregister(&olpc_bat); | ||
332 | battery_failed: | 380 | battery_failed: |
333 | power_supply_unregister(&olpc_ac); | 381 | power_supply_unregister(&olpc_ac); |
334 | ac_failed: | 382 | ac_failed: |
@@ -339,6 +387,7 @@ success: | |||
339 | 387 | ||
340 | static void __exit olpc_bat_exit(void) | 388 | static void __exit olpc_bat_exit(void) |
341 | { | 389 | { |
390 | device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); | ||
342 | power_supply_unregister(&olpc_bat); | 391 | power_supply_unregister(&olpc_bat); |
343 | power_supply_unregister(&olpc_ac); | 392 | power_supply_unregister(&olpc_ac); |
344 | platform_device_unregister(bat_pdev); | 393 | platform_device_unregister(bat_pdev); |