aboutsummaryrefslogtreecommitdiff
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-09-23 03:49:27 +0400
committerAnton Vorontsov <avorontsov@ru.mvista.com>2009-09-23 03:49:27 +0400
commitf056878332a91ed984a116bad4e7d49aefff9e6e (patch)
tree572f4757c8e7811d45e0be0c2ae529c78fb63441 /drivers/input/mouse
parent3961f7c3cf247eee5df7fabadc7a40f2deeb98f3 (diff)
parent7fa07729e439a6184bd824746d06a49cca553f15 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/power/wm97xx_battery.c
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/gpio_mouse.c11
-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.c867
-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/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, 1219 insertions, 608 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 8a2c5b14c8d..3feeb3af8ab 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH
entries. For further information,
see <file:Documentation/input/elantech.txt>.
+config MOUSE_PS2_SENTELIC
+ bool "Sentelic Finger Sensing Pad PS/2 protocol extension"
+ depends on MOUSE_PS2
+ help
+ Say Y here if you have a laptop (such as MSI WIND Netbook)
+ with Sentelic Finger Sensing Pad touchpad.
+
+ If unsure, say N.
config MOUSE_PS2_TOUCHKIT
bool "eGalax TouchKit PS/2 protocol extension"
@@ -262,14 +270,6 @@ config MOUSE_VSXXXAA
described in the source file). This driver also works with the
digitizer (VSXXX-AB) DEC produced.
-config MOUSE_HIL
- tristate "HIL pointers (mice etc)."
- depends on GSC || HP300
- select HP_SDC
- select HIL_MLC
- help
- Say Y here to support HIL pointers.
-
config MOUSE_GPIO
tristate "GPIO mouse"
depends on GENERIC_GPIO
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 010f265ec15..570c84a4a65 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
-obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_INPORT) += inport.o
obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
@@ -28,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o
psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
+psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 5547e2429fb..f36110689aa 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
* subsequent commands. It looks like glidepad is behind stickpointer,
* I'd thought it would be other way around...
*/
-static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
+static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
@@ -367,16 +367,16 @@ static int alps_poll(struct psmouse *psmouse)
{
struct alps_data *priv = psmouse->private;
unsigned char buf[6];
- int poll_failed;
+ bool poll_failed;
if (priv->i->flags & ALPS_PASS)
- alps_passthrough_mode(psmouse, 1);
+ alps_passthrough_mode(psmouse, true);
poll_failed = ps2_command(&psmouse->ps2dev, buf,
PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
if (priv->i->flags & ALPS_PASS)
- alps_passthrough_mode(psmouse, 0);
+ alps_passthrough_mode(psmouse, false);
if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
return -1;
@@ -401,10 +401,12 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
if (!priv->i)
return -1;
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
+ if ((priv->i->flags & ALPS_PASS) &&
+ alps_passthrough_mode(psmouse, true)) {
return -1;
+ }
- if (alps_tap_mode(psmouse, 1)) {
+ if (alps_tap_mode(psmouse, true)) {
printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
return -1;
}
@@ -414,8 +416,10 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
return -1;
}
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+ if ((priv->i->flags & ALPS_PASS) &&
+ alps_passthrough_mode(psmouse, false)) {
return -1;
+ }
/* ALPS needs stream mode, otherwise it won't report any data */
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
@@ -519,7 +523,7 @@ init_fail:
return -1;
}
-int alps_detect(struct psmouse *psmouse, int set_properties)
+int alps_detect(struct psmouse *psmouse, bool set_properties)
{
int version;
const struct alps_model_info *model;
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 4bbddc99962..bc87936fee1 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -26,10 +26,10 @@ struct alps_data {
};
#ifdef CONFIG_MOUSE_PS2_ALPS
-int alps_detect(struct psmouse *psmouse, int set_properties);
+int alps_detect(struct psmouse *psmouse, bool set_properties);
int alps_init(struct psmouse *psmouse);
#else
-inline int alps_detect(struct psmouse *psmouse, int set_properties)
+inline int alps_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 2d8fc0bf692..0d1d33468b4 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)
const struct tp_finger *f;
struct input_dev *input = dev->input;
int raw_p, raw_w, raw_x, raw_y, raw_n;
- int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0;
+ int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
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)
/* set the integrated button if applicable */
if (c->tp_type == TYPE2)
ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
- }
- /* while tracking finger still valid, count all fingers */
- if (ptest > PRESSURE_LOW && origin) {
- abs_p = ptest;
- abs_w = int2bound(&c->w, raw_w);
- abs_x = int2bound(&c->x, raw_x - c->x.devmin);
- abs_y = int2bound(&c->y, c->y.devmax - raw_y);
- while (raw_n--) {
- ptest = int2bound(&c->p, raw2int(f->force_major));
- if (ptest > PRESSURE_LOW)
- nmax++;
- if (ptest > PRESSURE_HIGH)
- nmin++;
- f++;
+ /* while tracking finger still valid, count all fingers */
+ if (ptest > PRESSURE_LOW && origin) {
+ abs_p = ptest;
+ abs_w = int2bound(&c->w, raw_w);
+ abs_x = int2bound(&c->x, raw_x - c->x.devmin);
+ abs_y = int2bound(&c->y, c->y.devmax - raw_y);
+ while (raw_n--) {
+ ptest = int2bound(&c->p,
+ raw2int(f->force_major));
+ if (ptest > PRESSURE_LOW)
+ nmax++;
+ if (ptest > PRESSURE_HIGH)
+ nmin++;
+ f++;
+ }
}
}
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 4bc78892ba9..fda35e615ab 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -553,7 +553,7 @@ static struct attribute_group elantech_attr_group = {
/*
* Use magic knock to detect Elantech touchpad
*/
-int elantech_detect(struct psmouse *psmouse, int set_properties)
+int elantech_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[3];
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index ed848cc8081..feac5f7af96 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -109,10 +109,10 @@ struct elantech_data {
};
#ifdef CONFIG_MOUSE_PS2_ELANTECH
-int elantech_detect(struct psmouse *psmouse, int set_properties);
+int elantech_detect(struct psmouse *psmouse, bool set_properties);
int elantech_init(struct psmouse *psmouse);
#else
-static inline int elantech_detect(struct psmouse *psmouse, int set_properties)
+static inline int elantech_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 5e5eb88d8d1..7b6ce178f1b 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -46,7 +46,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev)
input_sync(input);
}
-static int __init gpio_mouse_probe(struct platform_device *pdev)
+static int __devinit gpio_mouse_probe(struct platform_device *pdev)
{
struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
struct input_polled_dev *input_poll;
@@ -170,10 +170,8 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev)
return 0;
}
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:gpio_mouse");
-
static struct platform_driver gpio_mouse_device_driver = {
+ .probe = gpio_mouse_probe,
.remove = __devexit_p(gpio_mouse_remove),
.driver = {
.name = "gpio_mouse",
@@ -183,8 +181,7 @@ static struct platform_driver gpio_mouse_device_driver = {
static int __init gpio_mouse_init(void)
{
- return platform_driver_probe(&gpio_mouse_device_driver,
- gpio_mouse_probe);
+ return platform_driver_register(&gpio_mouse_device_driver);
}
module_init(gpio_mouse_init);
@@ -197,3 +194,5 @@ module_exit(gpio_mouse_exit);
MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
MODULE_DESCRIPTION("GPIO mouse driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */
+
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index a1ad2f1a7bb..de1e553028b 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,
}
__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
- hgpk_show_powered, hgpk_set_powered, 0);
+ hgpk_show_powered, hgpk_set_powered, false);
+
+static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ return -EINVAL;
+}
+
+static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ struct hgpk_data *priv = psmouse->private;
+ unsigned long value;
+ int err;
+
+ err = strict_strtoul(buf, 10, &value);
+ if (err || value != 1)
+ return -EINVAL;
+
+ /*
+ * We queue work instead of doing recalibration right here
+ * to avoid adding locking to to hgpk_force_recalibrate()
+ * since workqueue provides serialization.
+ */
+ psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
+ return count;
+}
+
+__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
+ hgpk_trigger_recal_show, hgpk_trigger_recal, false);
static void hgpk_disconnect(struct psmouse *psmouse)
{
@@ -375,6 +404,11 @@ static void hgpk_disconnect(struct psmouse *psmouse)
device_remove_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
+
+ if (psmouse->model >= HGPK_MODEL_C)
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_recalibrate.dattr);
+
psmouse_reset(psmouse);
kfree(priv);
}
@@ -423,10 +457,25 @@ static int hgpk_register(struct psmouse *psmouse)
err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr);
- if (err)
- hgpk_err(psmouse, "Failed to create sysfs attribute\n");
+ if (err) {
+ hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");
+ return err;
+ }
- return err;
+ /* C-series touchpads added the recalibrate command */
+ if (psmouse->model >= HGPK_MODEL_C) {
+ err = device_create_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_recalibrate.dattr);
+ if (err) {
+ hgpk_err(psmouse,
+ "Failed creating 'recalibrate' sysfs node\n");
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_powered.dattr);
+ return err;
+ }
+ }
+
+ return 0;
}
int hgpk_init(struct psmouse *psmouse)
@@ -440,7 +489,7 @@ int hgpk_init(struct psmouse *psmouse)
psmouse->private = priv;
priv->psmouse = psmouse;
- priv->powered = 1;
+ priv->powered = true;
INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
err = psmouse_reset(psmouse);
@@ -483,7 +532,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
return param[2];
}
-int hgpk_detect(struct psmouse *psmouse, int set_properties)
+int hgpk_detect(struct psmouse *psmouse, bool set_properties)
{
int version;
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
index a4b2a96f5f5..d61cfd3ee9c 100644
--- a/drivers/input/mouse/hgpk.h
+++ b/drivers/input/mouse/hgpk.h
@@ -15,7 +15,7 @@ enum hgpk_model_t {
struct hgpk_data {
struct psmouse *psmouse;
- int powered;
+ bool powered;
int count, x_tally, y_tally; /* hardware workaround stuff */
unsigned long recalib_window;
struct delayed_work recalib_wq;
@@ -33,10 +33,10 @@ struct hgpk_data {
dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#ifdef CONFIG_MOUSE_PS2_OLPC
-int hgpk_detect(struct psmouse *psmouse, int set_properties);
+int hgpk_detect(struct psmouse *psmouse, bool set_properties);
int hgpk_init(struct psmouse *psmouse);
#else
-static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
+static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENODEV;
}
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
deleted file mode 100644
index 3263ce083bf..00000000000
--- a/drivers/input/mouse/hil_ptr.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Generic linux-input device driver for axis-bearing devices
- *
- * Copyright (c) 2001 Brian S. Julin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL").
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *
- * References:
- * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
- *
- */
-
-#include <linux/hil.h>
-#include <linux/input.h>
-#include <linux/serio.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci_ids.h>
-
-#define PREFIX "HIL PTR: "
-#define HIL_GENERIC_NAME "HIL pointer device"
-
-MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
-MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("serio:ty03pr25id0Fex*");
-
-#define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */
-#undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */
-
-
-#define HIL_PTR_MAX_LENGTH 16
-
-struct hil_ptr {
- struct input_dev *dev;
- struct serio *serio;
-
- /* Input buffer and index for packets from HIL bus. */
- hil_packet data[HIL_PTR_MAX_LENGTH];
- int idx4; /* four counts per packet */
-
- /* Raw device info records from HIL bus, see hil.h for fields. */
- char idd[HIL_PTR_MAX_LENGTH]; /* DID byte and IDD record */
- char rsc[HIL_PTR_MAX_LENGTH]; /* RSC record */
- char exd[HIL_PTR_MAX_LENGTH]; /* EXD record */
- char rnm[HIL_PTR_MAX_LENGTH + 1]; /* RNM record + NULL term. */
-
- /* Extra device details not contained in struct input_dev. */
- unsigned int nbtn, naxes;
- unsigned int btnmap[7];
-
- /* Something to sleep around with. */
- struct semaphore sem;
-};
-
-/* Process a complete packet after transfer from the HIL */
-static void hil_ptr_process_record(struct hil_ptr *ptr)
-{
- struct input_dev *dev = ptr->dev;
- hil_packet *data = ptr->data;
- hil_packet p;
- int idx, i, cnt, laxis;
- int ax16, absdev;
-
- idx = ptr->idx4/4;
- p = data[idx - 1];
-
- if ((p & ~HIL_CMDCT_POL) ==
- (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
- goto report;
- if ((p & ~HIL_CMDCT_RPL) ==
- (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
- goto report;
-
- /* Not a poll response. See if we are loading config records. */
- switch (p & HIL_PKT_DATA_MASK) {
- case HIL_CMD_IDD:
- for (i = 0; i < idx; i++)
- ptr->idd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
- for (; i < HIL_PTR_MAX_LENGTH; i++)
- ptr->idd[i] = 0;
- break;
-
- case HIL_CMD_RSC:
- for (i = 0; i < idx; i++)
- ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
- for (; i < HIL_PTR_MAX_LENGTH; i++)
- ptr->rsc[i] = 0;
- break;
-
- case HIL_CMD_EXD:
- for (i = 0; i < idx; i++)
- ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
- for (; i < HIL_PTR_MAX_LENGTH; i++)
- ptr->exd[i] = 0;
- break;
-
- case HIL_CMD_RNM:
- for (i = 0; i < idx; i++)
- ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
- for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
- ptr->rnm[i] = 0;
- break;
-
- default:
- /* These occur when device isn't present */
- if (p == (HIL_ERR_INT | HIL_PKT_CMD))
- break;
- /* Anything else we'd like to know about. */
- printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
- break;
- }
- goto out;
-
- report:
- if ((p & HIL_CMDCT_POL) != idx - 1) {
- printk(KERN_WARNING PREFIX
- "Malformed poll packet %x (idx = %i)\n", p, idx);
- goto out;
- }
-
- i = (ptr->data[0] & HIL_POL_AXIS_ALT) ? 3 : 0;
- laxis = ptr->data[0] & HIL_POL_NUM_AXES_MASK;
- laxis += i;
-
- ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
- absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
-
- for (cnt = 1; i < laxis; i++) {
- unsigned int lo,hi,val;
- lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
- hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
- if (absdev) {
- val = lo + (hi<<8);
-#ifdef TABLET_AUTOADJUST
- if (val < dev->absmin[ABS_X + i])
- dev->absmin[ABS_X + i] = val;
- if (val > dev->absmax[ABS_X + i])
- dev->absmax[ABS_X + i] = val;
-#endif
- if (i%3) val = dev->absmax[ABS_X + i] - val;
- input_report_abs(dev, ABS_X + i, val);
- } else {
- val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
- if (i%3)
- val *= -1;
- input_report_rel(dev, REL_X + i, val);
- }
- }
-
- while (cnt < idx - 1) {
- unsigned int btn;
- int up;
- btn = ptr->data[cnt++];
- up = btn & 1;
- btn &= 0xfe;
- if (btn == 0x8e)
- continue; /* TODO: proximity == touch? */
- else
- if ((btn > 0x8c) || (btn < 0x80))
- continue;
- btn = (btn - 0x80) >> 1;
- btn = ptr->btnmap[btn];
- input_report_key(dev, btn, !up);
- }
- input_sync(dev);
- out:
- ptr->idx4 = 0;
- up(&ptr->sem);
-}
-
-static void hil_ptr_process_err(struct hil_ptr *ptr)
-{
- printk(KERN_WARNING PREFIX "errored HIL packet\n");
- ptr->idx4 = 0;
- up(&ptr->sem);
-}
-
-static irqreturn_t hil_ptr_interrupt(struct serio *serio,
- unsigned char data, unsigned int flags)
-{
- struct hil_ptr *ptr;
- hil_packet packet;
- int idx;
-
- ptr = serio_get_drvdata(serio);
- BUG_ON(ptr == NULL);
-
- if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
- hil_ptr_process_err(ptr);
- return IRQ_HANDLED;
- }
- idx = ptr->idx4/4;
- if (!(ptr->idx4 % 4))
- ptr->data[idx] = 0;
- packet = ptr->data[idx];
- packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
- ptr->data[idx] = packet;
-
- /* Records of N 4-byte hil_packets must terminate with a command. */
- if ((++(ptr->idx4)) % 4)
- return IRQ_HANDLED;
- if ((packet & 0xffff0000) != HIL_ERR_INT) {
- hil_ptr_process_err(ptr);
- return IRQ_HANDLED;
- }
- if (packet & HIL_PKT_CMD)
- hil_ptr_process_record(ptr);
-
- return IRQ_HANDLED;
-}
-
-static void hil_ptr_disconnect(struct serio *serio)
-{
- struct hil_ptr *ptr;
-
- ptr = serio_get_drvdata(serio);
- BUG_ON(ptr == NULL);
-
- serio_close(serio);
- input_unregister_device(ptr->dev);
- kfree(ptr);
-}
-
-static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
-{
- struct hil_ptr *ptr;
- const char *txt;
- unsigned int i, naxsets, btntype;
- uint8_t did, *idd;
- int error;
-
- ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
- if (!ptr)
- return -ENOMEM;
-
- ptr->dev = input_allocate_device();
- if (!ptr->dev) {
- error = -ENOMEM;
- goto bail0;
- }
-
- error = serio_open(serio, driver);
- if (error)
- goto bail1;
-
- serio_set_drvdata(serio, ptr);
- ptr->serio = serio;
-
- init_MUTEX_LOCKED(&ptr->sem);
-
- /* Get device info. MLC driver supplies devid/status/etc. */
- serio->write(serio, 0);
- serio->write(serio, 0);
- serio->write(serio, HIL_PKT_CMD >> 8);
- serio->write(serio, HIL_CMD_IDD);
- down(&ptr->sem);
-
- serio->write(serio, 0);
- serio->write(serio, 0);
- serio->write(serio, HIL_PKT_CMD >> 8);
- serio->write(serio, HIL_CMD_RSC);
- down(&ptr->sem);
-
- serio->write(serio, 0);
- serio->write(serio, 0);
- serio->write(serio, HIL_PKT_CMD >> 8);
- serio->write(serio, HIL_CMD_RNM);
- down(&ptr->sem);
-
- serio->write(serio, 0);
- serio->write(serio, 0);
- serio->write(serio, HIL_PKT_CMD >> 8);
- serio->write(serio, HIL_CMD_EXD);
- down(&ptr->sem);
-
- up(&ptr->sem);
-
- did = ptr->idd[0];
- idd = ptr->idd + 1;
- txt = "unknown";
-
- if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
- ptr->dev->evbit[0] = BIT_MASK(EV_REL);
- txt = "relative";
- }
-
- if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
- ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
- txt = "absolute";
- }
-
- if (!ptr->dev->evbit[0]) {
- error = -ENODEV;
- goto bail2;
- }
-
- ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
- if (ptr->nbtn)
- ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);
-
- naxsets = HIL_IDD_NUM_AXSETS(*idd);
- ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
-
- printk(KERN_INFO PREFIX "HIL pointer device found (did: 0x%02x, axis: %s)\n",
- did, txt);
- printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
- ptr->nbtn, naxsets, ptr->naxes);
-
- btntype = BTN_MISC;
- if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
-#ifdef TABLET_SIMULATES_MOUSE
- btntype = BTN_TOUCH;
-#else
- btntype = BTN_DIGI;
-#endif
- if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
- btntype = BTN_TOUCH;
-
- if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
- btntype = BTN_MOUSE;
-
- for (i = 0; i < ptr->nbtn; i++) {
- set_bit(btntype | i, ptr->dev->keybit);
- ptr->btnmap[i] = btntype | i;
- }
-
- if (btntype == BTN_MOUSE) {
- /* Swap buttons 2 and 3 */
- ptr->btnmap[1] = BTN_MIDDLE;
- ptr->btnmap[2] = BTN_RIGHT;
- }
-
- if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
- for (i = 0; i < ptr->naxes; i++)
- set_bit(REL_X + i, ptr->dev->relbit);
- for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
- set_bit(REL_X + i, ptr->dev->relbit);
- } else {
- for (i = 0; i < ptr->naxes; i++) {
- set_bit(ABS_X + i, ptr->dev->absbit);
- ptr->dev->absmin[ABS_X + i] = 0;
- ptr->dev->absmax[ABS_X + i] =
- HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
- }
- for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
- set_bit(ABS_X + i, ptr->dev->absbit);
- ptr->dev->absmin[ABS_X + i] = 0;
- ptr->dev->absmax[ABS_X + i] =
- HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
- }
-#ifdef TABLET_AUTOADJUST
- for (i = 0; i < ABS_MAX; i++) {
- int diff = ptr->dev->absmax[ABS_X + i] / 10;
- ptr->dev->absmin[ABS_X + i] += diff;
- ptr->dev->absmax[ABS_X + i] -= diff;
- }
-#endif
- }
-
- ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
-
- ptr->dev->id.bustype = BUS_HIL;
- ptr->dev->id.vendor = PCI_VENDOR_ID_HP;
- ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */
- ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */
- ptr->dev->dev.parent = &serio->dev;
-
- error = input_register_device(ptr->dev);
- if (error) {
- printk(KERN_INFO PREFIX "Unable to register input device\n");
- goto bail2;
- }
-
- printk(KERN_INFO "input: %s (%s), ID: %d\n",
- ptr->dev->name,
- (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
- did);
-
- return 0;
-
- bail2:
- serio_close(serio);
- bail1:
- input_free_device(ptr->dev);
- bail0:
- kfree(ptr);
- serio_set_drvdata(serio, NULL);
- return error;
-}
-
-static struct serio_device_id hil_ptr_ids[] = {
- {
- .type = SERIO_HIL_MLC,
- .proto = SERIO_HIL,
- .id = SERIO_ANY,
- .extra = SERIO_ANY,
- },
- { 0 }
-};
-
-static struct serio_driver hil_ptr_serio_driver = {
- .driver = {
- .name = "hil_ptr",
- },
- .description = "HP HIL mouse/tablet driver",
- .id_table = hil_ptr_ids,
- .connect = hil_ptr_connect,
- .disconnect = hil_ptr_disconnect,
- .interrupt = hil_ptr_interrupt
-};
-
-static int __init hil_ptr_init(void)
-{
- return serio_register_driver(&hil_ptr_serio_driver);
-}
-
-static void __exit hil_ptr_exit(void)
-{
- serio_unregister_driver(&hil_ptr_serio_driver);
-}
-
-module_init(hil_ptr_init);
-module_exit(hil_ptr_exit);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index dcd4236af1e..5e630869440 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)
return 0;
}
-static unsigned char lifebook_use_6byte_proto;
+static bool lifebook_use_6byte_proto;
static int lifebook_set_6byte_proto(const struct dmi_system_id *d)
{
- lifebook_use_6byte_proto = 1;
+ lifebook_use_6byte_proto = true;
return 0;
}
@@ -125,7 +125,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
struct input_dev *dev1 = psmouse->dev;
struct input_dev *dev2 = priv ? priv->dev2 : NULL;
unsigned char *packet = psmouse->packet;
- int relative_packet = packet[0] & 0x08;
+ bool relative_packet = packet[0] & 0x08;
if (relative_packet || !lifebook_use_6byte_proto) {
if (psmouse->pktcnt != 3)
@@ -242,7 +242,7 @@ static void lifebook_disconnect(struct psmouse *psmouse)
psmouse->private = NULL;
}
-int lifebook_detect(struct psmouse *psmouse, int set_properties)
+int lifebook_detect(struct psmouse *psmouse, bool set_properties)
{
if (!dmi_check_system(lifebook_dmi_table))
return -1;
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
index c1647cf036c..407cb226bc0 100644
--- a/drivers/input/mouse/lifebook.h
+++ b/drivers/input/mouse/lifebook.h
@@ -12,10 +12,10 @@
#define _LIFEBOOK_H
#ifdef CONFIG_MOUSE_PS2_LIFEBOOK
-int lifebook_detect(struct psmouse *psmouse, int set_properties);
+int lifebook_detect(struct psmouse *psmouse, bool set_properties);
int lifebook_init(struct psmouse *psmouse);
#else
-inline int lifebook_detect(struct psmouse *psmouse, int set_properties)
+inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 390f1dbb98a..de745d75116 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
* 0 - disabled
*/
-static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll)
+static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
- if (smartscroll > 1)
- smartscroll = 1;
-
ps2pp_cmd(psmouse, param, 0x32);
param[0] = 0;
@@ -149,12 +146,14 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
}
-static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf)
+static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse,
+ void *data, char *buf)
{
- return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0);
+ return sprintf(buf, "%d\n", psmouse->smartscroll);
}
-static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
+static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
{
unsigned long value;
@@ -261,29 +260,29 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
static void ps2pp_set_model_properties(struct psmouse *psmouse,
const struct ps2pp_info *model_info,
- int using_ps2pp)
+ bool using_ps2pp)
{
struct input_dev *input_dev = psmouse->dev;
if (model_info->features & PS2PP_SIDE_BTN)
- set_bit(BTN_SIDE, input_dev->keybit);
+ __set_bit(BTN_SIDE, input_dev->keybit);
if (model_info->features & PS2PP_EXTRA_BTN)
- set_bit(BTN_EXTRA, input_dev->keybit);
+ __set_bit(BTN_EXTRA, input_dev->keybit);
if (model_info->features & PS2PP_TASK_BTN)
- set_bit(BTN_TASK, input_dev->keybit);
+ __set_bit(BTN_TASK, input_dev->keybit);
if (model_info->features & PS2PP_NAV_BTN) {
- set_bit(BTN_FORWARD, input_dev->keybit);
- set_bit(BTN_BACK, input_dev->keybit);
+ __set_bit(BTN_FORWARD, input_dev->keybit);
+ __set_bit(BTN_BACK, input_dev->keybit);
}
if (model_info->features & PS2PP_WHEEL)
- set_bit(REL_WHEEL, input_dev->relbit);
+ __set_bit(REL_WHEEL, input_dev->relbit);
if (model_info->features & PS2PP_HWHEEL)
- set_bit(REL_HWHEEL, input_dev->relbit);
+ __set_bit(REL_HWHEEL, input_dev->relbit);
switch (model_info->kind) {
case PS2PP_KIND_WHEEL:
@@ -321,13 +320,13 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
* that support it.
*/
-int ps2pp_init(struct psmouse *psmouse, int set_properties)
+int ps2pp_init(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
unsigned char model, buttons;
const struct ps2pp_info *model_info;
- int use_ps2pp = 0;
+ bool use_ps2pp = false;
int error;
param[0] = 0;
@@ -364,7 +363,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
param[0] = 0;
if (!ps2_command(ps2dev, param, 0x13d1) &&
param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
- use_ps2pp = 1;
+ use_ps2pp = true;
}
} else {
@@ -376,8 +375,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
if ((param[0] & 0x78) == 0x48 &&
(param[1] & 0xf3) == 0xc2 &&
(param[2] & 0x03) == ((param[1] >> 2) & 3)) {
- ps2pp_set_smartscroll(psmouse, psmouse->smartscroll);
- use_ps2pp = 1;
+ ps2pp_set_smartscroll(psmouse, false);
+ use_ps2pp = true;
}
}
}
@@ -406,7 +405,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
}
if (buttons < 3)
- clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ __clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
if (model_info)
ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
index 6e5712525fd..0c186f0282d 100644
--- a/drivers/input/mouse/logips2pp.h
+++ b/drivers/input/mouse/logips2pp.h
@@ -12,9 +12,9 @@
#define _LOGIPS2PP_H
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
-int ps2pp_init(struct psmouse *psmouse, int set_properties);
+int ps2pp_init(struct psmouse *psmouse, bool set_properties);
#else
-inline int ps2pp_init(struct psmouse *psmouse, int set_properties)
+inline int ps2pp_init(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index b407b355dce..690aed90543 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -30,6 +30,7 @@
#include "trackpoint.h"
#include "touchkit_ps2.h"
#include "elantech.h"
+#include "sentelic.h"
#define DRIVER_DESC "PS/2 mouse driver"
@@ -108,10 +109,10 @@ static struct workqueue_struct *kpsmoused_wq;
struct psmouse_protocol {
enum psmouse_type type;
+ bool maxproto;
const char *name;
const char *alias;
- int maxproto;
- int (*detect)(struct psmouse *, int);
+ int (*detect)(struct psmouse *, bool);
int (*init)(struct psmouse *);
};
@@ -216,7 +217,7 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
{
psmouse->state = new_state;
- psmouse->pktcnt = psmouse->out_of_sync = 0;
+ psmouse->pktcnt = psmouse->out_of_sync_cnt = 0;
psmouse->ps2dev.flags = 0;
psmouse->last = jiffies;
}
@@ -249,7 +250,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
if (psmouse->state == PSMOUSE_ACTIVATED) {
printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
psmouse->name, psmouse->phys, psmouse->pktcnt);
- if (++psmouse->out_of_sync == psmouse->resetafter) {
+ if (++psmouse->out_of_sync_cnt == psmouse->resetafter) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
serio_reconnect(psmouse->ps2dev.serio);
@@ -261,8 +262,8 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
case PSMOUSE_FULL_PACKET:
psmouse->pktcnt = 0;
- if (psmouse->out_of_sync) {
- psmouse->out_of_sync = 0;
+ if (psmouse->out_of_sync_cnt) {
+ psmouse->out_of_sync_cnt = 0;
printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
psmouse->name, psmouse->phys);
}
@@ -408,7 +409,7 @@ int psmouse_reset(struct psmouse *psmouse)
/*
* Genius NetMouse magic init.
*/
-static int genius_detect(struct psmouse *psmouse, int set_properties)
+static int genius_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
@@ -424,9 +425,9 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_EXTRA, psmouse->dev->keybit);
- set_bit(BTN_SIDE, psmouse->dev->keybit);
- set_bit(REL_WHEEL, psmouse->dev->relbit);
+ __set_bit(BTN_EXTRA, psmouse->dev->keybit);
+ __set_bit(BTN_SIDE, psmouse->dev->keybit);
+ __set_bit(REL_WHEEL, psmouse->dev->relbit);
psmouse->vendor = "Genius";
psmouse->name = "Mouse";
@@ -439,7 +440,7 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
/*
* IntelliMouse magic init.
*/
-static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
+static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[2];
@@ -456,8 +457,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_MIDDLE, psmouse->dev->keybit);
- set_bit(REL_WHEEL, psmouse->dev->relbit);
+ __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ __set_bit(REL_WHEEL, psmouse->dev->relbit);
if (!psmouse->vendor) psmouse->vendor = "Generic";
if (!psmouse->name) psmouse->name = "Wheel Mouse";
@@ -470,7 +471,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
/*
* Try IntelliMouse/Explorer magic init.
*/
-static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
+static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[2];
@@ -497,11 +498,11 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
if (set_properties) {
- set_bit(BTN_MIDDLE, psmouse->dev->keybit);
- set_bit(REL_WHEEL, psmouse->dev->relbit);
- set_bit(REL_HWHEEL, psmouse->dev->relbit);
- set_bit(BTN_SIDE, psmouse->dev->keybit);
- set_bit(BTN_EXTRA, psmouse->dev->keybit);
+ __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ __set_bit(REL_WHEEL, psmouse->dev->relbit);
+ __set_bit(REL_HWHEEL, psmouse->dev->relbit);
+ __set_bit(BTN_SIDE, psmouse->dev->keybit);
+ __set_bit(BTN_EXTRA, psmouse->dev->keybit);
if (!psmouse->vendor) psmouse->vendor = "Generic";
if (!psmouse->name) psmouse->name = "Explorer Mouse";
@@ -514,7 +515,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
/*
* Kensington ThinkingMouse / ExpertMouse magic init.
*/
-static int thinking_detect(struct psmouse *psmouse, int set_properties)
+static int thinking_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[2];
@@ -535,7 +536,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
return -1;
if (set_properties) {
- set_bit(BTN_EXTRA, psmouse->dev->keybit);
+ __set_bit(BTN_EXTRA, psmouse->dev->keybit);
psmouse->vendor = "Kensington";
psmouse->name = "ThinkingMouse";
@@ -547,7 +548,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
/*
* Bare PS/2 protocol "detection". Always succeeds.
*/
-static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
+static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
{
if (set_properties) {
if (!psmouse->vendor) psmouse->vendor = "Generic";
@@ -561,12 +562,12 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
* Cortron PS/2 protocol detection. There's no special way to detect it, so it
* must be forced by sysfs protocol writing.
*/
-static int cortron_detect(struct psmouse *psmouse, int set_properties)
+static int cortron_detect(struct psmouse *psmouse, bool set_properties)
{
if (set_properties) {
psmouse->vendor = "Cortron";
psmouse->name = "PS/2 Trackball";
- set_bit(BTN_SIDE, psmouse->dev->keybit);
+ __set_bit(BTN_SIDE, psmouse->dev->keybit);
}
return 0;
@@ -578,9 +579,9 @@ static int cortron_detect(struct psmouse *psmouse, int set_properties)
*/
static int psmouse_extensions(struct psmouse *psmouse,
- unsigned int max_proto, int set_properties)
+ unsigned int max_proto, bool set_properties)
{
- int synaptics_hardware = 0;
+ bool synaptics_hardware = true;
/*
* We always check for lifebook because it does not disturb mouse
@@ -607,7 +608,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
* can reset it properly after probing for intellimouse.
*/
if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
- synaptics_hardware = 1;
+ synaptics_hardware = true;
if (max_proto > PSMOUSE_IMEX) {
if (!set_properties || synaptics_init(psmouse) == 0)
@@ -666,6 +667,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
max_proto = PSMOUSE_IMEX;
}
+/*
+ * Try Finger Sensing Pad
+ */
+ if (max_proto > PSMOUSE_IMEX) {
+ if (fsp_detect(psmouse, set_properties) == 0) {
+ if (!set_properties || fsp_init(psmouse) == 0)
+ return PSMOUSE_FSP;
+/*
+ * Init failed, try basic relative protocols
+ */
+ max_proto = PSMOUSE_IMEX;
+ }
+ }
+
if (max_proto > PSMOUSE_IMEX) {
if (genius_detect(psmouse, set_properties) == 0)
return PSMOUSE_GENPS;
@@ -718,7 +733,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.type = PSMOUSE_PS2,
.name = "PS/2",
.alias = "bare",
- .maxproto = 1,
+ .maxproto = true,
.detect = ps2bare_detect,
},
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
@@ -745,14 +760,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.type = PSMOUSE_IMPS,
.name = "ImPS/2",
.alias = "imps",
- .maxproto = 1,
+ .maxproto = true,
.detect = intellimouse_detect,
},
{
.type = PSMOUSE_IMEX,
.name = "ImExPS/2",
.alias = "exps",
- .maxproto = 1,
+ .maxproto = true,
.detect = im_explorer_detect,
},
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
@@ -813,7 +828,16 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.detect = elantech_detect,
.init = elantech_init,
},
- #endif
+#endif
+#ifdef CONFIG_MOUSE_PS2_SENTELIC
+ {
+ .type = PSMOUSE_FSP,
+ .name = "FSPPS/2",
+ .alias = "fsp",
+ .detect = fsp_detect,
+ .init = fsp_init,
+ },
+#endif
{
.type = PSMOUSE_CORTRON,
.name = "CortronPS/2",
@@ -824,7 +848,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.type = PSMOUSE_AUTO,
.name = "auto",
.alias = "any",
- .maxproto = 1,
+ .maxproto = true,
},
};
@@ -990,7 +1014,7 @@ static void psmouse_resync(struct work_struct *work)
container_of(work, struct psmouse, resync_work.work);
struct serio *serio = psmouse->ps2dev.serio;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
- int failed = 0, enabled = 0;
+ bool failed = false, enabled = false;
int i;
mutex_lock(&psmouse_mutex);
@@ -1017,9 +1041,9 @@ static void psmouse_resync(struct work_struct *work)
if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {
if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)
- failed = 1;
+ failed = true;
} else
- psmouse->acks_disable_command = 1;
+ psmouse->acks_disable_command = true;
/*
* 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)
*/
if (!failed) {
if (psmouse->poll(psmouse))
- failed = 1;
+ failed = true;
else {
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
for (i = 0; i < psmouse->pktsize; i++) {
@@ -1040,7 +1064,7 @@ static void psmouse_resync(struct work_struct *work)
break;
}
if (rc != PSMOUSE_FULL_PACKET)
- failed = 1;
+ failed = true;
psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
}
}
@@ -1051,7 +1075,7 @@ static void psmouse_resync(struct work_struct *work)
*/
for (i = 0; i < 5; i++) {
if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
- enabled = 1;
+ enabled = true;
break;
}
msleep(200);
@@ -1060,7 +1084,7 @@ static void psmouse_resync(struct work_struct *work)
if (!enabled) {
printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",
psmouse->ps2dev.serio->phys);
- failed = 1;
+ failed = true;
}
if (failed) {
@@ -1187,7 +1211,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
psmouse->type = proto->type;
}
else
- psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
+ psmouse->type = psmouse_extensions(psmouse,
+ psmouse_max_proto, true);
/*
* 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)
if (psmouse->reconnect(psmouse))
goto out;
} else if (psmouse_probe(psmouse) < 0 ||
- psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
+ psmouse->type != psmouse_extensions(psmouse,
+ psmouse_max_proto, false)) {
goto out;
+ }
/* ok, the device type (and capabilities) match the old one,
* we can continue using it, complete intialization
@@ -1528,7 +1555,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
while (serio->child) {
if (++retry > 3) {
- printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");
+ printk(KERN_WARNING
+ "psmouse: failed to destroy child port, "
+ "protocol change aborted.\n");
input_free_device(new_dev);
return -EIO;
}
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 54ed267894b..e053bdd137f 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -47,10 +47,10 @@ struct psmouse {
unsigned char pktcnt;
unsigned char pktsize;
unsigned char type;
- unsigned char acks_disable_command;
+ bool acks_disable_command;
unsigned int model;
unsigned long last;
- unsigned long out_of_sync;
+ unsigned long out_of_sync_cnt;
unsigned long num_resyncs;
enum psmouse_state state;
char devname[64];
@@ -60,7 +60,7 @@ struct psmouse {
unsigned int resolution;
unsigned int resetafter;
unsigned int resync_time;
- unsigned int smartscroll; /* Logitech only */
+ bool smartscroll; /* Logitech only */
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
@@ -91,6 +91,7 @@ enum psmouse_type {
PSMOUSE_CORTRON,
PSMOUSE_HGPK,
PSMOUSE_ELANTECH,
+ PSMOUSE_FSP,
PSMOUSE_AUTO /* This one should always be last */
};
@@ -107,7 +108,7 @@ struct psmouse_attribute {
ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
ssize_t (*set)(struct psmouse *psmouse, void *data,
const char *buf, size_t count);
- int protect;
+ bool protect;
};
#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
@@ -116,9 +117,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
-#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
-static ssize_t _show(struct psmouse *, void *data, char *); \
-static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
+#define __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect) \
static struct psmouse_attribute psmouse_attr_##_name = { \
.dattr = { \
.attr = { \
@@ -134,7 +133,20 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
.protect = _protect, \
}
-#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
- __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
+#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
+ static ssize_t _show(struct psmouse *, void *, char *); \
+ static ssize_t _set(struct psmouse *, void *, const char *, size_t); \
+ __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect)
+
+#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
+ __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, true)
+
+#define PSMOUSE_DEFINE_RO_ATTR(_name, _mode, _data, _show) \
+ static ssize_t _show(struct psmouse *, void *, char *); \
+ __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, NULL, true)
+
+#define PSMOUSE_DEFINE_WO_ATTR(_name, _mode, _data, _set) \
+ static ssize_t _set(struct psmouse *, void *, const char *, size_t); \
+ __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true)
#endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
new file mode 100644
index 00000000000..84e2fc04d11
--- /dev/null
+++ b/drivers/input/mouse/sentelic.c
@@ -0,0 +1,867 @@
+/*-
+ * Finger Sensing Pad PS/2 mouse driver.
+ *
+ * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
+ * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/input.h>
+#include <linux/ctype.h>
+#include <linux/libps2.h>
+#include <linux/serio.h>
+#include <linux/jiffies.h>
+
+#include "psmouse.h"
+#include "sentelic.h"
+
+/*
+ * Timeout for FSP PS/2 command only (in milliseconds).
+ */
+#define FSP_CMD_TIMEOUT 200
+#define FSP_CMD_TIMEOUT2 30
+
+/** Driver version. */
+static const char fsp_drv_ver[] = "1.0.0-K";
+
+/*
+ * Make sure that the value being sent to FSP will not conflict with
+ * possible sample rate values.
+ */
+static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
+{
+ switch (reg_val) {
+ case 10: case 20: case 40: case 60: case 80: case 100: case 200:
+ /*
+ * The requested value being sent to FSP matched to possible
+ * sample rates, swap the given value such that the hardware
+ * wouldn't get confused.
+ */
+ return (reg_val >> 4) | (reg_val << 4);
+ default:
+ return reg_val; /* swap isn't necessary */
+ }
+}
+
+/*
+ * Make sure that the value being sent to FSP will not conflict with certain
+ * commands.
+ */
+static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
+{
+ switch (reg_val) {
+ case 0xe9: case 0xee: case 0xf2: case 0xff:
+ /*
+ * The requested value being sent to FSP matched to certain
+ * commands, inverse the given value such that the hardware
+ * wouldn't get confused.
+ */
+ return ~reg_val;
+ default:
+ return reg_val; /* inversion isn't necessary */
+ }
+}
+
+static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char param[3];
+ unsigned char addr;
+ int rc = -1;
+
+ /*
+ * We need to shut off the device and switch it into command
+ * mode so we don't confuse our protocol handler. We don't need
+ * to do that for writes because sysfs set helper does this for
+ * us.
+ */
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+ mutex_lock(&ps2dev->cmd_mutex);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ goto out;
+
+ /* should return 0xfe(request for resending) */
+ ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
+ /* should return 0xfc(failed) */
+ ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ goto out;
+
+ if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
+ ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
+ } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
+ /* swapping is required */
+ ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
+ /* expect 0xfe */
+ } else {
+ /* swapping isn't necessary */
+ ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
+ /* expect 0xfe */
+ }
+ /* should return 0xfc(failed) */
+ ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
+
+ if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
+ goto out;
+
+ *reg_val = param[2];
+ rc = 0;
+
+ out:
+ mutex_unlock(&ps2dev->cmd_mutex);
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+ dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
+ reg_addr, *reg_val, rc);
+ return rc;
+}
+
+static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char v;
+ int rc = -1;
+
+ mutex_lock(&ps2dev->cmd_mutex);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ goto out;
+
+ if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
+ /* inversion is required */
+ ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
+ } else {
+ if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
+ /* swapping is required */
+ ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
+ } else {
+ /* swapping isn't necessary */
+ ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
+ }
+ }
+ /* write the register address in correct order */
+ ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ return -1;
+
+ if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
+ /* inversion is required */
+ ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
+ } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
+ /* swapping is required */
+ ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
+ } else {
+ /* swapping isn't necessary */
+ ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
+ }
+
+ /* write the register value in correct order */
+ ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
+ rc = 0;
+
+ out:
+ mutex_unlock(&ps2dev->cmd_mutex);
+ dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
+ reg_addr, reg_val, rc);
+ return rc;
+}
+
+/* Enable register clock gating for writing certain registers */
+static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
+{
+ int v, nv;
+
+ if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
+ return -1;
+
+ if (enable)
+ nv = v | FSP_BIT_EN_REG_CLK;
+ else
+ nv = v & ~FSP_BIT_EN_REG_CLK;
+
+ /* only write if necessary */
+ if (nv != v)
+ if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char param[3];
+ int rc = -1;
+
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+ mutex_lock(&ps2dev->cmd_mutex);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ goto out;
+
+ ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
+ ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ goto out;
+
+ ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
+ ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+ /* get the returned result */
+ if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
+ goto out;
+
+ *reg_val = param[2];
+ rc = 0;
+
+ out:
+ mutex_unlock(&ps2dev->cmd_mutex);
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+ dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n",
+ *reg_val, rc);
+ return rc;
+}
+
+static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char v;
+ int rc = -1;
+
+ mutex_lock(&ps2dev->cmd_mutex);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ goto out;
+
+ ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
+ ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+ if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+ return -1;
+
+ if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
+ ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
+ } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
+ /* swapping is required */
+ ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
+ } else {
+ /* swapping isn't necessary */
+ ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
+ }
+
+ ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
+ rc = 0;
+
+ out:
+ mutex_unlock(&ps2dev->cmd_mutex);
+ dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
+ reg_val, rc);
+ return rc;
+}
+
+static int fsp_get_version(struct psmouse *psmouse, int *version)
+{
+ if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
+ return -EIO;
+
+ return 0;
+}
+
+static int fsp_get_revision(struct psmouse *psmouse, int *rev)
+{
+ if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
+ return -EIO;
+
+ return 0;
+}
+
+static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
+{
+ static const int buttons[] = {
+ 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
+ 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
+ 0x04, /* Left/Middle/Right & Scroll Up/Down */
+ 0x02, /* Left/Middle/Right */
+ };
+ int val;
+
+ if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &val) == -1)
+ return -EIO;
+
+ *btn = buttons[(val & 0x30) >> 4];
+ return 0;
+}
+
+/* Enable on-pad command tag output */
+static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
+{
+ int v, nv;
+ int res = 0;
+
+ if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
+ dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n");
+ return -EIO;
+ }
+
+ if (enable)
+ nv = v | FSP_BIT_EN_OPC_TAG;
+ else
+ nv = v & ~FSP_BIT_EN_OPC_TAG;
+
+ /* only write if necessary */
+ if (nv != v) {
+ fsp_reg_write_enable(psmouse, true);
+ res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
+ fsp_reg_write_enable(psmouse, false);
+ }
+
+ if (res != 0) {
+ dev_err(&psmouse->ps2dev.serio->dev,
+ "Unable to enable OPC tag.\n");
+ res = -EIO;
+ }
+
+ return res;
+}
+
+static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
+{
+ struct fsp_data *pad = psmouse->private;
+ int val;
+
+ if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
+ return -EIO;
+
+ pad->vscroll = enable;
+
+ if (enable)
+ val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
+ else
+ val &= ~FSP_BIT_FIX_VSCR;
+
+ if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
+{
+ struct fsp_data *pad = psmouse->private;
+ int val, v2;
+
+ if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
+ return -EIO;
+
+ if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
+ return -EIO;
+
+ pad->hscroll = enable;
+
+ if (enable) {
+ val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
+ v2 |= FSP_BIT_EN_MSID6;
+ } else {
+ val &= ~FSP_BIT_FIX_HSCR;
+ v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
+ }
+
+ if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
+ return -EIO;
+
+ /* reconfigure horizontal scrolling packet output */
+ if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
+ return -EIO;
+
+ return 0;
+}
+
+/*
+ * Write device specific initial parameters.
+ *
+ * ex: 0xab 0xcd - write oxcd into register 0xab
+ */
+static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ unsigned long reg, val;
+ char *rest;
+ ssize_t retval;
+
+ reg = simple_strtoul(buf, &rest, 16);
+ if (rest == buf || *rest != ' ' || reg > 0xff)
+ return -EINVAL;
+
+ if (strict_strtoul(rest + 1, 16, &val) || val > 0xff)
+ return -EINVAL;
+
+ if (fsp_reg_write_enable(psmouse, true))
+ return -EIO;
+
+ retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
+
+ fsp_reg_write_enable(psmouse, false);
+
+ return count;
+}
+
+PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
+
+static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ struct fsp_data *pad = psmouse->private;
+
+ return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
+}
+
+/*
+ * Read a register from device.
+ *
+ * ex: 0xab -- read content from register 0xab
+ */
+static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ struct fsp_data *pad = psmouse->private;
+ unsigned long reg;
+ int val;
+
+ if (strict_strtoul(buf, 16, &reg) || reg > 0xff)
+ return -EINVAL;
+
+ if (fsp_reg_read(psmouse, reg, &val))
+ return -EIO;
+
+ pad->last_reg = reg;
+ pad->last_val = val;
+
+ return count;
+}
+
+PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
+ fsp_attr_show_getreg, fsp_attr_set_getreg);
+
+static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ int val = 0;
+
+ if (fsp_page_reg_read(psmouse, &val))
+ return -EIO;
+
+ return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+
+ if (strict_strtoul(buf, 16, &val) || val > 0xff)
+ return -EINVAL;
+
+ if (fsp_page_reg_write(psmouse, val))
+ return -EIO;
+
+ return count;
+}
+
+PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
+ fsp_attr_show_pagereg, fsp_attr_set_pagereg);
+
+static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ struct fsp_data *pad = psmouse->private;
+
+ return sprintf(buf, "%d\n", pad->vscroll);
+}
+
+static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) || val > 1)
+ return -EINVAL;
+
+ fsp_onpad_vscr(psmouse, val);
+
+ return count;
+}
+
+PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
+ fsp_attr_show_vscroll, fsp_attr_set_vscroll);
+
+static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ struct fsp_data *pad = psmouse->private;
+
+ return sprintf(buf, "%d\n", pad->hscroll);
+}
+
+static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) || val > 1)
+ return -EINVAL;
+
+ fsp_onpad_hscr(psmouse, val);
+
+ return count;
+}
+
+PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
+ fsp_attr_show_hscroll, fsp_attr_set_hscroll);
+
+static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ struct fsp_data *pad = psmouse->private;
+
+ return sprintf(buf, "%c\n",
+ pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
+}
+
+static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ struct fsp_data *pad = psmouse->private;
+ size_t i;
+
+ for (i = 0; i < count; i++) {
+ switch (buf[i]) {
+ case 'C':
+ pad->flags |= FSPDRV_FLAG_EN_OPC;
+ break;
+ case 'c':
+ pad->flags &= ~FSPDRV_FLAG_EN_OPC;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ return count;
+}
+
+PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
+ fsp_attr_show_flags, fsp_attr_set_flags);
+
+static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
+ void *data, char *buf)
+{
+ return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
+}
+
+PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
+
+static struct attribute *fsp_attributes[] = {
+ &psmouse_attr_setreg.dattr.attr,
+ &psmouse_attr_getreg.dattr.attr,
+ &psmouse_attr_page.dattr.attr,
+ &psmouse_attr_vscroll.dattr.attr,
+ &psmouse_attr_hscroll.dattr.attr,
+ &psmouse_attr_flags.dattr.attr,
+ &psmouse_attr_ver.dattr.attr,
+ NULL
+};
+
+static struct attribute_group fsp_attribute_group = {
+ .attrs = fsp_attributes,
+};
+
+#ifdef FSP_DEBUG
+static void fsp_packet_debug(unsigned char packet[])
+{
+ static unsigned int ps2_packet_cnt;
+ static unsigned int ps2_last_second;
+ unsigned int jiffies_msec;
+
+ ps2_packet_cnt++;
+ jiffies_msec = jiffies_to_msecs(jiffies);
+ printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n",
+ jiffies_msec, packet[0], packet[1], packet[2], packet[3]);
+
+ if (jiffies_msec - ps2_last_second > 1000) {
+ printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt);
+ ps2_packet_cnt = 0;
+ ps2_last_second = jiffies_msec;
+ }
+}
+#else
+static void fsp_packet_debug(unsigned char packet[])
+{
+}
+#endif
+
+static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
+{
+ struct input_dev *dev = psmouse->dev;
+ struct fsp_data *ad = psmouse->private;
+ unsigned char *packet = psmouse->packet;
+ unsigned char button_status = 0, lscroll = 0, rscroll = 0;
+ int rel_x, rel_y;
+
+ if (psmouse->pktcnt < 4)
+ return PSMOUSE_GOOD_DATA;
+
+ /*
+ * Full packet accumulated, process it
+ */
+
+ switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
+ case FSP_PKT_TYPE_ABS:
+ dev_warn(&psmouse->ps2dev.serio->dev,
+ "Unexpected absolute mode packet, ignored.\n");
+ break;
+
+ case FSP_PKT_TYPE_NORMAL_OPC:
+ /* on-pad click, filter it if necessary */
+ if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
+ packet[0] &= ~BIT(0);
+ /* fall through */
+
+ case FSP_PKT_TYPE_NORMAL:
+ /* normal packet */
+ /* special packet data translation from on-pad packets */
+ if (packet[3] != 0) {
+ if (packet[3] & BIT(0))
+ button_status |= 0x01; /* wheel down */
+ if (packet[3] & BIT(1))
+ button_status |= 0x0f; /* wheel up */
+ if (packet[3] & BIT(2))
+ button_status |= BIT(5);/* horizontal left */
+ if (packet[3] & BIT(3))
+ button_status |= BIT(4);/* horizontal right */
+ /* push back to packet queue */
+ if (button_status != 0)
+ packet[3] = button_status;
+ rscroll = (packet[3] >> 4) & 1;
+ lscroll = (packet[3] >> 5) & 1;
+ }
+ /*
+ * Processing wheel up/down and extra button events
+ */
+ input_report_rel(dev, REL_WHEEL,
+ (int)(packet[3] & 8) - (int)(packet[3] & 7));
+ input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
+ input_report_key(dev, BTN_BACK, lscroll);
+ input_report_key(dev, BTN_FORWARD, rscroll);
+
+ /*
+ * Standard PS/2 Mouse
+ */
+ input_report_key(dev, BTN_LEFT, packet[0] & 1);
+ input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
+ input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
+
+ rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0;
+ rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0;
+
+ input_report_rel(dev, REL_X, rel_x);
+ input_report_rel(dev, REL_Y, rel_y);
+ break;
+ }
+
+ input_sync(dev);
+
+ fsp_packet_debug(packet);
+
+ return PSMOUSE_FULL_PACKET;
+}
+
+static int fsp_activate_protocol(struct psmouse *psmouse)
+{
+ struct fsp_data *pad = psmouse->private;
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char param[2];
+ int val;
+
+ /*
+ * Standard procedure to enter FSP Intellimouse mode
+ * (scrolling wheel, 4th and 5th buttons)
+ */
+ param[0] = 200;
+ ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+ param[0] = 200;
+ ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+ param[0] = 80;
+ ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+
+ ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
+ if (param[0] != 0x04) {
+ dev_err(&psmouse->ps2dev.serio->dev,
+ "Unable to enable 4 bytes packet format.\n");
+ return -EIO;
+ }
+
+ if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
+ dev_err(&psmouse->ps2dev.serio->dev,
+ "Unable to read SYSCTL5 register.\n");
+ return -EIO;
+ }
+
+ val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
+ /* Ensure we are not in absolute mode */
+ val &= ~FSP_BIT_EN_PKT_G0;
+ if (pad->buttons == 0x06) {
+ /* Left/Middle/Right & Scroll Up/Down/Right/Left */
+ val |= FSP_BIT_EN_MSID6;
+ }
+
+ if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
+ dev_err(&psmouse->ps2dev.serio->dev,
+ "Unable to set up required mode bits.\n");
+ return -EIO;
+ }
+
+ /*
+ * Enable OPC tags such that driver can tell the difference between
+ * on-pad and real button click
+ */
+ if (fsp_opc_tag_enable(psmouse, true))
+ dev_warn(&psmouse->ps2dev.serio->dev,
+ "Failed to enable OPC tag mode.\n");
+
+ /* Enable on-pad vertical and horizontal scrolling */
+ fsp_onpad_vscr(psmouse, true);
+ fsp_onpad_hscr(psmouse, true);
+
+ return 0;
+}
+
+int fsp_detect(struct psmouse *psmouse, bool set_properties)
+{
+ int id;
+
+ if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
+ return -EIO;
+
+ if (id != 0x01)
+ return -ENODEV;
+
+ if (set_properties) {
+ psmouse->vendor = "Sentelic";
+ psmouse->name = "FingerSensingPad";
+ }
+
+ return 0;
+}
+
+static void fsp_reset(struct psmouse *psmouse)
+{
+ fsp_opc_tag_enable(psmouse, false);
+ fsp_onpad_vscr(psmouse, false);
+ fsp_onpad_hscr(psmouse, false);
+}
+
+static void fsp_disconnect(struct psmouse *psmouse)
+{
+ sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
+ &fsp_attribute_group);
+
+ fsp_reset(psmouse);
+ kfree(psmouse->private);
+}
+
+static int fsp_reconnect(struct psmouse *psmouse)
+{
+ int version;
+
+ if (fsp_detect(psmouse, 0))
+ return -ENODEV;
+
+ if (fsp_get_version(psmouse, &version))
+ return -ENODEV;
+
+ if (fsp_activate_protocol(psmouse))
+ return -EIO;
+
+ return 0;
+}
+
+int fsp_init(struct psmouse *psmouse)
+{
+ struct fsp_data *priv;
+ int ver, rev, buttons;
+ int error;
+
+ if (fsp_get_version(psmouse, &ver) ||
+ fsp_get_revision(psmouse, &rev) ||
+ fsp_get_buttons(psmouse, &buttons)) {
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO
+ "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n",
+ ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7);
+
+ psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->ver = ver;
+ priv->rev = rev;
+ priv->buttons = buttons;
+
+ /* enable on-pad click by default */
+ priv->flags |= FSPDRV_FLAG_EN_OPC;
+
+ /* Set up various supported input event bits */
+ __set_bit(BTN_BACK, psmouse->dev->keybit);
+ __set_bit(BTN_FORWARD, psmouse->dev->keybit);
+ __set_bit(REL_WHEEL, psmouse->dev->relbit);
+ __set_bit(REL_HWHEEL, psmouse->dev->relbit);
+
+ psmouse->protocol_handler = fsp_process_byte;
+ psmouse->disconnect = fsp_disconnect;
+ psmouse->reconnect = fsp_reconnect;
+ psmouse->cleanup = fsp_reset;
+ psmouse->pktsize = 4;
+
+ /* set default packet output based on number of buttons we found */
+ error = fsp_activate_protocol(psmouse);
+ if (error)
+ goto err_out;
+
+ error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
+ &fsp_attribute_group);
+ if (error) {
+ dev_err(&psmouse->ps2dev.serio->dev,
+ "Failed to create sysfs attributes (%d)", error);
+ goto err_out;
+ }
+
+ return 0;
+
+ err_out:
+ kfree(psmouse->private);
+ psmouse->private = NULL;
+ return error;
+}
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h
new file mode 100644
index 00000000000..ed1395ac7b8
--- /dev/null
+++ b/drivers/input/mouse/sentelic.h
@@ -0,0 +1,98 @@
+/*-
+ * Finger Sensing Pad PS/2 mouse driver.
+ *
+ * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
+ * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SENTELIC_H
+#define __SENTELIC_H
+
+/* Finger-sensing Pad information registers */
+#define FSP_REG_DEVICE_ID 0x00
+#define FSP_REG_VERSION 0x01
+#define FSP_REG_REVISION 0x04
+#define FSP_REG_TMOD_STATUS1 0x0B
+#define FSP_BIT_NO_ROTATION BIT(3)
+#define FSP_REG_PAGE_CTRL 0x0F
+
+/* Finger-sensing Pad control registers */
+#define FSP_REG_SYSCTL1 0x10
+#define FSP_BIT_EN_REG_CLK BIT(5)
+#define FSP_REG_OPC_QDOWN 0x31
+#define FSP_BIT_EN_OPC_TAG BIT(7)
+#define FSP_REG_OPTZ_XLO 0x34
+#define FSP_REG_OPTZ_XHI 0x35
+#define FSP_REG_OPTZ_YLO 0x36
+#define FSP_REG_OPTZ_YHI 0x37
+#define FSP_REG_SYSCTL5 0x40
+#define FSP_BIT_90_DEGREE BIT(0)
+#define FSP_BIT_EN_MSID6 BIT(1)
+#define FSP_BIT_EN_MSID7 BIT(2)
+#define FSP_BIT_EN_MSID8 BIT(3)
+#define FSP_BIT_EN_AUTO_MSID8 BIT(5)
+#define FSP_BIT_EN_PKT_G0 BIT(6)
+
+#define FSP_REG_ONPAD_CTL 0x43
+#define FSP_BIT_ONPAD_ENABLE BIT(0)
+#define FSP_BIT_ONPAD_FBBB BIT(1)
+#define FSP_BIT_FIX_VSCR BIT(3)
+#define FSP_BIT_FIX_HSCR BIT(5)
+#define FSP_BIT_DRAG_LOCK BIT(6)
+
+/* Finger-sensing Pad packet formating related definitions */
+
+/* absolute packet type */
+#define FSP_PKT_TYPE_NORMAL (0x00)
+#define FSP_PKT_TYPE_ABS (0x01)
+#define FSP_PKT_TYPE_NOTIFY (0x02)
+#define FSP_PKT_TYPE_NORMAL_OPC (0x03)
+#define FSP_PKT_TYPE_SHIFT (6)
+
+#ifdef __KERNEL__
+
+struct fsp_data {
+ unsigned char ver; /* hardware version */
+ unsigned char rev; /* hardware revison */
+ unsigned char buttons; /* Number of buttons */
+ unsigned int flags;
+#define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */
+
+ bool vscroll; /* Vertical scroll zone enabled */
+ bool hscroll; /* Horizontal scroll zone enabled */
+
+ unsigned char last_reg; /* Last register we requested read from */
+ unsigned char last_val;
+};
+
+#ifdef CONFIG_MOUSE_PS2_SENTELIC
+extern int fsp_detect(struct psmouse *psmouse, bool set_properties);
+extern int fsp_init(struct psmouse *psmouse);
+#else
+inline int fsp_detect(struct psmouse *psmouse, bool set_properties)
+{
+ return -ENOSYS;
+}
+inline int fsp_init(struct psmouse *psmouse)
+{
+ return -ENOSYS;
+}
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* !__SENTELIC_H */
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 19984bf06ca..b66ff1ac7de 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)
return 0;
}
-int synaptics_detect(struct psmouse *psmouse, int set_properties)
+int synaptics_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
@@ -556,38 +556,38 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
{
int i;
- set_bit(EV_ABS, dev->evbit);
+ __set_bit(EV_ABS, dev->evbit);
input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
- set_bit(ABS_TOOL_WIDTH, dev->absbit);
+ __set_bit(ABS_TOOL_WIDTH, dev->absbit);
- set_bit(EV_KEY, dev->evbit);
- set_bit(BTN_TOUCH, dev->keybit);
- set_bit(BTN_TOOL_FINGER, dev->keybit);
- set_bit(BTN_LEFT, dev->keybit);
- set_bit(BTN_RIGHT, dev->keybit);
+ __set_bit(EV_KEY, dev->evbit);
+ __set_bit(BTN_TOUCH, dev->keybit);
+ __set_bit(BTN_TOOL_FINGER, dev->keybit);
+ __set_bit(BTN_LEFT, dev->keybit);
+ __set_bit(BTN_RIGHT, dev->keybit);
if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
- set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
- set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+ __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
+ __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
}
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
- set_bit(BTN_MIDDLE, dev->keybit);
+ __set_bit(BTN_MIDDLE, dev->keybit);
if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
- set_bit(BTN_FORWARD, dev->keybit);
- set_bit(BTN_BACK, dev->keybit);
+ __set_bit(BTN_FORWARD, dev->keybit);
+ __set_bit(BTN_BACK, dev->keybit);
}
for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
- set_bit(BTN_0 + i, dev->keybit);
+ __set_bit(BTN_0 + i, dev->keybit);
- clear_bit(EV_REL, dev->evbit);
- clear_bit(REL_X, dev->relbit);
- clear_bit(REL_Y, dev->relbit);
+ __clear_bit(EV_REL, dev->evbit);
+ __clear_bit(REL_X, dev->relbit);
+ __clear_bit(REL_Y, dev->relbit);
dev->absres[ABS_X] = priv->x_res;
dev->absres[ABS_Y] = priv->y_res;
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 30238215175..871f6fe377f 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -105,7 +105,7 @@ struct synaptics_data {
int scroll;
};
-int synaptics_detect(struct psmouse *psmouse, int set_properties);
+int synaptics_detect(struct psmouse *psmouse, bool set_properties);
int synaptics_init(struct psmouse *psmouse);
void synaptics_reset(struct psmouse *psmouse);
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 3fadb2accac..0308a0faa94 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)
return PSMOUSE_FULL_PACKET;
}
-int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
+int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties)
{
struct input_dev *dev = psmouse->dev;
unsigned char param[3];
@@ -86,7 +86,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
if (set_properties) {
dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- set_bit(BTN_TOUCH, dev->keybit);
+ __set_bit(BTN_TOUCH, dev->keybit);
input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h
index 8a0dd3574ae..2efe9ea29d0 100644
--- a/drivers/input/mouse/touchkit_ps2.h
+++ b/drivers/input/mouse/touchkit_ps2.h
@@ -13,10 +13,10 @@
#define _TOUCHKIT_PS2_H
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
-int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties);
+int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties);
#else
static inline int touchkit_ps2_detect(struct psmouse *psmouse,
- int set_properties)
+ bool set_properties)
{
return -ENOSYS;
}
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index e68c814c436..e354362f297 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -282,7 +282,7 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
return 0;
}
-int trackpoint_detect(struct psmouse *psmouse, int set_properties)
+int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
{
struct trackpoint_data *priv;
struct ps2dev *ps2dev = &psmouse->ps2dev;
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index c10a6e7d010..e558a709661 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -143,9 +143,9 @@ struct trackpoint_data
};
#ifdef CONFIG_MOUSE_PS2_TRACKPOINT
-int trackpoint_detect(struct psmouse *psmouse, int set_properties);
+int trackpoint_detect(struct psmouse *psmouse, bool set_properties);
#else
-inline int trackpoint_detect(struct psmouse *psmouse, int set_properties)
+inline int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 404eedd5ffa..70111443678 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -384,11 +384,11 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
"incremental streaming mode and 72 samples/sec\n",
mouse->name, mouse->phys);
- mouse->serio->write (mouse->serio, 'S'); /* Standard format */
+ serio_write (mouse->serio, 'S'); /* Standard format */
mdelay (50);
- mouse->serio->write (mouse->serio, 'R'); /* Incremental */
+ serio_write (mouse->serio, 'R'); /* Incremental */
mdelay (50);
- mouse->serio->write (mouse->serio, 'L'); /* 72 samples/sec */
+ serio_write (mouse->serio, 'L'); /* 72 samples/sec */
}
static void
@@ -532,7 +532,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
* Request selftest. Standard packet format and differential
* mode will be requested after the device ID'ed successfully.
*/
- serio->write (serio, 'T'); /* Test */
+ serio_write (serio, 'T'); /* Test */
err = input_register_device (input_dev);
if (err)