OSDN Git Service

Avoid Bluetooth service crashing on VMware
[android-x86/device-generic-common.git] / tp_smapi / tp_smapi.c
1 /*
2  *  tp_smapi.c - ThinkPad SMAPI support
3  *
4  *  This driver exposes some features of the System Management Application
5  *  Program Interface (SMAPI) BIOS found on ThinkPad laptops. It works on
6  *  models in which the SMAPI BIOS runs in SMM and is invoked by writing
7  *  to the APM control port 0xB2.
8  *  It also exposes battery status information, obtained from the ThinkPad
9  *  embedded controller (via the thinkpad_ec module).
10  *  Ancient ThinkPad models use a different interface, supported by the
11  *  "thinkpad" module from "tpctl".
12  *
13  *  Many of the battery status values obtained from the EC simply mirror
14  *  values provided by the battery's Smart Battery System (SBS) interface, so
15  *  their meaning is defined by the Smart Battery Data Specification (see
16  *  http://sbs-forum.org/specs/sbdat110.pdf). References to this SBS spec
17  *  are given in the code where relevant.
18  *
19  *  Copyright (C) 2006 Shem Multinymous <multinymous@gmail.com>.
20  *  SMAPI access code based on the mwave driver by Mike Sullivan.
21  *
22  *  This program is free software; you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation; either version 2 of the License, or
25  *  (at your option) any later version.
26  *
27  *  This program is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with this program; if not, write to the Free Software
34  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
35  */
36
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/init.h>
40 #include <linux/types.h>
41 #include <linux/proc_fs.h>
42 #include <linux/mc146818rtc.h>  /* CMOS defines */
43 #include <linux/delay.h>
44 #include <linux/version.h>
45 #include "thinkpad_ec.h"
46 #include <linux/platform_device.h>
47 #include <asm/uaccess.h>
48 #include <asm/io.h>
49
50 #define TP_VERSION "0.42"
51 #define TP_DESC "ThinkPad SMAPI Support"
52 #define TP_DIR "smapi"
53
54 MODULE_AUTHOR("Shem Multinymous");
55 MODULE_DESCRIPTION(TP_DESC);
56 MODULE_VERSION(TP_VERSION);
57 MODULE_LICENSE("GPL");
58
59 static struct platform_device *pdev;
60
61 static int tp_debug;
62 module_param_named(debug, tp_debug, int, 0600);
63 MODULE_PARM_DESC(debug, "Debug level (0=off, 1=on)");
64
65 /* A few macros for printk()ing: */
66 #define TPRINTK(level, fmt, args...) \
67   dev_printk(level, &(pdev->dev), "%s: " fmt "\n", __func__, ## args)
68 #define DPRINTK(fmt, args...) \
69   do { if (tp_debug) TPRINTK(KERN_DEBUG, fmt, ## args); } while (0)
70
71 /*********************************************************************
72  * SMAPI interface
73  */
74
75 /* SMAPI functions (register BX when making the SMM call). */
76 #define SMAPI_GET_INHIBIT_CHARGE                0x2114
77 #define SMAPI_SET_INHIBIT_CHARGE                0x2115
78 #define SMAPI_GET_THRESH_START                  0x2116
79 #define SMAPI_SET_THRESH_START                  0x2117
80 #define SMAPI_GET_FORCE_DISCHARGE               0x2118
81 #define SMAPI_SET_FORCE_DISCHARGE               0x2119
82 #define SMAPI_GET_THRESH_STOP                   0x211a
83 #define SMAPI_SET_THRESH_STOP                   0x211b
84
85 /* SMAPI error codes (see ThinkPad 770 Technical Reference Manual p.83 at
86  http://www-307.ibm.com/pc/support/site.wss/document.do?lndocid=PFAN-3TUQQD */
87 #define SMAPI_RETCODE_EOF 0xff
88 static struct { u8 rc; char *msg; int ret; } smapi_retcode[] =
89 {
90         {0x00, "OK", 0},
91         {0x53, "SMAPI function is not available", -ENXIO},
92         {0x81, "Invalid parameter", -EINVAL},
93         {0x86, "Function is not supported by SMAPI BIOS", -EOPNOTSUPP},
94         {0x90, "System error", -EIO},
95         {0x91, "System is invalid", -EIO},
96         {0x92, "System is busy, -EBUSY"},
97         {0xa0, "Device error (disk read error)", -EIO},
98         {0xa1, "Device is busy", -EBUSY},
99         {0xa2, "Device is not attached", -ENXIO},
100         {0xa3, "Device is disbled", -EIO},
101         {0xa4, "Request parameter is out of range", -EINVAL},
102         {0xa5, "Request parameter is not accepted", -EINVAL},
103         {0xa6, "Transient error", -EBUSY}, /* ? */
104         {SMAPI_RETCODE_EOF, "Unknown error code", -EIO}
105 };
106
107
108 #define SMAPI_MAX_RETRIES 10
109 #define SMAPI_PORT2 0x4F           /* fixed port, meaning unclear */
110 static unsigned short smapi_port;  /* APM control port, normally 0xB2 */
111
112 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
113 static DECLARE_MUTEX(smapi_mutex);
114 #else
115 static DEFINE_SEMAPHORE(smapi_mutex);
116 #endif
117
118 /**
119  * find_smapi_port - read SMAPI port from NVRAM
120  */
121 static int __init find_smapi_port(void)
122 {
123         u16 smapi_id = 0;
124         unsigned short port = 0;
125         unsigned long flags;
126
127         spin_lock_irqsave(&rtc_lock, flags);
128         smapi_id = CMOS_READ(0x7C);
129         smapi_id |= (CMOS_READ(0x7D) << 8);
130         spin_unlock_irqrestore(&rtc_lock, flags);
131
132         if (smapi_id != 0x5349) {
133                 printk(KERN_ERR "SMAPI not supported (ID=0x%x)\n", smapi_id);
134                 return -ENXIO;
135         }
136         spin_lock_irqsave(&rtc_lock, flags);
137         port = CMOS_READ(0x7E);
138         port |= (CMOS_READ(0x7F) << 8);
139         spin_unlock_irqrestore(&rtc_lock, flags);
140         if (port == 0) {
141                 printk(KERN_ERR "unable to read SMAPI port number\n");
142                 return -ENXIO;
143         }
144         return port;
145 }
146
147 /**
148  * smapi_request - make a SMAPI call
149  * @inEBX, @inECX, @inEDI, @inESI: input registers
150  * @outEBX, @outECX, @outEDX, @outEDI, @outESI: outputs registers
151  * @msg: textual error message
152  * Invokes the SMAPI SMBIOS with the given input and outpu args.
153  * All outputs are optional (can be %NULL).
154  * Returns 0 when successful, and a negative errno constant
155  * (see smapi_retcode above) upon failure.
156  */
157 static int smapi_request(u32 inEBX, u32 inECX,
158                          u32 inEDI, u32 inESI,
159                          u32 *outEBX, u32 *outECX, u32 *outEDX,
160                          u32 *outEDI, u32 *outESI, const char **msg)
161 {
162         int ret = 0;
163         int i;
164         int retries;
165         u8 rc;
166         /* Must use local vars for output regs, due to reg pressure. */
167         u32 tmpEAX, tmpEBX, tmpECX, tmpEDX, tmpEDI, tmpESI;
168
169         for (retries = 0; retries < SMAPI_MAX_RETRIES; ++retries) {
170                 DPRINTK("req_in: BX=%x CX=%x DI=%x SI=%x",
171                         inEBX, inECX, inEDI, inESI);
172
173                 /* SMAPI's SMBIOS call and thinkpad_ec end up using use
174                  * different interfaces to the same chip, so play it safe. */
175                 ret = thinkpad_ec_lock();
176                 if (ret)
177                         return ret;
178
179                 __asm__ __volatile__(
180                         "movl  $0x00005380,%%eax\n\t"
181                         "movl  %6,%%ebx\n\t"
182                         "movl  %7,%%ecx\n\t"
183                         "movl  %8,%%edi\n\t"
184                         "movl  %9,%%esi\n\t"
185                         "xorl  %%edx,%%edx\n\t"
186                         "movw  %10,%%dx\n\t"
187                         "out   %%al,%%dx\n\t"  /* trigger SMI to SMBIOS */
188                         "out   %%al,$0x4F\n\t"
189                         "movl  %%eax,%0\n\t"
190                         "movl  %%ebx,%1\n\t"
191                         "movl  %%ecx,%2\n\t"
192                         "movl  %%edx,%3\n\t"
193                         "movl  %%edi,%4\n\t"
194                         "movl  %%esi,%5\n\t"
195                         :"=m"(tmpEAX),
196                          "=m"(tmpEBX),
197                          "=m"(tmpECX),
198                          "=m"(tmpEDX),
199                          "=m"(tmpEDI),
200                          "=m"(tmpESI)
201                         :"m"(inEBX), "m"(inECX), "m"(inEDI), "m"(inESI),
202                          "m"((u16)smapi_port)
203                         :"%eax", "%ebx", "%ecx", "%edx", "%edi",
204                          "%esi");
205
206                 thinkpad_ec_invalidate();
207                 thinkpad_ec_unlock();
208
209                 /* Don't let the next SMAPI access happen too quickly,
210                  * may case problems. (We're hold smapi_mutex).       */
211                 msleep(50);
212
213                 if (outEBX) *outEBX = tmpEBX;
214                 if (outECX) *outECX = tmpECX;
215                 if (outEDX) *outEDX = tmpEDX;
216                 if (outESI) *outESI = tmpESI;
217                 if (outEDI) *outEDI = tmpEDI;
218
219                 /* Look up error code */
220                 rc = (tmpEAX>>8)&0xFF;
221                 for (i = 0; smapi_retcode[i].rc != SMAPI_RETCODE_EOF &&
222                             smapi_retcode[i].rc != rc; ++i) {}
223                 ret = smapi_retcode[i].ret;
224                 if (msg)
225                         *msg = smapi_retcode[i].msg;
226
227                 DPRINTK("req_out: AX=%x BX=%x CX=%x DX=%x DI=%x SI=%x r=%d",
228                          tmpEAX, tmpEBX, tmpECX, tmpEDX, tmpEDI, tmpESI, ret);
229                 if (ret)
230                         TPRINTK(KERN_NOTICE, "SMAPI error: %s (func=%x)",
231                                 smapi_retcode[i].msg, inEBX);
232
233                 if (ret != -EBUSY)
234                         return ret;
235         }
236         return ret;
237 }
238
239 /* Convenience wrapper: discard output arguments */
240 static int smapi_write(u32 inEBX, u32 inECX,
241                        u32 inEDI, u32 inESI, const char **msg)
242 {
243         return smapi_request(inEBX, inECX, inEDI, inESI,
244                              NULL, NULL, NULL, NULL, NULL, msg);
245 }
246
247
248 /*********************************************************************
249  * Specific SMAPI services
250  * All of these functions return 0 upon success, and a negative errno
251  * constant (see smapi_retcode) on failure.
252  */
253
254 enum thresh_type {
255         THRESH_STOP  = 0, /* the code assumes this is 0 for brevity */
256         THRESH_START
257 };
258 #define THRESH_NAME(which) ((which == THRESH_START) ? "start" : "stop")
259
260 /**
261  * __get_real_thresh - read battery charge start/stop threshold from SMAPI
262  * @bat:    battery number (0 or 1)
263  * @which:  THRESH_START or THRESH_STOP
264  * @thresh: 1..99, 0=default 1..99, 0=default (pass this as-is to SMAPI)
265  * @outEDI: some additional state that needs to be preserved, meaning unknown
266  * @outESI: some additional state that needs to be preserved, meaning unknown
267  */
268 static int __get_real_thresh(int bat, enum thresh_type which, int *thresh,
269                              u32 *outEDI, u32 *outESI)
270 {
271         u32 ebx = (which == THRESH_START) ? SMAPI_GET_THRESH_START
272                                           : SMAPI_GET_THRESH_STOP;
273         u32 ecx = (bat+1)<<8;
274         const char *msg;
275         int ret = smapi_request(ebx, ecx, 0, 0, NULL,
276                                 &ecx, NULL, outEDI, outESI, &msg);
277         if (ret) {
278                 TPRINTK(KERN_NOTICE, "cannot get %s_thresh of bat=%d: %s",
279                         THRESH_NAME(which), bat, msg);
280                 return ret;
281         }
282         if (!(ecx&0x00000100)) {
283                 TPRINTK(KERN_NOTICE, "cannot get %s_thresh of bat=%d: ecx=0%x",
284                         THRESH_NAME(which), bat, ecx);
285                 return -EIO;
286         }
287         if (thresh)
288                 *thresh = ecx&0xFF;
289         return 0;
290 }
291
292 /**
293  * get_real_thresh - read battery charge start/stop threshold from SMAPI
294  * @bat:    battery number (0 or 1)
295  * @which:  THRESH_START or THRESH_STOP
296  * @thresh: 1..99, 0=default (passes as-is to SMAPI)
297  */
298 static int get_real_thresh(int bat, enum thresh_type which, int *thresh)
299 {
300         return __get_real_thresh(bat, which, thresh, NULL, NULL);
301 }
302
303 /**
304  * set_real_thresh - write battery start/top charge threshold to SMAPI
305  * @bat:    battery number (0 or 1)
306  * @which:  THRESH_START or THRESH_STOP
307  * @thresh: 1..99, 0=default (passes as-is to SMAPI)
308  */
309 static int set_real_thresh(int bat, enum thresh_type which, int thresh)
310 {
311         u32 ebx = (which == THRESH_START) ? SMAPI_SET_THRESH_START
312                                           : SMAPI_SET_THRESH_STOP;
313         u32 ecx = ((bat+1)<<8) + thresh;
314         u32 getDI, getSI;
315         const char *msg;
316         int ret;
317
318         /* verify read before writing */
319         ret = __get_real_thresh(bat, which, NULL, &getDI, &getSI);
320         if (ret)
321                 return ret;
322
323         ret = smapi_write(ebx, ecx, getDI, getSI, &msg);
324         if (ret)
325                 TPRINTK(KERN_NOTICE, "set %s to %d for bat=%d failed: %s",
326                         THRESH_NAME(which), thresh, bat, msg);
327         else
328                 TPRINTK(KERN_INFO, "set %s to %d for bat=%d",
329                         THRESH_NAME(which), thresh, bat);
330         return ret;
331 }
332
333 /**
334  * __get_inhibit_charge_minutes - get inhibit charge period from SMAPI
335  * @bat:     battery number (0 or 1)
336  * @minutes: period in minutes (1..65535 minutes, 0=disabled)
337  * @outECX: some additional state that needs to be preserved, meaning unknown
338  * Note that @minutes is the originally set value, it does not count down.
339  */
340 static int __get_inhibit_charge_minutes(int bat, int *minutes, u32 *outECX)
341 {
342         u32 ecx = (bat+1)<<8;
343         u32 esi;
344         const char *msg;
345         int ret = smapi_request(SMAPI_GET_INHIBIT_CHARGE, ecx, 0, 0,
346                                 NULL, &ecx, NULL, NULL, &esi, &msg);
347         if (ret) {
348                 TPRINTK(KERN_NOTICE, "failed for bat=%d: %s", bat, msg);
349                 return ret;
350         }
351         if (!(ecx&0x0100)) {
352                 TPRINTK(KERN_NOTICE, "bad ecx=0x%x for bat=%d", ecx, bat);
353                 return -EIO;
354         }
355         if (minutes)
356                 *minutes = (ecx&0x0001)?esi:0;
357         if (outECX)
358                 *outECX = ecx;
359         return 0;
360 }
361
362 /**
363  * get_inhibit_charge_minutes - get inhibit charge period from SMAPI
364  * @bat:     battery number (0 or 1)
365  * @minutes: period in minutes (1..65535 minutes, 0=disabled)
366  * Note that @minutes is the originally set value, it does not count down.
367  */
368 static int get_inhibit_charge_minutes(int bat, int *minutes)
369 {
370         return __get_inhibit_charge_minutes(bat, minutes, NULL);
371 }
372
373 /**
374  * set_inhibit_charge_minutes - write inhibit charge period to SMAPI
375  * @bat:     battery number (0 or 1)
376  * @minutes: period in minutes (1..65535 minutes, 0=disabled)
377  */
378 static int set_inhibit_charge_minutes(int bat, int minutes)
379 {
380         u32 ecx;
381         const char *msg;
382         int ret;
383
384         /* verify read before writing */
385         ret = __get_inhibit_charge_minutes(bat, NULL, &ecx);
386         if (ret)
387                 return ret;
388
389         ecx = ((bat+1)<<8) | (ecx&0x00FE) | (minutes > 0 ? 0x0001 : 0x0000);
390         if (minutes > 0xFFFF)
391                 minutes = 0xFFFF;
392         ret = smapi_write(SMAPI_SET_INHIBIT_CHARGE, ecx, 0, minutes, &msg);
393         if (ret)
394                 TPRINTK(KERN_NOTICE,
395                         "set to %d failed for bat=%d: %s", minutes, bat, msg);
396         else
397                 TPRINTK(KERN_INFO, "set to %d for bat=%d\n", minutes, bat);
398         return ret;
399 }
400
401
402 /**
403  * get_force_discharge - get status of forced discharging from SMAPI
404  * @bat:     battery number (0 or 1)
405  * @enabled: 1 if forced discharged is enabled, 0 if not
406  */
407 static int get_force_discharge(int bat, int *enabled)
408 {
409         u32 ecx = (bat+1)<<8;
410         const char *msg;
411         int ret = smapi_request(SMAPI_GET_FORCE_DISCHARGE, ecx, 0, 0,
412                                 NULL, &ecx, NULL, NULL, NULL, &msg);
413         if (ret) {
414                 TPRINTK(KERN_NOTICE, "failed for bat=%d: %s", bat, msg);
415                 return ret;
416         }
417         *enabled = (!(ecx&0x00000100) && (ecx&0x00000001))?1:0;
418         return 0;
419 }
420
421 /**
422  * set_force_discharge - write status of forced discharging to SMAPI
423  * @bat:     battery number (0 or 1)
424  * @enabled: 1 if forced discharged is enabled, 0 if not
425  */
426 static int set_force_discharge(int bat, int enabled)
427 {
428         u32 ecx = (bat+1)<<8;
429         const char *msg;
430         int ret = smapi_request(SMAPI_GET_FORCE_DISCHARGE, ecx, 0, 0,
431                                 NULL, &ecx, NULL, NULL, NULL, &msg);
432         if (ret) {
433                 TPRINTK(KERN_NOTICE, "get failed for bat=%d: %s", bat, msg);
434                 return ret;
435         }
436         if (ecx&0x00000100) {
437                 TPRINTK(KERN_NOTICE, "cannot force discharge bat=%d", bat);
438                 return -EIO;
439         }
440
441         ecx = ((bat+1)<<8) | (ecx&0x000000FA) | (enabled?0x00000001:0);
442         ret = smapi_write(SMAPI_SET_FORCE_DISCHARGE, ecx, 0, 0, &msg);
443         if (ret)
444                 TPRINTK(KERN_NOTICE, "set to %d failed for bat=%d: %s",
445                         enabled, bat, msg);
446         else
447                 TPRINTK(KERN_INFO, "set to %d for bat=%d", enabled, bat);
448         return ret;
449 }
450
451
452 /*********************************************************************
453  * Wrappers to threshold-related SMAPI functions, which handle default
454  * thresholds and related quirks.
455  */
456
457 /* Minimum, default and minimum difference for battery charging thresholds: */
458 #define MIN_THRESH_DELTA      4  /* Min delta between start and stop thresh */
459 #define MIN_THRESH_START      2
460 #define MAX_THRESH_START      (100-MIN_THRESH_DELTA)
461 #define MIN_THRESH_STOP       (MIN_THRESH_START + MIN_THRESH_DELTA)
462 #define MAX_THRESH_STOP       100
463 #define DEFAULT_THRESH_START  MAX_THRESH_START
464 #define DEFAULT_THRESH_STOP   MAX_THRESH_STOP
465
466 /* The GUI of IBM's Battery Maximizer seems to show a start threshold that
467  * is 1 more than the value we set/get via SMAPI. Since the threshold is
468  * maintained across reboot, this can be confusing. So we kludge our
469  * interface for interoperability: */
470 #define BATMAX_FIX   1
471
472 /* Get charge start/stop threshold (1..100),
473  * substituting default values if needed and applying BATMAT_FIX. */
474 static int get_thresh(int bat, enum thresh_type which, int *thresh)
475 {
476         int ret = get_real_thresh(bat, which, thresh);
477         if (ret)
478                 return ret;
479         if (*thresh == 0)
480                 *thresh = (which == THRESH_START) ? DEFAULT_THRESH_START
481                                                   : DEFAULT_THRESH_STOP;
482         else if (which == THRESH_START)
483                 *thresh += BATMAX_FIX;
484         return 0;
485 }
486
487
488 /* Set charge start/stop threshold (1..100),
489  * substituting default values if needed and applying BATMAT_FIX. */
490 static int set_thresh(int bat, enum thresh_type which, int thresh)
491 {
492         if (which == THRESH_STOP && thresh == DEFAULT_THRESH_STOP)
493                 thresh = 0; /* 100 is out of range, but default means 100 */
494         if (which == THRESH_START)
495                 thresh -= BATMAX_FIX;
496         return set_real_thresh(bat, which, thresh);
497 }
498
499 /*********************************************************************
500  * ThinkPad embedded controller readout and basic functions
501  */
502
503 /**
504  * read_tp_ec_row - read data row from the ThinkPad embedded controller
505  * @arg0: EC command code
506  * @bat: battery number, 0 or 1
507  * @j: the byte value to be used for "junk" (unused) input/outputs
508  * @dataval: result vector
509  */
510 static int read_tp_ec_row(u8 arg0, int bat, u8 j, u8 *dataval)
511 {
512         int ret;
513         const struct thinkpad_ec_row args = { .mask = 0xFFFF,
514                 .val = {arg0, j,j,j,j,j,j,j,j,j,j,j,j,j,j, (u8)bat} };
515         struct thinkpad_ec_row data = { .mask = 0xFFFF };
516
517         ret = thinkpad_ec_lock();
518         if (ret)
519                 return ret;
520         ret = thinkpad_ec_read_row(&args, &data);
521         thinkpad_ec_unlock();
522         memcpy(dataval, &data.val, TP_CONTROLLER_ROW_LEN);
523         return ret;
524 }
525
526 /**
527  * power_device_present - check for presence of battery or AC power
528  * @bat: 0 for battery 0, 1 for battery 1, otherwise AC power
529  * Returns 1 if present, 0 if not present, negative if error.
530  */
531 static int power_device_present(int bat)
532 {
533         u8 row[TP_CONTROLLER_ROW_LEN];
534         u8 test;
535         int ret = read_tp_ec_row(1, bat, 0, row);
536         if (ret)
537                 return ret;
538         switch (bat) {
539         case 0:  test = 0x40; break; /* battery 0 */
540         case 1:  test = 0x20; break; /* battery 1 */
541         default: test = 0x80;        /* AC power */
542         }
543         return (row[0] & test) ? 1 : 0;
544 }
545
546 /**
547  * bat_has_status - check if battery can report detailed status
548  * @bat: 0 for battery 0, 1 for battery 1
549  * Returns 1 if yes, 0 if no, negative if error.
550  */
551 static int bat_has_status(int bat)
552 {
553         u8 row[TP_CONTROLLER_ROW_LEN];
554         int ret = read_tp_ec_row(1, bat, 0, row);
555         if (ret)
556                 return ret;
557         if ((row[0] & (bat?0x20:0x40)) == 0) /* no battery */
558                 return 0;
559         if ((row[1] & (0x60)) == 0) /* no status */
560                 return 0;
561         return 1;
562 }
563
564 /**
565  * get_tp_ec_bat_16 - read a 16-bit value from EC battery status data
566  * @arg0: first argument to EC
567  * @off: offset in row returned from EC
568  * @bat: battery (0 or 1)
569  * @val: the 16-bit value obtained
570  * Returns nonzero on error.
571  */
572 static int get_tp_ec_bat_16(u8 arg0, int offset, int bat, u16 *val)
573 {
574         u8 row[TP_CONTROLLER_ROW_LEN];
575         int ret;
576         if (bat_has_status(bat) != 1)
577                 return -ENXIO;
578         ret = read_tp_ec_row(arg0, bat, 0, row);
579         if (ret)
580                 return ret;
581         *val = *(u16 *)(row+offset);
582         return 0;
583 }
584
585 /*********************************************************************
586  * sysfs attributes for batteries -
587  * definitions and helper functions
588  */
589
590 /* A custom device attribute struct which holds a battery number */
591 struct bat_device_attribute {
592         struct device_attribute dev_attr;
593         int bat;
594 };
595
596 /**
597  * attr_get_bat - get the battery to which the attribute belongs
598  */
599 static int attr_get_bat(struct device_attribute *attr)
600 {
601         return container_of(attr, struct bat_device_attribute, dev_attr)->bat;
602 }
603
604 /**
605  * show_tp_ec_bat_u16 - show an unsigned 16-bit battery attribute
606  * @arg0: specified 1st argument of EC raw to read
607  * @offset: byte offset in EC raw data
608  * @mul: correction factor to multiply by
609  * @na_msg: string to output is value not available (0xFFFFFFFF)
610  * @attr: battery attribute
611  * @buf: output buffer
612  * The 16-bit value is read from the EC, treated as unsigned,
613  * transformed as x->mul*x, and printed to the buffer.
614  * If the value is 0xFFFFFFFF and na_msg!=%NULL, na_msg is printed instead.
615  */
616 static ssize_t show_tp_ec_bat_u16(u8 arg0, int offset, int mul,
617                               const char *na_msg,
618                               struct device_attribute *attr, char *buf)
619 {
620         u16 val;
621         int ret = get_tp_ec_bat_16(arg0, offset, attr_get_bat(attr), &val);
622         if (ret)
623                 return ret;
624         if (na_msg && val == 0xFFFF)
625                 return sprintf(buf, "%s\n", na_msg);
626         else
627                 return sprintf(buf, "%u\n", mul*(unsigned int)val);
628 }
629
630 /**
631  * show_tp_ec_bat_s16 - show an signed 16-bit battery attribute
632  * @arg0: specified 1st argument of EC raw to read
633  * @offset: byte offset in EC raw data
634  * @mul: correction factor to multiply by
635  * @add: correction term to add after multiplication
636  * @attr: battery attribute
637  * @buf: output buffer
638  * The 16-bit value is read from the EC, treated as signed,
639  * transformed as x->mul*x+add, and printed to the buffer.
640  */
641 static ssize_t show_tp_ec_bat_s16(u8 arg0, int offset, int mul, int add,
642                               struct device_attribute *attr, char *buf)
643 {
644         u16 val;
645         int ret = get_tp_ec_bat_16(arg0, offset, attr_get_bat(attr), &val);
646         if (ret)
647                 return ret;
648         return sprintf(buf, "%d\n", mul*(s16)val+add);
649 }
650
651 /**
652  * show_tp_ec_bat_str - show a string from EC battery status data
653  * @arg0: specified 1st argument of EC raw to read
654  * @offset: byte offset in EC raw data
655  * @maxlen: maximum string length
656  * @attr: battery attribute
657  * @buf: output buffer
658  */
659 static ssize_t show_tp_ec_bat_str(u8 arg0, int offset, int maxlen,
660                               struct device_attribute *attr, char *buf)
661 {
662         int bat = attr_get_bat(attr);
663         u8 row[TP_CONTROLLER_ROW_LEN];
664         int ret;
665         if (bat_has_status(bat) != 1)
666                 return -ENXIO;
667         ret = read_tp_ec_row(arg0, bat, 0, row);
668         if (ret)
669                 return ret;
670         strncpy(buf, (char *)row+offset, maxlen);
671         buf[maxlen] = 0;
672         strcat(buf, "\n");
673         return strlen(buf);
674 }
675
676 /**
677  * show_tp_ec_bat_power - show a power readout from EC battery status data
678  * @arg0: specified 1st argument of EC raw to read
679  * @offV: byte offset of voltage in EC raw data
680  * @offI: byte offset of current in EC raw data
681  * @attr: battery attribute
682  * @buf: output buffer
683  * Computes the power as current*voltage from the two given readout offsets.
684  */
685 static ssize_t show_tp_ec_bat_power(u8 arg0, int offV, int offI,
686                                 struct device_attribute *attr, char *buf)
687 {
688         u8 row[TP_CONTROLLER_ROW_LEN];
689         int milliamp, millivolt, ret;
690         int bat = attr_get_bat(attr);
691         if (bat_has_status(bat) != 1)
692                 return -ENXIO;
693         ret = read_tp_ec_row(1, bat, 0, row);
694         if (ret)
695                 return ret;
696         millivolt = *(u16 *)(row+offV);
697         milliamp = *(s16 *)(row+offI);
698         return sprintf(buf, "%d\n", milliamp*millivolt/1000); /* units: mW */
699 }
700
701 /**
702  * show_tp_ec_bat_date - decode and show a date from EC battery status data
703  * @arg0: specified 1st argument of EC raw to read
704  * @offset: byte offset in EC raw data
705  * @attr: battery attribute
706  * @buf: output buffer
707  */
708 static ssize_t show_tp_ec_bat_date(u8 arg0, int offset,
709                                struct device_attribute *attr, char *buf)
710 {
711         u8 row[TP_CONTROLLER_ROW_LEN];
712         u16 v;
713         int ret;
714         int day, month, year;
715         int bat = attr_get_bat(attr);
716         if (bat_has_status(bat) != 1)
717                 return -ENXIO;
718         ret = read_tp_ec_row(arg0, bat, 0, row);
719         if (ret)
720                 return ret;
721
722         /* Decode bit-packed: v = day | (month<<5) | ((year-1980)<<9) */
723         v = *(u16 *)(row+offset);
724         day = v & 0x1F;
725         month = (v >> 5) & 0xF;
726         year = (v >> 9) + 1980;
727
728         return sprintf(buf, "%04d-%02d-%02d\n", year, month, day);
729 }
730
731
732 /*********************************************************************
733  * sysfs attribute I/O for batteries -
734  * the actual attribute show/store functions
735  */
736
737 static ssize_t show_battery_start_charge_thresh(struct device *dev,
738         struct device_attribute *attr, char *buf)
739 {
740         int thresh;
741         int bat = attr_get_bat(attr);
742         int ret = get_thresh(bat, THRESH_START, &thresh);
743         if (ret)
744                 return ret;
745         return sprintf(buf, "%d\n", thresh);  /* units: percent */
746 }
747
748 static ssize_t show_battery_stop_charge_thresh(struct device *dev,
749         struct device_attribute *attr, char *buf)
750 {
751         int thresh;
752         int bat = attr_get_bat(attr);
753         int ret = get_thresh(bat, THRESH_STOP, &thresh);
754         if (ret)
755                 return ret;
756         return sprintf(buf, "%d\n", thresh);  /* units: percent */
757 }
758
759 /**
760  * store_battery_start_charge_thresh - store battery_start_charge_thresh attr
761  * Since this is a kernel<->user interface, we ensure a valid state for
762  * the hardware. We do this by clamping the requested threshold to the
763  * valid range and, if necessary, moving the other threshold so that
764  * it's MIN_THRESH_DELTA away from this one.
765  */
766 static ssize_t store_battery_start_charge_thresh(struct device *dev,
767         struct device_attribute *attr, const char *buf, size_t count)
768 {
769         int thresh, other_thresh, ret;
770         int bat = attr_get_bat(attr);
771
772         if (sscanf(buf, "%d", &thresh) != 1 || thresh < 1 || thresh > 100)
773                 return -EINVAL;
774
775         if (thresh < MIN_THRESH_START) /* clamp up to MIN_THRESH_START */
776                 thresh = MIN_THRESH_START;
777         if (thresh > MAX_THRESH_START) /* clamp down to MAX_THRESH_START */
778                 thresh = MAX_THRESH_START;
779
780         down(&smapi_mutex);
781         ret = get_thresh(bat, THRESH_STOP, &other_thresh);
782         if (ret != -EOPNOTSUPP && ret != -ENXIO) {
783                 if (ret) /* other threshold is set? */
784                         goto out;
785                 ret = get_real_thresh(bat, THRESH_START, NULL);
786                 if (ret) /* this threshold is set? */
787                         goto out;
788                 if (other_thresh < thresh+MIN_THRESH_DELTA) {
789                         /* move other thresh to keep it above this one */
790                         ret = set_thresh(bat, THRESH_STOP,
791                                          thresh+MIN_THRESH_DELTA);
792                         if (ret)
793                                 goto out;
794                 }
795         }
796         ret = set_thresh(bat, THRESH_START, thresh);
797 out:
798         up(&smapi_mutex);
799         return count;
800
801 }
802
803 /**
804  * store_battery_stop_charge_thresh - store battery_stop_charge_thresh attr
805  * Since this is a kernel<->user interface, we ensure a valid state for
806  * the hardware. We do this by clamping the requested threshold to the
807  * valid range and, if necessary, moving the other threshold so that
808  * it's MIN_THRESH_DELTA away from this one.
809  */
810 static ssize_t store_battery_stop_charge_thresh(struct device *dev,
811         struct device_attribute *attr, const char *buf, size_t count)
812 {
813         int thresh, other_thresh, ret;
814         int bat = attr_get_bat(attr);
815
816         if (sscanf(buf, "%d", &thresh) != 1 || thresh < 1 || thresh > 100)
817                 return -EINVAL;
818
819         if (thresh < MIN_THRESH_STOP) /* clamp up to MIN_THRESH_STOP */
820                 thresh = MIN_THRESH_STOP;
821
822         down(&smapi_mutex);
823         ret = get_thresh(bat, THRESH_START, &other_thresh);
824         if (ret != -EOPNOTSUPP && ret != -ENXIO) { /* other threshold exists? */
825                 if (ret)
826                         goto out;
827                 /* this threshold exists? */
828                 ret = get_real_thresh(bat, THRESH_STOP, NULL);
829                 if (ret)
830                         goto out;
831                 if (other_thresh >= thresh-MIN_THRESH_DELTA) {
832                          /* move other thresh to be below this one */
833                         ret = set_thresh(bat, THRESH_START,
834                                          thresh-MIN_THRESH_DELTA);
835                         if (ret)
836                                 goto out;
837                 }
838         }
839         ret = set_thresh(bat, THRESH_STOP, thresh);
840 out:
841         up(&smapi_mutex);
842         return count;
843 }
844
845 static ssize_t show_battery_inhibit_charge_minutes(struct device *dev,
846         struct device_attribute *attr, char *buf)
847 {
848         int minutes;
849         int bat = attr_get_bat(attr);
850         int ret = get_inhibit_charge_minutes(bat, &minutes);
851         if (ret)
852                 return ret;
853         return sprintf(buf, "%d\n", minutes);  /* units: minutes */
854 }
855
856 static ssize_t store_battery_inhibit_charge_minutes(struct device *dev,
857                                 struct device_attribute *attr,
858                                 const char *buf, size_t count)
859 {
860         int ret;
861         int minutes;
862         int bat = attr_get_bat(attr);
863         if (sscanf(buf, "%d", &minutes) != 1 || minutes < 0) {
864                 TPRINTK(KERN_ERR, "inhibit_charge_minutes: "
865                               "must be a non-negative integer");
866                 return -EINVAL;
867         }
868         ret = set_inhibit_charge_minutes(bat, minutes);
869         if (ret)
870                 return ret;
871         return count;
872 }
873
874 static ssize_t show_battery_force_discharge(struct device *dev,
875         struct device_attribute *attr, char *buf)
876 {
877         int enabled;
878         int bat = attr_get_bat(attr);
879         int ret = get_force_discharge(bat, &enabled);
880         if (ret)
881                 return ret;
882         return sprintf(buf, "%d\n", enabled);  /* type: boolean */
883 }
884
885 static ssize_t store_battery_force_discharge(struct device *dev,
886         struct device_attribute *attr, const char *buf, size_t count)
887 {
888         int ret;
889         int enabled;
890         int bat = attr_get_bat(attr);
891         if (sscanf(buf, "%d", &enabled) != 1 || enabled < 0 || enabled > 1)
892                 return -EINVAL;
893         ret = set_force_discharge(bat, enabled);
894         if (ret)
895                 return ret;
896         return count;
897 }
898
899 static ssize_t show_battery_installed(
900         struct device *dev, struct device_attribute *attr, char *buf)
901 {
902         int bat = attr_get_bat(attr);
903         int ret = power_device_present(bat);
904         if (ret < 0)
905                 return ret;
906         return sprintf(buf, "%d\n", ret); /* type: boolean */
907 }
908
909 static ssize_t show_battery_state(
910         struct device *dev, struct device_attribute *attr, char *buf)
911 {
912         u8 row[TP_CONTROLLER_ROW_LEN];
913         const char *txt;
914         int ret;
915         int bat = attr_get_bat(attr);
916         if (bat_has_status(bat) != 1)
917                 return sprintf(buf, "none\n");
918         ret = read_tp_ec_row(1, bat, 0, row);
919         if (ret)
920                 return ret;
921         switch (row[1] & 0xf0) {
922         case 0xc0: txt = "idle"; break;
923         case 0xd0: txt = "discharging"; break;
924         case 0xe0: txt = "charging"; break;
925         default:   return sprintf(buf, "unknown (0x%x)\n", row[1]);
926         }
927         return sprintf(buf, "%s\n", txt);  /* type: string from fixed set */
928 }
929
930 static ssize_t show_battery_manufacturer(
931         struct device *dev, struct device_attribute *attr, char *buf)
932 {
933         /* type: string. SBS spec v1.1 p34: ManufacturerName() */
934         return show_tp_ec_bat_str(4, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf);
935 }
936
937 static ssize_t show_battery_model(
938         struct device *dev, struct device_attribute *attr, char *buf)
939 {
940         /* type: string. SBS spec v1.1 p34: DeviceName() */
941         return show_tp_ec_bat_str(5, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf);
942 }
943
944 static ssize_t show_battery_barcoding(
945         struct device *dev, struct device_attribute *attr, char *buf)
946 {
947         /* type: string */
948         return show_tp_ec_bat_str(7, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf);
949 }
950
951 static ssize_t show_battery_chemistry(
952         struct device *dev, struct device_attribute *attr, char *buf)
953 {
954         /* type: string. SBS spec v1.1 p34-35: DeviceChemistry() */
955         return show_tp_ec_bat_str(6, 2, 5, attr, buf);
956 }
957
958 static ssize_t show_battery_voltage(
959         struct device *dev, struct device_attribute *attr, char *buf)
960 {
961         /* units: mV. SBS spec v1.1 p24: Voltage() */
962         return show_tp_ec_bat_u16(1, 6, 1, NULL, attr, buf);
963 }
964
965 static ssize_t show_battery_design_voltage(
966         struct device *dev, struct device_attribute *attr, char *buf)
967 {
968         /* units: mV. SBS spec v1.1 p32: DesignVoltage() */
969         return show_tp_ec_bat_u16(3, 4, 1, NULL, attr, buf);
970 }
971
972 static ssize_t show_battery_charging_max_voltage(
973         struct device *dev, struct device_attribute *attr, char *buf)
974 {
975         /* units: mV. SBS spec v1.1 p37,39: ChargingVoltage() */
976         return show_tp_ec_bat_u16(9, 8, 1, NULL, attr, buf);
977 }
978
979 static ssize_t show_battery_group0_voltage(
980         struct device *dev, struct device_attribute *attr, char *buf)
981 {
982         /* units: mV */
983         return show_tp_ec_bat_u16(0xA, 12, 1, NULL, attr, buf);
984 }
985
986 static ssize_t show_battery_group1_voltage(
987         struct device *dev, struct device_attribute *attr, char *buf)
988 {
989         /* units: mV */
990         return show_tp_ec_bat_u16(0xA, 10, 1, NULL, attr, buf);
991 }
992
993 static ssize_t show_battery_group2_voltage(
994         struct device *dev, struct device_attribute *attr, char *buf)
995 {
996         /* units: mV */
997         return show_tp_ec_bat_u16(0xA, 8, 1, NULL, attr, buf);
998 }
999
1000 static ssize_t show_battery_group3_voltage(
1001         struct device *dev, struct device_attribute *attr, char *buf)
1002 {
1003         /* units: mV */
1004         return show_tp_ec_bat_u16(0xA, 6, 1, NULL, attr, buf);
1005 }
1006
1007 static ssize_t show_battery_current_now(
1008         struct device *dev, struct device_attribute *attr, char *buf)
1009 {
1010         /* units: mA. SBS spec v1.1 p24: Current() */
1011         return show_tp_ec_bat_s16(1, 8, 1, 0, attr, buf);
1012 }
1013
1014 static ssize_t show_battery_current_avg(
1015         struct device *dev, struct device_attribute *attr, char *buf)
1016 {
1017         /* units: mA. SBS spec v1.1 p24: AverageCurrent() */
1018         return show_tp_ec_bat_s16(1, 10, 1, 0, attr, buf);
1019 }
1020
1021 static ssize_t show_battery_charging_max_current(
1022         struct device *dev, struct device_attribute *attr, char *buf)
1023 {
1024         /* units: mA. SBS spec v1.1 p36,38: ChargingCurrent() */
1025         return show_tp_ec_bat_s16(9, 6, 1, 0, attr, buf);
1026 }
1027
1028 static ssize_t show_battery_power_now(
1029         struct device *dev, struct device_attribute *attr, char *buf)
1030 {
1031         /* units: mW. SBS spec v1.1: Voltage()*Current() */
1032         return show_tp_ec_bat_power(1, 6, 8, attr, buf);
1033 }
1034
1035 static ssize_t show_battery_power_avg(
1036         struct device *dev, struct device_attribute *attr, char *buf)
1037 {
1038         /* units: mW. SBS spec v1.1: Voltage()*AverageCurrent() */
1039         return show_tp_ec_bat_power(1, 6, 10, attr, buf);
1040 }
1041
1042 static ssize_t show_battery_remaining_percent(
1043         struct device *dev, struct device_attribute *attr, char *buf)
1044 {
1045         /* units: percent. SBS spec v1.1 p25: RelativeStateOfCharge() */
1046         return show_tp_ec_bat_u16(1, 12, 1, NULL, attr, buf);
1047 }
1048
1049 static ssize_t show_battery_remaining_percent_error(
1050         struct device *dev, struct device_attribute *attr, char *buf)
1051 {
1052         /* units: percent. SBS spec v1.1 p25: MaxError() */
1053         return show_tp_ec_bat_u16(9, 4, 1, NULL, attr, buf);
1054 }
1055
1056 static ssize_t show_battery_remaining_charging_time(
1057         struct device *dev, struct device_attribute *attr, char *buf)
1058 {
1059         /* units: minutes. SBS spec v1.1 p27: AverageTimeToFull() */
1060         return show_tp_ec_bat_u16(2, 8, 1, "not_charging", attr, buf);
1061 }
1062
1063 static ssize_t show_battery_remaining_running_time(
1064         struct device *dev, struct device_attribute *attr, char *buf)
1065 {
1066         /* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */
1067         return show_tp_ec_bat_u16(2, 6, 1, "not_discharging", attr, buf);
1068 }
1069
1070 static ssize_t show_battery_remaining_running_time_now(
1071         struct device *dev, struct device_attribute *attr, char *buf)
1072 {
1073         /* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */
1074         return show_tp_ec_bat_u16(2, 4, 1, "not_discharging", attr, buf);
1075 }
1076
1077 static ssize_t show_battery_remaining_capacity(
1078         struct device *dev, struct device_attribute *attr, char *buf)
1079 {
1080         /* units: mWh. SBS spec v1.1 p26. */
1081         return show_tp_ec_bat_u16(1, 14, 10, "", attr, buf);
1082 }
1083
1084 static ssize_t show_battery_last_full_capacity(
1085         struct device *dev, struct device_attribute *attr, char *buf)
1086 {
1087         /* units: mWh. SBS spec v1.1 p26: FullChargeCapacity() */
1088         return show_tp_ec_bat_u16(2, 2, 10, "", attr, buf);
1089 }
1090
1091 static ssize_t show_battery_design_capacity(
1092         struct device *dev, struct device_attribute *attr, char *buf)
1093 {
1094         /* units: mWh. SBS spec v1.1 p32: DesignCapacity() */
1095         return show_tp_ec_bat_u16(3, 2, 10, "", attr, buf);
1096 }
1097
1098 static ssize_t show_battery_cycle_count(
1099         struct device *dev, struct device_attribute *attr, char *buf)
1100 {
1101         /* units: ordinal. SBS spec v1.1 p32: CycleCount() */
1102         return show_tp_ec_bat_u16(2, 12, 1, "", attr, buf);
1103 }
1104
1105 static ssize_t show_battery_temperature(
1106         struct device *dev, struct device_attribute *attr, char *buf)
1107 {
1108         /* units: millicelsius. SBS spec v1.1: Temperature()*10 */
1109         return show_tp_ec_bat_s16(1, 4, 100, -273100, attr, buf);
1110 }
1111
1112 static ssize_t show_battery_serial(
1113         struct device *dev, struct device_attribute *attr, char *buf)
1114 {
1115         /* type: int. SBS spec v1.1 p34: SerialNumber() */
1116         return show_tp_ec_bat_u16(3, 10, 1, "", attr, buf);
1117 }
1118
1119 static ssize_t show_battery_manufacture_date(
1120         struct device *dev, struct device_attribute *attr, char *buf)
1121 {
1122         /* type: YYYY-MM-DD. SBS spec v1.1 p34: ManufactureDate() */
1123         return show_tp_ec_bat_date(3, 8, attr, buf);
1124 }
1125
1126 static ssize_t show_battery_first_use_date(
1127         struct device *dev, struct device_attribute *attr, char *buf)
1128 {
1129         /* type: YYYY-MM-DD */
1130         return show_tp_ec_bat_date(8, 2, attr, buf);
1131 }
1132
1133 /**
1134  * show_battery_dump - show the battery's dump attribute
1135  * The dump attribute gives a hex dump of all EC readouts related to a
1136  * battery. Some of the enumerated values don't really exist (i.e., the
1137  * EC function just leaves them untouched); we use a kludge to detect and
1138  * denote these.
1139  */
1140 #define MIN_DUMP_ARG0 0x00
1141 #define MAX_DUMP_ARG0 0x0a /* 0x0b is useful too but hangs old EC firmware */
1142 static ssize_t show_battery_dump(
1143         struct device *dev, struct device_attribute *attr, char *buf)
1144 {
1145         int i;
1146         char *p = buf;
1147         int bat = attr_get_bat(attr);
1148         u8 arg0; /* first argument to EC */
1149         u8 rowa[TP_CONTROLLER_ROW_LEN],
1150            rowb[TP_CONTROLLER_ROW_LEN];
1151         const u8 junka = 0xAA,
1152                  junkb = 0x55; /* junk values for testing changes */
1153         int ret;
1154
1155         for (arg0 = MIN_DUMP_ARG0; arg0 <= MAX_DUMP_ARG0; ++arg0) {
1156                 if ((p-buf) > PAGE_SIZE-TP_CONTROLLER_ROW_LEN*5)
1157                         return -ENOMEM; /* don't overflow sysfs buf */
1158                 /* Read raw twice with different junk values,
1159                  * to detect unused output bytes which are left unchaged: */
1160                 ret = read_tp_ec_row(arg0, bat, junka, rowa);
1161                 if (ret)
1162                         return ret;
1163                 ret = read_tp_ec_row(arg0, bat, junkb, rowb);
1164                 if (ret)
1165                         return ret;
1166                 for (i = 0; i < TP_CONTROLLER_ROW_LEN; i++) {
1167                         if (rowa[i] == junka && rowb[i] == junkb)
1168                                 p += sprintf(p, "-- "); /* unused by EC */
1169                         else
1170                                 p += sprintf(p, "%02x ", rowa[i]);
1171                 }
1172                 p += sprintf(p, "\n");
1173         }
1174         return p-buf;
1175 }
1176
1177
1178 /*********************************************************************
1179  * sysfs attribute I/O, other than batteries
1180  */
1181
1182 static ssize_t show_ac_connected(
1183         struct device *dev, struct device_attribute *attr, char *buf)
1184 {
1185         int ret = power_device_present(0xFF);
1186         if (ret < 0)
1187                 return ret;
1188         return sprintf(buf, "%d\n", ret);  /* type: boolean */
1189 }
1190
1191 /*********************************************************************
1192  * The the "smapi_request" sysfs attribute executes a raw SMAPI call.
1193  * You write to make a request and read to get the result. The state
1194  * is saved globally rather than per fd (sysfs limitation), so
1195  * simultaenous requests may get each other's results! So this is for
1196  * development and debugging only.
1197  */
1198 #define MAX_SMAPI_ATTR_ANSWER_LEN   128
1199 static char smapi_attr_answer[MAX_SMAPI_ATTR_ANSWER_LEN] = "";
1200
1201 static ssize_t show_smapi_request(struct device *dev,
1202                                   struct device_attribute *attr, char *buf)
1203 {
1204         int ret = snprintf(buf, PAGE_SIZE, "%s", smapi_attr_answer);
1205         smapi_attr_answer[0] = '\0';
1206         return ret;
1207 }
1208
1209 static ssize_t store_smapi_request(struct device *dev,
1210                                    struct device_attribute *attr,
1211                                    const char *buf, size_t count)
1212 {
1213         unsigned int inEBX, inECX, inEDI, inESI;
1214         u32 outEBX, outECX, outEDX, outEDI, outESI;
1215         const char *msg;
1216         int ret;
1217         if (sscanf(buf, "%x %x %x %x", &inEBX, &inECX, &inEDI, &inESI) != 4) {
1218                 smapi_attr_answer[0] = '\0';
1219                 return -EINVAL;
1220         }
1221         ret = smapi_request(
1222                    inEBX, inECX, inEDI, inESI,
1223                    &outEBX, &outECX, &outEDX, &outEDI, &outESI, &msg);
1224         snprintf(smapi_attr_answer, MAX_SMAPI_ATTR_ANSWER_LEN,
1225                  "%x %x %x %x %x %d '%s'\n",
1226                  (unsigned int)outEBX, (unsigned int)outECX,
1227                  (unsigned int)outEDX, (unsigned int)outEDI,
1228                  (unsigned int)outESI, ret, msg);
1229         if (ret)
1230                 return ret;
1231         else
1232                 return count;
1233 }
1234
1235 /*********************************************************************
1236  * Power management: the embedded controller forgets the battery
1237  * thresholds when the system is suspended to disk and unplugged from
1238  * AC and battery, so we restore it upon resume.
1239  */
1240
1241 static int saved_threshs[4] = {-1, -1, -1, -1};  /* -1 = don't know */
1242
1243 static int tp_suspend(struct platform_device *dev, pm_message_t state)
1244 {
1245         int restore = (state.event == PM_EVENT_HIBERNATE ||
1246                        state.event == PM_EVENT_FREEZE);
1247         if (!restore || get_real_thresh(0, THRESH_STOP , &saved_threshs[0]))
1248                 saved_threshs[0] = -1;
1249         if (!restore || get_real_thresh(0, THRESH_START, &saved_threshs[1]))
1250                 saved_threshs[1] = -1;
1251         if (!restore || get_real_thresh(1, THRESH_STOP , &saved_threshs[2]))
1252                 saved_threshs[2] = -1;
1253         if (!restore || get_real_thresh(1, THRESH_START, &saved_threshs[3]))
1254                 saved_threshs[3] = -1;
1255         DPRINTK("suspend saved: %d %d %d %d", saved_threshs[0],
1256                 saved_threshs[1], saved_threshs[2], saved_threshs[3]);
1257         return 0;
1258 }
1259
1260 static int tp_resume(struct platform_device *dev)
1261 {
1262         DPRINTK("resume restoring: %d %d %d %d", saved_threshs[0],
1263                 saved_threshs[1], saved_threshs[2], saved_threshs[3]);
1264         if (saved_threshs[0] >= 0)
1265                 set_real_thresh(0, THRESH_STOP , saved_threshs[0]);
1266         if (saved_threshs[1] >= 0)
1267                 set_real_thresh(0, THRESH_START, saved_threshs[1]);
1268         if (saved_threshs[2] >= 0)
1269                 set_real_thresh(1, THRESH_STOP , saved_threshs[2]);
1270         if (saved_threshs[3] >= 0)
1271                 set_real_thresh(1, THRESH_START, saved_threshs[3]);
1272         return 0;
1273 }
1274
1275
1276 /*********************************************************************
1277  * Driver model
1278  */
1279
1280 static struct platform_driver tp_driver = {
1281         .suspend = tp_suspend,
1282         .resume = tp_resume,
1283         .driver = {
1284                 .name = "smapi",
1285                 .owner = THIS_MODULE
1286         },
1287 };
1288
1289
1290 /*********************************************************************
1291  * Sysfs device model
1292  */
1293
1294 /* Attributes in /sys/devices/platform/smapi/ */
1295
1296 static DEVICE_ATTR(ac_connected, 0444, show_ac_connected, NULL);
1297 static DEVICE_ATTR(smapi_request, 0600, show_smapi_request,
1298                                         store_smapi_request);
1299
1300 static struct attribute *tp_root_attributes[] = {
1301         &dev_attr_ac_connected.attr,
1302         &dev_attr_smapi_request.attr,
1303         NULL
1304 };
1305 static struct attribute_group tp_root_attribute_group = {
1306         .attrs = tp_root_attributes
1307 };
1308
1309 /* Attributes under /sys/devices/platform/smapi/BAT{0,1}/ :
1310  * Every attribute needs to be defined (i.e., statically allocated) for
1311  * each battery, and then referenced in the attribute list of each battery.
1312  * We use preprocessor voodoo to avoid duplicating the list of attributes 4
1313  * times. The preprocessor output is just normal sysfs attributes code.
1314  */
1315
1316 /**
1317  * FOREACH_BAT_ATTR - invoke the given macros on all our battery attributes
1318  * @_BAT:     battery number (0 or 1)
1319  * @_ATTR_RW: macro to invoke for each read/write attribute
1320  * @_ATTR_R:  macro to invoke for each read-only  attribute
1321  */
1322 #define FOREACH_BAT_ATTR(_BAT, _ATTR_RW, _ATTR_R) \
1323         _ATTR_RW(_BAT, start_charge_thresh) \
1324         _ATTR_RW(_BAT, stop_charge_thresh) \
1325         _ATTR_RW(_BAT, inhibit_charge_minutes) \
1326         _ATTR_RW(_BAT, force_discharge) \
1327         _ATTR_R(_BAT, installed) \
1328         _ATTR_R(_BAT, state) \
1329         _ATTR_R(_BAT, manufacturer) \
1330         _ATTR_R(_BAT, model) \
1331         _ATTR_R(_BAT, barcoding) \
1332         _ATTR_R(_BAT, chemistry) \
1333         _ATTR_R(_BAT, voltage) \
1334         _ATTR_R(_BAT, group0_voltage) \
1335         _ATTR_R(_BAT, group1_voltage) \
1336         _ATTR_R(_BAT, group2_voltage) \
1337         _ATTR_R(_BAT, group3_voltage) \
1338         _ATTR_R(_BAT, current_now) \
1339         _ATTR_R(_BAT, current_avg) \
1340         _ATTR_R(_BAT, charging_max_current) \
1341         _ATTR_R(_BAT, power_now) \
1342         _ATTR_R(_BAT, power_avg) \
1343         _ATTR_R(_BAT, remaining_percent) \
1344         _ATTR_R(_BAT, remaining_percent_error) \
1345         _ATTR_R(_BAT, remaining_charging_time) \
1346         _ATTR_R(_BAT, remaining_running_time) \
1347         _ATTR_R(_BAT, remaining_running_time_now) \
1348         _ATTR_R(_BAT, remaining_capacity) \
1349         _ATTR_R(_BAT, last_full_capacity) \
1350         _ATTR_R(_BAT, design_voltage) \
1351         _ATTR_R(_BAT, charging_max_voltage) \
1352         _ATTR_R(_BAT, design_capacity) \
1353         _ATTR_R(_BAT, cycle_count) \
1354         _ATTR_R(_BAT, temperature) \
1355         _ATTR_R(_BAT, serial) \
1356         _ATTR_R(_BAT, manufacture_date) \
1357         _ATTR_R(_BAT, first_use_date) \
1358         _ATTR_R(_BAT, dump)
1359
1360 /* Define several macros we will feed into FOREACH_BAT_ATTR: */
1361
1362 #define DEFINE_BAT_ATTR_RW(_BAT,_NAME) \
1363         static struct bat_device_attribute dev_attr_##_NAME##_##_BAT = {  \
1364                 .dev_attr = __ATTR(_NAME, 0644, show_battery_##_NAME,   \
1365                                                 store_battery_##_NAME), \
1366                 .bat = _BAT \
1367         };
1368
1369 #define DEFINE_BAT_ATTR_R(_BAT,_NAME) \
1370         static struct bat_device_attribute dev_attr_##_NAME##_##_BAT = {    \
1371                 .dev_attr = __ATTR(_NAME, 0644, show_battery_##_NAME, 0), \
1372                 .bat = _BAT \
1373         };
1374
1375 #define REF_BAT_ATTR(_BAT,_NAME) \
1376         &dev_attr_##_NAME##_##_BAT.dev_attr.attr,
1377
1378 /* This provide all attributes for one battery: */
1379
1380 #define PROVIDE_BAT_ATTRS(_BAT) \
1381         FOREACH_BAT_ATTR(_BAT, DEFINE_BAT_ATTR_RW, DEFINE_BAT_ATTR_R) \
1382         static struct attribute *tp_bat##_BAT##_attributes[] = { \
1383                 FOREACH_BAT_ATTR(_BAT, REF_BAT_ATTR, REF_BAT_ATTR) \
1384                 NULL \
1385         }; \
1386         static struct attribute_group tp_bat##_BAT##_attribute_group = { \
1387                 .name  = "BAT" #_BAT, \
1388                 .attrs = tp_bat##_BAT##_attributes \
1389         };
1390
1391 /* Finally genereate the attributes: */
1392
1393 PROVIDE_BAT_ATTRS(0)
1394 PROVIDE_BAT_ATTRS(1)
1395
1396 /* List of attribute groups */
1397
1398 static struct attribute_group *attr_groups[] = {
1399         &tp_root_attribute_group,
1400         &tp_bat0_attribute_group,
1401         &tp_bat1_attribute_group,
1402         NULL
1403 };
1404
1405
1406 /*********************************************************************
1407  * Init and cleanup
1408  */
1409
1410 static struct attribute_group **next_attr_group; /* next to register */
1411
1412 static int __init tp_init(void)
1413 {
1414         int ret;
1415         printk(KERN_INFO "tp_smapi " TP_VERSION " loading...\n");
1416
1417         ret = find_smapi_port();
1418         if (ret < 0)
1419                 goto err;
1420         else
1421                 smapi_port = ret;
1422
1423         if (!request_region(smapi_port, 1, "smapi")) {
1424                 printk(KERN_ERR "tp_smapi cannot claim port 0x%x\n",
1425                        smapi_port);
1426                 ret = -ENXIO;
1427                 goto err;
1428         }
1429
1430         if (!request_region(SMAPI_PORT2, 1, "smapi")) {
1431                 printk(KERN_ERR "tp_smapi cannot claim port 0x%x\n",
1432                        SMAPI_PORT2);
1433                 ret = -ENXIO;
1434                 goto err_port1;
1435         }
1436
1437         ret = platform_driver_register(&tp_driver);
1438         if (ret)
1439                 goto err_port2;
1440
1441         pdev = platform_device_alloc("smapi", -1);
1442         if (!pdev) {
1443                 ret = -ENOMEM;
1444                 goto err_driver;
1445         }
1446
1447         ret = platform_device_add(pdev);
1448         if (ret)
1449                 goto err_device_free;
1450
1451         for (next_attr_group = attr_groups; *next_attr_group;
1452              ++next_attr_group) {
1453                 ret = sysfs_create_group(&pdev->dev.kobj, *next_attr_group);
1454                 if (ret)
1455                         goto err_attr;
1456         }
1457
1458         printk(KERN_INFO "tp_smapi successfully loaded (smapi_port=0x%x).\n",
1459                smapi_port);
1460         return 0;
1461
1462 err_attr:
1463         while (--next_attr_group >= attr_groups)
1464                 sysfs_remove_group(&pdev->dev.kobj, *next_attr_group);
1465         platform_device_unregister(pdev);
1466 err_device_free:
1467         platform_device_put(pdev);
1468 err_driver:
1469         platform_driver_unregister(&tp_driver);
1470 err_port2:
1471         release_region(SMAPI_PORT2, 1);
1472 err_port1:
1473         release_region(smapi_port, 1);
1474 err:
1475         printk(KERN_ERR "tp_smapi init failed (ret=%d)!\n", ret);
1476         return ret;
1477 }
1478
1479 static void __exit tp_exit(void)
1480 {
1481         while (next_attr_group && --next_attr_group >= attr_groups)
1482                 sysfs_remove_group(&pdev->dev.kobj, *next_attr_group);
1483         platform_device_unregister(pdev);
1484         platform_driver_unregister(&tp_driver);
1485         release_region(SMAPI_PORT2, 1);
1486         if (smapi_port)
1487                 release_region(smapi_port, 1);
1488
1489         printk(KERN_INFO "tp_smapi unloaded.\n");
1490 }
1491
1492 module_init(tp_init);
1493 module_exit(tp_exit);