aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/hdaps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/hdaps.c')
-rw-r--r--drivers/hwmon/hdaps.c373
1 files changed, 124 insertions, 249 deletions
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index eaebfc14c933..1e5dfc7805e2 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -4,11 +4,11 @@
4 * Copyright (C) 2005 Robert Love <rml@novell.com> 4 * Copyright (C) 2005 Robert Love <rml@novell.com>
5 * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> 5 * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
6 * 6 *
7 * The HardDisk Active Protection System (hdaps) is present in the IBM ThinkPad 7 * The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads
8 * T41, T42, T43, R51, and X40, at least. It provides a basic two-axis 8 * starting with the R40, T41, and X40. It provides a basic two-axis
9 * accelerometer and other data, such as the device's temperature. 9 * accelerometer and other data, such as the device's temperature.
10 * 10 *
11 * Based on the document by Mark A. Smith available at 11 * This driver is based on the document by Mark A. Smith available at
12 * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial 12 * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial
13 * and error. 13 * and error.
14 * 14 *
@@ -27,7 +27,7 @@
27 */ 27 */
28 28
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/device.h> 30#include <linux/platform_device.h>
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/module.h> 33#include <linux/module.h>
@@ -36,12 +36,7 @@
36#include <asm/io.h> 36#include <asm/io.h>
37 37
38#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ 38#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
39#define HDAPS_NR_PORTS 0x30 /* 0x1600 - 0x162f */ 39#define HDAPS_NR_PORTS 0x30 /* number of ports: 0x1600 - 0x162f */
40
41#define STATE_FRESH 0x50 /* accelerometer data is fresh */
42
43#define REFRESH_ASYNC 0x00 /* do asynchronous refresh */
44#define REFRESH_SYNC 0x01 /* do synchronous refresh */
45 40
46#define HDAPS_PORT_STATE 0x1611 /* device state */ 41#define HDAPS_PORT_STATE 0x1611 /* device state */
47#define HDAPS_PORT_YPOS 0x1612 /* y-axis position */ 42#define HDAPS_PORT_YPOS 0x1612 /* y-axis position */
@@ -53,7 +48,7 @@
53#define HDAPS_PORT_UNKNOWN 0x161c /* what is this? */ 48#define HDAPS_PORT_UNKNOWN 0x161c /* what is this? */
54#define HDAPS_PORT_KMACT 0x161d /* keyboard or mouse activity */ 49#define HDAPS_PORT_KMACT 0x161d /* keyboard or mouse activity */
55 50
56#define HDAPS_READ_MASK 0xff /* some reads have the low 8 bits set */ 51#define STATE_FRESH 0x50 /* accelerometer data is fresh */
57 52
58#define KEYBD_MASK 0x20 /* set if keyboard activity */ 53#define KEYBD_MASK 0x20 /* set if keyboard activity */
59#define MOUSE_MASK 0x40 /* set if mouse activity */ 54#define MOUSE_MASK 0x40 /* set if mouse activity */
@@ -63,12 +58,11 @@
63#define INIT_TIMEOUT_MSECS 4000 /* wait up to 4s for device init ... */ 58#define INIT_TIMEOUT_MSECS 4000 /* wait up to 4s for device init ... */
64#define INIT_WAIT_MSECS 200 /* ... in 200ms increments */ 59#define INIT_WAIT_MSECS 200 /* ... in 200ms increments */
65 60
66static struct platform_device *pdev; 61#define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
67static struct input_dev hdaps_idev; 62#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
63
68static struct timer_list hdaps_timer; 64static struct timer_list hdaps_timer;
69static unsigned int hdaps_mousedev_threshold = 4; 65static struct platform_device *pdev;
70static unsigned long hdaps_poll_ms = 50;
71static unsigned int hdaps_mousedev;
72static unsigned int hdaps_invert; 66static unsigned int hdaps_invert;
73static u8 km_activity; 67static u8 km_activity;
74static int rest_x; 68static int rest_x;
@@ -81,14 +75,14 @@ static DECLARE_MUTEX(hdaps_sem);
81 */ 75 */
82static inline u8 __get_latch(u16 port) 76static inline u8 __get_latch(u16 port)
83{ 77{
84 return inb(port) & HDAPS_READ_MASK; 78 return inb(port) & 0xff;
85} 79}
86 80
87/* 81/*
88 * __check_latch - Check a port latch for a given value. Callers must hold 82 * __check_latch - Check a port latch for a given value. Returns zero if the
89 * hdaps_sem. Returns zero if the port contains the given value. 83 * port contains the given value. Callers must hold hdaps_sem.
90 */ 84 */
91static inline unsigned int __check_latch(u16 port, u8 val) 85static inline int __check_latch(u16 port, u8 val)
92{ 86{
93 if (__get_latch(port) == val) 87 if (__get_latch(port) == val)
94 return 0; 88 return 0;
@@ -99,7 +93,7 @@ static inline unsigned int __check_latch(u16 port, u8 val)
99 * __wait_latch - Wait up to 100us for a port latch to get a certain value, 93 * __wait_latch - Wait up to 100us for a port latch to get a certain value,
100 * returning zero if the value is obtained. Callers must hold hdaps_sem. 94 * returning zero if the value is obtained. Callers must hold hdaps_sem.
101 */ 95 */
102static unsigned int __wait_latch(u16 port, u8 val) 96static int __wait_latch(u16 port, u8 val)
103{ 97{
104 unsigned int i; 98 unsigned int i;
105 99
@@ -109,59 +103,42 @@ static unsigned int __wait_latch(u16 port, u8 val)
109 udelay(5); 103 udelay(5);
110 } 104 }
111 105
112 return -EINVAL; 106 return -EIO;
113} 107}
114 108
115/* 109/*
116 * __device_refresh - Request a refresh from the accelerometer. 110 * __device_refresh - request a refresh from the accelerometer. Does not wait
117 * 111 * for refresh to complete. Callers must hold hdaps_sem.
118 * If sync is REFRESH_SYNC, we perform a synchronous refresh and will wait.
119 * Returns zero if successful and nonzero on error.
120 *
121 * If sync is REFRESH_ASYNC, we merely kick off a new refresh if the device is
122 * not up-to-date. Always returns zero.
123 *
124 * Callers must hold hdaps_sem.
125 */ 112 */
126static int __device_refresh(unsigned int sync) 113static void __device_refresh(void)
127{ 114{
128 u8 state; 115 udelay(200);
129 116 if (inb(0x1604) != STATE_FRESH) {
130 udelay(100); 117 outb(0x11, 0x1610);
131 118 outb(0x01, 0x161f);
132 state = inb(0x1604); 119 }
133 if (state == STATE_FRESH) 120}
134 return 0;
135
136 outb(0x11, 0x1610);
137 outb(0x01, 0x161f);
138 if (sync == REFRESH_ASYNC)
139 return 0;
140 121
122/*
123 * __device_refresh_sync - request a synchronous refresh from the
124 * accelerometer. We wait for the refresh to complete. Returns zero if
125 * successful and nonzero on error. Callers must hold hdaps_sem.
126 */
127static int __device_refresh_sync(void)
128{
129 __device_refresh();
141 return __wait_latch(0x1604, STATE_FRESH); 130 return __wait_latch(0x1604, STATE_FRESH);
142} 131}
143 132
144/* 133/*
145 * __device_complete - Indicate to the accelerometer that we are done reading 134 * __device_complete - indicate to the accelerometer that we are done reading
146 * data, and then initiate an async refresh. Callers must hold hdaps_sem. 135 * data, and then initiate an async refresh. Callers must hold hdaps_sem.
147 */ 136 */
148static inline void __device_complete(void) 137static inline void __device_complete(void)
149{ 138{
150 inb(0x161f); 139 inb(0x161f);
151 inb(0x1604); 140 inb(0x1604);
152 __device_refresh(REFRESH_ASYNC); 141 __device_refresh();
153}
154
155static int __hdaps_readb_one(unsigned int port, u8 *val)
156{
157 /* do a sync refresh -- we need to be sure that we read fresh data */
158 if (__device_refresh(REFRESH_SYNC))
159 return -EIO;
160
161 *val = inb(port);
162 __device_complete();
163
164 return 0;
165} 142}
166 143
167/* 144/*
@@ -174,17 +151,26 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
174 int ret; 151 int ret;
175 152
176 down(&hdaps_sem); 153 down(&hdaps_sem);
177 ret = __hdaps_readb_one(port, val);
178 up(&hdaps_sem);
179 154
155 /* do a sync refresh -- we need to be sure that we read fresh data */
156 ret = __device_refresh_sync();
157 if (ret)
158 goto out;
159
160 *val = inb(port);
161 __device_complete();
162
163out:
164 up(&hdaps_sem);
180 return ret; 165 return ret;
181} 166}
182 167
168/* __hdaps_read_pair - internal lockless helper for hdaps_read_pair(). */
183static int __hdaps_read_pair(unsigned int port1, unsigned int port2, 169static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
184 int *x, int *y) 170 int *x, int *y)
185{ 171{
186 /* do a sync refresh -- we need to be sure that we read fresh data */ 172 /* do a sync refresh -- we need to be sure that we read fresh data */
187 if (__device_refresh(REFRESH_SYNC)) 173 if (__device_refresh_sync())
188 return -EIO; 174 return -EIO;
189 175
190 *y = inw(port2); 176 *y = inw(port2);
@@ -217,11 +203,13 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2,
217 return ret; 203 return ret;
218} 204}
219 205
220/* initialize the accelerometer */ 206/*
207 * hdaps_device_init - initialize the accelerometer. Returns zero on success
208 * and negative error code on failure. Can sleep.
209 */
221static int hdaps_device_init(void) 210static int hdaps_device_init(void)
222{ 211{
223 unsigned int total_msecs = INIT_TIMEOUT_MSECS; 212 int total, ret = -ENXIO;
224 int ret = -ENXIO;
225 213
226 down(&hdaps_sem); 214 down(&hdaps_sem);
227 215
@@ -231,8 +219,10 @@ static int hdaps_device_init(void)
231 goto out; 219 goto out;
232 220
233 /* 221 /*
234 * The 0x03 value appears to only work on some thinkpads, such as the 222 * Most ThinkPads return 0x01.
235 * T42p. Others return 0x01. 223 *
224 * Others--namely the R50p, T41p, and T42p--return 0x03. These laptops
225 * have "inverted" axises.
236 * 226 *
237 * The 0x02 value occurs when the chip has been previously initialized. 227 * The 0x02 value occurs when the chip has been previously initialized.
238 */ 228 */
@@ -267,24 +257,23 @@ static int hdaps_device_init(void)
267 outb(0x01, 0x161f); 257 outb(0x01, 0x161f);
268 if (__wait_latch(0x161f, 0x00)) 258 if (__wait_latch(0x161f, 0x00))
269 goto out; 259 goto out;
270 if (__device_refresh(REFRESH_SYNC)) 260 if (__device_refresh_sync())
271 goto out; 261 goto out;
272 if (__wait_latch(0x1611, 0x00)) 262 if (__wait_latch(0x1611, 0x00))
273 goto out; 263 goto out;
274 264
275 /* we have done our dance, now let's wait for the applause */ 265 /* we have done our dance, now let's wait for the applause */
276 while (total_msecs > 0) { 266 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
277 u8 ignored; 267 int x, y;
278 268
279 /* a read of the device helps push it into action */ 269 /* a read of the device helps push it into action */
280 __hdaps_readb_one(HDAPS_PORT_UNKNOWN, &ignored); 270 __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y);
281 if (!__wait_latch(0x1611, 0x02)) { 271 if (!__wait_latch(0x1611, 0x02)) {
282 ret = 0; 272 ret = 0;
283 break; 273 break;
284 } 274 }
285 275
286 msleep(INIT_WAIT_MSECS); 276 msleep(INIT_WAIT_MSECS);
287 total_msecs -= INIT_WAIT_MSECS;
288 } 277 }
289 278
290out: 279out:
@@ -293,20 +282,51 @@ out:
293} 282}
294 283
295 284
285/* Device model stuff */
286
287static int hdaps_probe(struct device *dev)
288{
289 int ret;
290
291 ret = hdaps_device_init();
292 if (ret)
293 return ret;
294
295 printk(KERN_INFO "hdaps: device successfully initialized.\n");
296 return 0;
297}
298
299static int hdaps_resume(struct device *dev)
300{
301 return hdaps_device_init();
302}
303
304static struct device_driver hdaps_driver = {
305 .name = "hdaps",
306 .bus = &platform_bus_type,
307 .owner = THIS_MODULE,
308 .probe = hdaps_probe,
309 .resume = hdaps_resume
310};
311
296/* Input class stuff */ 312/* Input class stuff */
297 313
314static struct input_dev hdaps_idev = {
315 .name = "hdaps",
316 .evbit = { BIT(EV_ABS) },
317 .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
318 .absmin = { [ABS_X] = -256, [ABS_Y] = -256 },
319 .absmax = { [ABS_X] = 256, [ABS_Y] = 256 },
320 .absfuzz = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
321 .absflat = { [ABS_X] = HDAPS_INPUT_FUZZ, [ABS_Y] = HDAPS_INPUT_FUZZ },
322};
323
298/* 324/*
299 * hdaps_calibrate - Zero out our "resting" values. Callers must hold hdaps_sem. 325 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
300 */ 326 */
301static void hdaps_calibrate(void) 327static void hdaps_calibrate(void)
302{ 328{
303 int x, y; 329 __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &rest_x, &rest_y);
304
305 if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y))
306 return;
307
308 rest_x = x;
309 rest_y = y;
310} 330}
311 331
312static void hdaps_mousedev_poll(unsigned long unused) 332static void hdaps_mousedev_poll(unsigned long unused)
@@ -315,103 +335,23 @@ static void hdaps_mousedev_poll(unsigned long unused)
315 335
316 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ 336 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
317 if (down_trylock(&hdaps_sem)) { 337 if (down_trylock(&hdaps_sem)) {
318 mod_timer(&hdaps_timer,jiffies+msecs_to_jiffies(hdaps_poll_ms)); 338 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
319 return; 339 return;
320 } 340 }
321 341
322 if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y)) 342 if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y))
323 goto out; 343 goto out;
324 344
325 x -= rest_x; 345 input_report_abs(&hdaps_idev, ABS_X, x - rest_x);
326 y -= rest_y; 346 input_report_abs(&hdaps_idev, ABS_Y, y - rest_y);
327 if (abs(x) > hdaps_mousedev_threshold)
328 input_report_rel(&hdaps_idev, REL_X, x);
329 if (abs(y) > hdaps_mousedev_threshold)
330 input_report_rel(&hdaps_idev, REL_Y, y);
331 input_sync(&hdaps_idev); 347 input_sync(&hdaps_idev);
332 348
333 mod_timer(&hdaps_timer, jiffies + msecs_to_jiffies(hdaps_poll_ms)); 349 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
334 350
335out: 351out:
336 up(&hdaps_sem); 352 up(&hdaps_sem);
337} 353}
338 354
339/*
340 * hdaps_mousedev_enable - enable the input class device. Can sleep.
341 */
342static void hdaps_mousedev_enable(void)
343{
344 down(&hdaps_sem);
345
346 /* calibrate the device before enabling */
347 hdaps_calibrate();
348
349 /* initialize the input class */
350 init_input_dev(&hdaps_idev);
351 hdaps_idev.dev = &pdev->dev;
352 hdaps_idev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
353 hdaps_idev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
354 hdaps_idev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT);
355 input_register_device(&hdaps_idev);
356
357 /* start up our timer */
358 init_timer(&hdaps_timer);
359 hdaps_timer.function = hdaps_mousedev_poll;
360 hdaps_timer.expires = jiffies + msecs_to_jiffies(hdaps_poll_ms);
361 add_timer(&hdaps_timer);
362
363 hdaps_mousedev = 1;
364
365 up(&hdaps_sem);
366
367 printk(KERN_INFO "hdaps: input device enabled.\n");
368}
369
370/*
371 * hdaps_mousedev_disable - disable the input class device. Caller must hold
372 * hdaps_sem.
373 */
374static void hdaps_mousedev_disable(void)
375{
376 down(&hdaps_sem);
377 if (hdaps_mousedev) {
378 hdaps_mousedev = 0;
379 del_timer_sync(&hdaps_timer);
380 input_unregister_device(&hdaps_idev);
381 }
382 up(&hdaps_sem);
383}
384
385
386/* Device model stuff */
387
388static int hdaps_probe(struct device *dev)
389{
390 int ret;
391
392 ret = hdaps_device_init();
393 if (ret)
394 return ret;
395
396 printk(KERN_INFO "hdaps: device successfully initialized.\n");
397 return 0;
398}
399
400static int hdaps_resume(struct device *dev, u32 level)
401{
402 if (level == RESUME_ENABLE)
403 return hdaps_device_init();
404 return 0;
405}
406
407static struct device_driver hdaps_driver = {
408 .name = "hdaps",
409 .bus = &platform_bus_type,
410 .owner = THIS_MODULE,
411 .probe = hdaps_probe,
412 .resume = hdaps_resume
413};
414
415 355
416/* Sysfs Files */ 356/* Sysfs Files */
417 357
@@ -517,69 +457,6 @@ static ssize_t hdaps_invert_store(struct device *dev,
517 return count; 457 return count;
518} 458}
519 459
520static ssize_t hdaps_mousedev_show(struct device *dev,
521 struct device_attribute *attr, char *buf)
522{
523 return sprintf(buf, "%d\n", hdaps_mousedev);
524}
525
526static ssize_t hdaps_mousedev_store(struct device *dev,
527 struct device_attribute *attr,
528 const char *buf, size_t count)
529{
530 int enable;
531
532 if (sscanf(buf, "%d", &enable) != 1)
533 return -EINVAL;
534
535 if (enable == 1)
536 hdaps_mousedev_enable();
537 else if (enable == 0)
538 hdaps_mousedev_disable();
539 else
540 return -EINVAL;
541
542 return count;
543}
544
545static ssize_t hdaps_poll_show(struct device *dev,
546 struct device_attribute *attr, char *buf)
547{
548 return sprintf(buf, "%lu\n", hdaps_poll_ms);
549}
550
551static ssize_t hdaps_poll_store(struct device *dev,
552 struct device_attribute *attr,
553 const char *buf, size_t count)
554{
555 unsigned int poll;
556
557 if (sscanf(buf, "%u", &poll) != 1 || poll == 0)
558 return -EINVAL;
559 hdaps_poll_ms = poll;
560
561 return count;
562}
563
564static ssize_t hdaps_threshold_show(struct device *dev,
565 struct device_attribute *attr, char *buf)
566{
567 return sprintf(buf, "%u\n", hdaps_mousedev_threshold);
568}
569
570static ssize_t hdaps_threshold_store(struct device *dev,
571 struct device_attribute *attr,
572 const char *buf, size_t count)
573{
574 unsigned int threshold;
575
576 if (sscanf(buf, "%u", &threshold) != 1 || threshold == 0)
577 return -EINVAL;
578 hdaps_mousedev_threshold = threshold;
579
580 return count;
581}
582
583static DEVICE_ATTR(position, 0444, hdaps_position_show, NULL); 460static DEVICE_ATTR(position, 0444, hdaps_position_show, NULL);
584static DEVICE_ATTR(variance, 0444, hdaps_variance_show, NULL); 461static DEVICE_ATTR(variance, 0444, hdaps_variance_show, NULL);
585static DEVICE_ATTR(temp1, 0444, hdaps_temp1_show, NULL); 462static DEVICE_ATTR(temp1, 0444, hdaps_temp1_show, NULL);
@@ -588,10 +465,6 @@ static DEVICE_ATTR(keyboard_activity, 0444, hdaps_keyboard_activity_show, NULL);
588static DEVICE_ATTR(mouse_activity, 0444, hdaps_mouse_activity_show, NULL); 465static DEVICE_ATTR(mouse_activity, 0444, hdaps_mouse_activity_show, NULL);
589static DEVICE_ATTR(calibrate, 0644, hdaps_calibrate_show,hdaps_calibrate_store); 466static DEVICE_ATTR(calibrate, 0644, hdaps_calibrate_show,hdaps_calibrate_store);
590static DEVICE_ATTR(invert, 0644, hdaps_invert_show, hdaps_invert_store); 467static DEVICE_ATTR(invert, 0644, hdaps_invert_show, hdaps_invert_store);
591static DEVICE_ATTR(mousedev, 0644, hdaps_mousedev_show, hdaps_mousedev_store);
592static DEVICE_ATTR(mousedev_poll_ms, 0644, hdaps_poll_show, hdaps_poll_store);
593static DEVICE_ATTR(mousedev_threshold, 0644, hdaps_threshold_show,
594 hdaps_threshold_store);
595 468
596static struct attribute *hdaps_attributes[] = { 469static struct attribute *hdaps_attributes[] = {
597 &dev_attr_position.attr, 470 &dev_attr_position.attr,
@@ -601,9 +474,6 @@ static struct attribute *hdaps_attributes[] = {
601 &dev_attr_keyboard_activity.attr, 474 &dev_attr_keyboard_activity.attr,
602 &dev_attr_mouse_activity.attr, 475 &dev_attr_mouse_activity.attr,
603 &dev_attr_calibrate.attr, 476 &dev_attr_calibrate.attr,
604 &dev_attr_mousedev.attr,
605 &dev_attr_mousedev_threshold.attr,
606 &dev_attr_mousedev_poll_ms.attr,
607 &dev_attr_invert.attr, 477 &dev_attr_invert.attr,
608 NULL, 478 NULL,
609}; 479};
@@ -615,24 +485,19 @@ static struct attribute_group hdaps_attribute_group = {
615 485
616/* Module stuff */ 486/* Module stuff */
617 487
618/* 488/* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */
619 * XXX: We should be able to return nonzero and halt the detection process.
620 * But there is a bug in dmi_check_system() where a nonzero return from the
621 * first match will result in a return of failure from dmi_check_system().
622 * I fixed this; the patch is in 2.6-mm. Once in Linus's tree we can make
623 * hdaps_dmi_match_invert() return hdaps_dmi_match(), which in turn returns 1.
624 */
625static int hdaps_dmi_match(struct dmi_system_id *id) 489static int hdaps_dmi_match(struct dmi_system_id *id)
626{ 490{
627 printk(KERN_INFO "hdaps: %s detected.\n", id->ident); 491 printk(KERN_INFO "hdaps: %s detected.\n", id->ident);
628 return 0; 492 return 1;
629} 493}
630 494
495/* hdaps_dmi_match_invert - found an inverted match. */
631static int hdaps_dmi_match_invert(struct dmi_system_id *id) 496static int hdaps_dmi_match_invert(struct dmi_system_id *id)
632{ 497{
633 hdaps_invert = 1; 498 hdaps_invert = 1;
634 printk(KERN_INFO "hdaps: inverting axis readings.\n"); 499 printk(KERN_INFO "hdaps: inverting axis readings.\n");
635 return 0; 500 return hdaps_dmi_match(id);
636} 501}
637 502
638#define HDAPS_DMI_MATCH_NORMAL(model) { \ 503#define HDAPS_DMI_MATCH_NORMAL(model) { \
@@ -662,12 +527,15 @@ static int __init hdaps_init(void)
662 HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), 527 HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),
663 HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), 528 HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),
664 HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), 529 HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),
530 HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"),
665 HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), 531 HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"),
666 HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), 532 HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"),
667 HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), 533 HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),
668 HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), 534 HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"),
669 HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), 535 HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
670 HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), 536 HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
537 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"),
538 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
671 { .ident = NULL } 539 { .ident = NULL }
672 }; 540 };
673 541
@@ -696,8 +564,18 @@ static int __init hdaps_init(void)
696 if (ret) 564 if (ret)
697 goto out_device; 565 goto out_device;
698 566
699 if (hdaps_mousedev) 567 /* initial calibrate for the input device */
700 hdaps_mousedev_enable(); 568 hdaps_calibrate();
569
570 /* initialize the input class */
571 hdaps_idev.dev = &pdev->dev;
572 input_register_device(&hdaps_idev);
573
574 /* start up our timer for the input device */
575 init_timer(&hdaps_timer);
576 hdaps_timer.function = hdaps_mousedev_poll;
577 hdaps_timer.expires = jiffies + HDAPS_POLL_PERIOD;
578 add_timer(&hdaps_timer);
701 579
702 printk(KERN_INFO "hdaps: driver successfully loaded.\n"); 580 printk(KERN_INFO "hdaps: driver successfully loaded.\n");
703 return 0; 581 return 0;
@@ -715,8 +593,8 @@ out:
715 593
716static void __exit hdaps_exit(void) 594static void __exit hdaps_exit(void)
717{ 595{
718 hdaps_mousedev_disable(); 596 del_timer_sync(&hdaps_timer);
719 597 input_unregister_device(&hdaps_idev);
720 sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); 598 sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
721 platform_device_unregister(pdev); 599 platform_device_unregister(pdev);
722 driver_unregister(&hdaps_driver); 600 driver_unregister(&hdaps_driver);
@@ -728,9 +606,6 @@ static void __exit hdaps_exit(void)
728module_init(hdaps_init); 606module_init(hdaps_init);
729module_exit(hdaps_exit); 607module_exit(hdaps_exit);
730 608
731module_param_named(mousedev, hdaps_mousedev, bool, 0);
732MODULE_PARM_DESC(mousedev, "enable the input class device");
733
734module_param_named(invert, hdaps_invert, bool, 0); 609module_param_named(invert, hdaps_invert, bool, 0);
735MODULE_PARM_DESC(invert, "invert data along each axis"); 610MODULE_PARM_DESC(invert, "invert data along each axis");
736 611