diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/Kconfig | 2 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 1 | ||||
-rw-r--r-- | drivers/input/mouse/appletouch.c | 12 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 24 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 183 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 5 | ||||
-rw-r--r-- | drivers/input/mouse/hgpk.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 98 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 104 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse.h | 1 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 88 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 10 |
12 files changed, 321 insertions, 211 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index c714ca2407f8..eeb58c1cac16 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -17,7 +17,7 @@ config MOUSE_PS2 | |||
17 | default y | 17 | default y |
18 | select SERIO | 18 | select SERIO |
19 | select SERIO_LIBPS2 | 19 | select SERIO_LIBPS2 |
20 | select SERIO_I8042 if X86 | 20 | select SERIO_I8042 if X86 && !X86_MRST |
21 | select SERIO_GSCPS2 if GSC | 21 | select SERIO_GSCPS2 if GSC |
22 | help | 22 | help |
23 | Say Y here if you have a PS/2 mouse connected to your system. This | 23 | Say Y here if you have a PS/2 mouse connected to your system. This |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 0d22cb9ce42e..99d58764ef03 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -64,7 +64,6 @@ static const struct alps_model_info alps_model_data[] = { | |||
64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, | 64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, |
65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | 65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, |
66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
67 | { { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, /* HP Pavilion dm3 */ | ||
68 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, | 67 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, |
69 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | 68 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ |
70 | }; | 69 | }; |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 53ec7ddd1826..05edd75abca0 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -806,8 +806,8 @@ static int atp_probe(struct usb_interface *iface, | |||
806 | if (!dev->urb) | 806 | if (!dev->urb) |
807 | goto err_free_devs; | 807 | goto err_free_devs; |
808 | 808 | ||
809 | dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL, | 809 | dev->data = usb_alloc_coherent(dev->udev, dev->info->datalen, GFP_KERNEL, |
810 | &dev->urb->transfer_dma); | 810 | &dev->urb->transfer_dma); |
811 | if (!dev->data) | 811 | if (!dev->data) |
812 | goto err_free_urb; | 812 | goto err_free_urb; |
813 | 813 | ||
@@ -862,8 +862,8 @@ static int atp_probe(struct usb_interface *iface, | |||
862 | return 0; | 862 | return 0; |
863 | 863 | ||
864 | err_free_buffer: | 864 | err_free_buffer: |
865 | usb_buffer_free(dev->udev, dev->info->datalen, | 865 | usb_free_coherent(dev->udev, dev->info->datalen, |
866 | dev->data, dev->urb->transfer_dma); | 866 | dev->data, dev->urb->transfer_dma); |
867 | err_free_urb: | 867 | err_free_urb: |
868 | usb_free_urb(dev->urb); | 868 | usb_free_urb(dev->urb); |
869 | err_free_devs: | 869 | err_free_devs: |
@@ -881,8 +881,8 @@ static void atp_disconnect(struct usb_interface *iface) | |||
881 | if (dev) { | 881 | if (dev) { |
882 | usb_kill_urb(dev->urb); | 882 | usb_kill_urb(dev->urb); |
883 | input_unregister_device(dev->input); | 883 | input_unregister_device(dev->input); |
884 | usb_buffer_free(dev->udev, dev->info->datalen, | 884 | usb_free_coherent(dev->udev, dev->info->datalen, |
885 | dev->data, dev->urb->transfer_dma); | 885 | dev->data, dev->urb->transfer_dma); |
886 | usb_free_urb(dev->urb); | 886 | usb_free_urb(dev->urb); |
887 | kfree(dev); | 887 | kfree(dev); |
888 | } | 888 | } |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index b89879bd860f..6dedded27222 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -715,15 +715,15 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
715 | if (!dev->tp_urb) | 715 | if (!dev->tp_urb) |
716 | goto err_free_bt_urb; | 716 | goto err_free_bt_urb; |
717 | 717 | ||
718 | dev->bt_data = usb_buffer_alloc(dev->udev, | 718 | dev->bt_data = usb_alloc_coherent(dev->udev, |
719 | dev->cfg.bt_datalen, GFP_KERNEL, | 719 | dev->cfg.bt_datalen, GFP_KERNEL, |
720 | &dev->bt_urb->transfer_dma); | 720 | &dev->bt_urb->transfer_dma); |
721 | if (!dev->bt_data) | 721 | if (!dev->bt_data) |
722 | goto err_free_urb; | 722 | goto err_free_urb; |
723 | 723 | ||
724 | dev->tp_data = usb_buffer_alloc(dev->udev, | 724 | dev->tp_data = usb_alloc_coherent(dev->udev, |
725 | dev->cfg.tp_datalen, GFP_KERNEL, | 725 | dev->cfg.tp_datalen, GFP_KERNEL, |
726 | &dev->tp_urb->transfer_dma); | 726 | &dev->tp_urb->transfer_dma); |
727 | if (!dev->tp_data) | 727 | if (!dev->tp_data) |
728 | goto err_free_bt_buffer; | 728 | goto err_free_bt_buffer; |
729 | 729 | ||
@@ -765,10 +765,10 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
765 | return 0; | 765 | return 0; |
766 | 766 | ||
767 | err_free_buffer: | 767 | err_free_buffer: |
768 | usb_buffer_free(dev->udev, dev->cfg.tp_datalen, | 768 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
769 | dev->tp_data, dev->tp_urb->transfer_dma); | 769 | dev->tp_data, dev->tp_urb->transfer_dma); |
770 | err_free_bt_buffer: | 770 | err_free_bt_buffer: |
771 | usb_buffer_free(dev->udev, dev->cfg.bt_datalen, | 771 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
772 | dev->bt_data, dev->bt_urb->transfer_dma); | 772 | dev->bt_data, dev->bt_urb->transfer_dma); |
773 | err_free_urb: | 773 | err_free_urb: |
774 | usb_free_urb(dev->tp_urb); | 774 | usb_free_urb(dev->tp_urb); |
@@ -788,10 +788,10 @@ static void bcm5974_disconnect(struct usb_interface *iface) | |||
788 | usb_set_intfdata(iface, NULL); | 788 | usb_set_intfdata(iface, NULL); |
789 | 789 | ||
790 | input_unregister_device(dev->input); | 790 | input_unregister_device(dev->input); |
791 | usb_buffer_free(dev->udev, dev->cfg.tp_datalen, | 791 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
792 | dev->tp_data, dev->tp_urb->transfer_dma); | 792 | dev->tp_data, dev->tp_urb->transfer_dma); |
793 | usb_buffer_free(dev->udev, dev->cfg.bt_datalen, | 793 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
794 | dev->bt_data, dev->bt_urb->transfer_dma); | 794 | dev->bt_data, dev->bt_urb->transfer_dma); |
795 | usb_free_urb(dev->tp_urb); | 795 | usb_free_urb(dev->tp_urb); |
796 | usb_free_urb(dev->bt_urb); | 796 | usb_free_urb(dev->bt_urb); |
797 | kfree(dev); | 797 | kfree(dev); |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index a138b5da79f9..b18862b2a70e 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * Trademarks are the property of their respective owners. | 10 | * Trademarks are the property of their respective owners. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
14 | |||
13 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
@@ -19,12 +21,16 @@ | |||
19 | #include "psmouse.h" | 21 | #include "psmouse.h" |
20 | #include "elantech.h" | 22 | #include "elantech.h" |
21 | 23 | ||
22 | #define elantech_debug(format, arg...) \ | 24 | #define elantech_debug(fmt, ...) \ |
23 | do { \ | 25 | do { \ |
24 | if (etd->debug) \ | 26 | if (etd->debug) \ |
25 | printk(KERN_DEBUG format, ##arg); \ | 27 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ |
26 | } while (0) | 28 | } while (0) |
27 | 29 | ||
30 | static bool force_elantech; | ||
31 | module_param_named(force_elantech, force_elantech, bool, 0644); | ||
32 | MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default)."); | ||
33 | |||
28 | /* | 34 | /* |
29 | * Send a Synaptics style sliced query command | 35 | * Send a Synaptics style sliced query command |
30 | */ | 36 | */ |
@@ -33,7 +39,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, | |||
33 | { | 39 | { |
34 | if (psmouse_sliced_command(psmouse, c) || | 40 | if (psmouse_sliced_command(psmouse, c) || |
35 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 41 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
36 | pr_err("elantech.c: synaptics_send_cmd query 0x%02x failed.\n", c); | 42 | pr_err("synaptics_send_cmd query 0x%02x failed.\n", c); |
37 | return -1; | 43 | return -1; |
38 | } | 44 | } |
39 | 45 | ||
@@ -56,13 +62,13 @@ static int elantech_ps2_command(struct psmouse *psmouse, | |||
56 | if (rc == 0) | 62 | if (rc == 0) |
57 | break; | 63 | break; |
58 | tries--; | 64 | tries--; |
59 | elantech_debug("elantech.c: retrying ps2 command 0x%02x (%d).\n", | 65 | elantech_debug("retrying ps2 command 0x%02x (%d).\n", |
60 | command, tries); | 66 | command, tries); |
61 | msleep(ETP_PS2_COMMAND_DELAY); | 67 | msleep(ETP_PS2_COMMAND_DELAY); |
62 | } while (tries > 0); | 68 | } while (tries > 0); |
63 | 69 | ||
64 | if (rc) | 70 | if (rc) |
65 | pr_err("elantech.c: ps2 command 0x%02x failed.\n", command); | 71 | pr_err("ps2 command 0x%02x failed.\n", command); |
66 | 72 | ||
67 | return rc; | 73 | return rc; |
68 | } | 74 | } |
@@ -104,7 +110,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
104 | } | 110 | } |
105 | 111 | ||
106 | if (rc) | 112 | if (rc) |
107 | pr_err("elantech.c: failed to read register 0x%02x.\n", reg); | 113 | pr_err("failed to read register 0x%02x.\n", reg); |
108 | else | 114 | else |
109 | *val = param[0]; | 115 | *val = param[0]; |
110 | 116 | ||
@@ -150,7 +156,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
150 | } | 156 | } |
151 | 157 | ||
152 | if (rc) | 158 | if (rc) |
153 | pr_err("elantech.c: failed to write register 0x%02x with value 0x%02x.\n", | 159 | pr_err("failed to write register 0x%02x with value 0x%02x.\n", |
154 | reg, val); | 160 | reg, val); |
155 | 161 | ||
156 | return rc; | 162 | return rc; |
@@ -163,7 +169,7 @@ static void elantech_packet_dump(unsigned char *packet, int size) | |||
163 | { | 169 | { |
164 | int i; | 170 | int i; |
165 | 171 | ||
166 | printk(KERN_DEBUG "elantech.c: PS/2 packet ["); | 172 | printk(KERN_DEBUG pr_fmt("PS/2 packet [")); |
167 | for (i = 0; i < size; i++) | 173 | for (i = 0; i < size; i++) |
168 | printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); | 174 | printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); |
169 | printk("]\n"); | 175 | printk("]\n"); |
@@ -181,34 +187,40 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
181 | int fingers; | 187 | int fingers; |
182 | static int old_fingers; | 188 | static int old_fingers; |
183 | 189 | ||
184 | if (etd->fw_version_maj == 0x01) { | 190 | if (etd->fw_version < 0x020000) { |
185 | /* byte 0: D U p1 p2 1 p3 R L | 191 | /* |
186 | byte 1: f 0 th tw x9 x8 y9 y8 */ | 192 | * byte 0: D U p1 p2 1 p3 R L |
193 | * byte 1: f 0 th tw x9 x8 y9 y8 | ||
194 | */ | ||
187 | fingers = ((packet[1] & 0x80) >> 7) + | 195 | fingers = ((packet[1] & 0x80) >> 7) + |
188 | ((packet[1] & 0x30) >> 4); | 196 | ((packet[1] & 0x30) >> 4); |
189 | } else { | 197 | } else { |
190 | /* byte 0: n1 n0 p2 p1 1 p3 R L | 198 | /* |
191 | byte 1: 0 0 0 0 x9 x8 y9 y8 */ | 199 | * byte 0: n1 n0 p2 p1 1 p3 R L |
200 | * byte 1: 0 0 0 0 x9 x8 y9 y8 | ||
201 | */ | ||
192 | fingers = (packet[0] & 0xc0) >> 6; | 202 | fingers = (packet[0] & 0xc0) >> 6; |
193 | } | 203 | } |
194 | 204 | ||
195 | if (etd->jumpy_cursor) { | 205 | if (etd->jumpy_cursor) { |
196 | /* Discard packets that are likely to have bogus coordinates */ | 206 | /* Discard packets that are likely to have bogus coordinates */ |
197 | if (fingers > old_fingers) { | 207 | if (fingers > old_fingers) { |
198 | elantech_debug("elantech.c: discarding packet\n"); | 208 | elantech_debug("discarding packet\n"); |
199 | goto discard_packet_v1; | 209 | goto discard_packet_v1; |
200 | } | 210 | } |
201 | } | 211 | } |
202 | 212 | ||
203 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 213 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
204 | 214 | ||
205 | /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 | 215 | /* |
206 | byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ | 216 | * byte 2: x7 x6 x5 x4 x3 x2 x1 x0 |
217 | * byte 3: y7 y6 y5 y4 y3 y2 y1 y0 | ||
218 | */ | ||
207 | if (fingers) { | 219 | if (fingers) { |
208 | input_report_abs(dev, ABS_X, | 220 | input_report_abs(dev, ABS_X, |
209 | ((packet[1] & 0x0c) << 6) | packet[2]); | 221 | ((packet[1] & 0x0c) << 6) | packet[2]); |
210 | input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - | 222 | input_report_abs(dev, ABS_Y, |
211 | (((packet[1] & 0x03) << 8) | packet[3])); | 223 | ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); |
212 | } | 224 | } |
213 | 225 | ||
214 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 226 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
@@ -217,7 +229,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
217 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 229 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
218 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 230 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
219 | 231 | ||
220 | if ((etd->fw_version_maj == 0x01) && | 232 | if (etd->fw_version < 0x020000 && |
221 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 233 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
222 | /* rocker up */ | 234 | /* rocker up */ |
223 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 235 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
@@ -247,34 +259,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
247 | 259 | ||
248 | switch (fingers) { | 260 | switch (fingers) { |
249 | case 1: | 261 | case 1: |
250 | /* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 | 262 | /* |
251 | byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ | 263 | * byte 1: . . . . . x10 x9 x8 |
252 | input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); | 264 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
253 | /* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 | 265 | */ |
254 | byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ | 266 | input_report_abs(dev, ABS_X, |
255 | input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - | 267 | ((packet[1] & 0x07) << 8) | packet[2]); |
256 | ((packet[4] << 8) | packet[5])); | 268 | /* |
269 | * byte 4: . . . . . . y9 y8 | ||
270 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
271 | */ | ||
272 | input_report_abs(dev, ABS_Y, | ||
273 | ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); | ||
257 | break; | 274 | break; |
258 | 275 | ||
259 | case 2: | 276 | case 2: |
260 | /* The coordinate of each finger is reported separately with | 277 | /* |
261 | a lower resolution for two finger touches */ | 278 | * The coordinate of each finger is reported separately |
262 | /* byte 0: . . ay8 ax8 . . . . | 279 | * with a lower resolution for two finger touches: |
263 | byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ | 280 | * byte 0: . . ay8 ax8 . . . . |
281 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | ||
282 | */ | ||
264 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; | 283 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; |
265 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ | 284 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ |
266 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); | 285 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); |
267 | /* byte 3: . . by8 bx8 . . . . | 286 | /* |
268 | byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ | 287 | * byte 3: . . by8 bx8 . . . . |
288 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | ||
289 | */ | ||
269 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; | 290 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; |
270 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ | 291 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ |
271 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); | 292 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); |
272 | /* For compatibility with the X Synaptics driver scale up one | 293 | /* |
273 | coordinate and report as ordinary mouse movent */ | 294 | * For compatibility with the X Synaptics driver scale up |
295 | * one coordinate and report as ordinary mouse movent | ||
296 | */ | ||
274 | input_report_abs(dev, ABS_X, x1 << 2); | 297 | input_report_abs(dev, ABS_X, x1 << 2); |
275 | input_report_abs(dev, ABS_Y, y1 << 2); | 298 | input_report_abs(dev, ABS_Y, y1 << 2); |
276 | /* For compatibility with the proprietary X Elantech driver | 299 | /* |
277 | report both coordinates as hat coordinates */ | 300 | * For compatibility with the proprietary X Elantech driver |
301 | * report both coordinates as hat coordinates | ||
302 | */ | ||
278 | input_report_abs(dev, ABS_HAT0X, x1); | 303 | input_report_abs(dev, ABS_HAT0X, x1); |
279 | input_report_abs(dev, ABS_HAT0Y, y1); | 304 | input_report_abs(dev, ABS_HAT0Y, y1); |
280 | input_report_abs(dev, ABS_HAT1X, x2); | 305 | input_report_abs(dev, ABS_HAT1X, x2); |
@@ -298,7 +323,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
298 | unsigned char p1, p2, p3; | 323 | unsigned char p1, p2, p3; |
299 | 324 | ||
300 | /* Parity bits are placed differently */ | 325 | /* Parity bits are placed differently */ |
301 | if (etd->fw_version_maj == 0x01) { | 326 | if (etd->fw_version < 0x020000) { |
302 | /* byte 0: D U p1 p2 1 p3 R L */ | 327 | /* byte 0: D U p1 p2 1 p3 R L */ |
303 | p1 = (packet[0] & 0x20) >> 5; | 328 | p1 = (packet[0] & 0x20) >> 5; |
304 | p2 = (packet[0] & 0x10) >> 4; | 329 | p2 = (packet[0] & 0x10) >> 4; |
@@ -390,23 +415,21 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
390 | if (rc == 0) | 415 | if (rc == 0) |
391 | break; | 416 | break; |
392 | tries--; | 417 | tries--; |
393 | elantech_debug("elantech.c: retrying read (%d).\n", | 418 | elantech_debug("retrying read (%d).\n", tries); |
394 | tries); | ||
395 | msleep(ETP_READ_BACK_DELAY); | 419 | msleep(ETP_READ_BACK_DELAY); |
396 | } while (tries > 0); | 420 | } while (tries > 0); |
397 | 421 | ||
398 | if (rc) { | 422 | if (rc) { |
399 | pr_err("elantech.c: failed to read back register 0x10.\n"); | 423 | pr_err("failed to read back register 0x10.\n"); |
400 | } else if (etd->hw_version == 1 && | 424 | } else if (etd->hw_version == 1 && |
401 | !(val & ETP_R10_ABSOLUTE_MODE)) { | 425 | !(val & ETP_R10_ABSOLUTE_MODE)) { |
402 | pr_err("elantech.c: touchpad refuses " | 426 | pr_err("touchpad refuses to switch to absolute mode.\n"); |
403 | "to switch to absolute mode.\n"); | ||
404 | rc = -1; | 427 | rc = -1; |
405 | } | 428 | } |
406 | } | 429 | } |
407 | 430 | ||
408 | if (rc) | 431 | if (rc) |
409 | pr_err("elantech.c: failed to initialise registers.\n"); | 432 | pr_err("failed to initialise registers.\n"); |
410 | 433 | ||
411 | return rc; | 434 | return rc; |
412 | } | 435 | } |
@@ -434,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
434 | switch (etd->hw_version) { | 457 | switch (etd->hw_version) { |
435 | case 1: | 458 | case 1: |
436 | /* Rocker button */ | 459 | /* Rocker button */ |
437 | if ((etd->fw_version_maj == 0x01) && | 460 | if (etd->fw_version < 0x020000 && |
438 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 461 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
439 | __set_bit(BTN_FORWARD, dev->keybit); | 462 | __set_bit(BTN_FORWARD, dev->keybit); |
440 | __set_bit(BTN_BACK, dev->keybit); | 463 | __set_bit(BTN_BACK, dev->keybit); |
@@ -552,6 +575,24 @@ static struct attribute_group elantech_attr_group = { | |||
552 | .attrs = elantech_attrs, | 575 | .attrs = elantech_attrs, |
553 | }; | 576 | }; |
554 | 577 | ||
578 | static bool elantech_is_signature_valid(const unsigned char *param) | ||
579 | { | ||
580 | static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10 }; | ||
581 | int i; | ||
582 | |||
583 | if (param[0] == 0) | ||
584 | return false; | ||
585 | |||
586 | if (param[1] == 0) | ||
587 | return true; | ||
588 | |||
589 | for (i = 0; i < ARRAY_SIZE(rates); i++) | ||
590 | if (param[2] == rates[i]) | ||
591 | return false; | ||
592 | |||
593 | return true; | ||
594 | } | ||
595 | |||
555 | /* | 596 | /* |
556 | * Use magic knock to detect Elantech touchpad | 597 | * Use magic knock to detect Elantech touchpad |
557 | */ | 598 | */ |
@@ -567,7 +608,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
567 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 608 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
568 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 609 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
569 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 610 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
570 | pr_debug("elantech.c: sending Elantech magic knock failed.\n"); | 611 | pr_debug("sending Elantech magic knock failed.\n"); |
571 | return -1; | 612 | return -1; |
572 | } | 613 | } |
573 | 614 | ||
@@ -576,8 +617,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
576 | * set of magic numbers | 617 | * set of magic numbers |
577 | */ | 618 | */ |
578 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { | 619 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { |
579 | pr_debug("elantech.c: " | 620 | pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", |
580 | "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", | ||
581 | param[0], param[1], param[2]); | 621 | param[0], param[1], param[2]); |
582 | return -1; | 622 | return -1; |
583 | } | 623 | } |
@@ -588,16 +628,20 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
588 | * to Elantech magic knock and there might be more. | 628 | * to Elantech magic knock and there might be more. |
589 | */ | 629 | */ |
590 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 630 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
591 | pr_debug("elantech.c: failed to query firmware version.\n"); | 631 | pr_debug("failed to query firmware version.\n"); |
592 | return -1; | 632 | return -1; |
593 | } | 633 | } |
594 | 634 | ||
595 | pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", | 635 | pr_debug("Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", |
596 | param[0], param[1], param[2]); | 636 | param[0], param[1], param[2]); |
597 | 637 | ||
598 | if (param[0] == 0 || param[1] != 0) { | 638 | if (!elantech_is_signature_valid(param)) { |
599 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); | 639 | if (!force_elantech) { |
600 | return -1; | 640 | pr_debug("Probably not a real Elantech touchpad. Aborting.\n"); |
641 | return -1; | ||
642 | } | ||
643 | |||
644 | pr_debug("Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); | ||
601 | } | 645 | } |
602 | 646 | ||
603 | if (set_properties) { | 647 | if (set_properties) { |
@@ -628,7 +672,7 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
628 | return -1; | 672 | return -1; |
629 | 673 | ||
630 | if (elantech_set_absolute_mode(psmouse)) { | 674 | if (elantech_set_absolute_mode(psmouse)) { |
631 | pr_err("elantech.c: failed to put touchpad back into absolute mode.\n"); | 675 | pr_err("failed to put touchpad back into absolute mode.\n"); |
632 | return -1; | 676 | return -1; |
633 | } | 677 | } |
634 | 678 | ||
@@ -656,17 +700,17 @@ int elantech_init(struct psmouse *psmouse) | |||
656 | * Do the version query again so we can store the result | 700 | * Do the version query again so we can store the result |
657 | */ | 701 | */ |
658 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 702 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
659 | pr_err("elantech.c: failed to query firmware version.\n"); | 703 | pr_err("failed to query firmware version.\n"); |
660 | goto init_fail; | 704 | goto init_fail; |
661 | } | 705 | } |
662 | etd->fw_version_maj = param[0]; | 706 | |
663 | etd->fw_version_min = param[2]; | 707 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
664 | 708 | ||
665 | /* | 709 | /* |
666 | * Assume every version greater than this is new EeePC style | 710 | * Assume every version greater than this is new EeePC style |
667 | * hardware with 6 byte packets | 711 | * hardware with 6 byte packets |
668 | */ | 712 | */ |
669 | if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) { | 713 | if (etd->fw_version >= 0x020030) { |
670 | etd->hw_version = 2; | 714 | etd->hw_version = 2; |
671 | /* For now show extra debug information */ | 715 | /* For now show extra debug information */ |
672 | etd->debug = 1; | 716 | etd->debug = 1; |
@@ -676,14 +720,15 @@ int elantech_init(struct psmouse *psmouse) | |||
676 | etd->hw_version = 1; | 720 | etd->hw_version = 1; |
677 | etd->paritycheck = 1; | 721 | etd->paritycheck = 1; |
678 | } | 722 | } |
679 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n", | 723 | |
680 | etd->hw_version, etd->fw_version_maj, etd->fw_version_min); | 724 | pr_info("assuming hardware version %d, firmware version %d.%d.%d\n", |
725 | etd->hw_version, param[0], param[1], param[2]); | ||
681 | 726 | ||
682 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | 727 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { |
683 | pr_err("elantech.c: failed to query capabilities.\n"); | 728 | pr_err("failed to query capabilities.\n"); |
684 | goto init_fail; | 729 | goto init_fail; |
685 | } | 730 | } |
686 | pr_info("elantech.c: Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", | 731 | pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", |
687 | param[0], param[1], param[2]); | 732 | param[0], param[1], param[2]); |
688 | etd->capabilities = param[0]; | 733 | etd->capabilities = param[0]; |
689 | 734 | ||
@@ -692,14 +737,13 @@ int elantech_init(struct psmouse *psmouse) | |||
692 | * a touch action starts causing the mouse cursor or scrolled page | 737 | * a touch action starts causing the mouse cursor or scrolled page |
693 | * to jump. Enable a workaround. | 738 | * to jump. Enable a workaround. |
694 | */ | 739 | */ |
695 | if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { | 740 | if (etd->fw_version == 0x020022) { |
696 | pr_info("elantech.c: firmware version 2.34 detected, " | 741 | pr_info("firmware version 2.0.34 detected, enabling jumpy cursor workaround\n"); |
697 | "enabling jumpy cursor workaround\n"); | ||
698 | etd->jumpy_cursor = 1; | 742 | etd->jumpy_cursor = 1; |
699 | } | 743 | } |
700 | 744 | ||
701 | if (elantech_set_absolute_mode(psmouse)) { | 745 | if (elantech_set_absolute_mode(psmouse)) { |
702 | pr_err("elantech.c: failed to put touchpad into absolute mode.\n"); | 746 | pr_err("failed to put touchpad into absolute mode.\n"); |
703 | goto init_fail; | 747 | goto init_fail; |
704 | } | 748 | } |
705 | 749 | ||
@@ -708,8 +752,7 @@ int elantech_init(struct psmouse *psmouse) | |||
708 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, | 752 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, |
709 | &elantech_attr_group); | 753 | &elantech_attr_group); |
710 | if (error) { | 754 | if (error) { |
711 | pr_err("elantech.c: failed to create sysfs attributes, error: %d.\n", | 755 | pr_err("failed to create sysfs attributes, error: %d.\n", error); |
712 | error); | ||
713 | goto init_fail; | 756 | goto init_fail; |
714 | } | 757 | } |
715 | 758 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index feac5f7af966..ac57bde1bb9f 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -100,11 +100,10 @@ struct elantech_data { | |||
100 | unsigned char reg_26; | 100 | unsigned char reg_26; |
101 | unsigned char debug; | 101 | unsigned char debug; |
102 | unsigned char capabilities; | 102 | unsigned char capabilities; |
103 | unsigned char fw_version_maj; | ||
104 | unsigned char fw_version_min; | ||
105 | unsigned char hw_version; | ||
106 | unsigned char paritycheck; | 103 | unsigned char paritycheck; |
107 | unsigned char jumpy_cursor; | 104 | unsigned char jumpy_cursor; |
105 | unsigned char hw_version; | ||
106 | unsigned int fw_version; | ||
108 | unsigned char parity[256]; | 107 | unsigned char parity[256]; |
109 | }; | 108 | }; |
110 | 109 | ||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 08d66d820d2b..1d2205b24800 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -40,8 +40,8 @@ | |||
40 | #include "psmouse.h" | 40 | #include "psmouse.h" |
41 | #include "hgpk.h" | 41 | #include "hgpk.h" |
42 | 42 | ||
43 | static int tpdebug; | 43 | static bool tpdebug; |
44 | module_param(tpdebug, int, 0644); | 44 | module_param(tpdebug, bool, 0644); |
45 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); | 45 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); |
46 | 46 | ||
47 | static int recalib_delta = 100; | 47 | static int recalib_delta = 100; |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 543c240a85f2..c9983aee9082 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -56,36 +56,36 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
56 | /* Logitech extended packet */ | 56 | /* Logitech extended packet */ |
57 | switch ((packet[1] >> 4) | (packet[0] & 0x30)) { | 57 | switch ((packet[1] >> 4) | (packet[0] & 0x30)) { |
58 | 58 | ||
59 | case 0x0d: /* Mouse extra info */ | 59 | case 0x0d: /* Mouse extra info */ |
60 | 60 | ||
61 | input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, | 61 | input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, |
62 | (int) (packet[2] & 8) - (int) (packet[2] & 7)); | 62 | (int) (packet[2] & 8) - (int) (packet[2] & 7)); |
63 | input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); | 63 | input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); |
64 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); | 64 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); |
65 | 65 | ||
66 | break; | 66 | break; |
67 | 67 | ||
68 | case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ | 68 | case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ |
69 | 69 | ||
70 | input_report_key(dev, BTN_SIDE, (packet[2]) & 1); | 70 | input_report_key(dev, BTN_SIDE, (packet[2]) & 1); |
71 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); | 71 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); |
72 | input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); | 72 | input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); |
73 | input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); | 73 | input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); |
74 | input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); | 74 | input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); |
75 | 75 | ||
76 | break; | 76 | break; |
77 | 77 | ||
78 | case 0x0f: /* TouchPad extra info */ | 78 | case 0x0f: /* TouchPad extra info */ |
79 | 79 | ||
80 | input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, | 80 | input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, |
81 | (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); | 81 | (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); |
82 | packet[0] = packet[2] | 0x08; | 82 | packet[0] = packet[2] | 0x08; |
83 | break; | 83 | break; |
84 | 84 | ||
85 | #ifdef DEBUG | 85 | #ifdef DEBUG |
86 | default: | 86 | default: |
87 | printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", | 87 | printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", |
88 | (packet[1] >> 4) | (packet[0] & 0x30)); | 88 | (packet[1] >> 4) | (packet[0] & 0x30)); |
89 | #endif | 89 | #endif |
90 | } | 90 | } |
91 | } else { | 91 | } else { |
@@ -250,7 +250,6 @@ static const struct ps2pp_info *get_model_info(unsigned char model) | |||
250 | if (model == ps2pp_list[i].model) | 250 | if (model == ps2pp_list[i].model) |
251 | return &ps2pp_list[i]; | 251 | return &ps2pp_list[i]; |
252 | 252 | ||
253 | printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); | ||
254 | return NULL; | 253 | return NULL; |
255 | } | 254 | } |
256 | 255 | ||
@@ -285,31 +284,32 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, | |||
285 | __set_bit(REL_HWHEEL, input_dev->relbit); | 284 | __set_bit(REL_HWHEEL, input_dev->relbit); |
286 | 285 | ||
287 | switch (model_info->kind) { | 286 | switch (model_info->kind) { |
288 | case PS2PP_KIND_WHEEL: | ||
289 | psmouse->name = "Wheel Mouse"; | ||
290 | break; | ||
291 | |||
292 | case PS2PP_KIND_MX: | ||
293 | psmouse->name = "MX Mouse"; | ||
294 | break; | ||
295 | 287 | ||
296 | case PS2PP_KIND_TP3: | 288 | case PS2PP_KIND_WHEEL: |
297 | psmouse->name = "TouchPad 3"; | 289 | psmouse->name = "Wheel Mouse"; |
298 | break; | 290 | break; |
299 | 291 | ||
300 | case PS2PP_KIND_TRACKMAN: | 292 | case PS2PP_KIND_MX: |
301 | psmouse->name = "TrackMan"; | 293 | psmouse->name = "MX Mouse"; |
302 | break; | 294 | break; |
303 | 295 | ||
304 | default: | 296 | case PS2PP_KIND_TP3: |
305 | /* | 297 | psmouse->name = "TouchPad 3"; |
306 | * Set name to "Mouse" only when using PS2++, | 298 | break; |
307 | * otherwise let other protocols define suitable | 299 | |
308 | * name | 300 | case PS2PP_KIND_TRACKMAN: |
309 | */ | 301 | psmouse->name = "TrackMan"; |
310 | if (using_ps2pp) | 302 | break; |
311 | psmouse->name = "Mouse"; | 303 | |
312 | break; | 304 | default: |
305 | /* | ||
306 | * Set name to "Mouse" only when using PS2++, | ||
307 | * otherwise let other protocols define suitable | ||
308 | * name | ||
309 | */ | ||
310 | if (using_ps2pp) | ||
311 | psmouse->name = "Mouse"; | ||
312 | break; | ||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
@@ -343,7 +343,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
343 | if (!model || !buttons) | 343 | if (!model || !buttons) |
344 | return -1; | 344 | return -1; |
345 | 345 | ||
346 | if ((model_info = get_model_info(model)) != NULL) { | 346 | model_info = get_model_info(model); |
347 | if (model_info) { | ||
347 | 348 | ||
348 | /* | 349 | /* |
349 | * Do Logitech PS2++ / PS2T++ magic init. | 350 | * Do Logitech PS2++ / PS2T++ magic init. |
@@ -379,6 +380,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
379 | use_ps2pp = true; | 380 | use_ps2pp = true; |
380 | } | 381 | } |
381 | } | 382 | } |
383 | |||
384 | } else { | ||
385 | printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); | ||
382 | } | 386 | } |
383 | 387 | ||
384 | if (set_properties) { | 388 | if (set_properties) { |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index d8c0c8d6992c..979c50215282 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmoused_wq; | |||
110 | struct psmouse_protocol { | 110 | struct psmouse_protocol { |
111 | enum psmouse_type type; | 111 | enum psmouse_type type; |
112 | bool maxproto; | 112 | bool maxproto; |
113 | bool ignore_parity; /* Protocol should ignore parity errors from KBC */ | ||
113 | const char *name; | 114 | const char *name; |
114 | const char *alias; | 115 | const char *alias; |
115 | int (*detect)(struct psmouse *, bool); | 116 | int (*detect)(struct psmouse *, bool); |
@@ -146,18 +147,18 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | |||
146 | 147 | ||
147 | if (psmouse->type == PSMOUSE_IMEX) { | 148 | if (psmouse->type == PSMOUSE_IMEX) { |
148 | switch (packet[3] & 0xC0) { | 149 | switch (packet[3] & 0xC0) { |
149 | case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ | 150 | case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ |
150 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); | 151 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); |
151 | break; | 152 | break; |
152 | case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ | 153 | case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ |
153 | input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); | 154 | input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); |
154 | break; | 155 | break; |
155 | case 0x00: | 156 | case 0x00: |
156 | case 0xC0: | 157 | case 0xC0: |
157 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); | 158 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); |
158 | input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); | 159 | input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); |
159 | input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); | 160 | input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); |
160 | break; | 161 | break; |
161 | } | 162 | } |
162 | } | 163 | } |
163 | 164 | ||
@@ -246,31 +247,31 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
246 | psmouse_ret_t rc = psmouse->protocol_handler(psmouse); | 247 | psmouse_ret_t rc = psmouse->protocol_handler(psmouse); |
247 | 248 | ||
248 | switch (rc) { | 249 | switch (rc) { |
249 | case PSMOUSE_BAD_DATA: | 250 | case PSMOUSE_BAD_DATA: |
250 | if (psmouse->state == PSMOUSE_ACTIVATED) { | 251 | if (psmouse->state == PSMOUSE_ACTIVATED) { |
251 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", | 252 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", |
252 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 253 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
253 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { | 254 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { |
254 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 255 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
255 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); | 256 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); |
256 | serio_reconnect(psmouse->ps2dev.serio); | 257 | serio_reconnect(psmouse->ps2dev.serio); |
257 | return -1; | 258 | return -1; |
258 | } | ||
259 | } | ||
260 | psmouse->pktcnt = 0; | ||
261 | break; | ||
262 | |||
263 | case PSMOUSE_FULL_PACKET: | ||
264 | psmouse->pktcnt = 0; | ||
265 | if (psmouse->out_of_sync_cnt) { | ||
266 | psmouse->out_of_sync_cnt = 0; | ||
267 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | ||
268 | psmouse->name, psmouse->phys); | ||
269 | } | 259 | } |
270 | break; | 260 | } |
261 | psmouse->pktcnt = 0; | ||
262 | break; | ||
263 | |||
264 | case PSMOUSE_FULL_PACKET: | ||
265 | psmouse->pktcnt = 0; | ||
266 | if (psmouse->out_of_sync_cnt) { | ||
267 | psmouse->out_of_sync_cnt = 0; | ||
268 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | ||
269 | psmouse->name, psmouse->phys); | ||
270 | } | ||
271 | break; | ||
271 | 272 | ||
272 | case PSMOUSE_GOOD_DATA: | 273 | case PSMOUSE_GOOD_DATA: |
273 | break; | 274 | break; |
274 | } | 275 | } |
275 | return 0; | 276 | return 0; |
276 | } | 277 | } |
@@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
288 | if (psmouse->state == PSMOUSE_IGNORE) | 289 | if (psmouse->state == PSMOUSE_IGNORE) |
289 | goto out; | 290 | goto out; |
290 | 291 | ||
291 | if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) { | 292 | if (unlikely((flags & SERIO_TIMEOUT) || |
293 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { | ||
294 | |||
292 | if (psmouse->state == PSMOUSE_ACTIVATED) | 295 | if (psmouse->state == PSMOUSE_ACTIVATED) |
293 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", | 296 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", |
294 | flags & SERIO_TIMEOUT ? " timeout" : "", | 297 | flags & SERIO_TIMEOUT ? " timeout" : "", |
@@ -759,6 +762,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
759 | .name = "PS/2", | 762 | .name = "PS/2", |
760 | .alias = "bare", | 763 | .alias = "bare", |
761 | .maxproto = true, | 764 | .maxproto = true, |
765 | .ignore_parity = true, | ||
762 | .detect = ps2bare_detect, | 766 | .detect = ps2bare_detect, |
763 | }, | 767 | }, |
764 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | 768 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP |
@@ -786,6 +790,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
786 | .name = "ImPS/2", | 790 | .name = "ImPS/2", |
787 | .alias = "imps", | 791 | .alias = "imps", |
788 | .maxproto = true, | 792 | .maxproto = true, |
793 | .ignore_parity = true, | ||
789 | .detect = intellimouse_detect, | 794 | .detect = intellimouse_detect, |
790 | }, | 795 | }, |
791 | { | 796 | { |
@@ -793,6 +798,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
793 | .name = "ImExPS/2", | 798 | .name = "ImExPS/2", |
794 | .alias = "exps", | 799 | .alias = "exps", |
795 | .maxproto = true, | 800 | .maxproto = true, |
801 | .ignore_parity = true, | ||
796 | .detect = im_explorer_detect, | 802 | .detect = im_explorer_detect, |
797 | }, | 803 | }, |
798 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 804 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
@@ -1222,6 +1228,7 @@ static void psmouse_disconnect(struct serio *serio) | |||
1222 | static int psmouse_switch_protocol(struct psmouse *psmouse, | 1228 | static int psmouse_switch_protocol(struct psmouse *psmouse, |
1223 | const struct psmouse_protocol *proto) | 1229 | const struct psmouse_protocol *proto) |
1224 | { | 1230 | { |
1231 | const struct psmouse_protocol *selected_proto; | ||
1225 | struct input_dev *input_dev = psmouse->dev; | 1232 | struct input_dev *input_dev = psmouse->dev; |
1226 | 1233 | ||
1227 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; | 1234 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
@@ -1238,16 +1245,21 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1238 | psmouse->pktsize = 3; | 1245 | psmouse->pktsize = 3; |
1239 | 1246 | ||
1240 | if (proto && (proto->detect || proto->init)) { | 1247 | if (proto && (proto->detect || proto->init)) { |
1241 | if (proto->detect && proto->detect(psmouse, 1) < 0) | 1248 | if (proto->detect && proto->detect(psmouse, true) < 0) |
1242 | return -1; | 1249 | return -1; |
1243 | 1250 | ||
1244 | if (proto->init && proto->init(psmouse) < 0) | 1251 | if (proto->init && proto->init(psmouse) < 0) |
1245 | return -1; | 1252 | return -1; |
1246 | 1253 | ||
1247 | psmouse->type = proto->type; | 1254 | psmouse->type = proto->type; |
1248 | } else | 1255 | selected_proto = proto; |
1256 | } else { | ||
1249 | psmouse->type = psmouse_extensions(psmouse, | 1257 | psmouse->type = psmouse_extensions(psmouse, |
1250 | psmouse_max_proto, true); | 1258 | psmouse_max_proto, true); |
1259 | selected_proto = psmouse_protocol_by_type(psmouse->type); | ||
1260 | } | ||
1261 | |||
1262 | psmouse->ignore_parity = selected_proto->ignore_parity; | ||
1251 | 1263 | ||
1252 | /* | 1264 | /* |
1253 | * If mouse's packet size is 3 there is no point in polling the | 1265 | * If mouse's packet size is 3 there is no point in polling the |
@@ -1267,7 +1279,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1267 | psmouse->resync_time = 0; | 1279 | psmouse->resync_time = 0; |
1268 | 1280 | ||
1269 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", | 1281 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", |
1270 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | 1282 | selected_proto->name, psmouse->vendor, psmouse->name); |
1271 | 1283 | ||
1272 | input_dev->name = psmouse->devname; | 1284 | input_dev->name = psmouse->devname; |
1273 | input_dev->phys = psmouse->phys; | 1285 | input_dev->phys = psmouse->phys; |
@@ -1382,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1382 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1394 | struct psmouse *psmouse = serio_get_drvdata(serio); |
1383 | struct psmouse *parent = NULL; | 1395 | struct psmouse *parent = NULL; |
1384 | struct serio_driver *drv = serio->drv; | 1396 | struct serio_driver *drv = serio->drv; |
1397 | unsigned char type; | ||
1385 | int rc = -1; | 1398 | int rc = -1; |
1386 | 1399 | ||
1387 | if (!drv || !psmouse) { | 1400 | if (!drv || !psmouse) { |
@@ -1401,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio) | |||
1401 | if (psmouse->reconnect) { | 1414 | if (psmouse->reconnect) { |
1402 | if (psmouse->reconnect(psmouse)) | 1415 | if (psmouse->reconnect(psmouse)) |
1403 | goto out; | 1416 | goto out; |
1404 | } else if (psmouse_probe(psmouse) < 0 || | 1417 | } else { |
1405 | psmouse->type != psmouse_extensions(psmouse, | 1418 | psmouse_reset(psmouse); |
1406 | psmouse_max_proto, false)) { | 1419 | |
1407 | goto out; | 1420 | if (psmouse_probe(psmouse) < 0) |
1421 | goto out; | ||
1422 | |||
1423 | type = psmouse_extensions(psmouse, psmouse_max_proto, false); | ||
1424 | if (psmouse->type != type) | ||
1425 | goto out; | ||
1408 | } | 1426 | } |
1409 | 1427 | ||
1410 | /* ok, the device type (and capabilities) match the old one, | 1428 | /* ok, the device type (and capabilities) match the old one, |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index e053bdd137ff..593e910bfc7a 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -47,6 +47,7 @@ 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 | bool ignore_parity; | ||
50 | bool acks_disable_command; | 51 | bool acks_disable_command; |
51 | unsigned int model; | 52 | unsigned int model; |
52 | unsigned long last; | 53 | unsigned long last; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 026df6010161..40cea334ad13 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -36,6 +36,8 @@ | |||
36 | * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, | 36 | * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, |
37 | * section 2.3.2, which says that they should be valid regardless of the | 37 | * section 2.3.2, which says that they should be valid regardless of the |
38 | * actual size of the sensor. | 38 | * actual size of the sensor. |
39 | * Note that newer firmware allows querying device for maximum useable | ||
40 | * coordinates. | ||
39 | */ | 41 | */ |
40 | #define XMIN_NOMINAL 1472 | 42 | #define XMIN_NOMINAL 1472 |
41 | #define XMAX_NOMINAL 5472 | 43 | #define XMAX_NOMINAL 5472 |
@@ -137,7 +139,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
137 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) | 139 | if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) |
138 | return -1; | 140 | return -1; |
139 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 141 | priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
140 | priv->ext_cap = 0; | 142 | priv->ext_cap = priv->ext_cap_0c = 0; |
143 | |||
141 | if (!SYN_CAP_VALID(priv->capabilities)) | 144 | if (!SYN_CAP_VALID(priv->capabilities)) |
142 | return -1; | 145 | return -1; |
143 | 146 | ||
@@ -150,7 +153,7 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
150 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { | 153 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { |
151 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { | 154 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { |
152 | printk(KERN_ERR "Synaptics claims to have extended capabilities," | 155 | printk(KERN_ERR "Synaptics claims to have extended capabilities," |
153 | " but I'm not able to read them."); | 156 | " but I'm not able to read them.\n"); |
154 | } else { | 157 | } else { |
155 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 158 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
156 | 159 | ||
@@ -162,6 +165,16 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
162 | priv->ext_cap &= 0xff0fff; | 165 | priv->ext_cap &= 0xff0fff; |
163 | } | 166 | } |
164 | } | 167 | } |
168 | |||
169 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { | ||
170 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { | ||
171 | printk(KERN_ERR "Synaptics claims to have extended capability 0x0c," | ||
172 | " but I'm not able to read it.\n"); | ||
173 | } else { | ||
174 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | ||
175 | } | ||
176 | } | ||
177 | |||
165 | return 0; | 178 | return 0; |
166 | } | 179 | } |
167 | 180 | ||
@@ -183,23 +196,33 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
183 | } | 196 | } |
184 | 197 | ||
185 | /* | 198 | /* |
186 | * Read touchpad resolution | 199 | * Read touchpad resolution and maximum reported coordinates |
187 | * Resolution is left zero if touchpad does not support the query | 200 | * Resolution is left zero if touchpad does not support the query |
188 | */ | 201 | */ |
189 | static int synaptics_resolution(struct psmouse *psmouse) | 202 | static int synaptics_resolution(struct psmouse *psmouse) |
190 | { | 203 | { |
191 | struct synaptics_data *priv = psmouse->private; | 204 | struct synaptics_data *priv = psmouse->private; |
192 | unsigned char res[3]; | 205 | unsigned char res[3]; |
206 | unsigned char max[3]; | ||
193 | 207 | ||
194 | if (SYN_ID_MAJOR(priv->identity) < 4) | 208 | if (SYN_ID_MAJOR(priv->identity) < 4) |
195 | return 0; | ||
196 | 209 | ||
197 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res)) | 210 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { |
198 | return 0; | 211 | if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { |
212 | priv->x_res = res[0]; /* x resolution in units/mm */ | ||
213 | priv->y_res = res[2]; /* y resolution in units/mm */ | ||
214 | } | ||
215 | } | ||
199 | 216 | ||
200 | if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) { | 217 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
201 | priv->x_res = res[0]; /* x resolution in units/mm */ | 218 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
202 | priv->y_res = res[2]; /* y resolution in units/mm */ | 219 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) { |
220 | printk(KERN_ERR "Synaptics claims to have dimensions query," | ||
221 | " but I'm not able to read it.\n"); | ||
222 | } else { | ||
223 | priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1); | ||
224 | priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3); | ||
225 | } | ||
203 | } | 226 | } |
204 | 227 | ||
205 | return 0; | 228 | return 0; |
@@ -348,7 +371,15 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
348 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 371 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
349 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 372 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
350 | 373 | ||
351 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | 374 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
375 | /* | ||
376 | * Clickpad's button is transmitted as middle button, | ||
377 | * however, since it is primary button, we will report | ||
378 | * it as BTN_LEFT. | ||
379 | */ | ||
380 | hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | ||
381 | |||
382 | } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | ||
352 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; | 383 | hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; |
353 | if (hw->w == 2) | 384 | if (hw->w == 2) |
354 | hw->scroll = (signed char)(buf[1]); | 385 | hw->scroll = (signed char)(buf[1]); |
@@ -501,19 +532,20 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha | |||
501 | return 0; | 532 | return 0; |
502 | 533 | ||
503 | switch (pkt_type) { | 534 | switch (pkt_type) { |
504 | case SYN_NEWABS: | ||
505 | case SYN_NEWABS_RELAXED: | ||
506 | return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx]; | ||
507 | 535 | ||
508 | case SYN_NEWABS_STRICT: | 536 | case SYN_NEWABS: |
509 | return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx]; | 537 | case SYN_NEWABS_RELAXED: |
538 | return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx]; | ||
510 | 539 | ||
511 | case SYN_OLDABS: | 540 | case SYN_NEWABS_STRICT: |
512 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; | 541 | return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx]; |
513 | 542 | ||
514 | default: | 543 | case SYN_OLDABS: |
515 | printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); | 544 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; |
516 | return 0; | 545 | |
546 | default: | ||
547 | printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); | ||
548 | return 0; | ||
517 | } | 549 | } |
518 | } | 550 | } |
519 | 551 | ||
@@ -559,8 +591,10 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
559 | int i; | 591 | int i; |
560 | 592 | ||
561 | __set_bit(EV_ABS, dev->evbit); | 593 | __set_bit(EV_ABS, dev->evbit); |
562 | input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); | 594 | input_set_abs_params(dev, ABS_X, |
563 | input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); | 595 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); |
596 | input_set_abs_params(dev, ABS_Y, | ||
597 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); | ||
564 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 598 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
565 | __set_bit(ABS_TOOL_WIDTH, dev->absbit); | 599 | __set_bit(ABS_TOOL_WIDTH, dev->absbit); |
566 | 600 | ||
@@ -593,6 +627,12 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
593 | 627 | ||
594 | dev->absres[ABS_X] = priv->x_res; | 628 | dev->absres[ABS_X] = priv->x_res; |
595 | dev->absres[ABS_Y] = priv->y_res; | 629 | dev->absres[ABS_Y] = priv->y_res; |
630 | |||
631 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | ||
632 | /* Clickpads report only left button */ | ||
633 | __clear_bit(BTN_RIGHT, dev->keybit); | ||
634 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
635 | } | ||
596 | } | 636 | } |
597 | 637 | ||
598 | static void synaptics_disconnect(struct psmouse *psmouse) | 638 | static void synaptics_disconnect(struct psmouse *psmouse) |
@@ -697,10 +737,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
697 | 737 | ||
698 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 738 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
699 | 739 | ||
700 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", | 740 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
701 | SYN_ID_MODEL(priv->identity), | 741 | SYN_ID_MODEL(priv->identity), |
702 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 742 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
703 | priv->model_id, priv->capabilities, priv->ext_cap); | 743 | priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); |
704 | 744 | ||
705 | set_input_params(psmouse->dev, priv); | 745 | set_input_params(psmouse->dev, priv); |
706 | 746 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index f0f40a331dc8..7d4d5e12c0df 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 | 18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 |
19 | #define SYN_QUE_RESOLUTION 0x08 | 19 | #define SYN_QUE_RESOLUTION 0x08 |
20 | #define SYN_QUE_EXT_CAPAB 0x09 | 20 | #define SYN_QUE_EXT_CAPAB 0x09 |
21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c | ||
22 | #define SYN_QUE_EXT_DIMENSIONS 0x0d | ||
21 | 23 | ||
22 | /* synatics modes */ | 24 | /* synatics modes */ |
23 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) | 25 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) |
@@ -48,6 +50,9 @@ | |||
48 | #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) | 50 | #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) |
49 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) | 51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
50 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) | 52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) | ||
54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) | ||
55 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | ||
51 | 56 | ||
52 | /* synaptics modes query bits */ | 57 | /* synaptics modes query bits */ |
53 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 58 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -96,9 +101,10 @@ struct synaptics_data { | |||
96 | unsigned long int model_id; /* Model-ID */ | 101 | unsigned long int model_id; /* Model-ID */ |
97 | unsigned long int capabilities; /* Capabilities */ | 102 | unsigned long int capabilities; /* Capabilities */ |
98 | unsigned long int ext_cap; /* Extended Capabilities */ | 103 | unsigned long int ext_cap; /* Extended Capabilities */ |
104 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ | ||
99 | unsigned long int identity; /* Identification */ | 105 | unsigned long int identity; /* Identification */ |
100 | int x_res; /* X resolution in units/mm */ | 106 | unsigned int x_res, y_res; /* X/Y resolution in units/mm */ |
101 | int y_res; /* Y resolution in units/mm */ | 107 | unsigned int x_max, y_max; /* Max dimensions (from FW) */ |
102 | 108 | ||
103 | unsigned char pkt_type; /* packet type - old, new, etc */ | 109 | unsigned char pkt_type; /* packet type - old, new, etc */ |
104 | unsigned char mode; /* current mode byte */ | 110 | unsigned char mode; /* current mode byte */ |