summaryrefslogtreecommitdiff
path: root/drivers/input/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/synaptics.c60
-rw-r--r--drivers/input/mouse/synaptics.h3
-rw-r--r--drivers/input/mouse/synaptics_usb.c2
3 files changed, 62 insertions, 3 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index c703d53be3a0..14eaecea2b70 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -40,11 +40,27 @@
* Note that newer firmware allows querying device for maximum useable
* coordinates.
*/
+#define XMIN 0
+#define XMAX 6143
+#define YMIN 0
+#define YMAX 6143
#define XMIN_NOMINAL 1472
#define XMAX_NOMINAL 5472
#define YMIN_NOMINAL 1408
#define YMAX_NOMINAL 4448
+/* Size in bits of absolute position values reported by the hardware */
+#define ABS_POS_BITS 13
+
+/*
+ * Any position values from the hardware above the following limits are
+ * treated as "wrapped around negative" values that have been truncated to
+ * the 13-bit reporting range of the hardware. These are just reasonable
+ * guesses and can be adjusted if hardware is found that operates outside
+ * of these parameters.
+ */
+#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2)
+#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2)
/*****************************************************************************
* Stuff we need even when we do not want native Synaptics support
@@ -139,6 +155,35 @@ static int synaptics_model_id(struct psmouse *psmouse)
}
/*
+ * Read the board id from the touchpad
+ * The board id is encoded in the "QUERY MODES" response
+ */
+static int synaptics_board_id(struct psmouse *psmouse)
+{
+ struct synaptics_data *priv = psmouse->private;
+ unsigned char bid[3];
+
+ if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid))
+ return -1;
+ priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1];
+ return 0;
+}
+
+/*
+ * Read the firmware id from the touchpad
+ */
+static int synaptics_firmware_id(struct psmouse *psmouse)
+{
+ struct synaptics_data *priv = psmouse->private;
+ unsigned char fwid[3];
+
+ if (synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid))
+ return -1;
+ priv->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2];
+ return 0;
+}
+
+/*
* Read the capability-bits from the touchpad
* see also the SYN_CAP_* macros
*/
@@ -261,6 +306,10 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
return -1;
if (synaptics_model_id(psmouse))
return -1;
+ if (synaptics_firmware_id(psmouse))
+ return -1;
+ if (synaptics_board_id(psmouse))
+ return -1;
if (synaptics_capability(psmouse))
return -1;
if (synaptics_resolution(psmouse))
@@ -555,6 +604,12 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
hw->right = (buf[0] & 0x02) ? 1 : 0;
}
+ /* Convert wrap-around values to negative */
+ if (hw->x > X_MAX_POSITIVE)
+ hw->x -= 1 << ABS_POS_BITS;
+ if (hw->y > Y_MAX_POSITIVE)
+ hw->y -= 1 << ABS_POS_BITS;
+
return 0;
}
@@ -1435,11 +1490,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
psmouse_info(psmouse,
- "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
+ "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n",
SYN_ID_MODEL(priv->identity),
SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
priv->model_id,
- priv->capabilities, priv->ext_cap, priv->ext_cap_0c);
+ priv->capabilities, priv->ext_cap, priv->ext_cap_0c,
+ priv->board_id, priv->firmware_id);
set_input_params(psmouse->dev, priv);
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index fd26ccca13d7..e594af0b264b 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -18,6 +18,7 @@
#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
#define SYN_QUE_RESOLUTION 0x08
#define SYN_QUE_EXT_CAPAB 0x09
+#define SYN_QUE_FIRMWARE_ID 0x0a
#define SYN_QUE_EXT_CAPAB_0C 0x0c
#define SYN_QUE_EXT_MAX_COORDS 0x0d
#define SYN_QUE_EXT_MIN_COORDS 0x0f
@@ -148,6 +149,8 @@ struct synaptics_hw_state {
struct synaptics_data {
/* Data read from the touchpad */
unsigned long int model_id; /* Model-ID */
+ unsigned long int firmware_id; /* Firmware-ID */
+ unsigned long int board_id; /* Board-ID */
unsigned long int capabilities; /* Capabilities */
unsigned long int ext_cap; /* Extended Capabilities */
unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c
index 3c5eaaa5d154..64cf34ea7604 100644
--- a/drivers/input/mouse/synaptics_usb.c
+++ b/drivers/input/mouse/synaptics_usb.c
@@ -364,7 +364,7 @@ static int synusb_probe(struct usb_interface *intf,
le16_to_cpu(udev->descriptor.idProduct));
if (synusb->flags & SYNUSB_STICK)
- strlcat(synusb->name, " (Stick) ", sizeof(synusb->name));
+ strlcat(synusb->name, " (Stick)", sizeof(synusb->name));
usb_make_path(udev, synusb->phys, sizeof(synusb->phys));
strlcat(synusb->phys, "/input0", sizeof(synusb->phys));