aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/Kconfig16
-rw-r--r--drivers/input/mouse/Makefile2
-rw-r--r--drivers/input/mouse/alps.c20
-rw-r--r--drivers/input/mouse/alps.h4
-rw-r--r--drivers/input/mouse/bcm5974.c31
-rw-r--r--drivers/input/mouse/elantech.c2
-rw-r--r--drivers/input/mouse/elantech.h4
-rw-r--r--drivers/input/mouse/hgpk.c61
-rw-r--r--drivers/input/mouse/hgpk.h6
-rw-r--r--drivers/input/mouse/hil_ptr.c447
-rw-r--r--drivers/input/mouse/lifebook.c8
-rw-r--r--drivers/input/mouse/lifebook.h4
-rw-r--r--drivers/input/mouse/logips2pp.c41
-rw-r--r--drivers/input/mouse/logips2pp.h4
-rw-r--r--drivers/input/mouse/psmouse-base.c113
-rw-r--r--drivers/input/mouse/psmouse.h30
-rw-r--r--drivers/input/mouse/sentelic.c869
-rw-r--r--drivers/input/mouse/sentelic.h98
-rw-r--r--drivers/input/mouse/synaptics.c34
-rw-r--r--drivers/input/mouse/synaptics.h2
-rw-r--r--drivers/input/mouse/synaptics_i2c.c51
-rw-r--r--drivers/input/mouse/touchkit_ps2.c4
-rw-r--r--drivers/input/mouse/touchkit_ps2.h4
-rw-r--r--drivers/input/mouse/trackpoint.c2
-rw-r--r--drivers/input/mouse/trackpoint.h4
-rw-r--r--drivers/input/mouse/vsxxxaa.c8
26 files changed, 1248 insertions, 621 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 8a2c5b14c8d8..3feeb3af8abd 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH
107 entries. For further information, 107 entries. For further information,
108 see <file:Documentation/input/elantech.txt>. 108 see <file:Documentation/input/elantech.txt>.
109 109
110config MOUSE_PS2_SENTELIC
111 bool "Sentelic Finger Sensing Pad PS/2 protocol extension"
112 depends on MOUSE_PS2
113 help
114 Say Y here if you have a laptop (such as MSI WIND Netbook)
115 with Sentelic Finger Sensing Pad touchpad.
116
117 If unsure, say N.
110 118
111config MOUSE_PS2_TOUCHKIT 119config MOUSE_PS2_TOUCHKIT
112 bool "eGalax TouchKit PS/2 protocol extension" 120 bool "eGalax TouchKit PS/2 protocol extension"
@@ -262,14 +270,6 @@ config MOUSE_VSXXXAA
262 described in the source file). This driver also works with the 270 described in the source file). This driver also works with the
263 digitizer (VSXXX-AB) DEC produced. 271 digitizer (VSXXX-AB) DEC produced.
264 272
265config MOUSE_HIL
266 tristate "HIL pointers (mice etc)."
267 depends on GSC || HP300
268 select HP_SDC
269 select HIL_MLC
270 help
271 Say Y here to support HIL pointers.
272
273config MOUSE_GPIO 273config MOUSE_GPIO
274 tristate "GPIO mouse" 274 tristate "GPIO mouse"
275 depends on GENERIC_GPIO 275 depends on GENERIC_GPIO
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 010f265ec152..570c84a4a654 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
9obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o 9obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
10obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o 10obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
11obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o 11obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
12obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
13obj-$(CONFIG_MOUSE_INPORT) += inport.o 12obj-$(CONFIG_MOUSE_INPORT) += inport.o
14obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o 13obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
15obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o 14obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
@@ -28,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o
28psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o 27psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
29psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o 28psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
30psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o 29psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
30psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
31psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o 31psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
32psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o 32psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 5547e2429fbe..f36110689aae 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -279,7 +279,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
279 * subsequent commands. It looks like glidepad is behind stickpointer, 279 * subsequent commands. It looks like glidepad is behind stickpointer,
280 * I'd thought it would be other way around... 280 * I'd thought it would be other way around...
281 */ 281 */
282static int alps_passthrough_mode(struct psmouse *psmouse, int enable) 282static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
283{ 283{
284 struct ps2dev *ps2dev = &psmouse->ps2dev; 284 struct ps2dev *ps2dev = &psmouse->ps2dev;
285 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; 285 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
@@ -367,16 +367,16 @@ static int alps_poll(struct psmouse *psmouse)
367{ 367{
368 struct alps_data *priv = psmouse->private; 368 struct alps_data *priv = psmouse->private;
369 unsigned char buf[6]; 369 unsigned char buf[6];
370 int poll_failed; 370 bool poll_failed;
371 371
372 if (priv->i->flags & ALPS_PASS) 372 if (priv->i->flags & ALPS_PASS)
373 alps_passthrough_mode(psmouse, 1); 373 alps_passthrough_mode(psmouse, true);
374 374
375 poll_failed = ps2_command(&psmouse->ps2dev, buf, 375 poll_failed = ps2_command(&psmouse->ps2dev, buf,
376 PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; 376 PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
377 377
378 if (priv->i->flags & ALPS_PASS) 378 if (priv->i->flags & ALPS_PASS)
379 alps_passthrough_mode(psmouse, 0); 379 alps_passthrough_mode(psmouse, false);
380 380
381 if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) 381 if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
382 return -1; 382 return -1;
@@ -401,10 +401,12 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
401 if (!priv->i) 401 if (!priv->i)
402 return -1; 402 return -1;
403 403
404 if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) 404 if ((priv->i->flags & ALPS_PASS) &&
405 alps_passthrough_mode(psmouse, true)) {
405 return -1; 406 return -1;
407 }
406 408
407 if (alps_tap_mode(psmouse, 1)) { 409 if (alps_tap_mode(psmouse, true)) {
408 printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); 410 printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
409 return -1; 411 return -1;
410 } 412 }
@@ -414,8 +416,10 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
414 return -1; 416 return -1;
415 } 417 }
416 418
417 if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) 419 if ((priv->i->flags & ALPS_PASS) &&
420 alps_passthrough_mode(psmouse, false)) {
418 return -1; 421 return -1;
422 }
419 423
420 /* ALPS needs stream mode, otherwise it won't report any data */ 424 /* ALPS needs stream mode, otherwise it won't report any data */
421 if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { 425 if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
@@ -519,7 +523,7 @@ init_fail:
519 return -1; 523 return -1;
520} 524}
521 525
522int alps_detect(struct psmouse *psmouse, int set_properties) 526int alps_detect(struct psmouse *psmouse, bool set_properties)
523{ 527{
524 int version; 528 int version;
525 const struct alps_model_info *model; 529 const struct alps_model_info *model;
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 4bbddc99962b..bc87936fee1a 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -26,10 +26,10 @@ struct alps_data {
26}; 26};
27 27
28#ifdef CONFIG_MOUSE_PS2_ALPS 28#ifdef CONFIG_MOUSE_PS2_ALPS
29int alps_detect(struct psmouse *psmouse, int set_properties); 29int alps_detect(struct psmouse *psmouse, bool set_properties);
30int alps_init(struct psmouse *psmouse); 30int alps_init(struct psmouse *psmouse);
31#else 31#else
32inline int alps_detect(struct psmouse *psmouse, int set_properties) 32inline int alps_detect(struct psmouse *psmouse, bool set_properties)
33{ 33{
34 return -ENOSYS; 34 return -ENOSYS;
35} 35}
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 2d8fc0bf6923..0d1d33468b43 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -317,7 +317,7 @@ static int report_tp_state(struct bcm5974 *dev, int size)
317 const struct tp_finger *f; 317 const struct tp_finger *f;
318 struct input_dev *input = dev->input; 318 struct input_dev *input = dev->input;
319 int raw_p, raw_w, raw_x, raw_y, raw_n; 319 int raw_p, raw_w, raw_x, raw_y, raw_n;
320 int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0; 320 int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
321 int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; 321 int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
322 322
323 if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) 323 if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
@@ -345,21 +345,22 @@ static int report_tp_state(struct bcm5974 *dev, int size)
345 /* set the integrated button if applicable */ 345 /* set the integrated button if applicable */
346 if (c->tp_type == TYPE2) 346 if (c->tp_type == TYPE2)
347 ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); 347 ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
348 }
349 348
350 /* while tracking finger still valid, count all fingers */ 349 /* while tracking finger still valid, count all fingers */
351 if (ptest > PRESSURE_LOW && origin) { 350 if (ptest > PRESSURE_LOW && origin) {
352 abs_p = ptest; 351 abs_p = ptest;
353 abs_w = int2bound(&c->w, raw_w); 352 abs_w = int2bound(&c->w, raw_w);
354 abs_x = int2bound(&c->x, raw_x - c->x.devmin); 353 abs_x = int2bound(&c->x, raw_x - c->x.devmin);
355 abs_y = int2bound(&c->y, c->y.devmax - raw_y); 354 abs_y = int2bound(&c->y, c->y.devmax - raw_y);
356 while (raw_n--) { 355 while (raw_n--) {
357 ptest = int2bound(&c->p, raw2int(f->force_major)); 356 ptest = int2bound(&c->p,
358 if (ptest > PRESSURE_LOW) 357 raw2int(f->force_major));
359 nmax++; 358 if (ptest > PRESSURE_LOW)
360 if (ptest > PRESSURE_HIGH) 359 nmax++;
361 nmin++; 360 if (ptest > PRESSURE_HIGH)
362 f++; 361 nmin++;
362 f++;
363 }
363 } 364 }
364 } 365 }
365 366
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 4bc78892ba91..fda35e615abf 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -553,7 +553,7 @@ static struct attribute_group elantech_attr_group = {
553/* 553/*
554 * Use magic knock to detect Elantech touchpad 554 * Use magic knock to detect Elantech touchpad
555 */ 555 */
556int elantech_detect(struct psmouse *psmouse, int set_properties) 556int elantech_detect(struct psmouse *psmouse, bool set_properties)
557{ 557{
558 struct ps2dev *ps2dev = &psmouse->ps2dev; 558 struct ps2dev *ps2dev = &psmouse->ps2dev;
559 unsigned char param[3]; 559 unsigned char param[3];
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index ed848cc80814..feac5f7af966 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -109,10 +109,10 @@ struct elantech_data {
109}; 109};
110 110
111#ifdef CONFIG_MOUSE_PS2_ELANTECH 111#ifdef CONFIG_MOUSE_PS2_ELANTECH
112int elantech_detect(struct psmouse *psmouse, int set_properties); 112int elantech_detect(struct psmouse *psmouse, bool set_properties);
113int elantech_init(struct psmouse *psmouse); 113int elantech_init(struct psmouse *psmouse);
114#else 114#else
115static inline int elantech_detect(struct psmouse *psmouse, int set_properties) 115static inline int elantech_detect(struct psmouse *psmouse, bool set_properties)
116{ 116{
117 return -ENOSYS; 117 return -ENOSYS;
118} 118}
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index a1ad2f1a7bb3..de1e553028b7 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -367,7 +367,36 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
367} 367}
368 368
369__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, 369__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
370 hgpk_show_powered, hgpk_set_powered, 0); 370 hgpk_show_powered, hgpk_set_powered, false);
371
372static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
373 void *data, char *buf)
374{
375 return -EINVAL;
376}
377
378static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
379 const char *buf, size_t count)
380{
381 struct hgpk_data *priv = psmouse->private;
382 unsigned long value;
383 int err;
384
385 err = strict_strtoul(buf, 10, &value);
386 if (err || value != 1)
387 return -EINVAL;
388
389 /*
390 * We queue work instead of doing recalibration right here
391 * to avoid adding locking to to hgpk_force_recalibrate()
392 * since workqueue provides serialization.
393 */
394 psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
395 return count;
396}
397
398__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
399 hgpk_trigger_recal_show, hgpk_trigger_recal, false);
371 400
372static void hgpk_disconnect(struct psmouse *psmouse) 401static void hgpk_disconnect(struct psmouse *psmouse)
373{ 402{
@@ -375,6 +404,11 @@ static void hgpk_disconnect(struct psmouse *psmouse)
375 404
376 device_remove_file(&psmouse->ps2dev.serio->dev, 405 device_remove_file(&psmouse->ps2dev.serio->dev,
377 &psmouse_attr_powered.dattr); 406 &psmouse_attr_powered.dattr);
407
408 if (psmouse->model >= HGPK_MODEL_C)
409 device_remove_file(&psmouse->ps2dev.serio->dev,
410 &psmouse_attr_recalibrate.dattr);
411
378 psmouse_reset(psmouse); 412 psmouse_reset(psmouse);
379 kfree(priv); 413 kfree(priv);
380} 414}
@@ -423,10 +457,25 @@ static int hgpk_register(struct psmouse *psmouse)
423 457
424 err = device_create_file(&psmouse->ps2dev.serio->dev, 458 err = device_create_file(&psmouse->ps2dev.serio->dev,
425 &psmouse_attr_powered.dattr); 459 &psmouse_attr_powered.dattr);
426 if (err) 460 if (err) {
427 hgpk_err(psmouse, "Failed to create sysfs attribute\n"); 461 hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");
462 return err;
463 }
428 464
429 return err; 465 /* C-series touchpads added the recalibrate command */
466 if (psmouse->model >= HGPK_MODEL_C) {
467 err = device_create_file(&psmouse->ps2dev.serio->dev,
468 &psmouse_attr_recalibrate.dattr);
469 if (err) {
470 hgpk_err(psmouse,
471 "Failed creating 'recalibrate' sysfs node\n");
472 device_remove_file(&psmouse->ps2dev.serio->dev,
473 &psmouse_attr_powered.dattr);
474 return err;
475 }
476 }
477
478 return 0;
430} 479}
431 480
432int hgpk_init(struct psmouse *psmouse) 481int hgpk_init(struct psmouse *psmouse)
@@ -440,7 +489,7 @@ int hgpk_init(struct psmouse *psmouse)
440 489
441 psmouse->private = priv; 490 psmouse->private = priv;
442 priv->psmouse = psmouse; 491 priv->psmouse = psmouse;
443 priv->powered = 1; 492 priv->powered = true;
444 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); 493 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
445 494
446 err = psmouse_reset(psmouse); 495 err = psmouse_reset(psmouse);
@@ -483,7 +532,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
483 return param[2]; 532 return param[2];
484} 533}
485 534
486int hgpk_detect(struct psmouse *psmouse, int set_properties) 535int hgpk_detect(struct psmouse *psmouse, bool set_properties)
487{ 536{
488 int version; 537 int version;
489 538
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
index a4b2a96f5f54..d61cfd3ee9cb 100644
--- a/drivers/input/mouse/hgpk.h
+++ b/drivers/input/mouse/hgpk.h
@@ -15,7 +15,7 @@ enum hgpk_model_t {
15 15
16struct hgpk_data { 16struct hgpk_data {
17 struct psmouse *psmouse; 17 struct psmouse *psmouse;
18 int powered; 18 bool powered;
19 int count, x_tally, y_tally; /* hardware workaround stuff */ 19 int count, x_tally, y_tally; /* hardware workaround stuff */
20 unsigned long recalib_window; 20 unsigned long recalib_window;
21 struct delayed_work recalib_wq; 21 struct delayed_work recalib_wq;
@@ -33,10 +33,10 @@ struct hgpk_data {
33 dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) 33 dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
34 34
35#ifdef CONFIG_MOUSE_PS2_OLPC 35#ifdef CONFIG_MOUSE_PS2_OLPC
36int hgpk_detect(struct psmouse *psmouse, int set_properties); 36int hgpk_detect(struct psmouse *psmouse, bool set_properties);
37int hgpk_init(struct psmouse *psmouse); 37int hgpk_init(struct psmouse *psmouse);
38#else 38#else
39static inline int hgpk_detect(struct psmouse *psmouse, int set_properties) 39static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)
40{ 40{
41 return -ENODEV; 41 return -ENODEV;
42} 42}
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
deleted file mode 100644
index 3263ce083bf0..000000000000
--- a/drivers/input/mouse/hil_ptr.c
+++ /dev/null
@@ -1,447 +0,0 @@
1/*
2 * Generic linux-input device driver for axis-bearing devices
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
31 *
32 */
33
34#include <linux/hil.h>
35#include <linux/input.h>
36#include <linux/serio.h>
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/slab.h>
41#include <linux/pci_ids.h>
42
43#define PREFIX "HIL PTR: "
44#define HIL_GENERIC_NAME "HIL pointer device"
45
46MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
47MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
48MODULE_LICENSE("Dual BSD/GPL");
49MODULE_ALIAS("serio:ty03pr25id0Fex*");
50
51#define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */
52#undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */
53
54
55#define HIL_PTR_MAX_LENGTH 16
56
57struct hil_ptr {
58 struct input_dev *dev;
59 struct serio *serio;
60
61 /* Input buffer and index for packets from HIL bus. */
62 hil_packet data[HIL_PTR_MAX_LENGTH];
63 int idx4; /* four counts per packet */
64
65 /* Raw device info records from HIL bus, see hil.h for fields. */
66 char idd[HIL_PTR_MAX_LENGTH]; /* DID byte and IDD record */
67 char rsc[HIL_PTR_MAX_LENGTH]; /* RSC record */
68 char exd[HIL_PTR_MAX_LENGTH]; /* EXD record */
69 char rnm[HIL_PTR_MAX_LENGTH + 1]; /* RNM record + NULL term. */
70
71 /* Extra device details not contained in struct input_dev. */
72 unsigned int nbtn, naxes;
73 unsigned int btnmap[7];
74
75 /* Something to sleep around with. */
76 struct semaphore sem;
77};
78
79/* Process a complete packet after transfer from the HIL */
80static void hil_ptr_process_record(struct hil_ptr *ptr)
81{
82 struct input_dev *dev = ptr->dev;
83 hil_packet *data = ptr->data;
84 hil_packet p;
85 int idx, i, cnt, laxis;
86 int ax16, absdev;
87
88 idx = ptr->idx4/4;
89 p = data[idx - 1];
90
91 if ((p & ~HIL_CMDCT_POL) ==
92 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
93 goto report;
94 if ((p & ~HIL_CMDCT_RPL) ==
95 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
96 goto report;
97
98 /* Not a poll response. See if we are loading config records. */
99 switch (p & HIL_PKT_DATA_MASK) {
100 case HIL_CMD_IDD:
101 for (i = 0; i < idx; i++)
102 ptr->idd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
103 for (; i < HIL_PTR_MAX_LENGTH; i++)
104 ptr->idd[i] = 0;
105 break;
106
107 case HIL_CMD_RSC:
108 for (i = 0; i < idx; i++)
109 ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
110 for (; i < HIL_PTR_MAX_LENGTH; i++)
111 ptr->rsc[i] = 0;
112 break;
113
114 case HIL_CMD_EXD:
115 for (i = 0; i < idx; i++)
116 ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
117 for (; i < HIL_PTR_MAX_LENGTH; i++)
118 ptr->exd[i] = 0;
119 break;
120
121 case HIL_CMD_RNM:
122 for (i = 0; i < idx; i++)
123 ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
124 for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
125 ptr->rnm[i] = 0;
126 break;
127
128 default:
129 /* These occur when device isn't present */
130 if (p == (HIL_ERR_INT | HIL_PKT_CMD))
131 break;
132 /* Anything else we'd like to know about. */
133 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
134 break;
135 }
136 goto out;
137
138 report:
139 if ((p & HIL_CMDCT_POL) != idx - 1) {
140 printk(KERN_WARNING PREFIX
141 "Malformed poll packet %x (idx = %i)\n", p, idx);
142 goto out;
143 }
144
145 i = (ptr->data[0] & HIL_POL_AXIS_ALT) ? 3 : 0;
146 laxis = ptr->data[0] & HIL_POL_NUM_AXES_MASK;
147 laxis += i;
148
149 ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
150 absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
151
152 for (cnt = 1; i < laxis; i++) {
153 unsigned int lo,hi,val;
154 lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
155 hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
156 if (absdev) {
157 val = lo + (hi<<8);
158#ifdef TABLET_AUTOADJUST
159 if (val < dev->absmin[ABS_X + i])
160 dev->absmin[ABS_X + i] = val;
161 if (val > dev->absmax[ABS_X + i])
162 dev->absmax[ABS_X + i] = val;
163#endif
164 if (i%3) val = dev->absmax[ABS_X + i] - val;
165 input_report_abs(dev, ABS_X + i, val);
166 } else {
167 val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
168 if (i%3)
169 val *= -1;
170 input_report_rel(dev, REL_X + i, val);
171 }
172 }
173
174 while (cnt < idx - 1) {
175 unsigned int btn;
176 int up;
177 btn = ptr->data[cnt++];
178 up = btn & 1;
179 btn &= 0xfe;
180 if (btn == 0x8e)
181 continue; /* TODO: proximity == touch? */
182 else
183 if ((btn > 0x8c) || (btn < 0x80))
184 continue;
185 btn = (btn - 0x80) >> 1;
186 btn = ptr->btnmap[btn];
187 input_report_key(dev, btn, !up);
188 }
189 input_sync(dev);
190 out:
191 ptr->idx4 = 0;
192 up(&ptr->sem);
193}
194
195static void hil_ptr_process_err(struct hil_ptr *ptr)
196{
197 printk(KERN_WARNING PREFIX "errored HIL packet\n");
198 ptr->idx4 = 0;
199 up(&ptr->sem);
200}
201
202static irqreturn_t hil_ptr_interrupt(struct serio *serio,
203 unsigned char data, unsigned int flags)
204{
205 struct hil_ptr *ptr;
206 hil_packet packet;
207 int idx;
208
209 ptr = serio_get_drvdata(serio);
210 BUG_ON(ptr == NULL);
211
212 if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
213 hil_ptr_process_err(ptr);
214 return IRQ_HANDLED;
215 }
216 idx = ptr->idx4/4;
217 if (!(ptr->idx4 % 4))
218 ptr->data[idx] = 0;
219 packet = ptr->data[idx];
220 packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
221 ptr->data[idx] = packet;
222
223 /* Records of N 4-byte hil_packets must terminate with a command. */
224 if ((++(ptr->idx4)) % 4)
225 return IRQ_HANDLED;
226 if ((packet & 0xffff0000) != HIL_ERR_INT) {
227 hil_ptr_process_err(ptr);
228 return IRQ_HANDLED;
229 }
230 if (packet & HIL_PKT_CMD)
231 hil_ptr_process_record(ptr);
232
233 return IRQ_HANDLED;
234}
235
236static void hil_ptr_disconnect(struct serio *serio)
237{
238 struct hil_ptr *ptr;
239
240 ptr = serio_get_drvdata(serio);
241 BUG_ON(ptr == NULL);
242
243 serio_close(serio);
244 input_unregister_device(ptr->dev);
245 kfree(ptr);
246}
247
248static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
249{
250 struct hil_ptr *ptr;
251 const char *txt;
252 unsigned int i, naxsets, btntype;
253 uint8_t did, *idd;
254 int error;
255
256 ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
257 if (!ptr)
258 return -ENOMEM;
259
260 ptr->dev = input_allocate_device();
261 if (!ptr->dev) {
262 error = -ENOMEM;
263 goto bail0;
264 }
265
266 error = serio_open(serio, driver);
267 if (error)
268 goto bail1;
269
270 serio_set_drvdata(serio, ptr);
271 ptr->serio = serio;
272
273 init_MUTEX_LOCKED(&ptr->sem);
274
275 /* Get device info. MLC driver supplies devid/status/etc. */
276 serio->write(serio, 0);
277 serio->write(serio, 0);
278 serio->write(serio, HIL_PKT_CMD >> 8);
279 serio->write(serio, HIL_CMD_IDD);
280 down(&ptr->sem);
281
282 serio->write(serio, 0);
283 serio->write(serio, 0);
284 serio->write(serio, HIL_PKT_CMD >> 8);
285 serio->write(serio, HIL_CMD_RSC);
286 down(&ptr->sem);
287
288 serio->write(serio, 0);
289 serio->write(serio, 0);
290 serio->write(serio, HIL_PKT_CMD >> 8);
291 serio->write(serio, HIL_CMD_RNM);
292 down(&ptr->sem);
293
294 serio->write(serio, 0);
295 serio->write(serio, 0);
296 serio->write(serio, HIL_PKT_CMD >> 8);
297 serio->write(serio, HIL_CMD_EXD);
298 down(&ptr->sem);
299
300 up(&ptr->sem);
301
302 did = ptr->idd[0];
303 idd = ptr->idd + 1;
304 txt = "unknown";
305
306 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
307 ptr->dev->evbit[0] = BIT_MASK(EV_REL);
308 txt = "relative";
309 }
310
311 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
312 ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
313 txt = "absolute";
314 }
315
316 if (!ptr->dev->evbit[0]) {
317 error = -ENODEV;
318 goto bail2;
319 }
320
321 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
322 if (ptr->nbtn)
323 ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);
324
325 naxsets = HIL_IDD_NUM_AXSETS(*idd);
326 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
327
328 printk(KERN_INFO PREFIX "HIL pointer device found (did: 0x%02x, axis: %s)\n",
329 did, txt);
330 printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
331 ptr->nbtn, naxsets, ptr->naxes);
332
333 btntype = BTN_MISC;
334 if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
335#ifdef TABLET_SIMULATES_MOUSE
336 btntype = BTN_TOUCH;
337#else
338 btntype = BTN_DIGI;
339#endif
340 if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
341 btntype = BTN_TOUCH;
342
343 if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
344 btntype = BTN_MOUSE;
345
346 for (i = 0; i < ptr->nbtn; i++) {
347 set_bit(btntype | i, ptr->dev->keybit);
348 ptr->btnmap[i] = btntype | i;
349 }
350
351 if (btntype == BTN_MOUSE) {
352 /* Swap buttons 2 and 3 */
353 ptr->btnmap[1] = BTN_MIDDLE;
354 ptr->btnmap[2] = BTN_RIGHT;
355 }
356
357 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
358 for (i = 0; i < ptr->naxes; i++)
359 set_bit(REL_X + i, ptr->dev->relbit);
360 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
361 set_bit(REL_X + i, ptr->dev->relbit);
362 } else {
363 for (i = 0; i < ptr->naxes; i++) {
364 set_bit(ABS_X + i, ptr->dev->absbit);
365 ptr->dev->absmin[ABS_X + i] = 0;
366 ptr->dev->absmax[ABS_X + i] =
367 HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
368 }
369 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
370 set_bit(ABS_X + i, ptr->dev->absbit);
371 ptr->dev->absmin[ABS_X + i] = 0;
372 ptr->dev->absmax[ABS_X + i] =
373 HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
374 }
375#ifdef TABLET_AUTOADJUST
376 for (i = 0; i < ABS_MAX; i++) {
377 int diff = ptr->dev->absmax[ABS_X + i] / 10;
378 ptr->dev->absmin[ABS_X + i] += diff;
379 ptr->dev->absmax[ABS_X + i] -= diff;
380 }
381#endif
382 }
383
384 ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
385
386 ptr->dev->id.bustype = BUS_HIL;
387 ptr->dev->id.vendor = PCI_VENDOR_ID_HP;
388 ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */
389 ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */
390 ptr->dev->dev.parent = &serio->dev;
391
392 error = input_register_device(ptr->dev);
393 if (error) {
394 printk(KERN_INFO PREFIX "Unable to register input device\n");
395 goto bail2;
396 }
397
398 printk(KERN_INFO "input: %s (%s), ID: %d\n",
399 ptr->dev->name,
400 (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
401 did);
402
403 return 0;
404
405 bail2:
406 serio_close(serio);
407 bail1:
408 input_free_device(ptr->dev);
409 bail0:
410 kfree(ptr);
411 serio_set_drvdata(serio, NULL);
412 return error;
413}
414
415static struct serio_device_id hil_ptr_ids[] = {
416 {
417 .type = SERIO_HIL_MLC,
418 .proto = SERIO_HIL,
419 .id = SERIO_ANY,
420 .extra = SERIO_ANY,
421 },
422 { 0 }
423};
424
425static struct serio_driver hil_ptr_serio_driver = {
426 .driver = {
427 .name = "hil_ptr",
428 },
429 .description = "HP HIL mouse/tablet driver",
430 .id_table = hil_ptr_ids,
431 .connect = hil_ptr_connect,
432 .disconnect = hil_ptr_disconnect,
433 .interrupt = hil_ptr_interrupt
434};
435
436static int __init hil_ptr_init(void)
437{
438 return serio_register_driver(&hil_ptr_serio_driver);
439}
440
441static void __exit hil_ptr_exit(void)
442{
443 serio_unregister_driver(&hil_ptr_serio_driver);
444}
445
446module_init(hil_ptr_init);
447module_exit(hil_ptr_exit);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index dcd4236af1e3..5e6308694408 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -33,11 +33,11 @@ static int lifebook_set_serio_phys(const struct dmi_system_id *d)
33 return 0; 33 return 0;
34} 34}
35 35
36static unsigned char lifebook_use_6byte_proto; 36static bool lifebook_use_6byte_proto;
37 37
38static int lifebook_set_6byte_proto(const struct dmi_system_id *d) 38static int lifebook_set_6byte_proto(const struct dmi_system_id *d)
39{ 39{
40 lifebook_use_6byte_proto = 1; 40 lifebook_use_6byte_proto = true;
41 return 0; 41 return 0;
42} 42}
43 43
@@ -125,7 +125,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
125 struct input_dev *dev1 = psmouse->dev; 125 struct input_dev *dev1 = psmouse->dev;
126 struct input_dev *dev2 = priv ? priv->dev2 : NULL; 126 struct input_dev *dev2 = priv ? priv->dev2 : NULL;
127 unsigned char *packet = psmouse->packet; 127 unsigned char *packet = psmouse->packet;
128 int relative_packet = packet[0] & 0x08; 128 bool relative_packet = packet[0] & 0x08;
129 129
130 if (relative_packet || !lifebook_use_6byte_proto) { 130 if (relative_packet || !lifebook_use_6byte_proto) {
131 if (psmouse->pktcnt != 3) 131 if (psmouse->pktcnt != 3)
@@ -242,7 +242,7 @@ static void lifebook_disconnect(struct psmouse *psmouse)
242 psmouse->private = NULL; 242 psmouse->private = NULL;
243} 243}
244 244
245int lifebook_detect(struct psmouse *psmouse, int set_properties) 245int lifebook_detect(struct psmouse *psmouse, bool set_properties)
246{ 246{
247 if (!dmi_check_system(lifebook_dmi_table)) 247 if (!dmi_check_system(lifebook_dmi_table))
248 return -1; 248 return -1;
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
index c1647cf036c2..407cb226bc0a 100644
--- a/drivers/input/mouse/lifebook.h
+++ b/drivers/input/mouse/lifebook.h
@@ -12,10 +12,10 @@
12#define _LIFEBOOK_H 12#define _LIFEBOOK_H
13 13
14#ifdef CONFIG_MOUSE_PS2_LIFEBOOK 14#ifdef CONFIG_MOUSE_PS2_LIFEBOOK
15int lifebook_detect(struct psmouse *psmouse, int set_properties); 15int lifebook_detect(struct psmouse *psmouse, bool set_properties);
16int lifebook_init(struct psmouse *psmouse); 16int lifebook_init(struct psmouse *psmouse);
17#else 17#else
18inline int lifebook_detect(struct psmouse *psmouse, int set_properties) 18inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
19{ 19{
20 return -ENOSYS; 20 return -ENOSYS;
21} 21}
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 390f1dbb98a4..de745d751162 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -130,14 +130,11 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
130 * 0 - disabled 130 * 0 - disabled
131 */ 131 */
132 132
133static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll) 133static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
134{ 134{
135 struct ps2dev *ps2dev = &psmouse->ps2dev; 135 struct ps2dev *ps2dev = &psmouse->ps2dev;
136 unsigned char param[4]; 136 unsigned char param[4];
137 137
138 if (smartscroll > 1)
139 smartscroll = 1;
140
141 ps2pp_cmd(psmouse, param, 0x32); 138 ps2pp_cmd(psmouse, param, 0x32);
142 139
143 param[0] = 0; 140 param[0] = 0;
@@ -149,12 +146,14 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr
149 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); 146 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
150} 147}
151 148
152static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf) 149static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse,
150 void *data, char *buf)
153{ 151{
154 return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0); 152 return sprintf(buf, "%d\n", psmouse->smartscroll);
155} 153}
156 154
157static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) 155static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
156 const char *buf, size_t count)
158{ 157{
159 unsigned long value; 158 unsigned long value;
160 159
@@ -261,29 +260,29 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
261 260
262static void ps2pp_set_model_properties(struct psmouse *psmouse, 261static void ps2pp_set_model_properties(struct psmouse *psmouse,
263 const struct ps2pp_info *model_info, 262 const struct ps2pp_info *model_info,
264 int using_ps2pp) 263 bool using_ps2pp)
265{ 264{
266 struct input_dev *input_dev = psmouse->dev; 265 struct input_dev *input_dev = psmouse->dev;
267 266
268 if (model_info->features & PS2PP_SIDE_BTN) 267 if (model_info->features & PS2PP_SIDE_BTN)
269 set_bit(BTN_SIDE, input_dev->keybit); 268 __set_bit(BTN_SIDE, input_dev->keybit);
270 269
271 if (model_info->features & PS2PP_EXTRA_BTN) 270 if (model_info->features & PS2PP_EXTRA_BTN)
272 set_bit(BTN_EXTRA, input_dev->keybit); 271 __set_bit(BTN_EXTRA, input_dev->keybit);
273 272
274 if (model_info->features & PS2PP_TASK_BTN) 273 if (model_info->features & PS2PP_TASK_BTN)
275 set_bit(BTN_TASK, input_dev->keybit); 274 __set_bit(BTN_TASK, input_dev->keybit);
276 275
277 if (model_info->features & PS2PP_NAV_BTN) { 276 if (model_info->features & PS2PP_NAV_BTN) {
278 set_bit(BTN_FORWARD, input_dev->keybit); 277 __set_bit(BTN_FORWARD, input_dev->keybit);
279 set_bit(BTN_BACK, input_dev->keybit); 278 __set_bit(BTN_BACK, input_dev->keybit);
280 } 279 }
281 280
282 if (model_info->features & PS2PP_WHEEL) 281 if (model_info->features & PS2PP_WHEEL)
283 set_bit(REL_WHEEL, input_dev->relbit); 282 __set_bit(REL_WHEEL, input_dev->relbit);
284 283
285 if (model_info->features & PS2PP_HWHEEL) 284 if (model_info->features & PS2PP_HWHEEL)
286 set_bit(REL_HWHEEL, input_dev->relbit); 285 __set_bit(REL_HWHEEL, input_dev->relbit);
287 286
288 switch (model_info->kind) { 287 switch (model_info->kind) {
289 case PS2PP_KIND_WHEEL: 288 case PS2PP_KIND_WHEEL:
@@ -321,13 +320,13 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
321 * that support it. 320 * that support it.
322 */ 321 */
323 322
324int ps2pp_init(struct psmouse *psmouse, int set_properties) 323int ps2pp_init(struct psmouse *psmouse, bool set_properties)
325{ 324{
326 struct ps2dev *ps2dev = &psmouse->ps2dev; 325 struct ps2dev *ps2dev = &psmouse->ps2dev;
327 unsigned char param[4]; 326 unsigned char param[4];
328 unsigned char model, buttons; 327 unsigned char model, buttons;
329 const struct ps2pp_info *model_info; 328 const struct ps2pp_info *model_info;
330 int use_ps2pp = 0; 329 bool use_ps2pp = false;
331 int error; 330 int error;
332 331
333 param[0] = 0; 332 param[0] = 0;
@@ -364,7 +363,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
364 param[0] = 0; 363 param[0] = 0;
365 if (!ps2_command(ps2dev, param, 0x13d1) && 364 if (!ps2_command(ps2dev, param, 0x13d1) &&
366 param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { 365 param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
367 use_ps2pp = 1; 366 use_ps2pp = true;
368 } 367 }
369 368
370 } else { 369 } else {
@@ -376,8 +375,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
376 if ((param[0] & 0x78) == 0x48 && 375 if ((param[0] & 0x78) == 0x48 &&
377 (param[1] & 0xf3) == 0xc2 && 376 (param[1] & 0xf3) == 0xc2 &&
378 (param[2] & 0x03) == ((param[1] >> 2) & 3)) { 377 (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
379 ps2pp_set_smartscroll(psmouse, psmouse->smartscroll); 378 ps2pp_set_smartscroll(psmouse, false);
380 use_ps2pp = 1; 379 use_ps2pp = true;
381 } 380 }
382 } 381 }
383 } 382 }
@@ -406,7 +405,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
406 } 405 }
407 406
408 if (buttons < 3) 407 if (buttons < 3)
409 clear_bit(BTN_MIDDLE, psmouse->dev->keybit); 408 __clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
410 409
411 if (model_info) 410 if (model_info)
412 ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); 411 ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
index 6e5712525fd6..0c186f0282d9 100644
--- a/drivers/input/mouse/logips2pp.h
+++ b/drivers/input/mouse/logips2pp.h
@@ -12,9 +12,9 @@
12#define _LOGIPS2PP_H 12#define _LOGIPS2PP_H
13 13
14#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP 14#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
15int ps2pp_init(struct psmouse *psmouse, int set_properties); 15int ps2pp_init(struct psmouse *psmouse, bool set_properties);
16#else 16#else
17inline int ps2pp_init(struct psmouse *psmouse, int set_properties) 17inline int ps2pp_init(struct psmouse *psmouse, bool set_properties)
18{ 18{
19 return -ENOSYS; 19 return -ENOSYS;
20} 20}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index b407b355dceb..690aed905436 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -30,6 +30,7 @@
30#include "trackpoint.h" 30#include "trackpoint.h"
31#include "touchkit_ps2.h" 31#include "touchkit_ps2.h"
32#include "elantech.h" 32#include "elantech.h"
33#include "sentelic.h"
33 34
34#define DRIVER_DESC "PS/2 mouse driver" 35#define DRIVER_DESC "PS/2 mouse driver"
35 36
@@ -108,10 +109,10 @@ static struct workqueue_struct *kpsmoused_wq;
108 109
109struct psmouse_protocol { 110struct psmouse_protocol {
110 enum psmouse_type type; 111 enum psmouse_type type;
112 bool maxproto;
111 const char *name; 113 const char *name;
112 const char *alias; 114 const char *alias;
113 int maxproto; 115 int (*detect)(struct psmouse *, bool);
114 int (*detect)(struct psmouse *, int);
115 int (*init)(struct psmouse *); 116 int (*init)(struct psmouse *);
116}; 117};
117 118
@@ -216,7 +217,7 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
216static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) 217static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
217{ 218{
218 psmouse->state = new_state; 219 psmouse->state = new_state;
219 psmouse->pktcnt = psmouse->out_of_sync = 0; 220 psmouse->pktcnt = psmouse->out_of_sync_cnt = 0;
220 psmouse->ps2dev.flags = 0; 221 psmouse->ps2dev.flags = 0;
221 psmouse->last = jiffies; 222 psmouse->last = jiffies;
222} 223}
@@ -249,7 +250,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
249 if (psmouse->state == PSMOUSE_ACTIVATED) { 250 if (psmouse->state == PSMOUSE_ACTIVATED) {
250 printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", 251 printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
251 psmouse->name, psmouse->phys, psmouse->pktcnt); 252 psmouse->name, psmouse->phys, psmouse->pktcnt);
252 if (++psmouse->out_of_sync == psmouse->resetafter) { 253 if (++psmouse->out_of_sync_cnt == psmouse->resetafter) {
253 __psmouse_set_state(psmouse, PSMOUSE_IGNORE); 254 __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
254 printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); 255 printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
255 serio_reconnect(psmouse->ps2dev.serio); 256 serio_reconnect(psmouse->ps2dev.serio);
@@ -261,8 +262,8 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
261 262
262 case PSMOUSE_FULL_PACKET: 263 case PSMOUSE_FULL_PACKET:
263 psmouse->pktcnt = 0; 264 psmouse->pktcnt = 0;
264 if (psmouse->out_of_sync) { 265 if (psmouse->out_of_sync_cnt) {
265 psmouse->out_of_sync = 0; 266 psmouse->out_of_sync_cnt = 0;
266 printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", 267 printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
267 psmouse->name, psmouse->phys); 268 psmouse->name, psmouse->phys);
268 } 269 }
@@ -408,7 +409,7 @@ int psmouse_reset(struct psmouse *psmouse)
408/* 409/*
409 * Genius NetMouse magic init. 410 * Genius NetMouse magic init.
410 */ 411 */
411static int genius_detect(struct psmouse *psmouse, int set_properties) 412static int genius_detect(struct psmouse *psmouse, bool set_properties)
412{ 413{
413 struct ps2dev *ps2dev = &psmouse->ps2dev; 414 struct ps2dev *ps2dev = &psmouse->ps2dev;
414 unsigned char param[4]; 415 unsigned char param[4];
@@ -424,9 +425,9 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
424 return -1; 425 return -1;
425 426
426 if (set_properties) { 427 if (set_properties) {
427 set_bit(BTN_EXTRA, psmouse->dev->keybit); 428 __set_bit(BTN_EXTRA, psmouse->dev->keybit);
428 set_bit(BTN_SIDE, psmouse->dev->keybit); 429 __set_bit(BTN_SIDE, psmouse->dev->keybit);
429 set_bit(REL_WHEEL, psmouse->dev->relbit); 430 __set_bit(REL_WHEEL, psmouse->dev->relbit);
430 431
431 psmouse->vendor = "Genius"; 432 psmouse->vendor = "Genius";
432 psmouse->name = "Mouse"; 433 psmouse->name = "Mouse";
@@ -439,7 +440,7 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
439/* 440/*
440 * IntelliMouse magic init. 441 * IntelliMouse magic init.
441 */ 442 */
442static int intellimouse_detect(struct psmouse *psmouse, int set_properties) 443static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
443{ 444{
444 struct ps2dev *ps2dev = &psmouse->ps2dev; 445 struct ps2dev *ps2dev = &psmouse->ps2dev;
445 unsigned char param[2]; 446 unsigned char param[2];
@@ -456,8 +457,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
456 return -1; 457 return -1;
457 458
458 if (set_properties) { 459 if (set_properties) {
459 set_bit(BTN_MIDDLE, psmouse->dev->keybit); 460 __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
460 set_bit(REL_WHEEL, psmouse->dev->relbit); 461 __set_bit(REL_WHEEL, psmouse->dev->relbit);
461 462
462 if (!psmouse->vendor) psmouse->vendor = "Generic"; 463 if (!psmouse->vendor) psmouse->vendor = "Generic";
463 if (!psmouse->name) psmouse->name = "Wheel Mouse"; 464 if (!psmouse->name) psmouse->name = "Wheel Mouse";
@@ -470,7 +471,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
470/* 471/*
471 * Try IntelliMouse/Explorer magic init. 472 * Try IntelliMouse/Explorer magic init.
472 */ 473 */
473static int im_explorer_detect(struct psmouse *psmouse, int set_properties) 474static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
474{ 475{
475 struct ps2dev *ps2dev = &psmouse->ps2dev; 476 struct ps2dev *ps2dev = &psmouse->ps2dev;
476 unsigned char param[2]; 477 unsigned char param[2];
@@ -497,11 +498,11 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
497 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 498 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
498 499
499 if (set_properties) { 500 if (set_properties) {
500 set_bit(BTN_MIDDLE, psmouse->dev->keybit); 501 __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
501 set_bit(REL_WHEEL, psmouse->dev->relbit); 502 __set_bit(REL_WHEEL, psmouse->dev->relbit);
502 set_bit(REL_HWHEEL, psmouse->dev->relbit); 503 __set_bit(REL_HWHEEL, psmouse->dev->relbit);
503 set_bit(BTN_SIDE, psmouse->dev->keybit); 504 __set_bit(BTN_SIDE, psmouse->dev->keybit);
504 set_bit(BTN_EXTRA, psmouse->dev->keybit); 505 __set_bit(BTN_EXTRA, psmouse->dev->keybit);
505 506
506 if (!psmouse->vendor) psmouse->vendor = "Generic"; 507 if (!psmouse->vendor) psmouse->vendor = "Generic";
507 if (!psmouse->name) psmouse->name = "Explorer Mouse"; 508 if (!psmouse->name) psmouse->name = "Explorer Mouse";
@@ -514,7 +515,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
514/* 515/*
515 * Kensington ThinkingMouse / ExpertMouse magic init. 516 * Kensington ThinkingMouse / ExpertMouse magic init.
516 */ 517 */
517static int thinking_detect(struct psmouse *psmouse, int set_properties) 518static int thinking_detect(struct psmouse *psmouse, bool set_properties)
518{ 519{
519 struct ps2dev *ps2dev = &psmouse->ps2dev; 520 struct ps2dev *ps2dev = &psmouse->ps2dev;
520 unsigned char param[2]; 521 unsigned char param[2];
@@ -535,7 +536,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
535 return -1; 536 return -1;
536 537
537 if (set_properties) { 538 if (set_properties) {
538 set_bit(BTN_EXTRA, psmouse->dev->keybit); 539 __set_bit(BTN_EXTRA, psmouse->dev->keybit);
539 540
540 psmouse->vendor = "Kensington"; 541 psmouse->vendor = "Kensington";
541 psmouse->name = "ThinkingMouse"; 542 psmouse->name = "ThinkingMouse";
@@ -547,7 +548,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
547/* 548/*
548 * Bare PS/2 protocol "detection". Always succeeds. 549 * Bare PS/2 protocol "detection". Always succeeds.
549 */ 550 */
550static int ps2bare_detect(struct psmouse *psmouse, int set_properties) 551static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
551{ 552{
552 if (set_properties) { 553 if (set_properties) {
553 if (!psmouse->vendor) psmouse->vendor = "Generic"; 554 if (!psmouse->vendor) psmouse->vendor = "Generic";
@@ -561,12 +562,12 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
561 * Cortron PS/2 protocol detection. There's no special way to detect it, so it 562 * Cortron PS/2 protocol detection. There's no special way to detect it, so it
562 * must be forced by sysfs protocol writing. 563 * must be forced by sysfs protocol writing.
563 */ 564 */
564static int cortron_detect(struct psmouse *psmouse, int set_properties) 565static int cortron_detect(struct psmouse *psmouse, bool set_properties)
565{ 566{
566 if (set_properties) { 567 if (set_properties) {
567 psmouse->vendor = "Cortron"; 568 psmouse->vendor = "Cortron";
568 psmouse->name = "PS/2 Trackball"; 569 psmouse->name = "PS/2 Trackball";
569 set_bit(BTN_SIDE, psmouse->dev->keybit); 570 __set_bit(BTN_SIDE, psmouse->dev->keybit);
570 } 571 }
571 572
572 return 0; 573 return 0;
@@ -578,9 +579,9 @@ static int cortron_detect(struct psmouse *psmouse, int set_properties)
578 */ 579 */
579 580
580static int psmouse_extensions(struct psmouse *psmouse, 581static int psmouse_extensions(struct psmouse *psmouse,
581 unsigned int max_proto, int set_properties) 582 unsigned int max_proto, bool set_properties)
582{ 583{
583 int synaptics_hardware = 0; 584 bool synaptics_hardware = true;
584 585
585/* 586/*
586 * We always check for lifebook because it does not disturb mouse 587 * We always check for lifebook because it does not disturb mouse
@@ -607,7 +608,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
607 * can reset it properly after probing for intellimouse. 608 * can reset it properly after probing for intellimouse.
608 */ 609 */
609 if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { 610 if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
610 synaptics_hardware = 1; 611 synaptics_hardware = true;
611 612
612 if (max_proto > PSMOUSE_IMEX) { 613 if (max_proto > PSMOUSE_IMEX) {
613 if (!set_properties || synaptics_init(psmouse) == 0) 614 if (!set_properties || synaptics_init(psmouse) == 0)
@@ -666,6 +667,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
666 max_proto = PSMOUSE_IMEX; 667 max_proto = PSMOUSE_IMEX;
667 } 668 }
668 669
670/*
671 * Try Finger Sensing Pad
672 */
673 if (max_proto > PSMOUSE_IMEX) {
674 if (fsp_detect(psmouse, set_properties) == 0) {
675 if (!set_properties || fsp_init(psmouse) == 0)
676 return PSMOUSE_FSP;
677/*
678 * Init failed, try basic relative protocols
679 */
680 max_proto = PSMOUSE_IMEX;
681 }
682 }
683
669 if (max_proto > PSMOUSE_IMEX) { 684 if (max_proto > PSMOUSE_IMEX) {
670 if (genius_detect(psmouse, set_properties) == 0) 685 if (genius_detect(psmouse, set_properties) == 0)
671 return PSMOUSE_GENPS; 686 return PSMOUSE_GENPS;
@@ -718,7 +733,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
718 .type = PSMOUSE_PS2, 733 .type = PSMOUSE_PS2,
719 .name = "PS/2", 734 .name = "PS/2",
720 .alias = "bare", 735 .alias = "bare",
721 .maxproto = 1, 736 .maxproto = true,
722 .detect = ps2bare_detect, 737 .detect = ps2bare_detect,
723 }, 738 },
724#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP 739#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
@@ -745,14 +760,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
745 .type = PSMOUSE_IMPS, 760 .type = PSMOUSE_IMPS,
746 .name = "ImPS/2", 761 .name = "ImPS/2",
747 .alias = "imps", 762 .alias = "imps",
748 .maxproto = 1, 763 .maxproto = true,
749 .detect = intellimouse_detect, 764 .detect = intellimouse_detect,
750 }, 765 },
751 { 766 {
752 .type = PSMOUSE_IMEX, 767 .type = PSMOUSE_IMEX,
753 .name = "ImExPS/2", 768 .name = "ImExPS/2",
754 .alias = "exps", 769 .alias = "exps",
755 .maxproto = 1, 770 .maxproto = true,
756 .detect = im_explorer_detect, 771 .detect = im_explorer_detect,
757 }, 772 },
758#ifdef CONFIG_MOUSE_PS2_SYNAPTICS 773#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
@@ -813,7 +828,16 @@ static const struct psmouse_protocol psmouse_protocols[] = {
813 .detect = elantech_detect, 828 .detect = elantech_detect,
814 .init = elantech_init, 829 .init = elantech_init,
815 }, 830 },
816 #endif 831#endif
832#ifdef CONFIG_MOUSE_PS2_SENTELIC
833 {
834 .type = PSMOUSE_FSP,
835 .name = "FSPPS/2",
836 .alias = "fsp",
837 .detect = fsp_detect,
838 .init = fsp_init,
839 },
840#endif
817 { 841 {
818 .type = PSMOUSE_CORTRON, 842 .type = PSMOUSE_CORTRON,
819 .name = "CortronPS/2", 843 .name = "CortronPS/2",
@@ -824,7 +848,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
824 .type = PSMOUSE_AUTO, 848 .type = PSMOUSE_AUTO,
825 .name = "auto", 849 .name = "auto",
826 .alias = "any", 850 .alias = "any",
827 .maxproto = 1, 851 .maxproto = true,
828 }, 852 },
829}; 853};
830 854
@@ -990,7 +1014,7 @@ static void psmouse_resync(struct work_struct *work)
990 container_of(work, struct psmouse, resync_work.work); 1014 container_of(work, struct psmouse, resync_work.work);
991 struct serio *serio = psmouse->ps2dev.serio; 1015 struct serio *serio = psmouse->ps2dev.serio;
992 psmouse_ret_t rc = PSMOUSE_GOOD_DATA; 1016 psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
993 int failed = 0, enabled = 0; 1017 bool failed = false, enabled = false;
994 int i; 1018 int i;
995 1019
996 mutex_lock(&psmouse_mutex); 1020 mutex_lock(&psmouse_mutex);
@@ -1017,9 +1041,9 @@ static void psmouse_resync(struct work_struct *work)
1017 1041
1018 if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { 1042 if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {
1019 if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command) 1043 if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)
1020 failed = 1; 1044 failed = true;
1021 } else 1045 } else
1022 psmouse->acks_disable_command = 1; 1046 psmouse->acks_disable_command = true;
1023 1047
1024/* 1048/*
1025 * Poll the mouse. If it was reset the packet will be shorter than 1049 * Poll the mouse. If it was reset the packet will be shorter than
@@ -1030,7 +1054,7 @@ static void psmouse_resync(struct work_struct *work)
1030 */ 1054 */
1031 if (!failed) { 1055 if (!failed) {
1032 if (psmouse->poll(psmouse)) 1056 if (psmouse->poll(psmouse))
1033 failed = 1; 1057 failed = true;
1034 else { 1058 else {
1035 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 1059 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
1036 for (i = 0; i < psmouse->pktsize; i++) { 1060 for (i = 0; i < psmouse->pktsize; i++) {
@@ -1040,7 +1064,7 @@ static void psmouse_resync(struct work_struct *work)
1040 break; 1064 break;
1041 } 1065 }
1042 if (rc != PSMOUSE_FULL_PACKET) 1066 if (rc != PSMOUSE_FULL_PACKET)
1043 failed = 1; 1067 failed = true;
1044 psmouse_set_state(psmouse, PSMOUSE_RESYNCING); 1068 psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
1045 } 1069 }
1046 } 1070 }
@@ -1051,7 +1075,7 @@ static void psmouse_resync(struct work_struct *work)
1051 */ 1075 */
1052 for (i = 0; i < 5; i++) { 1076 for (i = 0; i < 5; i++) {
1053 if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { 1077 if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
1054 enabled = 1; 1078 enabled = true;
1055 break; 1079 break;
1056 } 1080 }
1057 msleep(200); 1081 msleep(200);
@@ -1060,7 +1084,7 @@ static void psmouse_resync(struct work_struct *work)
1060 if (!enabled) { 1084 if (!enabled) {
1061 printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", 1085 printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",
1062 psmouse->ps2dev.serio->phys); 1086 psmouse->ps2dev.serio->phys);
1063 failed = 1; 1087 failed = true;
1064 } 1088 }
1065 1089
1066 if (failed) { 1090 if (failed) {
@@ -1187,7 +1211,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
1187 psmouse->type = proto->type; 1211 psmouse->type = proto->type;
1188 } 1212 }
1189 else 1213 else
1190 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); 1214 psmouse->type = psmouse_extensions(psmouse,
1215 psmouse_max_proto, true);
1191 1216
1192 /* 1217 /*
1193 * If mouse's packet size is 3 there is no point in polling the 1218 * If mouse's packet size is 3 there is no point in polling the
@@ -1342,8 +1367,10 @@ static int psmouse_reconnect(struct serio *serio)
1342 if (psmouse->reconnect(psmouse)) 1367 if (psmouse->reconnect(psmouse))
1343 goto out; 1368 goto out;
1344 } else if (psmouse_probe(psmouse) < 0 || 1369 } else if (psmouse_probe(psmouse) < 0 ||
1345 psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0)) 1370 psmouse->type != psmouse_extensions(psmouse,
1371 psmouse_max_proto, false)) {
1346 goto out; 1372 goto out;
1373 }
1347 1374
1348 /* ok, the device type (and capabilities) match the old one, 1375 /* ok, the device type (and capabilities) match the old one,
1349 * we can continue using it, complete intialization 1376 * we can continue using it, complete intialization
@@ -1528,7 +1555,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
1528 1555
1529 while (serio->child) { 1556 while (serio->child) {
1530 if (++retry > 3) { 1557 if (++retry > 3) {
1531 printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); 1558 printk(KERN_WARNING
1559 "psmouse: failed to destroy child port, "
1560 "protocol change aborted.\n");
1532 input_free_device(new_dev); 1561 input_free_device(new_dev);
1533 return -EIO; 1562 return -EIO;
1534 } 1563 }
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 54ed267894bd..e053bdd137ff 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -47,10 +47,10 @@ struct psmouse {
47 unsigned char pktcnt; 47 unsigned char pktcnt;
48 unsigned char pktsize; 48 unsigned char pktsize;
49 unsigned char type; 49 unsigned char type;
50 unsigned char acks_disable_command; 50 bool acks_disable_command;
51 unsigned int model; 51 unsigned int model;
52 unsigned long last; 52 unsigned long last;
53 unsigned long out_of_sync; 53 unsigned long out_of_sync_cnt;
54 unsigned long num_resyncs; 54 unsigned long num_resyncs;
55 enum psmouse_state state; 55 enum psmouse_state state;
56 char devname[64]; 56 char devname[64];
@@ -60,7 +60,7 @@ struct psmouse {
60 unsigned int resolution; 60 unsigned int resolution;
61 unsigned int resetafter; 61 unsigned int resetafter;
62 unsigned int resync_time; 62 unsigned int resync_time;
63 unsigned int smartscroll; /* Logitech only */ 63 bool smartscroll; /* Logitech only */
64 64
65 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); 65 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
66 void (*set_rate)(struct psmouse *psmouse, unsigned int rate); 66 void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
@@ -91,6 +91,7 @@ enum psmouse_type {
91 PSMOUSE_CORTRON, 91 PSMOUSE_CORTRON,
92 PSMOUSE_HGPK, 92 PSMOUSE_HGPK,
93 PSMOUSE_ELANTECH, 93 PSMOUSE_ELANTECH,
94 PSMOUSE_FSP,
94 PSMOUSE_AUTO /* This one should always be last */ 95 PSMOUSE_AUTO /* This one should always be last */
95}; 96};
96 97
@@ -107,7 +108,7 @@ struct psmouse_attribute {
107 ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); 108 ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
108 ssize_t (*set)(struct psmouse *psmouse, void *data, 109 ssize_t (*set)(struct psmouse *psmouse, void *data,
109 const char *buf, size_t count); 110 const char *buf, size_t count);
110 int protect; 111 bool protect;
111}; 112};
112#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) 113#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
113 114
@@ -116,9 +117,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
116ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, 117ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
117 const char *buf, size_t count); 118 const char *buf, size_t count);
118 119
119#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \ 120#define __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect) \
120static ssize_t _show(struct psmouse *, void *data, char *); \
121static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
122static struct psmouse_attribute psmouse_attr_##_name = { \ 121static struct psmouse_attribute psmouse_attr_##_name = { \
123 .dattr = { \ 122 .dattr = { \
124 .attr = { \ 123 .attr = { \
@@ -134,7 +133,20 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
134 .protect = _protect, \ 133 .protect = _protect, \
135} 134}
136 135
137#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ 136#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
138 __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1) 137 static ssize_t _show(struct psmouse *, void *, char *); \
138 static ssize_t _set(struct psmouse *, void *, const char *, size_t); \
139 __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect)
140
141#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
142 __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, true)
143
144#define PSMOUSE_DEFINE_RO_ATTR(_name, _mode, _data, _show) \
145 static ssize_t _show(struct psmouse *, void *, char *); \
146 __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, NULL, true)
147
148#define PSMOUSE_DEFINE_WO_ATTR(_name, _mode, _data, _set) \
149 static ssize_t _set(struct psmouse *, void *, const char *, size_t); \
150 __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true)
139 151
140#endif /* _PSMOUSE_H */ 152#endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
new file mode 100644
index 000000000000..f84cbd97c884
--- /dev/null
+++ b/drivers/input/mouse/sentelic.c
@@ -0,0 +1,869 @@
1/*-
2 * Finger Sensing Pad PS/2 mouse driver.
3 *
4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
5 * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/version.h>
24#include <linux/input.h>
25#include <linux/ctype.h>
26#include <linux/libps2.h>
27#include <linux/serio.h>
28#include <linux/jiffies.h>
29
30#include "psmouse.h"
31#include "sentelic.h"
32
33/*
34 * Timeout for FSP PS/2 command only (in milliseconds).
35 */
36#define FSP_CMD_TIMEOUT 200
37#define FSP_CMD_TIMEOUT2 30
38
39/** Driver version. */
40static const char fsp_drv_ver[] = "1.0.0-K";
41
42/*
43 * Make sure that the value being sent to FSP will not conflict with
44 * possible sample rate values.
45 */
46static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
47{
48 switch (reg_val) {
49 case 10: case 20: case 40: case 60: case 80: case 100: case 200:
50 /*
51 * The requested value being sent to FSP matched to possible
52 * sample rates, swap the given value such that the hardware
53 * wouldn't get confused.
54 */
55 return (reg_val >> 4) | (reg_val << 4);
56 default:
57 return reg_val; /* swap isn't necessary */
58 }
59}
60
61/*
62 * Make sure that the value being sent to FSP will not conflict with certain
63 * commands.
64 */
65static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
66{
67 switch (reg_val) {
68 case 0xe9: case 0xee: case 0xf2: case 0xff:
69 /*
70 * The requested value being sent to FSP matched to certain
71 * commands, inverse the given value such that the hardware
72 * wouldn't get confused.
73 */
74 return ~reg_val;
75 default:
76 return reg_val; /* inversion isn't necessary */
77 }
78}
79
80static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
81{
82 struct ps2dev *ps2dev = &psmouse->ps2dev;
83 unsigned char param[3];
84 unsigned char addr;
85 int rc = -1;
86
87 /*
88 * We need to shut off the device and switch it into command
89 * mode so we don't confuse our protocol handler. We don't need
90 * to do that for writes because sysfs set helper does this for
91 * us.
92 */
93 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
94 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
95
96 ps2_begin_command(ps2dev);
97
98 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
99 goto out;
100
101 /* should return 0xfe(request for resending) */
102 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
103 /* should return 0xfc(failed) */
104 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
105
106 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
107 goto out;
108
109 if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
110 ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
111 } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
112 /* swapping is required */
113 ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
114 /* expect 0xfe */
115 } else {
116 /* swapping isn't necessary */
117 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
118 /* expect 0xfe */
119 }
120 /* should return 0xfc(failed) */
121 ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
122
123 if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
124 goto out;
125
126 *reg_val = param[2];
127 rc = 0;
128
129 out:
130 ps2_end_command(ps2dev);
131 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
132 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
133 dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
134 reg_addr, *reg_val, rc);
135 return rc;
136}
137
138static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
139{
140 struct ps2dev *ps2dev = &psmouse->ps2dev;
141 unsigned char v;
142 int rc = -1;
143
144 ps2_begin_command(ps2dev);
145
146 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
147 goto out;
148
149 if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
150 /* inversion is required */
151 ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
152 } else {
153 if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
154 /* swapping is required */
155 ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
156 } else {
157 /* swapping isn't necessary */
158 ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
159 }
160 }
161 /* write the register address in correct order */
162 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
163
164 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
165 return -1;
166
167 if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
168 /* inversion is required */
169 ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
170 } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
171 /* swapping is required */
172 ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
173 } else {
174 /* swapping isn't necessary */
175 ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
176 }
177
178 /* write the register value in correct order */
179 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
180 rc = 0;
181
182 out:
183 ps2_end_command(ps2dev);
184 dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
185 reg_addr, reg_val, rc);
186 return rc;
187}
188
189/* Enable register clock gating for writing certain registers */
190static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
191{
192 int v, nv;
193
194 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
195 return -1;
196
197 if (enable)
198 nv = v | FSP_BIT_EN_REG_CLK;
199 else
200 nv = v & ~FSP_BIT_EN_REG_CLK;
201
202 /* only write if necessary */
203 if (nv != v)
204 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
205 return -1;
206
207 return 0;
208}
209
210static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
211{
212 struct ps2dev *ps2dev = &psmouse->ps2dev;
213 unsigned char param[3];
214 int rc = -1;
215
216 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
217 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
218
219 ps2_begin_command(ps2dev);
220
221 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
222 goto out;
223
224 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
225 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
226
227 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
228 goto out;
229
230 ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
231 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
232
233 /* get the returned result */
234 if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
235 goto out;
236
237 *reg_val = param[2];
238 rc = 0;
239
240 out:
241 ps2_end_command(ps2dev);
242 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
243 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
244 dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n",
245 *reg_val, rc);
246 return rc;
247}
248
249static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
250{
251 struct ps2dev *ps2dev = &psmouse->ps2dev;
252 unsigned char v;
253 int rc = -1;
254
255 ps2_begin_command(ps2dev);
256
257 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
258 goto out;
259
260 ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
261 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
262
263 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
264 return -1;
265
266 if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
267 ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
268 } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
269 /* swapping is required */
270 ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
271 } else {
272 /* swapping isn't necessary */
273 ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
274 }
275
276 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
277 rc = 0;
278
279 out:
280 ps2_end_command(ps2dev);
281 dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
282 reg_val, rc);
283 return rc;
284}
285
286static int fsp_get_version(struct psmouse *psmouse, int *version)
287{
288 if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
289 return -EIO;
290
291 return 0;
292}
293
294static int fsp_get_revision(struct psmouse *psmouse, int *rev)
295{
296 if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
297 return -EIO;
298
299 return 0;
300}
301
302static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
303{
304 static const int buttons[] = {
305 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
306 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
307 0x04, /* Left/Middle/Right & Scroll Up/Down */
308 0x02, /* Left/Middle/Right */
309 };
310 int val;
311
312 if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &val) == -1)
313 return -EIO;
314
315 *btn = buttons[(val & 0x30) >> 4];
316 return 0;
317}
318
319/* Enable on-pad command tag output */
320static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
321{
322 int v, nv;
323 int res = 0;
324
325 if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
326 dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n");
327 return -EIO;
328 }
329
330 if (enable)
331 nv = v | FSP_BIT_EN_OPC_TAG;
332 else
333 nv = v & ~FSP_BIT_EN_OPC_TAG;
334
335 /* only write if necessary */
336 if (nv != v) {
337 fsp_reg_write_enable(psmouse, true);
338 res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
339 fsp_reg_write_enable(psmouse, false);
340 }
341
342 if (res != 0) {
343 dev_err(&psmouse->ps2dev.serio->dev,
344 "Unable to enable OPC tag.\n");
345 res = -EIO;
346 }
347
348 return res;
349}
350
351static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
352{
353 struct fsp_data *pad = psmouse->private;
354 int val;
355
356 if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
357 return -EIO;
358
359 pad->vscroll = enable;
360
361 if (enable)
362 val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
363 else
364 val &= ~FSP_BIT_FIX_VSCR;
365
366 if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
367 return -EIO;
368
369 return 0;
370}
371
372static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
373{
374 struct fsp_data *pad = psmouse->private;
375 int val, v2;
376
377 if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
378 return -EIO;
379
380 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
381 return -EIO;
382
383 pad->hscroll = enable;
384
385 if (enable) {
386 val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
387 v2 |= FSP_BIT_EN_MSID6;
388 } else {
389 val &= ~FSP_BIT_FIX_HSCR;
390 v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
391 }
392
393 if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
394 return -EIO;
395
396 /* reconfigure horizontal scrolling packet output */
397 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
398 return -EIO;
399
400 return 0;
401}
402
403/*
404 * Write device specific initial parameters.
405 *
406 * ex: 0xab 0xcd - write oxcd into register 0xab
407 */
408static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
409 const char *buf, size_t count)
410{
411 unsigned long reg, val;
412 char *rest;
413 ssize_t retval;
414
415 reg = simple_strtoul(buf, &rest, 16);
416 if (rest == buf || *rest != ' ' || reg > 0xff)
417 return -EINVAL;
418
419 if (strict_strtoul(rest + 1, 16, &val) || val > 0xff)
420 return -EINVAL;
421
422 if (fsp_reg_write_enable(psmouse, true))
423 return -EIO;
424
425 retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
426
427 fsp_reg_write_enable(psmouse, false);
428
429 return count;
430}
431
432PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
433
434static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
435 void *data, char *buf)
436{
437 struct fsp_data *pad = psmouse->private;
438
439 return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
440}
441
442/*
443 * Read a register from device.
444 *
445 * ex: 0xab -- read content from register 0xab
446 */
447static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
448 const char *buf, size_t count)
449{
450 struct fsp_data *pad = psmouse->private;
451 unsigned long reg;
452 int val;
453
454 if (strict_strtoul(buf, 16, &reg) || reg > 0xff)
455 return -EINVAL;
456
457 if (fsp_reg_read(psmouse, reg, &val))
458 return -EIO;
459
460 pad->last_reg = reg;
461 pad->last_val = val;
462
463 return count;
464}
465
466PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
467 fsp_attr_show_getreg, fsp_attr_set_getreg);
468
469static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
470 void *data, char *buf)
471{
472 int val = 0;
473
474 if (fsp_page_reg_read(psmouse, &val))
475 return -EIO;
476
477 return sprintf(buf, "%02x\n", val);
478}
479
480static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
481 const char *buf, size_t count)
482{
483 unsigned long val;
484
485 if (strict_strtoul(buf, 16, &val) || val > 0xff)
486 return -EINVAL;
487
488 if (fsp_page_reg_write(psmouse, val))
489 return -EIO;
490
491 return count;
492}
493
494PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
495 fsp_attr_show_pagereg, fsp_attr_set_pagereg);
496
497static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
498 void *data, char *buf)
499{
500 struct fsp_data *pad = psmouse->private;
501
502 return sprintf(buf, "%d\n", pad->vscroll);
503}
504
505static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
506 const char *buf, size_t count)
507{
508 unsigned long val;
509
510 if (strict_strtoul(buf, 10, &val) || val > 1)
511 return -EINVAL;
512
513 fsp_onpad_vscr(psmouse, val);
514
515 return count;
516}
517
518PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
519 fsp_attr_show_vscroll, fsp_attr_set_vscroll);
520
521static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
522 void *data, char *buf)
523{
524 struct fsp_data *pad = psmouse->private;
525
526 return sprintf(buf, "%d\n", pad->hscroll);
527}
528
529static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
530 const char *buf, size_t count)
531{
532 unsigned long val;
533
534 if (strict_strtoul(buf, 10, &val) || val > 1)
535 return -EINVAL;
536
537 fsp_onpad_hscr(psmouse, val);
538
539 return count;
540}
541
542PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
543 fsp_attr_show_hscroll, fsp_attr_set_hscroll);
544
545static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
546 void *data, char *buf)
547{
548 struct fsp_data *pad = psmouse->private;
549
550 return sprintf(buf, "%c\n",
551 pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
552}
553
554static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
555 const char *buf, size_t count)
556{
557 struct fsp_data *pad = psmouse->private;
558 size_t i;
559
560 for (i = 0; i < count; i++) {
561 switch (buf[i]) {
562 case 'C':
563 pad->flags |= FSPDRV_FLAG_EN_OPC;
564 break;
565 case 'c':
566 pad->flags &= ~FSPDRV_FLAG_EN_OPC;
567 break;
568 default:
569 return -EINVAL;
570 }
571 }
572 return count;
573}
574
575PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
576 fsp_attr_show_flags, fsp_attr_set_flags);
577
578static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
579 void *data, char *buf)
580{
581 return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
582}
583
584PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
585
586static struct attribute *fsp_attributes[] = {
587 &psmouse_attr_setreg.dattr.attr,
588 &psmouse_attr_getreg.dattr.attr,
589 &psmouse_attr_page.dattr.attr,
590 &psmouse_attr_vscroll.dattr.attr,
591 &psmouse_attr_hscroll.dattr.attr,
592 &psmouse_attr_flags.dattr.attr,
593 &psmouse_attr_ver.dattr.attr,
594 NULL
595};
596
597static struct attribute_group fsp_attribute_group = {
598 .attrs = fsp_attributes,
599};
600
601#ifdef FSP_DEBUG
602static void fsp_packet_debug(unsigned char packet[])
603{
604 static unsigned int ps2_packet_cnt;
605 static unsigned int ps2_last_second;
606 unsigned int jiffies_msec;
607
608 ps2_packet_cnt++;
609 jiffies_msec = jiffies_to_msecs(jiffies);
610 printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n",
611 jiffies_msec, packet[0], packet[1], packet[2], packet[3]);
612
613 if (jiffies_msec - ps2_last_second > 1000) {
614 printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt);
615 ps2_packet_cnt = 0;
616 ps2_last_second = jiffies_msec;
617 }
618}
619#else
620static void fsp_packet_debug(unsigned char packet[])
621{
622}
623#endif
624
625static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
626{
627 struct input_dev *dev = psmouse->dev;
628 struct fsp_data *ad = psmouse->private;
629 unsigned char *packet = psmouse->packet;
630 unsigned char button_status = 0, lscroll = 0, rscroll = 0;
631 int rel_x, rel_y;
632
633 if (psmouse->pktcnt < 4)
634 return PSMOUSE_GOOD_DATA;
635
636 /*
637 * Full packet accumulated, process it
638 */
639
640 switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
641 case FSP_PKT_TYPE_ABS:
642 dev_warn(&psmouse->ps2dev.serio->dev,
643 "Unexpected absolute mode packet, ignored.\n");
644 break;
645
646 case FSP_PKT_TYPE_NORMAL_OPC:
647 /* on-pad click, filter it if necessary */
648 if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
649 packet[0] &= ~BIT(0);
650 /* fall through */
651
652 case FSP_PKT_TYPE_NORMAL:
653 /* normal packet */
654 /* special packet data translation from on-pad packets */
655 if (packet[3] != 0) {
656 if (packet[3] & BIT(0))
657 button_status |= 0x01; /* wheel down */
658 if (packet[3] & BIT(1))
659 button_status |= 0x0f; /* wheel up */
660 if (packet[3] & BIT(2))
661 button_status |= BIT(5);/* horizontal left */
662 if (packet[3] & BIT(3))
663 button_status |= BIT(4);/* horizontal right */
664 /* push back to packet queue */
665 if (button_status != 0)
666 packet[3] = button_status;
667 rscroll = (packet[3] >> 4) & 1;
668 lscroll = (packet[3] >> 5) & 1;
669 }
670 /*
671 * Processing wheel up/down and extra button events
672 */
673 input_report_rel(dev, REL_WHEEL,
674 (int)(packet[3] & 8) - (int)(packet[3] & 7));
675 input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
676 input_report_key(dev, BTN_BACK, lscroll);
677 input_report_key(dev, BTN_FORWARD, rscroll);
678
679 /*
680 * Standard PS/2 Mouse
681 */
682 input_report_key(dev, BTN_LEFT, packet[0] & 1);
683 input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
684 input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
685
686 rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0;
687 rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0;
688
689 input_report_rel(dev, REL_X, rel_x);
690 input_report_rel(dev, REL_Y, rel_y);
691 break;
692 }
693
694 input_sync(dev);
695
696 fsp_packet_debug(packet);
697
698 return PSMOUSE_FULL_PACKET;
699}
700
701static int fsp_activate_protocol(struct psmouse *psmouse)
702{
703 struct fsp_data *pad = psmouse->private;
704 struct ps2dev *ps2dev = &psmouse->ps2dev;
705 unsigned char param[2];
706 int val;
707
708 /*
709 * Standard procedure to enter FSP Intellimouse mode
710 * (scrolling wheel, 4th and 5th buttons)
711 */
712 param[0] = 200;
713 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
714 param[0] = 200;
715 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
716 param[0] = 80;
717 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
718
719 ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
720 if (param[0] != 0x04) {
721 dev_err(&psmouse->ps2dev.serio->dev,
722 "Unable to enable 4 bytes packet format.\n");
723 return -EIO;
724 }
725
726 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
727 dev_err(&psmouse->ps2dev.serio->dev,
728 "Unable to read SYSCTL5 register.\n");
729 return -EIO;
730 }
731
732 val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
733 /* Ensure we are not in absolute mode */
734 val &= ~FSP_BIT_EN_PKT_G0;
735 if (pad->buttons == 0x06) {
736 /* Left/Middle/Right & Scroll Up/Down/Right/Left */
737 val |= FSP_BIT_EN_MSID6;
738 }
739
740 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
741 dev_err(&psmouse->ps2dev.serio->dev,
742 "Unable to set up required mode bits.\n");
743 return -EIO;
744 }
745
746 /*
747 * Enable OPC tags such that driver can tell the difference between
748 * on-pad and real button click
749 */
750 if (fsp_opc_tag_enable(psmouse, true))
751 dev_warn(&psmouse->ps2dev.serio->dev,
752 "Failed to enable OPC tag mode.\n");
753
754 /* Enable on-pad vertical and horizontal scrolling */
755 fsp_onpad_vscr(psmouse, true);
756 fsp_onpad_hscr(psmouse, true);
757
758 return 0;
759}
760
761int fsp_detect(struct psmouse *psmouse, bool set_properties)
762{
763 int id;
764
765 if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
766 return -EIO;
767
768 if (id != 0x01)
769 return -ENODEV;
770
771 if (set_properties) {
772 psmouse->vendor = "Sentelic";
773 psmouse->name = "FingerSensingPad";
774 }
775
776 return 0;
777}
778
779static void fsp_reset(struct psmouse *psmouse)
780{
781 fsp_opc_tag_enable(psmouse, false);
782 fsp_onpad_vscr(psmouse, false);
783 fsp_onpad_hscr(psmouse, false);
784}
785
786static void fsp_disconnect(struct psmouse *psmouse)
787{
788 sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
789 &fsp_attribute_group);
790
791 fsp_reset(psmouse);
792 kfree(psmouse->private);
793}
794
795static int fsp_reconnect(struct psmouse *psmouse)
796{
797 int version;
798
799 if (fsp_detect(psmouse, 0))
800 return -ENODEV;
801
802 if (fsp_get_version(psmouse, &version))
803 return -ENODEV;
804
805 if (fsp_activate_protocol(psmouse))
806 return -EIO;
807
808 return 0;
809}
810
811int fsp_init(struct psmouse *psmouse)
812{
813 struct fsp_data *priv;
814 int ver, rev, buttons;
815 int error;
816
817 if (fsp_get_version(psmouse, &ver) ||
818 fsp_get_revision(psmouse, &rev) ||
819 fsp_get_buttons(psmouse, &buttons)) {
820 return -ENODEV;
821 }
822
823 printk(KERN_INFO
824 "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n",
825 ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7);
826
827 psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
828 if (!priv)
829 return -ENOMEM;
830
831 priv->ver = ver;
832 priv->rev = rev;
833 priv->buttons = buttons;
834
835 /* enable on-pad click by default */
836 priv->flags |= FSPDRV_FLAG_EN_OPC;
837
838 /* Set up various supported input event bits */
839 __set_bit(BTN_BACK, psmouse->dev->keybit);
840 __set_bit(BTN_FORWARD, psmouse->dev->keybit);
841 __set_bit(REL_WHEEL, psmouse->dev->relbit);
842 __set_bit(REL_HWHEEL, psmouse->dev->relbit);
843
844 psmouse->protocol_handler = fsp_process_byte;
845 psmouse->disconnect = fsp_disconnect;
846 psmouse->reconnect = fsp_reconnect;
847 psmouse->cleanup = fsp_reset;
848 psmouse->pktsize = 4;
849
850 /* set default packet output based on number of buttons we found */
851 error = fsp_activate_protocol(psmouse);
852 if (error)
853 goto err_out;
854
855 error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
856 &fsp_attribute_group);
857 if (error) {
858 dev_err(&psmouse->ps2dev.serio->dev,
859 "Failed to create sysfs attributes (%d)", error);
860 goto err_out;
861 }
862
863 return 0;
864
865 err_out:
866 kfree(psmouse->private);
867 psmouse->private = NULL;
868 return error;
869}
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h
new file mode 100644
index 000000000000..ed1395ac7b8b
--- /dev/null
+++ b/drivers/input/mouse/sentelic.h
@@ -0,0 +1,98 @@
1/*-
2 * Finger Sensing Pad PS/2 mouse driver.
3 *
4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
5 * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __SENTELIC_H
23#define __SENTELIC_H
24
25/* Finger-sensing Pad information registers */
26#define FSP_REG_DEVICE_ID 0x00
27#define FSP_REG_VERSION 0x01
28#define FSP_REG_REVISION 0x04
29#define FSP_REG_TMOD_STATUS1 0x0B
30#define FSP_BIT_NO_ROTATION BIT(3)
31#define FSP_REG_PAGE_CTRL 0x0F
32
33/* Finger-sensing Pad control registers */
34#define FSP_REG_SYSCTL1 0x10
35#define FSP_BIT_EN_REG_CLK BIT(5)
36#define FSP_REG_OPC_QDOWN 0x31
37#define FSP_BIT_EN_OPC_TAG BIT(7)
38#define FSP_REG_OPTZ_XLO 0x34
39#define FSP_REG_OPTZ_XHI 0x35
40#define FSP_REG_OPTZ_YLO 0x36
41#define FSP_REG_OPTZ_YHI 0x37
42#define FSP_REG_SYSCTL5 0x40
43#define FSP_BIT_90_DEGREE BIT(0)
44#define FSP_BIT_EN_MSID6 BIT(1)
45#define FSP_BIT_EN_MSID7 BIT(2)
46#define FSP_BIT_EN_MSID8 BIT(3)
47#define FSP_BIT_EN_AUTO_MSID8 BIT(5)
48#define FSP_BIT_EN_PKT_G0 BIT(6)
49
50#define FSP_REG_ONPAD_CTL 0x43
51#define FSP_BIT_ONPAD_ENABLE BIT(0)
52#define FSP_BIT_ONPAD_FBBB BIT(1)
53#define FSP_BIT_FIX_VSCR BIT(3)
54#define FSP_BIT_FIX_HSCR BIT(5)
55#define FSP_BIT_DRAG_LOCK BIT(6)
56
57/* Finger-sensing Pad packet formating related definitions */
58
59/* absolute packet type */
60#define FSP_PKT_TYPE_NORMAL (0x00)
61#define FSP_PKT_TYPE_ABS (0x01)
62#define FSP_PKT_TYPE_NOTIFY (0x02)
63#define FSP_PKT_TYPE_NORMAL_OPC (0x03)
64#define FSP_PKT_TYPE_SHIFT (6)
65
66#ifdef __KERNEL__
67
68struct fsp_data {
69 unsigned char ver; /* hardware version */
70 unsigned char rev; /* hardware revison */
71 unsigned char buttons; /* Number of buttons */
72 unsigned int flags;
73#define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */
74
75 bool vscroll; /* Vertical scroll zone enabled */
76 bool hscroll; /* Horizontal scroll zone enabled */
77
78 unsigned char last_reg; /* Last register we requested read from */
79 unsigned char last_val;
80};
81
82#ifdef CONFIG_MOUSE_PS2_SENTELIC
83extern int fsp_detect(struct psmouse *psmouse, bool set_properties);
84extern int fsp_init(struct psmouse *psmouse);
85#else
86inline int fsp_detect(struct psmouse *psmouse, bool set_properties)
87{
88 return -ENOSYS;
89}
90inline int fsp_init(struct psmouse *psmouse)
91{
92 return -ENOSYS;
93}
94#endif
95
96#endif /* __KERNEL__ */
97
98#endif /* !__SENTELIC_H */
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 19984bf06cad..b66ff1ac7dea 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -60,7 +60,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
60 return 0; 60 return 0;
61} 61}
62 62
63int synaptics_detect(struct psmouse *psmouse, int set_properties) 63int synaptics_detect(struct psmouse *psmouse, bool set_properties)
64{ 64{
65 struct ps2dev *ps2dev = &psmouse->ps2dev; 65 struct ps2dev *ps2dev = &psmouse->ps2dev;
66 unsigned char param[4]; 66 unsigned char param[4];
@@ -556,38 +556,38 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
556{ 556{
557 int i; 557 int i;
558 558
559 set_bit(EV_ABS, dev->evbit); 559 __set_bit(EV_ABS, dev->evbit);
560 input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); 560 input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
561 input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); 561 input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
562 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); 562 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
563 set_bit(ABS_TOOL_WIDTH, dev->absbit); 563 __set_bit(ABS_TOOL_WIDTH, dev->absbit);
564 564
565 set_bit(EV_KEY, dev->evbit); 565 __set_bit(EV_KEY, dev->evbit);
566 set_bit(BTN_TOUCH, dev->keybit); 566 __set_bit(BTN_TOUCH, dev->keybit);
567 set_bit(BTN_TOOL_FINGER, dev->keybit); 567 __set_bit(BTN_TOOL_FINGER, dev->keybit);
568 set_bit(BTN_LEFT, dev->keybit); 568 __set_bit(BTN_LEFT, dev->keybit);
569 set_bit(BTN_RIGHT, dev->keybit); 569 __set_bit(BTN_RIGHT, dev->keybit);
570 570
571 if (SYN_CAP_MULTIFINGER(priv->capabilities)) { 571 if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
572 set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); 572 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
573 set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); 573 __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
574 } 574 }
575 575
576 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) 576 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
577 set_bit(BTN_MIDDLE, dev->keybit); 577 __set_bit(BTN_MIDDLE, dev->keybit);
578 578
579 if (SYN_CAP_FOUR_BUTTON(priv->capabilities) || 579 if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
580 SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { 580 SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
581 set_bit(BTN_FORWARD, dev->keybit); 581 __set_bit(BTN_FORWARD, dev->keybit);
582 set_bit(BTN_BACK, dev->keybit); 582 __set_bit(BTN_BACK, dev->keybit);
583 } 583 }
584 584
585 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) 585 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
586 set_bit(BTN_0 + i, dev->keybit); 586 __set_bit(BTN_0 + i, dev->keybit);
587 587
588 clear_bit(EV_REL, dev->evbit); 588 __clear_bit(EV_REL, dev->evbit);
589 clear_bit(REL_X, dev->relbit); 589 __clear_bit(REL_X, dev->relbit);
590 clear_bit(REL_Y, dev->relbit); 590 __clear_bit(REL_Y, dev->relbit);
591 591
592 dev->absres[ABS_X] = priv->x_res; 592 dev->absres[ABS_X] = priv->x_res;
593 dev->absres[ABS_Y] = priv->y_res; 593 dev->absres[ABS_Y] = priv->y_res;
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 302382151752..871f6fe377f9 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -105,7 +105,7 @@ struct synaptics_data {
105 int scroll; 105 int scroll;
106}; 106};
107 107
108int synaptics_detect(struct psmouse *psmouse, int set_properties); 108int synaptics_detect(struct psmouse *psmouse, bool set_properties);
109int synaptics_init(struct psmouse *psmouse); 109int synaptics_init(struct psmouse *psmouse);
110void synaptics_reset(struct psmouse *psmouse); 110void synaptics_reset(struct psmouse *psmouse);
111 111
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index eac9fdde7ee9..7283c78044af 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -203,7 +203,7 @@ MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)");
203 * and the irq configuration should be set to Falling Edge Trigger 203 * and the irq configuration should be set to Falling Edge Trigger
204 */ 204 */
205/* Control IRQ / Polling option */ 205/* Control IRQ / Polling option */
206static int polling_req; 206static bool polling_req;
207module_param(polling_req, bool, 0444); 207module_param(polling_req, bool, 0444);
208MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); 208MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)");
209 209
@@ -217,6 +217,7 @@ struct synaptics_i2c {
217 struct i2c_client *client; 217 struct i2c_client *client;
218 struct input_dev *input; 218 struct input_dev *input;
219 struct delayed_work dwork; 219 struct delayed_work dwork;
220 spinlock_t lock;
220 int no_data_count; 221 int no_data_count;
221 int no_decel_param; 222 int no_decel_param;
222 int reduce_report_param; 223 int reduce_report_param;
@@ -366,17 +367,28 @@ static bool synaptics_i2c_get_input(struct synaptics_i2c *touch)
366 return xy_delta || gesture; 367 return xy_delta || gesture;
367} 368}
368 369
369static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) 370static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch,
371 unsigned long delay)
370{ 372{
371 struct synaptics_i2c *touch = dev_id; 373 unsigned long flags;
374
375 spin_lock_irqsave(&touch->lock, flags);
372 376
373 /* 377 /*
374 * We want to have the work run immediately but it might have 378 * If work is already scheduled then subsequent schedules will not
375 * already been scheduled with a delay, that's why we have to 379 * change the scheduled time that's why we have to cancel it first.
376 * cancel it first.
377 */ 380 */
378 cancel_delayed_work(&touch->dwork); 381 __cancel_delayed_work(&touch->dwork);
379 schedule_delayed_work(&touch->dwork, 0); 382 schedule_delayed_work(&touch->dwork, delay);
383
384 spin_unlock_irqrestore(&touch->lock, flags);
385}
386
387static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id)
388{
389 struct synaptics_i2c *touch = dev_id;
390
391 synaptics_i2c_reschedule_work(touch, 0);
380 392
381 return IRQ_HANDLED; 393 return IRQ_HANDLED;
382} 394}
@@ -452,7 +464,7 @@ static void synaptics_i2c_work_handler(struct work_struct *work)
452 * We poll the device once in THREAD_IRQ_SLEEP_SECS and 464 * We poll the device once in THREAD_IRQ_SLEEP_SECS and
453 * if error is detected, we try to reset and reconfigure the touchpad. 465 * if error is detected, we try to reset and reconfigure the touchpad.
454 */ 466 */
455 schedule_delayed_work(&touch->dwork, delay); 467 synaptics_i2c_reschedule_work(touch, delay);
456} 468}
457 469
458static int synaptics_i2c_open(struct input_dev *input) 470static int synaptics_i2c_open(struct input_dev *input)
@@ -465,8 +477,8 @@ static int synaptics_i2c_open(struct input_dev *input)
465 return ret; 477 return ret;
466 478
467 if (polling_req) 479 if (polling_req)
468 schedule_delayed_work(&touch->dwork, 480 synaptics_i2c_reschedule_work(touch,
469 msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); 481 msecs_to_jiffies(NO_DATA_SLEEP_MSECS));
470 482
471 return 0; 483 return 0;
472} 484}
@@ -521,6 +533,7 @@ struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)
521 touch->scan_rate_param = scan_rate; 533 touch->scan_rate_param = scan_rate;
522 set_scan_rate(touch, scan_rate); 534 set_scan_rate(touch, scan_rate);
523 INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler); 535 INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler);
536 spin_lock_init(&touch->lock);
524 537
525 return touch; 538 return touch;
526} 539}
@@ -535,14 +548,12 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
535 if (!touch) 548 if (!touch)
536 return -ENOMEM; 549 return -ENOMEM;
537 550
538 i2c_set_clientdata(client, touch);
539
540 ret = synaptics_i2c_reset_config(client); 551 ret = synaptics_i2c_reset_config(client);
541 if (ret) 552 if (ret)
542 goto err_mem_free; 553 goto err_mem_free;
543 554
544 if (client->irq < 1) 555 if (client->irq < 1)
545 polling_req = 1; 556 polling_req = true;
546 557
547 touch->input = input_allocate_device(); 558 touch->input = input_allocate_device();
548 if (!touch->input) { 559 if (!touch->input) {
@@ -563,7 +574,7 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
563 dev_warn(&touch->client->dev, 574 dev_warn(&touch->client->dev,
564 "IRQ request failed: %d, " 575 "IRQ request failed: %d, "
565 "falling back to polling\n", ret); 576 "falling back to polling\n", ret);
566 polling_req = 1; 577 polling_req = true;
567 synaptics_i2c_reg_set(touch->client, 578 synaptics_i2c_reg_set(touch->client,
568 INTERRUPT_EN_REG, 0); 579 INTERRUPT_EN_REG, 0);
569 } 580 }
@@ -580,12 +591,14 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
580 "Input device register failed: %d\n", ret); 591 "Input device register failed: %d\n", ret);
581 goto err_input_free; 592 goto err_input_free;
582 } 593 }
594
595 i2c_set_clientdata(client, touch);
596
583 return 0; 597 return 0;
584 598
585err_input_free: 599err_input_free:
586 input_free_device(touch->input); 600 input_free_device(touch->input);
587err_mem_free: 601err_mem_free:
588 i2c_set_clientdata(client, NULL);
589 kfree(touch); 602 kfree(touch);
590 603
591 return ret; 604 return ret;
@@ -596,7 +609,7 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client)
596 struct synaptics_i2c *touch = i2c_get_clientdata(client); 609 struct synaptics_i2c *touch = i2c_get_clientdata(client);
597 610
598 if (!polling_req) 611 if (!polling_req)
599 free_irq(touch->client->irq, touch); 612 free_irq(client->irq, touch);
600 613
601 input_unregister_device(touch->input); 614 input_unregister_device(touch->input);
602 i2c_set_clientdata(client, NULL); 615 i2c_set_clientdata(client, NULL);
@@ -627,8 +640,8 @@ static int synaptics_i2c_resume(struct i2c_client *client)
627 if (ret) 640 if (ret)
628 return ret; 641 return ret;
629 642
630 schedule_delayed_work(&touch->dwork, 643 synaptics_i2c_reschedule_work(touch,
631 msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); 644 msecs_to_jiffies(NO_DATA_SLEEP_MSECS));
632 645
633 return 0; 646 return 0;
634} 647}
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 3fadb2accac0..0308a0faa94d 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -67,7 +67,7 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
67 return PSMOUSE_FULL_PACKET; 67 return PSMOUSE_FULL_PACKET;
68} 68}
69 69
70int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) 70int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties)
71{ 71{
72 struct input_dev *dev = psmouse->dev; 72 struct input_dev *dev = psmouse->dev;
73 unsigned char param[3]; 73 unsigned char param[3];
@@ -86,7 +86,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
86 86
87 if (set_properties) { 87 if (set_properties) {
88 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 88 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
89 set_bit(BTN_TOUCH, dev->keybit); 89 __set_bit(BTN_TOUCH, dev->keybit);
90 input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); 90 input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
91 input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); 91 input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
92 92
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h
index 8a0dd3574aef..2efe9ea29d0c 100644
--- a/drivers/input/mouse/touchkit_ps2.h
+++ b/drivers/input/mouse/touchkit_ps2.h
@@ -13,10 +13,10 @@
13#define _TOUCHKIT_PS2_H 13#define _TOUCHKIT_PS2_H
14 14
15#ifdef CONFIG_MOUSE_PS2_TOUCHKIT 15#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
16int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); 16int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties);
17#else 17#else
18static inline int touchkit_ps2_detect(struct psmouse *psmouse, 18static inline int touchkit_ps2_detect(struct psmouse *psmouse,
19 int set_properties) 19 bool set_properties)
20{ 20{
21 return -ENOSYS; 21 return -ENOSYS;
22} 22}
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index e68c814c4361..e354362f2971 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -282,7 +282,7 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
282 return 0; 282 return 0;
283} 283}
284 284
285int trackpoint_detect(struct psmouse *psmouse, int set_properties) 285int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
286{ 286{
287 struct trackpoint_data *priv; 287 struct trackpoint_data *priv;
288 struct ps2dev *ps2dev = &psmouse->ps2dev; 288 struct ps2dev *ps2dev = &psmouse->ps2dev;
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index c10a6e7d0101..e558a7096618 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -143,9 +143,9 @@ struct trackpoint_data
143}; 143};
144 144
145#ifdef CONFIG_MOUSE_PS2_TRACKPOINT 145#ifdef CONFIG_MOUSE_PS2_TRACKPOINT
146int trackpoint_detect(struct psmouse *psmouse, int set_properties); 146int trackpoint_detect(struct psmouse *psmouse, bool set_properties);
147#else 147#else
148inline int trackpoint_detect(struct psmouse *psmouse, int set_properties) 148inline int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
149{ 149{
150 return -ENOSYS; 150 return -ENOSYS;
151} 151}
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 404eedd5ffa2..70111443678e 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -384,11 +384,11 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
384 printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " 384 printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
385 "incremental streaming mode and 72 samples/sec\n", 385 "incremental streaming mode and 72 samples/sec\n",
386 mouse->name, mouse->phys); 386 mouse->name, mouse->phys);
387 mouse->serio->write (mouse->serio, 'S'); /* Standard format */ 387 serio_write (mouse->serio, 'S'); /* Standard format */
388 mdelay (50); 388 mdelay (50);
389 mouse->serio->write (mouse->serio, 'R'); /* Incremental */ 389 serio_write (mouse->serio, 'R'); /* Incremental */
390 mdelay (50); 390 mdelay (50);
391 mouse->serio->write (mouse->serio, 'L'); /* 72 samples/sec */ 391 serio_write (mouse->serio, 'L'); /* 72 samples/sec */
392} 392}
393 393
394static void 394static void
@@ -532,7 +532,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
532 * Request selftest. Standard packet format and differential 532 * Request selftest. Standard packet format and differential
533 * mode will be requested after the device ID'ed successfully. 533 * mode will be requested after the device ID'ed successfully.
534 */ 534 */
535 serio->write (serio, 'T'); /* Test */ 535 serio_write (serio, 'T'); /* Test */
536 536
537 err = input_register_device (input_dev); 537 err = input_register_device (input_dev);
538 if (err) 538 if (err)