GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / power / supply / olpc_battery.c
1 /*
2  * Battery driver for One Laptop Per Child board.
3  *
4  *      Copyright © 2006-2010  David Woodhouse <dwmw2@infradead.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/types.h>
15 #include <linux/err.h>
16 #include <linux/device.h>
17 #include <linux/platform_device.h>
18 #include <linux/power_supply.h>
19 #include <linux/jiffies.h>
20 #include <linux/sched.h>
21 #include <linux/olpc-ec.h>
22 #include <asm/olpc.h>
23
24
25 #define EC_BAT_VOLTAGE  0x10    /* uint16_t,    *9.76/32,    mV   */
26 #define EC_BAT_CURRENT  0x11    /* int16_t,     *15.625/120, mA   */
27 #define EC_BAT_ACR      0x12    /* int16_t,     *6250/15,    µAh  */
28 #define EC_BAT_TEMP     0x13    /* uint16_t,    *100/256,   °C  */
29 #define EC_AMB_TEMP     0x14    /* uint16_t,    *100/256,   °C  */
30 #define EC_BAT_STATUS   0x15    /* uint8_t,     bitmask */
31 #define EC_BAT_SOC      0x16    /* uint8_t,     percentage */
32 #define EC_BAT_SERIAL   0x17    /* uint8_t[6] */
33 #define EC_BAT_EEPROM   0x18    /* uint8_t adr as input, uint8_t output */
34 #define EC_BAT_ERRCODE  0x1f    /* uint8_t,     bitmask */
35
36 #define BAT_STAT_PRESENT        0x01
37 #define BAT_STAT_FULL           0x02
38 #define BAT_STAT_LOW            0x04
39 #define BAT_STAT_DESTROY        0x08
40 #define BAT_STAT_AC             0x10
41 #define BAT_STAT_CHARGING       0x20
42 #define BAT_STAT_DISCHARGING    0x40
43 #define BAT_STAT_TRICKLE        0x80
44
45 #define BAT_ERR_INFOFAIL        0x02
46 #define BAT_ERR_OVERVOLTAGE     0x04
47 #define BAT_ERR_OVERTEMP        0x05
48 #define BAT_ERR_GAUGESTOP       0x06
49 #define BAT_ERR_OUT_OF_CONTROL  0x07
50 #define BAT_ERR_ID_FAIL         0x09
51 #define BAT_ERR_ACR_FAIL        0x10
52
53 #define BAT_ADDR_MFR_TYPE       0x5F
54
55 /*********************************************************************
56  *              Power
57  *********************************************************************/
58
59 static int olpc_ac_get_prop(struct power_supply *psy,
60                             enum power_supply_property psp,
61                             union power_supply_propval *val)
62 {
63         int ret = 0;
64         uint8_t status;
65
66         switch (psp) {
67         case POWER_SUPPLY_PROP_ONLINE:
68                 ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
69                 if (ret)
70                         return ret;
71
72                 val->intval = !!(status & BAT_STAT_AC);
73                 break;
74         default:
75                 ret = -EINVAL;
76                 break;
77         }
78         return ret;
79 }
80
81 static enum power_supply_property olpc_ac_props[] = {
82         POWER_SUPPLY_PROP_ONLINE,
83 };
84
85 static const struct power_supply_desc olpc_ac_desc = {
86         .name = "olpc-ac",
87         .type = POWER_SUPPLY_TYPE_MAINS,
88         .properties = olpc_ac_props,
89         .num_properties = ARRAY_SIZE(olpc_ac_props),
90         .get_property = olpc_ac_get_prop,
91 };
92
93 static struct power_supply *olpc_ac;
94
95 static char bat_serial[17]; /* Ick */
96
97 static int olpc_bat_get_status(union power_supply_propval *val, uint8_t ec_byte)
98 {
99         if (olpc_platform_info.ecver > 0x44) {
100                 if (ec_byte & (BAT_STAT_CHARGING | BAT_STAT_TRICKLE))
101                         val->intval = POWER_SUPPLY_STATUS_CHARGING;
102                 else if (ec_byte & BAT_STAT_DISCHARGING)
103                         val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
104                 else if (ec_byte & BAT_STAT_FULL)
105                         val->intval = POWER_SUPPLY_STATUS_FULL;
106                 else /* er,... */
107                         val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
108         } else {
109                 /* Older EC didn't report charge/discharge bits */
110                 if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
111                         val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
112                 else if (ec_byte & BAT_STAT_FULL)
113                         val->intval = POWER_SUPPLY_STATUS_FULL;
114                 else /* Not _necessarily_ true but EC doesn't tell all yet */
115                         val->intval = POWER_SUPPLY_STATUS_CHARGING;
116         }
117
118         return 0;
119 }
120
121 static int olpc_bat_get_health(union power_supply_propval *val)
122 {
123         uint8_t ec_byte;
124         int ret;
125
126         ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
127         if (ret)
128                 return ret;
129
130         switch (ec_byte) {
131         case 0:
132                 val->intval = POWER_SUPPLY_HEALTH_GOOD;
133                 break;
134
135         case BAT_ERR_OVERTEMP:
136                 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
137                 break;
138
139         case BAT_ERR_OVERVOLTAGE:
140                 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
141                 break;
142
143         case BAT_ERR_INFOFAIL:
144         case BAT_ERR_OUT_OF_CONTROL:
145         case BAT_ERR_ID_FAIL:
146         case BAT_ERR_ACR_FAIL:
147                 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
148                 break;
149
150         default:
151                 /* Eep. We don't know this failure code */
152                 ret = -EIO;
153         }
154
155         return ret;
156 }
157
158 static int olpc_bat_get_mfr(union power_supply_propval *val)
159 {
160         uint8_t ec_byte;
161         int ret;
162
163         ec_byte = BAT_ADDR_MFR_TYPE;
164         ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
165         if (ret)
166                 return ret;
167
168         switch (ec_byte >> 4) {
169         case 1:
170                 val->strval = "Gold Peak";
171                 break;
172         case 2:
173                 val->strval = "BYD";
174                 break;
175         default:
176                 val->strval = "Unknown";
177                 break;
178         }
179
180         return ret;
181 }
182
183 static int olpc_bat_get_tech(union power_supply_propval *val)
184 {
185         uint8_t ec_byte;
186         int ret;
187
188         ec_byte = BAT_ADDR_MFR_TYPE;
189         ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
190         if (ret)
191                 return ret;
192
193         switch (ec_byte & 0xf) {
194         case 1:
195                 val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
196                 break;
197         case 2:
198                 val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
199                 break;
200         default:
201                 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
202                 break;
203         }
204
205         return ret;
206 }
207
208 static int olpc_bat_get_charge_full_design(union power_supply_propval *val)
209 {
210         uint8_t ec_byte;
211         union power_supply_propval tech;
212         int ret, mfr;
213
214         ret = olpc_bat_get_tech(&tech);
215         if (ret)
216                 return ret;
217
218         ec_byte = BAT_ADDR_MFR_TYPE;
219         ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
220         if (ret)
221                 return ret;
222
223         mfr = ec_byte >> 4;
224
225         switch (tech.intval) {
226         case POWER_SUPPLY_TECHNOLOGY_NiMH:
227                 switch (mfr) {
228                 case 1: /* Gold Peak */
229                         val->intval = 3000000*.8;
230                         break;
231                 default:
232                         return -EIO;
233                 }
234                 break;
235
236         case POWER_SUPPLY_TECHNOLOGY_LiFe:
237                 switch (mfr) {
238                 case 1: /* Gold Peak, fall through */
239                 case 2: /* BYD */
240                         val->intval = 2800000;
241                         break;
242                 default:
243                         return -EIO;
244                 }
245                 break;
246
247         default:
248                 return -EIO;
249         }
250
251         return ret;
252 }
253
254 static int olpc_bat_get_charge_now(union power_supply_propval *val)
255 {
256         uint8_t soc;
257         union power_supply_propval full;
258         int ret;
259
260         ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &soc, 1);
261         if (ret)
262                 return ret;
263
264         ret = olpc_bat_get_charge_full_design(&full);
265         if (ret)
266                 return ret;
267
268         val->intval = soc * (full.intval / 100);
269         return 0;
270 }
271
272 static int olpc_bat_get_voltage_max_design(union power_supply_propval *val)
273 {
274         uint8_t ec_byte;
275         union power_supply_propval tech;
276         int mfr;
277         int ret;
278
279         ret = olpc_bat_get_tech(&tech);
280         if (ret)
281                 return ret;
282
283         ec_byte = BAT_ADDR_MFR_TYPE;
284         ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
285         if (ret)
286                 return ret;
287
288         mfr = ec_byte >> 4;
289
290         switch (tech.intval) {
291         case POWER_SUPPLY_TECHNOLOGY_NiMH:
292                 switch (mfr) {
293                 case 1: /* Gold Peak */
294                         val->intval = 6000000;
295                         break;
296                 default:
297                         return -EIO;
298                 }
299                 break;
300
301         case POWER_SUPPLY_TECHNOLOGY_LiFe:
302                 switch (mfr) {
303                 case 1: /* Gold Peak */
304                         val->intval = 6400000;
305                         break;
306                 case 2: /* BYD */
307                         val->intval = 6500000;
308                         break;
309                 default:
310                         return -EIO;
311                 }
312                 break;
313
314         default:
315                 return -EIO;
316         }
317
318         return ret;
319 }
320
321 /*********************************************************************
322  *              Battery properties
323  *********************************************************************/
324 static int olpc_bat_get_property(struct power_supply *psy,
325                                  enum power_supply_property psp,
326                                  union power_supply_propval *val)
327 {
328         int ret = 0;
329         __be16 ec_word;
330         uint8_t ec_byte;
331         __be64 ser_buf;
332
333         ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
334         if (ret)
335                 return ret;
336
337         /* Theoretically there's a race here -- the battery could be
338            removed immediately after we check whether it's present, and
339            then we query for some other property of the now-absent battery.
340            It doesn't matter though -- the EC will return the last-known
341            information, and it's as if we just ran that _little_ bit faster
342            and managed to read it out before the battery went away. */
343         if (!(ec_byte & (BAT_STAT_PRESENT | BAT_STAT_TRICKLE)) &&
344                         psp != POWER_SUPPLY_PROP_PRESENT)
345                 return -ENODEV;
346
347         switch (psp) {
348         case POWER_SUPPLY_PROP_STATUS:
349                 ret = olpc_bat_get_status(val, ec_byte);
350                 if (ret)
351                         return ret;
352                 break;
353         case POWER_SUPPLY_PROP_CHARGE_TYPE:
354                 if (ec_byte & BAT_STAT_TRICKLE)
355                         val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
356                 else if (ec_byte & BAT_STAT_CHARGING)
357                         val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
358                 else
359                         val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
360                 break;
361         case POWER_SUPPLY_PROP_PRESENT:
362                 val->intval = !!(ec_byte & (BAT_STAT_PRESENT |
363                                             BAT_STAT_TRICKLE));
364                 break;
365
366         case POWER_SUPPLY_PROP_HEALTH:
367                 if (ec_byte & BAT_STAT_DESTROY)
368                         val->intval = POWER_SUPPLY_HEALTH_DEAD;
369                 else {
370                         ret = olpc_bat_get_health(val);
371                         if (ret)
372                                 return ret;
373                 }
374                 break;
375
376         case POWER_SUPPLY_PROP_MANUFACTURER:
377                 ret = olpc_bat_get_mfr(val);
378                 if (ret)
379                         return ret;
380                 break;
381         case POWER_SUPPLY_PROP_TECHNOLOGY:
382                 ret = olpc_bat_get_tech(val);
383                 if (ret)
384                         return ret;
385                 break;
386         case POWER_SUPPLY_PROP_VOLTAGE_AVG:
387         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
388                 ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);
389                 if (ret)
390                         return ret;
391
392                 val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32;
393                 break;
394         case POWER_SUPPLY_PROP_CURRENT_AVG:
395         case POWER_SUPPLY_PROP_CURRENT_NOW:
396                 ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
397                 if (ret)
398                         return ret;
399
400                 val->intval = (s16)be16_to_cpu(ec_word) * 15625L / 120;
401                 break;
402         case POWER_SUPPLY_PROP_CAPACITY:
403                 ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
404                 if (ret)
405                         return ret;
406                 val->intval = ec_byte;
407                 break;
408         case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
409                 if (ec_byte & BAT_STAT_FULL)
410                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
411                 else if (ec_byte & BAT_STAT_LOW)
412                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
413                 else
414                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
415                 break;
416         case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
417                 ret = olpc_bat_get_charge_full_design(val);
418                 if (ret)
419                         return ret;
420                 break;
421         case POWER_SUPPLY_PROP_CHARGE_NOW:
422                 ret = olpc_bat_get_charge_now(val);
423                 if (ret)
424                         return ret;
425                 break;
426         case POWER_SUPPLY_PROP_TEMP:
427                 ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
428                 if (ret)
429                         return ret;
430
431                 val->intval = (s16)be16_to_cpu(ec_word) * 10 / 256;
432                 break;
433         case POWER_SUPPLY_PROP_TEMP_AMBIENT:
434                 ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
435                 if (ret)
436                         return ret;
437
438                 val->intval = (int)be16_to_cpu(ec_word) * 10 / 256;
439                 break;
440         case POWER_SUPPLY_PROP_CHARGE_COUNTER:
441                 ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2);
442                 if (ret)
443                         return ret;
444
445                 val->intval = (s16)be16_to_cpu(ec_word) * 6250 / 15;
446                 break;
447         case POWER_SUPPLY_PROP_SERIAL_NUMBER:
448                 ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8);
449                 if (ret)
450                         return ret;
451
452                 sprintf(bat_serial, "%016llx", (long long)be64_to_cpu(ser_buf));
453                 val->strval = bat_serial;
454                 break;
455         case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
456                 ret = olpc_bat_get_voltage_max_design(val);
457                 if (ret)
458                         return ret;
459                 break;
460         default:
461                 ret = -EINVAL;
462                 break;
463         }
464
465         return ret;
466 }
467
468 static enum power_supply_property olpc_xo1_bat_props[] = {
469         POWER_SUPPLY_PROP_STATUS,
470         POWER_SUPPLY_PROP_CHARGE_TYPE,
471         POWER_SUPPLY_PROP_PRESENT,
472         POWER_SUPPLY_PROP_HEALTH,
473         POWER_SUPPLY_PROP_TECHNOLOGY,
474         POWER_SUPPLY_PROP_VOLTAGE_AVG,
475         POWER_SUPPLY_PROP_VOLTAGE_NOW,
476         POWER_SUPPLY_PROP_CURRENT_AVG,
477         POWER_SUPPLY_PROP_CURRENT_NOW,
478         POWER_SUPPLY_PROP_CAPACITY,
479         POWER_SUPPLY_PROP_CAPACITY_LEVEL,
480         POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
481         POWER_SUPPLY_PROP_CHARGE_NOW,
482         POWER_SUPPLY_PROP_TEMP,
483         POWER_SUPPLY_PROP_TEMP_AMBIENT,
484         POWER_SUPPLY_PROP_MANUFACTURER,
485         POWER_SUPPLY_PROP_SERIAL_NUMBER,
486         POWER_SUPPLY_PROP_CHARGE_COUNTER,
487         POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
488 };
489
490 /* XO-1.5 does not have ambient temperature property */
491 static enum power_supply_property olpc_xo15_bat_props[] = {
492         POWER_SUPPLY_PROP_STATUS,
493         POWER_SUPPLY_PROP_CHARGE_TYPE,
494         POWER_SUPPLY_PROP_PRESENT,
495         POWER_SUPPLY_PROP_HEALTH,
496         POWER_SUPPLY_PROP_TECHNOLOGY,
497         POWER_SUPPLY_PROP_VOLTAGE_AVG,
498         POWER_SUPPLY_PROP_VOLTAGE_NOW,
499         POWER_SUPPLY_PROP_CURRENT_AVG,
500         POWER_SUPPLY_PROP_CURRENT_NOW,
501         POWER_SUPPLY_PROP_CAPACITY,
502         POWER_SUPPLY_PROP_CAPACITY_LEVEL,
503         POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
504         POWER_SUPPLY_PROP_CHARGE_NOW,
505         POWER_SUPPLY_PROP_TEMP,
506         POWER_SUPPLY_PROP_MANUFACTURER,
507         POWER_SUPPLY_PROP_SERIAL_NUMBER,
508         POWER_SUPPLY_PROP_CHARGE_COUNTER,
509         POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
510 };
511
512 /* EEPROM reading goes completely around the power_supply API, sadly */
513
514 #define EEPROM_START    0x20
515 #define EEPROM_END      0x80
516 #define EEPROM_SIZE     (EEPROM_END - EEPROM_START)
517
518 static ssize_t olpc_bat_eeprom_read(struct file *filp, struct kobject *kobj,
519                 struct bin_attribute *attr, char *buf, loff_t off, size_t count)
520 {
521         uint8_t ec_byte;
522         int ret;
523         int i;
524
525         for (i = 0; i < count; i++) {
526                 ec_byte = EEPROM_START + off + i;
527                 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &buf[i], 1);
528                 if (ret) {
529                         pr_err("olpc-battery: "
530                                "EC_BAT_EEPROM cmd @ 0x%x failed - %d!\n",
531                                ec_byte, ret);
532                         return -EIO;
533                 }
534         }
535
536         return count;
537 }
538
539 static const struct bin_attribute olpc_bat_eeprom = {
540         .attr = {
541                 .name = "eeprom",
542                 .mode = S_IRUGO,
543         },
544         .size = EEPROM_SIZE,
545         .read = olpc_bat_eeprom_read,
546 };
547
548 /* Allow userspace to see the specific error value pulled from the EC */
549
550 static ssize_t olpc_bat_error_read(struct device *dev,
551                 struct device_attribute *attr, char *buf)
552 {
553         uint8_t ec_byte;
554         ssize_t ret;
555
556         ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
557         if (ret < 0)
558                 return ret;
559
560         return sprintf(buf, "%d\n", ec_byte);
561 }
562
563 static const struct device_attribute olpc_bat_error = {
564         .attr = {
565                 .name = "error",
566                 .mode = S_IRUGO,
567         },
568         .show = olpc_bat_error_read,
569 };
570
571 /*********************************************************************
572  *              Initialisation
573  *********************************************************************/
574
575 static struct power_supply_desc olpc_bat_desc = {
576         .name = "olpc-battery",
577         .get_property = olpc_bat_get_property,
578         .use_for_apm = 1,
579 };
580
581 static struct power_supply *olpc_bat;
582
583 static int olpc_battery_suspend(struct platform_device *pdev,
584                                 pm_message_t state)
585 {
586         if (device_may_wakeup(&olpc_ac->dev))
587                 olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR);
588         else
589                 olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR);
590
591         if (device_may_wakeup(&olpc_bat->dev))
592                 olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
593                                    | EC_SCI_SRC_BATERR);
594         else
595                 olpc_ec_wakeup_clear(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
596                                      | EC_SCI_SRC_BATERR);
597
598         return 0;
599 }
600
601 static int olpc_battery_probe(struct platform_device *pdev)
602 {
603         int ret;
604         uint8_t status;
605
606         /*
607          * We've seen a number of EC protocol changes; this driver requires
608          * the latest EC protocol, supported by 0x44 and above.
609          */
610         if (olpc_platform_info.ecver < 0x44) {
611                 printk(KERN_NOTICE "OLPC EC version 0x%02x too old for "
612                         "battery driver.\n", olpc_platform_info.ecver);
613                 return -ENXIO;
614         }
615
616         ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
617         if (ret)
618                 return ret;
619
620         /* Ignore the status. It doesn't actually matter */
621
622         olpc_ac = power_supply_register(&pdev->dev, &olpc_ac_desc, NULL);
623         if (IS_ERR(olpc_ac))
624                 return PTR_ERR(olpc_ac);
625
626         if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */
627                 olpc_bat_desc.properties = olpc_xo15_bat_props;
628                 olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo15_bat_props);
629         } else { /* XO-1 */
630                 olpc_bat_desc.properties = olpc_xo1_bat_props;
631                 olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props);
632         }
633
634         olpc_bat = power_supply_register(&pdev->dev, &olpc_bat_desc, NULL);
635         if (IS_ERR(olpc_bat)) {
636                 ret = PTR_ERR(olpc_bat);
637                 goto battery_failed;
638         }
639
640         ret = device_create_bin_file(&olpc_bat->dev, &olpc_bat_eeprom);
641         if (ret)
642                 goto eeprom_failed;
643
644         ret = device_create_file(&olpc_bat->dev, &olpc_bat_error);
645         if (ret)
646                 goto error_failed;
647
648         if (olpc_ec_wakeup_available()) {
649                 device_set_wakeup_capable(&olpc_ac->dev, true);
650                 device_set_wakeup_capable(&olpc_bat->dev, true);
651         }
652
653         return 0;
654
655 error_failed:
656         device_remove_bin_file(&olpc_bat->dev, &olpc_bat_eeprom);
657 eeprom_failed:
658         power_supply_unregister(olpc_bat);
659 battery_failed:
660         power_supply_unregister(olpc_ac);
661         return ret;
662 }
663
664 static int olpc_battery_remove(struct platform_device *pdev)
665 {
666         device_remove_file(&olpc_bat->dev, &olpc_bat_error);
667         device_remove_bin_file(&olpc_bat->dev, &olpc_bat_eeprom);
668         power_supply_unregister(olpc_bat);
669         power_supply_unregister(olpc_ac);
670         return 0;
671 }
672
673 static const struct of_device_id olpc_battery_ids[] = {
674         { .compatible = "olpc,xo1-battery" },
675         {}
676 };
677 MODULE_DEVICE_TABLE(of, olpc_battery_ids);
678
679 static struct platform_driver olpc_battery_driver = {
680         .driver = {
681                 .name = "olpc-battery",
682                 .of_match_table = olpc_battery_ids,
683         },
684         .probe = olpc_battery_probe,
685         .remove = olpc_battery_remove,
686         .suspend = olpc_battery_suspend,
687 };
688
689 module_platform_driver(olpc_battery_driver);
690
691 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
692 MODULE_LICENSE("GPL");
693 MODULE_DESCRIPTION("Battery driver for One Laptop Per Child 'XO' machine");