diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/input/mouse | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/input/mouse')
30 files changed, 1024 insertions, 4467 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index cd6268cf7cd..9c1e6ee8353 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -322,33 +322,4 @@ config MOUSE_SYNAPTICS_I2C | |||
322 | To compile this driver as a module, choose M here: the | 322 | To compile this driver as a module, choose M here: the |
323 | module will be called synaptics_i2c. | 323 | module will be called synaptics_i2c. |
324 | 324 | ||
325 | config MOUSE_SYNAPTICS_USB | ||
326 | tristate "Synaptics USB device support" | ||
327 | depends on USB_ARCH_HAS_HCD | ||
328 | select USB | ||
329 | help | ||
330 | Say Y here if you want to use a Synaptics USB touchpad or pointing | ||
331 | stick. | ||
332 | |||
333 | While these devices emulate an USB mouse by default and can be used | ||
334 | with standard usbhid driver, this driver, together with its X.Org | ||
335 | counterpart, allows you to fully utilize capabilities of the device. | ||
336 | More information can be found at: | ||
337 | <http://jan-steinhoff.de/linux/synaptics-usb.html> | ||
338 | |||
339 | To compile this driver as a module, choose M here: the | ||
340 | module will be called synaptics_usb. | ||
341 | |||
342 | config MOUSE_NAVPOINT_PXA27x | ||
343 | tristate "Synaptics NavPoint (PXA27x SSP/SPI)" | ||
344 | depends on PXA27x && PXA_SSP | ||
345 | help | ||
346 | This driver adds support for the Synaptics NavPoint touchpad connected | ||
347 | to a PXA27x SSP port in SPI slave mode. The device emulates a mouse; | ||
348 | a tap or tap-and-a-half drag gesture emulates the left mouse button. | ||
349 | For example, use the xf86-input-evdev driver for an X pointing device. | ||
350 | |||
351 | To compile this driver as a module, choose M here: the | ||
352 | module will be called navpoint. | ||
353 | |||
354 | endif | 325 | endif |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 46ba7556fd4..570c84a4a65 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -12,14 +12,12 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | |||
12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
14 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o | 14 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o |
15 | obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x) += navpoint.o | ||
16 | obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o | 15 | obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o |
17 | obj-$(CONFIG_MOUSE_PS2) += psmouse.o | 16 | obj-$(CONFIG_MOUSE_PS2) += psmouse.o |
18 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o | 17 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o |
19 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o | 18 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o |
20 | obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o | 19 | obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o |
21 | obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o | 20 | obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o |
22 | obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o | ||
23 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 21 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
24 | 22 | ||
25 | psmouse-objs := psmouse-base.o synaptics.o | 23 | psmouse-objs := psmouse-base.o synaptics.o |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index e229fa3cad9..99d58764ef0 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -17,63 +17,20 @@ | |||
17 | 17 | ||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/input/mt.h> | ||
21 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
22 | #include <linux/libps2.h> | 21 | #include <linux/libps2.h> |
23 | 22 | ||
24 | #include "psmouse.h" | 23 | #include "psmouse.h" |
25 | #include "alps.h" | 24 | #include "alps.h" |
26 | 25 | ||
27 | /* | 26 | #undef DEBUG |
28 | * Definitions for ALPS version 3 and 4 command mode protocol | 27 | #ifdef DEBUG |
29 | */ | 28 | #define dbg(format, arg...) printk(KERN_INFO "alps.c: " format "\n", ## arg) |
30 | #define ALPS_V3_X_MAX 2000 | 29 | #else |
31 | #define ALPS_V3_Y_MAX 1400 | 30 | #define dbg(format, arg...) do {} while (0) |
32 | 31 | #endif | |
33 | #define ALPS_BITMAP_X_BITS 15 | ||
34 | #define ALPS_BITMAP_Y_BITS 11 | ||
35 | |||
36 | #define ALPS_CMD_NIBBLE_10 0x01f2 | ||
37 | |||
38 | static const struct alps_nibble_commands alps_v3_nibble_commands[] = { | ||
39 | { PSMOUSE_CMD_SETPOLL, 0x00 }, /* 0 */ | ||
40 | { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */ | ||
41 | { PSMOUSE_CMD_SETSCALE21, 0x00 }, /* 2 */ | ||
42 | { PSMOUSE_CMD_SETRATE, 0x0a }, /* 3 */ | ||
43 | { PSMOUSE_CMD_SETRATE, 0x14 }, /* 4 */ | ||
44 | { PSMOUSE_CMD_SETRATE, 0x28 }, /* 5 */ | ||
45 | { PSMOUSE_CMD_SETRATE, 0x3c }, /* 6 */ | ||
46 | { PSMOUSE_CMD_SETRATE, 0x50 }, /* 7 */ | ||
47 | { PSMOUSE_CMD_SETRATE, 0x64 }, /* 8 */ | ||
48 | { PSMOUSE_CMD_SETRATE, 0xc8 }, /* 9 */ | ||
49 | { ALPS_CMD_NIBBLE_10, 0x00 }, /* a */ | ||
50 | { PSMOUSE_CMD_SETRES, 0x00 }, /* b */ | ||
51 | { PSMOUSE_CMD_SETRES, 0x01 }, /* c */ | ||
52 | { PSMOUSE_CMD_SETRES, 0x02 }, /* d */ | ||
53 | { PSMOUSE_CMD_SETRES, 0x03 }, /* e */ | ||
54 | { PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */ | ||
55 | }; | ||
56 | |||
57 | static const struct alps_nibble_commands alps_v4_nibble_commands[] = { | ||
58 | { PSMOUSE_CMD_ENABLE, 0x00 }, /* 0 */ | ||
59 | { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */ | ||
60 | { PSMOUSE_CMD_SETSCALE21, 0x00 }, /* 2 */ | ||
61 | { PSMOUSE_CMD_SETRATE, 0x0a }, /* 3 */ | ||
62 | { PSMOUSE_CMD_SETRATE, 0x14 }, /* 4 */ | ||
63 | { PSMOUSE_CMD_SETRATE, 0x28 }, /* 5 */ | ||
64 | { PSMOUSE_CMD_SETRATE, 0x3c }, /* 6 */ | ||
65 | { PSMOUSE_CMD_SETRATE, 0x50 }, /* 7 */ | ||
66 | { PSMOUSE_CMD_SETRATE, 0x64 }, /* 8 */ | ||
67 | { PSMOUSE_CMD_SETRATE, 0xc8 }, /* 9 */ | ||
68 | { ALPS_CMD_NIBBLE_10, 0x00 }, /* a */ | ||
69 | { PSMOUSE_CMD_SETRES, 0x00 }, /* b */ | ||
70 | { PSMOUSE_CMD_SETRES, 0x01 }, /* c */ | ||
71 | { PSMOUSE_CMD_SETRES, 0x02 }, /* d */ | ||
72 | { PSMOUSE_CMD_SETRES, 0x03 }, /* e */ | ||
73 | { PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */ | ||
74 | }; | ||
75 | |||
76 | 32 | ||
33 | #define ALPS_OLDPROTO 0x01 /* old style input */ | ||
77 | #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ | 34 | #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ |
78 | #define ALPS_PASS 0x04 /* device has a pass-through port */ | 35 | #define ALPS_PASS 0x04 /* device has a pass-through port */ |
79 | 36 | ||
@@ -85,33 +42,30 @@ static const struct alps_nibble_commands alps_v4_nibble_commands[] = { | |||
85 | 6-byte ALPS packet */ | 42 | 6-byte ALPS packet */ |
86 | 43 | ||
87 | static const struct alps_model_info alps_model_data[] = { | 44 | static const struct alps_model_info alps_model_data[] = { |
88 | { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | 45 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ |
89 | { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */ | 46 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ |
90 | { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 47 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
91 | { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 48 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
92 | { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */ | 49 | { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */ |
93 | { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 50 | { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
94 | { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 51 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
95 | { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ | 52 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ |
96 | { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ | 53 | { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ |
97 | { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ | 54 | { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ |
98 | { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 55 | { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, |
99 | { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */ | 56 | { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */ |
100 | { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */ | 57 | { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */ |
101 | { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 58 | { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
102 | { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ | 59 | { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ |
103 | { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ | 60 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ |
104 | { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, | 61 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, |
105 | { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ | 62 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ |
106 | /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ | 63 | /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ |
107 | { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, | 64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, |
108 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | 65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, |
109 | { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
110 | { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, | 67 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, |
111 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | 68 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ |
112 | { { 0x73, 0x02, 0x64 }, 0x9b, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT }, | ||
113 | { { 0x73, 0x02, 0x64 }, 0x9d, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT }, | ||
114 | { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 }, | ||
115 | }; | 69 | }; |
116 | 70 | ||
117 | /* | 71 | /* |
@@ -120,7 +74,42 @@ static const struct alps_model_info alps_model_data[] = { | |||
120 | * isn't valid per PS/2 spec. | 74 | * isn't valid per PS/2 spec. |
121 | */ | 75 | */ |
122 | 76 | ||
123 | /* Packet formats are described in Documentation/input/alps.txt */ | 77 | /* |
78 | * PS/2 packet format | ||
79 | * | ||
80 | * byte 0: 0 0 YSGN XSGN 1 M R L | ||
81 | * byte 1: X7 X6 X5 X4 X3 X2 X1 X0 | ||
82 | * byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 | ||
83 | * | ||
84 | * Note that the device never signals overflow condition. | ||
85 | * | ||
86 | * ALPS absolute Mode - new format | ||
87 | * | ||
88 | * byte 0: 1 ? ? ? 1 ? ? ? | ||
89 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | ||
90 | * byte 2: 0 x10 x9 x8 x7 ? fin ges | ||
91 | * byte 3: 0 y9 y8 y7 1 M R L | ||
92 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 | ||
93 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 | ||
94 | * | ||
95 | * Dualpoint device -- interleaved packet format | ||
96 | * | ||
97 | * byte 0: 1 1 0 0 1 1 1 1 | ||
98 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | ||
99 | * byte 2: 0 x10 x9 x8 x7 0 fin ges | ||
100 | * byte 3: 0 0 YSGN XSGN 1 1 1 1 | ||
101 | * byte 4: X7 X6 X5 X4 X3 X2 X1 X0 | ||
102 | * byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 | ||
103 | * byte 6: 0 y9 y8 y7 1 m r l | ||
104 | * byte 7: 0 y6 y5 y4 y3 y2 y1 y0 | ||
105 | * byte 8: 0 z6 z5 z4 z3 z2 z1 z0 | ||
106 | * | ||
107 | * CAPITALS = stick, miniscules = touchpad | ||
108 | * | ||
109 | * ?'s can have different meanings on different models, | ||
110 | * such as wheel rotation, extra buttons, stick buttons | ||
111 | * on a dualpoint, etc. | ||
112 | */ | ||
124 | 113 | ||
125 | static bool alps_is_valid_first_byte(const struct alps_model_info *model, | 114 | static bool alps_is_valid_first_byte(const struct alps_model_info *model, |
126 | unsigned char data) | 115 | unsigned char data) |
@@ -155,7 +144,7 @@ static void alps_report_buttons(struct psmouse *psmouse, | |||
155 | input_sync(dev2); | 144 | input_sync(dev2); |
156 | } | 145 | } |
157 | 146 | ||
158 | static void alps_process_packet_v1_v2(struct psmouse *psmouse) | 147 | static void alps_process_packet(struct psmouse *psmouse) |
159 | { | 148 | { |
160 | struct alps_data *priv = psmouse->private; | 149 | struct alps_data *priv = psmouse->private; |
161 | const struct alps_model_info *model = priv->i; | 150 | const struct alps_model_info *model = priv->i; |
@@ -165,7 +154,7 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
165 | int x, y, z, ges, fin, left, right, middle; | 154 | int x, y, z, ges, fin, left, right, middle; |
166 | int back = 0, forward = 0; | 155 | int back = 0, forward = 0; |
167 | 156 | ||
168 | if (model->proto_version == ALPS_PROTO_V1) { | 157 | if (model->flags & ALPS_OLDPROTO) { |
169 | left = packet[2] & 0x10; | 158 | left = packet[2] & 0x10; |
170 | right = packet[2] & 0x08; | 159 | right = packet[2] & 0x08; |
171 | middle = 0; | 160 | middle = 0; |
@@ -257,464 +246,6 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
257 | input_sync(dev); | 246 | input_sync(dev); |
258 | } | 247 | } |
259 | 248 | ||
260 | /* | ||
261 | * Process bitmap data from v3 and v4 protocols. Returns the number of | ||
262 | * fingers detected. A return value of 0 means at least one of the | ||
263 | * bitmaps was empty. | ||
264 | * | ||
265 | * The bitmaps don't have enough data to track fingers, so this function | ||
266 | * only generates points representing a bounding box of all contacts. | ||
267 | * These points are returned in x1, y1, x2, and y2 when the return value | ||
268 | * is greater than 0. | ||
269 | */ | ||
270 | static int alps_process_bitmap(unsigned int x_map, unsigned int y_map, | ||
271 | int *x1, int *y1, int *x2, int *y2) | ||
272 | { | ||
273 | struct alps_bitmap_point { | ||
274 | int start_bit; | ||
275 | int num_bits; | ||
276 | }; | ||
277 | |||
278 | int fingers_x = 0, fingers_y = 0, fingers; | ||
279 | int i, bit, prev_bit; | ||
280 | struct alps_bitmap_point x_low = {0,}, x_high = {0,}; | ||
281 | struct alps_bitmap_point y_low = {0,}, y_high = {0,}; | ||
282 | struct alps_bitmap_point *point; | ||
283 | |||
284 | if (!x_map || !y_map) | ||
285 | return 0; | ||
286 | |||
287 | *x1 = *y1 = *x2 = *y2 = 0; | ||
288 | |||
289 | prev_bit = 0; | ||
290 | point = &x_low; | ||
291 | for (i = 0; x_map != 0; i++, x_map >>= 1) { | ||
292 | bit = x_map & 1; | ||
293 | if (bit) { | ||
294 | if (!prev_bit) { | ||
295 | point->start_bit = i; | ||
296 | fingers_x++; | ||
297 | } | ||
298 | point->num_bits++; | ||
299 | } else { | ||
300 | if (prev_bit) | ||
301 | point = &x_high; | ||
302 | else | ||
303 | point->num_bits = 0; | ||
304 | } | ||
305 | prev_bit = bit; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * y bitmap is reversed for what we need (lower positions are in | ||
310 | * higher bits), so we process from the top end. | ||
311 | */ | ||
312 | y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - ALPS_BITMAP_Y_BITS); | ||
313 | prev_bit = 0; | ||
314 | point = &y_low; | ||
315 | for (i = 0; y_map != 0; i++, y_map <<= 1) { | ||
316 | bit = y_map & (1 << (sizeof(y_map) * BITS_PER_BYTE - 1)); | ||
317 | if (bit) { | ||
318 | if (!prev_bit) { | ||
319 | point->start_bit = i; | ||
320 | fingers_y++; | ||
321 | } | ||
322 | point->num_bits++; | ||
323 | } else { | ||
324 | if (prev_bit) | ||
325 | point = &y_high; | ||
326 | else | ||
327 | point->num_bits = 0; | ||
328 | } | ||
329 | prev_bit = bit; | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * Fingers can overlap, so we use the maximum count of fingers | ||
334 | * on either axis as the finger count. | ||
335 | */ | ||
336 | fingers = max(fingers_x, fingers_y); | ||
337 | |||
338 | /* | ||
339 | * If total fingers is > 1 but either axis reports only a single | ||
340 | * contact, we have overlapping or adjacent fingers. For the | ||
341 | * purposes of creating a bounding box, divide the single contact | ||
342 | * (roughly) equally between the two points. | ||
343 | */ | ||
344 | if (fingers > 1) { | ||
345 | if (fingers_x == 1) { | ||
346 | i = x_low.num_bits / 2; | ||
347 | x_low.num_bits = x_low.num_bits - i; | ||
348 | x_high.start_bit = x_low.start_bit + i; | ||
349 | x_high.num_bits = max(i, 1); | ||
350 | } else if (fingers_y == 1) { | ||
351 | i = y_low.num_bits / 2; | ||
352 | y_low.num_bits = y_low.num_bits - i; | ||
353 | y_high.start_bit = y_low.start_bit + i; | ||
354 | y_high.num_bits = max(i, 1); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | *x1 = (ALPS_V3_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) / | ||
359 | (2 * (ALPS_BITMAP_X_BITS - 1)); | ||
360 | *y1 = (ALPS_V3_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) / | ||
361 | (2 * (ALPS_BITMAP_Y_BITS - 1)); | ||
362 | |||
363 | if (fingers > 1) { | ||
364 | *x2 = (ALPS_V3_X_MAX * (2 * x_high.start_bit + x_high.num_bits - 1)) / | ||
365 | (2 * (ALPS_BITMAP_X_BITS - 1)); | ||
366 | *y2 = (ALPS_V3_Y_MAX * (2 * y_high.start_bit + y_high.num_bits - 1)) / | ||
367 | (2 * (ALPS_BITMAP_Y_BITS - 1)); | ||
368 | } | ||
369 | |||
370 | return fingers; | ||
371 | } | ||
372 | |||
373 | static void alps_set_slot(struct input_dev *dev, int slot, bool active, | ||
374 | int x, int y) | ||
375 | { | ||
376 | input_mt_slot(dev, slot); | ||
377 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | ||
378 | if (active) { | ||
379 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
380 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers, | ||
385 | int x1, int y1, int x2, int y2) | ||
386 | { | ||
387 | alps_set_slot(dev, 0, num_fingers != 0, x1, y1); | ||
388 | alps_set_slot(dev, 1, num_fingers == 2, x2, y2); | ||
389 | } | ||
390 | |||
391 | static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) | ||
392 | { | ||
393 | struct alps_data *priv = psmouse->private; | ||
394 | unsigned char *packet = psmouse->packet; | ||
395 | struct input_dev *dev = priv->dev2; | ||
396 | int x, y, z, left, right, middle; | ||
397 | |||
398 | /* Sanity check packet */ | ||
399 | if (!(packet[0] & 0x40)) { | ||
400 | psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n"); | ||
401 | return; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * There's a special packet that seems to indicate the end | ||
406 | * of a stream of trackstick data. Filter these out. | ||
407 | */ | ||
408 | if (packet[1] == 0x7f && packet[2] == 0x7f && packet[4] == 0x7f) | ||
409 | return; | ||
410 | |||
411 | x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f)); | ||
412 | y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f)); | ||
413 | z = (packet[4] & 0x7c) >> 2; | ||
414 | |||
415 | /* | ||
416 | * The x and y values tend to be quite large, and when used | ||
417 | * alone the trackstick is difficult to use. Scale them down | ||
418 | * to compensate. | ||
419 | */ | ||
420 | x /= 8; | ||
421 | y /= 8; | ||
422 | |||
423 | input_report_rel(dev, REL_X, x); | ||
424 | input_report_rel(dev, REL_Y, -y); | ||
425 | |||
426 | /* | ||
427 | * Most ALPS models report the trackstick buttons in the touchpad | ||
428 | * packets, but a few report them here. No reliable way has been | ||
429 | * found to differentiate between the models upfront, so we enable | ||
430 | * the quirk in response to seeing a button press in the trackstick | ||
431 | * packet. | ||
432 | */ | ||
433 | left = packet[3] & 0x01; | ||
434 | right = packet[3] & 0x02; | ||
435 | middle = packet[3] & 0x04; | ||
436 | |||
437 | if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) && | ||
438 | (left || right || middle)) | ||
439 | priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS; | ||
440 | |||
441 | if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) { | ||
442 | input_report_key(dev, BTN_LEFT, left); | ||
443 | input_report_key(dev, BTN_RIGHT, right); | ||
444 | input_report_key(dev, BTN_MIDDLE, middle); | ||
445 | } | ||
446 | |||
447 | input_sync(dev); | ||
448 | return; | ||
449 | } | ||
450 | |||
451 | static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | ||
452 | { | ||
453 | struct alps_data *priv = psmouse->private; | ||
454 | unsigned char *packet = psmouse->packet; | ||
455 | struct input_dev *dev = psmouse->dev; | ||
456 | struct input_dev *dev2 = priv->dev2; | ||
457 | int x, y, z; | ||
458 | int left, right, middle; | ||
459 | int x1 = 0, y1 = 0, x2 = 0, y2 = 0; | ||
460 | int fingers = 0, bmap_fingers; | ||
461 | unsigned int x_bitmap, y_bitmap; | ||
462 | |||
463 | /* | ||
464 | * There's no single feature of touchpad position and bitmap packets | ||
465 | * that can be used to distinguish between them. We rely on the fact | ||
466 | * that a bitmap packet should always follow a position packet with | ||
467 | * bit 6 of packet[4] set. | ||
468 | */ | ||
469 | if (priv->multi_packet) { | ||
470 | /* | ||
471 | * Sometimes a position packet will indicate a multi-packet | ||
472 | * sequence, but then what follows is another position | ||
473 | * packet. Check for this, and when it happens process the | ||
474 | * position packet as usual. | ||
475 | */ | ||
476 | if (packet[0] & 0x40) { | ||
477 | fingers = (packet[5] & 0x3) + 1; | ||
478 | x_bitmap = ((packet[4] & 0x7e) << 8) | | ||
479 | ((packet[1] & 0x7f) << 2) | | ||
480 | ((packet[0] & 0x30) >> 4); | ||
481 | y_bitmap = ((packet[3] & 0x70) << 4) | | ||
482 | ((packet[2] & 0x7f) << 1) | | ||
483 | (packet[4] & 0x01); | ||
484 | |||
485 | bmap_fingers = alps_process_bitmap(x_bitmap, y_bitmap, | ||
486 | &x1, &y1, &x2, &y2); | ||
487 | |||
488 | /* | ||
489 | * We shouldn't report more than one finger if | ||
490 | * we don't have two coordinates. | ||
491 | */ | ||
492 | if (fingers > 1 && bmap_fingers < 2) | ||
493 | fingers = bmap_fingers; | ||
494 | |||
495 | /* Now process position packet */ | ||
496 | packet = priv->multi_data; | ||
497 | } else { | ||
498 | priv->multi_packet = 0; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | /* | ||
503 | * Bit 6 of byte 0 is not usually set in position packets. The only | ||
504 | * times it seems to be set is in situations where the data is | ||
505 | * suspect anyway, e.g. a palm resting flat on the touchpad. Given | ||
506 | * this combined with the fact that this bit is useful for filtering | ||
507 | * out misidentified bitmap packets, we reject anything with this | ||
508 | * bit set. | ||
509 | */ | ||
510 | if (packet[0] & 0x40) | ||
511 | return; | ||
512 | |||
513 | if (!priv->multi_packet && (packet[4] & 0x40)) { | ||
514 | priv->multi_packet = 1; | ||
515 | memcpy(priv->multi_data, packet, sizeof(priv->multi_data)); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | priv->multi_packet = 0; | ||
520 | |||
521 | left = packet[3] & 0x01; | ||
522 | right = packet[3] & 0x02; | ||
523 | middle = packet[3] & 0x04; | ||
524 | |||
525 | x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) | | ||
526 | ((packet[0] & 0x30) >> 4); | ||
527 | y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f); | ||
528 | z = packet[5] & 0x7f; | ||
529 | |||
530 | /* | ||
531 | * Sometimes the hardware sends a single packet with z = 0 | ||
532 | * in the middle of a stream. Real releases generate packets | ||
533 | * with x, y, and z all zero, so these seem to be flukes. | ||
534 | * Ignore them. | ||
535 | */ | ||
536 | if (x && y && !z) | ||
537 | return; | ||
538 | |||
539 | /* | ||
540 | * If we don't have MT data or the bitmaps were empty, we have | ||
541 | * to rely on ST data. | ||
542 | */ | ||
543 | if (!fingers) { | ||
544 | x1 = x; | ||
545 | y1 = y; | ||
546 | fingers = z > 0 ? 1 : 0; | ||
547 | } | ||
548 | |||
549 | if (z >= 64) | ||
550 | input_report_key(dev, BTN_TOUCH, 1); | ||
551 | else | ||
552 | input_report_key(dev, BTN_TOUCH, 0); | ||
553 | |||
554 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
555 | |||
556 | input_mt_report_finger_count(dev, fingers); | ||
557 | |||
558 | input_report_key(dev, BTN_LEFT, left); | ||
559 | input_report_key(dev, BTN_RIGHT, right); | ||
560 | input_report_key(dev, BTN_MIDDLE, middle); | ||
561 | |||
562 | if (z > 0) { | ||
563 | input_report_abs(dev, ABS_X, x); | ||
564 | input_report_abs(dev, ABS_Y, y); | ||
565 | } | ||
566 | input_report_abs(dev, ABS_PRESSURE, z); | ||
567 | |||
568 | input_sync(dev); | ||
569 | |||
570 | if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) { | ||
571 | left = packet[3] & 0x10; | ||
572 | right = packet[3] & 0x20; | ||
573 | middle = packet[3] & 0x40; | ||
574 | |||
575 | input_report_key(dev2, BTN_LEFT, left); | ||
576 | input_report_key(dev2, BTN_RIGHT, right); | ||
577 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
578 | input_sync(dev2); | ||
579 | } | ||
580 | } | ||
581 | |||
582 | static void alps_process_packet_v3(struct psmouse *psmouse) | ||
583 | { | ||
584 | unsigned char *packet = psmouse->packet; | ||
585 | |||
586 | /* | ||
587 | * v3 protocol packets come in three types, two representing | ||
588 | * touchpad data and one representing trackstick data. | ||
589 | * Trackstick packets seem to be distinguished by always | ||
590 | * having 0x3f in the last byte. This value has never been | ||
591 | * observed in the last byte of either of the other types | ||
592 | * of packets. | ||
593 | */ | ||
594 | if (packet[5] == 0x3f) { | ||
595 | alps_process_trackstick_packet_v3(psmouse); | ||
596 | return; | ||
597 | } | ||
598 | |||
599 | alps_process_touchpad_packet_v3(psmouse); | ||
600 | } | ||
601 | |||
602 | static void alps_process_packet_v4(struct psmouse *psmouse) | ||
603 | { | ||
604 | struct alps_data *priv = psmouse->private; | ||
605 | unsigned char *packet = psmouse->packet; | ||
606 | struct input_dev *dev = psmouse->dev; | ||
607 | int offset; | ||
608 | int x, y, z; | ||
609 | int left, right; | ||
610 | int x1, y1, x2, y2; | ||
611 | int fingers = 0; | ||
612 | unsigned int x_bitmap, y_bitmap; | ||
613 | |||
614 | /* | ||
615 | * v4 has a 6-byte encoding for bitmap data, but this data is | ||
616 | * broken up between 3 normal packets. Use priv->multi_packet to | ||
617 | * track our position in the bitmap packet. | ||
618 | */ | ||
619 | if (packet[6] & 0x40) { | ||
620 | /* sync, reset position */ | ||
621 | priv->multi_packet = 0; | ||
622 | } | ||
623 | |||
624 | if (WARN_ON_ONCE(priv->multi_packet > 2)) | ||
625 | return; | ||
626 | |||
627 | offset = 2 * priv->multi_packet; | ||
628 | priv->multi_data[offset] = packet[6]; | ||
629 | priv->multi_data[offset + 1] = packet[7]; | ||
630 | |||
631 | if (++priv->multi_packet > 2) { | ||
632 | priv->multi_packet = 0; | ||
633 | |||
634 | x_bitmap = ((priv->multi_data[2] & 0x1f) << 10) | | ||
635 | ((priv->multi_data[3] & 0x60) << 3) | | ||
636 | ((priv->multi_data[0] & 0x3f) << 2) | | ||
637 | ((priv->multi_data[1] & 0x60) >> 5); | ||
638 | y_bitmap = ((priv->multi_data[5] & 0x01) << 10) | | ||
639 | ((priv->multi_data[3] & 0x1f) << 5) | | ||
640 | (priv->multi_data[1] & 0x1f); | ||
641 | |||
642 | fingers = alps_process_bitmap(x_bitmap, y_bitmap, | ||
643 | &x1, &y1, &x2, &y2); | ||
644 | |||
645 | /* Store MT data.*/ | ||
646 | priv->fingers = fingers; | ||
647 | priv->x1 = x1; | ||
648 | priv->x2 = x2; | ||
649 | priv->y1 = y1; | ||
650 | priv->y2 = y2; | ||
651 | } | ||
652 | |||
653 | left = packet[4] & 0x01; | ||
654 | right = packet[4] & 0x02; | ||
655 | |||
656 | x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | | ||
657 | ((packet[0] & 0x30) >> 4); | ||
658 | y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f); | ||
659 | z = packet[5] & 0x7f; | ||
660 | |||
661 | /* | ||
662 | * If there were no contacts in the bitmap, use ST | ||
663 | * points in MT reports. | ||
664 | * If there were two contacts or more, report MT data. | ||
665 | */ | ||
666 | if (priv->fingers < 2) { | ||
667 | x1 = x; | ||
668 | y1 = y; | ||
669 | fingers = z > 0 ? 1 : 0; | ||
670 | } else { | ||
671 | fingers = priv->fingers; | ||
672 | x1 = priv->x1; | ||
673 | x2 = priv->x2; | ||
674 | y1 = priv->y1; | ||
675 | y2 = priv->y2; | ||
676 | } | ||
677 | |||
678 | if (z >= 64) | ||
679 | input_report_key(dev, BTN_TOUCH, 1); | ||
680 | else | ||
681 | input_report_key(dev, BTN_TOUCH, 0); | ||
682 | |||
683 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
684 | |||
685 | input_mt_report_finger_count(dev, fingers); | ||
686 | |||
687 | input_report_key(dev, BTN_LEFT, left); | ||
688 | input_report_key(dev, BTN_RIGHT, right); | ||
689 | |||
690 | if (z > 0) { | ||
691 | input_report_abs(dev, ABS_X, x); | ||
692 | input_report_abs(dev, ABS_Y, y); | ||
693 | } | ||
694 | input_report_abs(dev, ABS_PRESSURE, z); | ||
695 | |||
696 | input_sync(dev); | ||
697 | } | ||
698 | |||
699 | static void alps_process_packet(struct psmouse *psmouse) | ||
700 | { | ||
701 | struct alps_data *priv = psmouse->private; | ||
702 | const struct alps_model_info *model = priv->i; | ||
703 | |||
704 | switch (model->proto_version) { | ||
705 | case ALPS_PROTO_V1: | ||
706 | case ALPS_PROTO_V2: | ||
707 | alps_process_packet_v1_v2(psmouse); | ||
708 | break; | ||
709 | case ALPS_PROTO_V3: | ||
710 | alps_process_packet_v3(psmouse); | ||
711 | break; | ||
712 | case ALPS_PROTO_V4: | ||
713 | alps_process_packet_v4(psmouse); | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | |||
718 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, | 249 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, |
719 | unsigned char packet[], | 250 | unsigned char packet[], |
720 | bool report_buttons) | 251 | bool report_buttons) |
@@ -766,9 +297,10 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
766 | psmouse->packet[4] | | 297 | psmouse->packet[4] | |
767 | psmouse->packet[5]) & 0x80) || | 298 | psmouse->packet[5]) & 0x80) || |
768 | (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { | 299 | (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { |
769 | psmouse_dbg(psmouse, | 300 | dbg("refusing packet %x %x %x %x " |
770 | "refusing packet %4ph (suspected interleaved ps/2)\n", | 301 | "(suspected interleaved ps/2)\n", |
771 | psmouse->packet + 3); | 302 | psmouse->packet[3], psmouse->packet[4], |
303 | psmouse->packet[5], psmouse->packet[6]); | ||
772 | return PSMOUSE_BAD_DATA; | 304 | return PSMOUSE_BAD_DATA; |
773 | } | 305 | } |
774 | 306 | ||
@@ -787,13 +319,13 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
787 | * There is also possibility that we got 6-byte ALPS | 319 | * There is also possibility that we got 6-byte ALPS |
788 | * packet followed by 3-byte packet from trackpoint. We | 320 | * packet followed by 3-byte packet from trackpoint. We |
789 | * can not distinguish between these 2 scenarios but | 321 | * can not distinguish between these 2 scenarios but |
790 | * because the latter is unlikely to happen in course of | 322 | * becase the latter is unlikely to happen in course of |
791 | * normal operation (user would need to press all | 323 | * normal operation (user would need to press all |
792 | * buttons on the pad and start moving trackpoint | 324 | * buttons on the pad and start moving trackpoint |
793 | * without touching the pad surface) we assume former. | 325 | * without touching the pad surface) we assume former. |
794 | * Even if we are wrong the wost thing that would happen | 326 | * Even if we are wrong the wost thing that would happen |
795 | * the cursor would jump but we should not get protocol | 327 | * the cursor would jump but we should not get protocol |
796 | * de-synchronization. | 328 | * desynchronization. |
797 | */ | 329 | */ |
798 | 330 | ||
799 | alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], | 331 | alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], |
@@ -819,7 +351,7 @@ static void alps_flush_packet(unsigned long data) | |||
819 | 351 | ||
820 | serio_pause_rx(psmouse->ps2dev.serio); | 352 | serio_pause_rx(psmouse->ps2dev.serio); |
821 | 353 | ||
822 | if (psmouse->pktcnt == psmouse->pktsize) { | 354 | if (psmouse->pktcnt == 6) { |
823 | 355 | ||
824 | /* | 356 | /* |
825 | * We did not any more data in reasonable amount of time. | 357 | * We did not any more data in reasonable amount of time. |
@@ -829,9 +361,10 @@ static void alps_flush_packet(unsigned long data) | |||
829 | if ((psmouse->packet[3] | | 361 | if ((psmouse->packet[3] | |
830 | psmouse->packet[4] | | 362 | psmouse->packet[4] | |
831 | psmouse->packet[5]) & 0x80) { | 363 | psmouse->packet[5]) & 0x80) { |
832 | psmouse_dbg(psmouse, | 364 | dbg("refusing packet %x %x %x " |
833 | "refusing packet %3ph (suspected interleaved ps/2)\n", | 365 | "(suspected interleaved ps/2)\n", |
834 | psmouse->packet + 3); | 366 | psmouse->packet[3], psmouse->packet[4], |
367 | psmouse->packet[5]); | ||
835 | } else { | 368 | } else { |
836 | alps_process_packet(psmouse); | 369 | alps_process_packet(psmouse); |
837 | } | 370 | } |
@@ -863,22 +396,20 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
863 | } | 396 | } |
864 | 397 | ||
865 | if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { | 398 | if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { |
866 | psmouse_dbg(psmouse, | 399 | dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", |
867 | "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", | 400 | psmouse->packet[0], model->mask0, model->byte0); |
868 | psmouse->packet[0], model->mask0, model->byte0); | ||
869 | return PSMOUSE_BAD_DATA; | 401 | return PSMOUSE_BAD_DATA; |
870 | } | 402 | } |
871 | 403 | ||
872 | /* Bytes 2 - pktsize should have 0 in the highest bit */ | 404 | /* Bytes 2 - 6 should have 0 in the highest bit */ |
873 | if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && | 405 | if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && |
874 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { | 406 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { |
875 | psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", | 407 | dbg("refusing packet[%i] = %x\n", |
876 | psmouse->pktcnt - 1, | 408 | psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); |
877 | psmouse->packet[psmouse->pktcnt - 1]); | ||
878 | return PSMOUSE_BAD_DATA; | 409 | return PSMOUSE_BAD_DATA; |
879 | } | 410 | } |
880 | 411 | ||
881 | if (psmouse->pktcnt == psmouse->pktsize) { | 412 | if (psmouse->pktcnt == 6) { |
882 | alps_process_packet(psmouse); | 413 | alps_process_packet(psmouse); |
883 | return PSMOUSE_FULL_PACKET; | 414 | return PSMOUSE_FULL_PACKET; |
884 | } | 415 | } |
@@ -886,134 +417,16 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
886 | return PSMOUSE_GOOD_DATA; | 417 | return PSMOUSE_GOOD_DATA; |
887 | } | 418 | } |
888 | 419 | ||
889 | static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble) | ||
890 | { | ||
891 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
892 | struct alps_data *priv = psmouse->private; | ||
893 | int command; | ||
894 | unsigned char *param; | ||
895 | unsigned char dummy[4]; | ||
896 | |||
897 | BUG_ON(nibble > 0xf); | ||
898 | |||
899 | command = priv->nibble_commands[nibble].command; | ||
900 | param = (command & 0x0f00) ? | ||
901 | dummy : (unsigned char *)&priv->nibble_commands[nibble].data; | ||
902 | |||
903 | if (ps2_command(ps2dev, param, command)) | ||
904 | return -1; | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static int alps_command_mode_set_addr(struct psmouse *psmouse, int addr) | ||
910 | { | ||
911 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
912 | struct alps_data *priv = psmouse->private; | ||
913 | int i, nibble; | ||
914 | |||
915 | if (ps2_command(ps2dev, NULL, priv->addr_command)) | ||
916 | return -1; | ||
917 | |||
918 | for (i = 12; i >= 0; i -= 4) { | ||
919 | nibble = (addr >> i) & 0xf; | ||
920 | if (alps_command_mode_send_nibble(psmouse, nibble)) | ||
921 | return -1; | ||
922 | } | ||
923 | |||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int __alps_command_mode_read_reg(struct psmouse *psmouse, int addr) | ||
928 | { | ||
929 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
930 | unsigned char param[4]; | ||
931 | |||
932 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
933 | return -1; | ||
934 | |||
935 | /* | ||
936 | * The address being read is returned in the first two bytes | ||
937 | * of the result. Check that this address matches the expected | ||
938 | * address. | ||
939 | */ | ||
940 | if (addr != ((param[0] << 8) | param[1])) | ||
941 | return -1; | ||
942 | |||
943 | return param[2]; | ||
944 | } | ||
945 | |||
946 | static int alps_command_mode_read_reg(struct psmouse *psmouse, int addr) | ||
947 | { | ||
948 | if (alps_command_mode_set_addr(psmouse, addr)) | ||
949 | return -1; | ||
950 | return __alps_command_mode_read_reg(psmouse, addr); | ||
951 | } | ||
952 | |||
953 | static int __alps_command_mode_write_reg(struct psmouse *psmouse, u8 value) | ||
954 | { | ||
955 | if (alps_command_mode_send_nibble(psmouse, (value >> 4) & 0xf)) | ||
956 | return -1; | ||
957 | if (alps_command_mode_send_nibble(psmouse, value & 0xf)) | ||
958 | return -1; | ||
959 | return 0; | ||
960 | } | ||
961 | |||
962 | static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr, | ||
963 | u8 value) | ||
964 | { | ||
965 | if (alps_command_mode_set_addr(psmouse, addr)) | ||
966 | return -1; | ||
967 | return __alps_command_mode_write_reg(psmouse, value); | ||
968 | } | ||
969 | |||
970 | static int alps_enter_command_mode(struct psmouse *psmouse, | ||
971 | unsigned char *resp) | ||
972 | { | ||
973 | unsigned char param[4]; | ||
974 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
975 | |||
976 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || | ||
977 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || | ||
978 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || | ||
979 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | ||
980 | psmouse_err(psmouse, "failed to enter command mode\n"); | ||
981 | return -1; | ||
982 | } | ||
983 | |||
984 | if (param[0] != 0x88 && param[1] != 0x07) { | ||
985 | psmouse_dbg(psmouse, | ||
986 | "unknown response while entering command mode: %2.2x %2.2x %2.2x\n", | ||
987 | param[0], param[1], param[2]); | ||
988 | return -1; | ||
989 | } | ||
990 | |||
991 | if (resp) | ||
992 | *resp = param[2]; | ||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | static inline int alps_exit_command_mode(struct psmouse *psmouse) | ||
997 | { | ||
998 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
999 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) | ||
1000 | return -1; | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version) | 420 | static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version) |
1005 | { | 421 | { |
1006 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 422 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
1007 | static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 }; | 423 | static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 }; |
1008 | unsigned char param[4]; | 424 | unsigned char param[4]; |
1009 | const struct alps_model_info *model = NULL; | ||
1010 | int i; | 425 | int i; |
1011 | 426 | ||
1012 | /* | 427 | /* |
1013 | * First try "E6 report". | 428 | * First try "E6 report". |
1014 | * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. | 429 | * ALPS should return 0,0,10 or 0,0,100 |
1015 | * The bits 0-2 of the first byte will be 1s if some buttons are | ||
1016 | * pressed. | ||
1017 | */ | 430 | */ |
1018 | param[0] = 0; | 431 | param[0] = 0; |
1019 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || | 432 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || |
@@ -1026,11 +439,9 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
1026 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | 439 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) |
1027 | return NULL; | 440 | return NULL; |
1028 | 441 | ||
1029 | psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x", | 442 | dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); |
1030 | param[0], param[1], param[2]); | ||
1031 | 443 | ||
1032 | if ((param[0] & 0xf8) != 0 || param[1] != 0 || | 444 | if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100)) |
1033 | (param[2] != 10 && param[2] != 100)) | ||
1034 | return NULL; | 445 | return NULL; |
1035 | 446 | ||
1036 | /* | 447 | /* |
@@ -1048,8 +459,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
1048 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | 459 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) |
1049 | return NULL; | 460 | return NULL; |
1050 | 461 | ||
1051 | psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x", | 462 | dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); |
1052 | param[0], param[1], param[2]); | ||
1053 | 463 | ||
1054 | if (version) { | 464 | if (version) { |
1055 | for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) | 465 | for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) |
@@ -1057,41 +467,12 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
1057 | *version = (param[0] << 8) | (param[1] << 4) | i; | 467 | *version = (param[0] << 8) | (param[1] << 4) | i; |
1058 | } | 468 | } |
1059 | 469 | ||
1060 | for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { | 470 | for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) |
1061 | if (!memcmp(param, alps_model_data[i].signature, | 471 | if (!memcmp(param, alps_model_data[i].signature, |
1062 | sizeof(alps_model_data[i].signature))) { | 472 | sizeof(alps_model_data[i].signature))) |
1063 | model = alps_model_data + i; | 473 | return alps_model_data + i; |
1064 | break; | ||
1065 | } | ||
1066 | } | ||
1067 | 474 | ||
1068 | if (model && model->proto_version > ALPS_PROTO_V2) { | 475 | return NULL; |
1069 | /* | ||
1070 | * Need to check command mode response to identify | ||
1071 | * model | ||
1072 | */ | ||
1073 | model = NULL; | ||
1074 | if (alps_enter_command_mode(psmouse, param)) { | ||
1075 | psmouse_warn(psmouse, | ||
1076 | "touchpad failed to enter command mode\n"); | ||
1077 | } else { | ||
1078 | for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { | ||
1079 | if (alps_model_data[i].proto_version > ALPS_PROTO_V2 && | ||
1080 | alps_model_data[i].command_mode_resp == param[0]) { | ||
1081 | model = alps_model_data + i; | ||
1082 | break; | ||
1083 | } | ||
1084 | } | ||
1085 | alps_exit_command_mode(psmouse); | ||
1086 | |||
1087 | if (!model) | ||
1088 | psmouse_dbg(psmouse, | ||
1089 | "Unknown command mode response %2.2x\n", | ||
1090 | param[0]); | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | return model; | ||
1095 | } | 476 | } |
1096 | 477 | ||
1097 | /* | 478 | /* |
@@ -1099,7 +480,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
1099 | * subsequent commands. It looks like glidepad is behind stickpointer, | 480 | * subsequent commands. It looks like glidepad is behind stickpointer, |
1100 | * I'd thought it would be other way around... | 481 | * I'd thought it would be other way around... |
1101 | */ | 482 | */ |
1102 | static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable) | 483 | static int alps_passthrough_mode(struct psmouse *psmouse, bool enable) |
1103 | { | 484 | { |
1104 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 485 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
1105 | int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; | 486 | int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; |
@@ -1116,7 +497,7 @@ static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable) | |||
1116 | return 0; | 497 | return 0; |
1117 | } | 498 | } |
1118 | 499 | ||
1119 | static int alps_absolute_mode_v1_v2(struct psmouse *psmouse) | 500 | static int alps_absolute_mode(struct psmouse *psmouse) |
1120 | { | 501 | { |
1121 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 502 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
1122 | 503 | ||
@@ -1146,8 +527,7 @@ static int alps_get_status(struct psmouse *psmouse, char *param) | |||
1146 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | 527 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) |
1147 | return -1; | 528 | return -1; |
1148 | 529 | ||
1149 | psmouse_dbg(psmouse, "Status: %2.2x %2.2x %2.2x", | 530 | dbg("Status: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); |
1150 | param[0], param[1], param[2]); | ||
1151 | 531 | ||
1152 | return 0; | 532 | return 0; |
1153 | } | 533 | } |
@@ -1187,17 +567,17 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable) | |||
1187 | static int alps_poll(struct psmouse *psmouse) | 567 | static int alps_poll(struct psmouse *psmouse) |
1188 | { | 568 | { |
1189 | struct alps_data *priv = psmouse->private; | 569 | struct alps_data *priv = psmouse->private; |
1190 | unsigned char buf[sizeof(psmouse->packet)]; | 570 | unsigned char buf[6]; |
1191 | bool poll_failed; | 571 | bool poll_failed; |
1192 | 572 | ||
1193 | if (priv->i->flags & ALPS_PASS) | 573 | if (priv->i->flags & ALPS_PASS) |
1194 | alps_passthrough_mode_v2(psmouse, true); | 574 | alps_passthrough_mode(psmouse, true); |
1195 | 575 | ||
1196 | poll_failed = ps2_command(&psmouse->ps2dev, buf, | 576 | poll_failed = ps2_command(&psmouse->ps2dev, buf, |
1197 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; | 577 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; |
1198 | 578 | ||
1199 | if (priv->i->flags & ALPS_PASS) | 579 | if (priv->i->flags & ALPS_PASS) |
1200 | alps_passthrough_mode_v2(psmouse, false); | 580 | alps_passthrough_mode(psmouse, false); |
1201 | 581 | ||
1202 | if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) | 582 | if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) |
1203 | return -1; | 583 | return -1; |
@@ -1214,331 +594,40 @@ static int alps_poll(struct psmouse *psmouse) | |||
1214 | return 0; | 594 | return 0; |
1215 | } | 595 | } |
1216 | 596 | ||
1217 | static int alps_hw_init_v1_v2(struct psmouse *psmouse) | 597 | static int alps_hw_init(struct psmouse *psmouse) |
1218 | { | 598 | { |
1219 | struct alps_data *priv = psmouse->private; | 599 | struct alps_data *priv = psmouse->private; |
1220 | const struct alps_model_info *model = priv->i; | 600 | const struct alps_model_info *model = priv->i; |
1221 | 601 | ||
1222 | if ((model->flags & ALPS_PASS) && | 602 | if ((model->flags & ALPS_PASS) && |
1223 | alps_passthrough_mode_v2(psmouse, true)) { | 603 | alps_passthrough_mode(psmouse, true)) { |
1224 | return -1; | 604 | return -1; |
1225 | } | 605 | } |
1226 | 606 | ||
1227 | if (alps_tap_mode(psmouse, true)) { | 607 | if (alps_tap_mode(psmouse, true)) { |
1228 | psmouse_warn(psmouse, "Failed to enable hardware tapping\n"); | 608 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); |
1229 | return -1; | 609 | return -1; |
1230 | } | 610 | } |
1231 | 611 | ||
1232 | if (alps_absolute_mode_v1_v2(psmouse)) { | 612 | if (alps_absolute_mode(psmouse)) { |
1233 | psmouse_err(psmouse, "Failed to enable absolute mode\n"); | 613 | printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); |
1234 | return -1; | 614 | return -1; |
1235 | } | 615 | } |
1236 | 616 | ||
1237 | if ((model->flags & ALPS_PASS) && | 617 | if ((model->flags & ALPS_PASS) && |
1238 | alps_passthrough_mode_v2(psmouse, false)) { | 618 | alps_passthrough_mode(psmouse, false)) { |
1239 | return -1; | 619 | return -1; |
1240 | } | 620 | } |
1241 | 621 | ||
1242 | /* ALPS needs stream mode, otherwise it won't report any data */ | 622 | /* ALPS needs stream mode, otherwise it won't report any data */ |
1243 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { | 623 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { |
1244 | psmouse_err(psmouse, "Failed to enable stream mode\n"); | 624 | printk(KERN_ERR "alps.c: Failed to enable stream mode\n"); |
1245 | return -1; | 625 | return -1; |
1246 | } | 626 | } |
1247 | 627 | ||
1248 | return 0; | 628 | return 0; |
1249 | } | 629 | } |
1250 | 630 | ||
1251 | /* | ||
1252 | * Enable or disable passthrough mode to the trackstick. Must be in | ||
1253 | * command mode when calling this function. | ||
1254 | */ | ||
1255 | static int alps_passthrough_mode_v3(struct psmouse *psmouse, bool enable) | ||
1256 | { | ||
1257 | int reg_val; | ||
1258 | |||
1259 | reg_val = alps_command_mode_read_reg(psmouse, 0x0008); | ||
1260 | if (reg_val == -1) | ||
1261 | return -1; | ||
1262 | |||
1263 | if (enable) | ||
1264 | reg_val |= 0x01; | ||
1265 | else | ||
1266 | reg_val &= ~0x01; | ||
1267 | |||
1268 | if (__alps_command_mode_write_reg(psmouse, reg_val)) | ||
1269 | return -1; | ||
1270 | |||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1274 | /* Must be in command mode when calling this function */ | ||
1275 | static int alps_absolute_mode_v3(struct psmouse *psmouse) | ||
1276 | { | ||
1277 | int reg_val; | ||
1278 | |||
1279 | reg_val = alps_command_mode_read_reg(psmouse, 0x0004); | ||
1280 | if (reg_val == -1) | ||
1281 | return -1; | ||
1282 | |||
1283 | reg_val |= 0x06; | ||
1284 | if (__alps_command_mode_write_reg(psmouse, reg_val)) | ||
1285 | return -1; | ||
1286 | |||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | static int alps_hw_init_v3(struct psmouse *psmouse) | ||
1291 | { | ||
1292 | struct alps_data *priv = psmouse->private; | ||
1293 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1294 | int reg_val; | ||
1295 | unsigned char param[4]; | ||
1296 | |||
1297 | priv->nibble_commands = alps_v3_nibble_commands; | ||
1298 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | ||
1299 | |||
1300 | if (alps_enter_command_mode(psmouse, NULL)) | ||
1301 | goto error; | ||
1302 | |||
1303 | /* Check for trackstick */ | ||
1304 | reg_val = alps_command_mode_read_reg(psmouse, 0x0008); | ||
1305 | if (reg_val == -1) | ||
1306 | goto error; | ||
1307 | if (reg_val & 0x80) { | ||
1308 | if (alps_passthrough_mode_v3(psmouse, true)) | ||
1309 | goto error; | ||
1310 | if (alps_exit_command_mode(psmouse)) | ||
1311 | goto error; | ||
1312 | |||
1313 | /* | ||
1314 | * E7 report for the trackstick | ||
1315 | * | ||
1316 | * There have been reports of failures to seem to trace back | ||
1317 | * to the above trackstick check failing. When these occur | ||
1318 | * this E7 report fails, so when that happens we continue | ||
1319 | * with the assumption that there isn't a trackstick after | ||
1320 | * all. | ||
1321 | */ | ||
1322 | param[0] = 0x64; | ||
1323 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | ||
1324 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | ||
1325 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | ||
1326 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | ||
1327 | psmouse_warn(psmouse, "trackstick E7 report failed\n"); | ||
1328 | } else { | ||
1329 | psmouse_dbg(psmouse, | ||
1330 | "trackstick E7 report: %2.2x %2.2x %2.2x\n", | ||
1331 | param[0], param[1], param[2]); | ||
1332 | |||
1333 | /* | ||
1334 | * Not sure what this does, but it is absolutely | ||
1335 | * essential. Without it, the touchpad does not | ||
1336 | * work at all and the trackstick just emits normal | ||
1337 | * PS/2 packets. | ||
1338 | */ | ||
1339 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1340 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1341 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1342 | alps_command_mode_send_nibble(psmouse, 0x9) || | ||
1343 | alps_command_mode_send_nibble(psmouse, 0x4)) { | ||
1344 | psmouse_err(psmouse, | ||
1345 | "Error sending magic E6 sequence\n"); | ||
1346 | goto error_passthrough; | ||
1347 | } | ||
1348 | } | ||
1349 | |||
1350 | if (alps_enter_command_mode(psmouse, NULL)) | ||
1351 | goto error_passthrough; | ||
1352 | if (alps_passthrough_mode_v3(psmouse, false)) | ||
1353 | goto error; | ||
1354 | } | ||
1355 | |||
1356 | if (alps_absolute_mode_v3(psmouse)) { | ||
1357 | psmouse_err(psmouse, "Failed to enter absolute mode\n"); | ||
1358 | goto error; | ||
1359 | } | ||
1360 | |||
1361 | reg_val = alps_command_mode_read_reg(psmouse, 0x0006); | ||
1362 | if (reg_val == -1) | ||
1363 | goto error; | ||
1364 | if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01)) | ||
1365 | goto error; | ||
1366 | |||
1367 | reg_val = alps_command_mode_read_reg(psmouse, 0x0007); | ||
1368 | if (reg_val == -1) | ||
1369 | goto error; | ||
1370 | if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01)) | ||
1371 | goto error; | ||
1372 | |||
1373 | if (alps_command_mode_read_reg(psmouse, 0x0144) == -1) | ||
1374 | goto error; | ||
1375 | if (__alps_command_mode_write_reg(psmouse, 0x04)) | ||
1376 | goto error; | ||
1377 | |||
1378 | if (alps_command_mode_read_reg(psmouse, 0x0159) == -1) | ||
1379 | goto error; | ||
1380 | if (__alps_command_mode_write_reg(psmouse, 0x03)) | ||
1381 | goto error; | ||
1382 | |||
1383 | if (alps_command_mode_read_reg(psmouse, 0x0163) == -1) | ||
1384 | goto error; | ||
1385 | if (alps_command_mode_write_reg(psmouse, 0x0163, 0x03)) | ||
1386 | goto error; | ||
1387 | |||
1388 | if (alps_command_mode_read_reg(psmouse, 0x0162) == -1) | ||
1389 | goto error; | ||
1390 | if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04)) | ||
1391 | goto error; | ||
1392 | |||
1393 | /* | ||
1394 | * This ensures the trackstick packets are in the format | ||
1395 | * supported by this driver. If bit 1 isn't set the packet | ||
1396 | * format is different. | ||
1397 | */ | ||
1398 | if (alps_command_mode_write_reg(psmouse, 0x0008, 0x82)) | ||
1399 | goto error; | ||
1400 | |||
1401 | alps_exit_command_mode(psmouse); | ||
1402 | |||
1403 | /* Set rate and enable data reporting */ | ||
1404 | param[0] = 0x64; | ||
1405 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) || | ||
1406 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { | ||
1407 | psmouse_err(psmouse, "Failed to enable data reporting\n"); | ||
1408 | return -1; | ||
1409 | } | ||
1410 | |||
1411 | return 0; | ||
1412 | |||
1413 | error_passthrough: | ||
1414 | /* Something failed while in passthrough mode, so try to get out */ | ||
1415 | if (!alps_enter_command_mode(psmouse, NULL)) | ||
1416 | alps_passthrough_mode_v3(psmouse, false); | ||
1417 | error: | ||
1418 | /* | ||
1419 | * Leaving the touchpad in command mode will essentially render | ||
1420 | * it unusable until the machine reboots, so exit it here just | ||
1421 | * to be safe | ||
1422 | */ | ||
1423 | alps_exit_command_mode(psmouse); | ||
1424 | return -1; | ||
1425 | } | ||
1426 | |||
1427 | /* Must be in command mode when calling this function */ | ||
1428 | static int alps_absolute_mode_v4(struct psmouse *psmouse) | ||
1429 | { | ||
1430 | int reg_val; | ||
1431 | |||
1432 | reg_val = alps_command_mode_read_reg(psmouse, 0x0004); | ||
1433 | if (reg_val == -1) | ||
1434 | return -1; | ||
1435 | |||
1436 | reg_val |= 0x02; | ||
1437 | if (__alps_command_mode_write_reg(psmouse, reg_val)) | ||
1438 | return -1; | ||
1439 | |||
1440 | return 0; | ||
1441 | } | ||
1442 | |||
1443 | static int alps_hw_init_v4(struct psmouse *psmouse) | ||
1444 | { | ||
1445 | struct alps_data *priv = psmouse->private; | ||
1446 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1447 | unsigned char param[4]; | ||
1448 | |||
1449 | priv->nibble_commands = alps_v4_nibble_commands; | ||
1450 | priv->addr_command = PSMOUSE_CMD_DISABLE; | ||
1451 | |||
1452 | if (alps_enter_command_mode(psmouse, NULL)) | ||
1453 | goto error; | ||
1454 | |||
1455 | if (alps_absolute_mode_v4(psmouse)) { | ||
1456 | psmouse_err(psmouse, "Failed to enter absolute mode\n"); | ||
1457 | goto error; | ||
1458 | } | ||
1459 | |||
1460 | if (alps_command_mode_write_reg(psmouse, 0x0007, 0x8c)) | ||
1461 | goto error; | ||
1462 | |||
1463 | if (alps_command_mode_write_reg(psmouse, 0x0149, 0x03)) | ||
1464 | goto error; | ||
1465 | |||
1466 | if (alps_command_mode_write_reg(psmouse, 0x0160, 0x03)) | ||
1467 | goto error; | ||
1468 | |||
1469 | if (alps_command_mode_write_reg(psmouse, 0x017f, 0x15)) | ||
1470 | goto error; | ||
1471 | |||
1472 | if (alps_command_mode_write_reg(psmouse, 0x0151, 0x01)) | ||
1473 | goto error; | ||
1474 | |||
1475 | if (alps_command_mode_write_reg(psmouse, 0x0168, 0x03)) | ||
1476 | goto error; | ||
1477 | |||
1478 | if (alps_command_mode_write_reg(psmouse, 0x014a, 0x03)) | ||
1479 | goto error; | ||
1480 | |||
1481 | if (alps_command_mode_write_reg(psmouse, 0x0161, 0x03)) | ||
1482 | goto error; | ||
1483 | |||
1484 | alps_exit_command_mode(psmouse); | ||
1485 | |||
1486 | /* | ||
1487 | * This sequence changes the output from a 9-byte to an | ||
1488 | * 8-byte format. All the same data seems to be present, | ||
1489 | * just in a more compact format. | ||
1490 | */ | ||
1491 | param[0] = 0xc8; | ||
1492 | param[1] = 0x64; | ||
1493 | param[2] = 0x50; | ||
1494 | if (ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) || | ||
1495 | ps2_command(ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE) || | ||
1496 | ps2_command(ps2dev, ¶m[2], PSMOUSE_CMD_SETRATE) || | ||
1497 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) | ||
1498 | return -1; | ||
1499 | |||
1500 | /* Set rate and enable data reporting */ | ||
1501 | param[0] = 0x64; | ||
1502 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) || | ||
1503 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { | ||
1504 | psmouse_err(psmouse, "Failed to enable data reporting\n"); | ||
1505 | return -1; | ||
1506 | } | ||
1507 | |||
1508 | return 0; | ||
1509 | |||
1510 | error: | ||
1511 | /* | ||
1512 | * Leaving the touchpad in command mode will essentially render | ||
1513 | * it unusable until the machine reboots, so exit it here just | ||
1514 | * to be safe | ||
1515 | */ | ||
1516 | alps_exit_command_mode(psmouse); | ||
1517 | return -1; | ||
1518 | } | ||
1519 | |||
1520 | static int alps_hw_init(struct psmouse *psmouse) | ||
1521 | { | ||
1522 | struct alps_data *priv = psmouse->private; | ||
1523 | const struct alps_model_info *model = priv->i; | ||
1524 | int ret = -1; | ||
1525 | |||
1526 | switch (model->proto_version) { | ||
1527 | case ALPS_PROTO_V1: | ||
1528 | case ALPS_PROTO_V2: | ||
1529 | ret = alps_hw_init_v1_v2(psmouse); | ||
1530 | break; | ||
1531 | case ALPS_PROTO_V3: | ||
1532 | ret = alps_hw_init_v3(psmouse); | ||
1533 | break; | ||
1534 | case ALPS_PROTO_V4: | ||
1535 | ret = alps_hw_init_v4(psmouse); | ||
1536 | break; | ||
1537 | } | ||
1538 | |||
1539 | return ret; | ||
1540 | } | ||
1541 | |||
1542 | static int alps_reconnect(struct psmouse *psmouse) | 631 | static int alps_reconnect(struct psmouse *psmouse) |
1543 | { | 632 | { |
1544 | const struct alps_model_info *model; | 633 | const struct alps_model_info *model; |
@@ -1579,8 +668,6 @@ int alps_init(struct psmouse *psmouse) | |||
1579 | 668 | ||
1580 | psmouse->private = priv; | 669 | psmouse->private = priv; |
1581 | 670 | ||
1582 | psmouse_reset(psmouse); | ||
1583 | |||
1584 | model = alps_get_model(psmouse, &version); | 671 | model = alps_get_model(psmouse, &version); |
1585 | if (!model) | 672 | if (!model) |
1586 | goto init_fail; | 673 | goto init_fail; |
@@ -1608,29 +695,8 @@ int alps_init(struct psmouse *psmouse) | |||
1608 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); | 695 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
1609 | 696 | ||
1610 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); | 697 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); |
1611 | 698 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); | |
1612 | switch (model->proto_version) { | 699 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); |
1613 | case ALPS_PROTO_V1: | ||
1614 | case ALPS_PROTO_V2: | ||
1615 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); | ||
1616 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); | ||
1617 | break; | ||
1618 | case ALPS_PROTO_V3: | ||
1619 | case ALPS_PROTO_V4: | ||
1620 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | ||
1621 | input_mt_init_slots(dev1, 2, 0); | ||
1622 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); | ||
1623 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); | ||
1624 | |||
1625 | set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); | ||
1626 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); | ||
1627 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); | ||
1628 | |||
1629 | input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0); | ||
1630 | input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0); | ||
1631 | break; | ||
1632 | } | ||
1633 | |||
1634 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); | 700 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); |
1635 | 701 | ||
1636 | if (model->flags & ALPS_WHEEL) { | 702 | if (model->flags & ALPS_WHEEL) { |
@@ -1673,7 +739,7 @@ int alps_init(struct psmouse *psmouse) | |||
1673 | psmouse->poll = alps_poll; | 739 | psmouse->poll = alps_poll; |
1674 | psmouse->disconnect = alps_disconnect; | 740 | psmouse->disconnect = alps_disconnect; |
1675 | psmouse->reconnect = alps_reconnect; | 741 | psmouse->reconnect = alps_reconnect; |
1676 | psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6; | 742 | psmouse->pktsize = 6; |
1677 | 743 | ||
1678 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ | 744 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ |
1679 | psmouse->resync_time = 0; | 745 | psmouse->resync_time = 0; |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index ae1ac354c77..904ed8b3c8b 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -12,41 +12,20 @@ | |||
12 | #ifndef _ALPS_H | 12 | #ifndef _ALPS_H |
13 | #define _ALPS_H | 13 | #define _ALPS_H |
14 | 14 | ||
15 | #define ALPS_PROTO_V1 0 | ||
16 | #define ALPS_PROTO_V2 1 | ||
17 | #define ALPS_PROTO_V3 2 | ||
18 | #define ALPS_PROTO_V4 3 | ||
19 | |||
20 | struct alps_model_info { | 15 | struct alps_model_info { |
21 | unsigned char signature[3]; | 16 | unsigned char signature[3]; |
22 | unsigned char command_mode_resp; /* v3/v4 only */ | ||
23 | unsigned char proto_version; | ||
24 | unsigned char byte0, mask0; | 17 | unsigned char byte0, mask0; |
25 | unsigned char flags; | 18 | unsigned char flags; |
26 | }; | 19 | }; |
27 | 20 | ||
28 | struct alps_nibble_commands { | ||
29 | int command; | ||
30 | unsigned char data; | ||
31 | }; | ||
32 | |||
33 | struct alps_data { | 21 | struct alps_data { |
34 | struct input_dev *dev2; /* Relative device */ | 22 | struct input_dev *dev2; /* Relative device */ |
35 | char phys[32]; /* Phys */ | 23 | char phys[32]; /* Phys */ |
36 | const struct alps_model_info *i;/* Info */ | 24 | const struct alps_model_info *i;/* Info */ |
37 | const struct alps_nibble_commands *nibble_commands; | ||
38 | int addr_command; /* Command to set register address */ | ||
39 | int prev_fin; /* Finger bit from previous packet */ | 25 | int prev_fin; /* Finger bit from previous packet */ |
40 | int multi_packet; /* Multi-packet data in progress */ | ||
41 | unsigned char multi_data[6]; /* Saved multi-packet data */ | ||
42 | int x1, x2, y1, y2; /* Coordinates from last MT report */ | ||
43 | int fingers; /* Number of fingers from MT report */ | ||
44 | u8 quirks; | ||
45 | struct timer_list timer; | 26 | struct timer_list timer; |
46 | }; | 27 | }; |
47 | 28 | ||
48 | #define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */ | ||
49 | |||
50 | #ifdef CONFIG_MOUSE_PS2_ALPS | 29 | #ifdef CONFIG_MOUSE_PS2_ALPS |
51 | int alps_detect(struct psmouse *psmouse, bool set_properties); | 30 | int alps_detect(struct psmouse *psmouse, bool set_properties); |
52 | int alps_init(struct psmouse *psmouse); | 31 | int alps_init(struct psmouse *psmouse); |
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index 5fa99341a39..ff5f61a0fd3 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
28 | #include <asm/system.h> | ||
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/amigahw.h> | 30 | #include <asm/amigahw.h> |
30 | #include <asm/amigaints.h> | 31 | #include <asm/amigaints.h> |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index e42f1fa8cdc..b77f9991278 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -195,7 +195,6 @@ enum atp_status_bits { | |||
195 | struct atp { | 195 | struct atp { |
196 | char phys[64]; | 196 | char phys[64]; |
197 | struct usb_device *udev; /* usb device */ | 197 | struct usb_device *udev; /* usb device */ |
198 | struct usb_interface *intf; /* usb interface */ | ||
199 | struct urb *urb; /* usb request block */ | 198 | struct urb *urb; /* usb request block */ |
200 | u8 *data; /* transferred data */ | 199 | u8 *data; /* transferred data */ |
201 | struct input_dev *input; /* input dev */ | 200 | struct input_dev *input; /* input dev */ |
@@ -254,9 +253,8 @@ MODULE_PARM_DESC(debug, "Activate debugging output"); | |||
254 | * packets (Report ID 2). This code changes device mode, so it | 253 | * packets (Report ID 2). This code changes device mode, so it |
255 | * sends raw sensor reports (Report ID 5). | 254 | * sends raw sensor reports (Report ID 5). |
256 | */ | 255 | */ |
257 | static int atp_geyser_init(struct atp *dev) | 256 | static int atp_geyser_init(struct usb_device *udev) |
258 | { | 257 | { |
259 | struct usb_device *udev = dev->udev; | ||
260 | char *data; | 258 | char *data; |
261 | int size; | 259 | int size; |
262 | int i; | 260 | int i; |
@@ -264,7 +262,7 @@ static int atp_geyser_init(struct atp *dev) | |||
264 | 262 | ||
265 | data = kmalloc(8, GFP_KERNEL); | 263 | data = kmalloc(8, GFP_KERNEL); |
266 | if (!data) { | 264 | if (!data) { |
267 | dev_err(&dev->intf->dev, "Out of memory\n"); | 265 | err("Out of memory"); |
268 | return -ENOMEM; | 266 | return -ENOMEM; |
269 | } | 267 | } |
270 | 268 | ||
@@ -279,7 +277,7 @@ static int atp_geyser_init(struct atp *dev) | |||
279 | for (i = 0; i < 8; i++) | 277 | for (i = 0; i < 8; i++) |
280 | dprintk("appletouch[%d]: %d\n", i, data[i]); | 278 | dprintk("appletouch[%d]: %d\n", i, data[i]); |
281 | 279 | ||
282 | dev_err(&dev->intf->dev, "Failed to read mode from device.\n"); | 280 | err("Failed to read mode from device."); |
283 | ret = -EIO; | 281 | ret = -EIO; |
284 | goto out_free; | 282 | goto out_free; |
285 | } | 283 | } |
@@ -298,7 +296,7 @@ static int atp_geyser_init(struct atp *dev) | |||
298 | for (i = 0; i < 8; i++) | 296 | for (i = 0; i < 8; i++) |
299 | dprintk("appletouch[%d]: %d\n", i, data[i]); | 297 | dprintk("appletouch[%d]: %d\n", i, data[i]); |
300 | 298 | ||
301 | dev_err(&dev->intf->dev, "Failed to request geyser raw mode\n"); | 299 | err("Failed to request geyser raw mode"); |
302 | ret = -EIO; | 300 | ret = -EIO; |
303 | goto out_free; | 301 | goto out_free; |
304 | } | 302 | } |
@@ -315,16 +313,16 @@ out_free: | |||
315 | static void atp_reinit(struct work_struct *work) | 313 | static void atp_reinit(struct work_struct *work) |
316 | { | 314 | { |
317 | struct atp *dev = container_of(work, struct atp, work); | 315 | struct atp *dev = container_of(work, struct atp, work); |
316 | struct usb_device *udev = dev->udev; | ||
318 | int retval; | 317 | int retval; |
319 | 318 | ||
320 | dprintk("appletouch: putting appletouch to sleep (reinit)\n"); | 319 | dprintk("appletouch: putting appletouch to sleep (reinit)\n"); |
321 | atp_geyser_init(dev); | 320 | atp_geyser_init(udev); |
322 | 321 | ||
323 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | 322 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
324 | if (retval) | 323 | if (retval) |
325 | dev_err(&dev->intf->dev, | 324 | err("atp_reinit: usb_submit_urb failed with error %d", |
326 | "atp_reinit: usb_submit_urb failed with error %d\n", | 325 | retval); |
327 | retval); | ||
328 | } | 326 | } |
329 | 327 | ||
330 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | 328 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, |
@@ -402,7 +400,6 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers) | |||
402 | static int atp_status_check(struct urb *urb) | 400 | static int atp_status_check(struct urb *urb) |
403 | { | 401 | { |
404 | struct atp *dev = urb->context; | 402 | struct atp *dev = urb->context; |
405 | struct usb_interface *intf = dev->intf; | ||
406 | 403 | ||
407 | switch (urb->status) { | 404 | switch (urb->status) { |
408 | case 0: | 405 | case 0: |
@@ -410,8 +407,8 @@ static int atp_status_check(struct urb *urb) | |||
410 | break; | 407 | break; |
411 | case -EOVERFLOW: | 408 | case -EOVERFLOW: |
412 | if (!dev->overflow_warned) { | 409 | if (!dev->overflow_warned) { |
413 | dev_warn(&intf->dev, | 410 | printk(KERN_WARNING "appletouch: OVERFLOW with data " |
414 | "appletouch: OVERFLOW with data length %d, actual length is %d\n", | 411 | "length %d, actual length is %d\n", |
415 | dev->info->datalen, dev->urb->actual_length); | 412 | dev->info->datalen, dev->urb->actual_length); |
416 | dev->overflow_warned = true; | 413 | dev->overflow_warned = true; |
417 | } | 414 | } |
@@ -419,15 +416,13 @@ static int atp_status_check(struct urb *urb) | |||
419 | case -ENOENT: | 416 | case -ENOENT: |
420 | case -ESHUTDOWN: | 417 | case -ESHUTDOWN: |
421 | /* This urb is terminated, clean up */ | 418 | /* This urb is terminated, clean up */ |
422 | dev_dbg(&intf->dev, | 419 | dbg("atp_complete: urb shutting down with status: %d", |
423 | "atp_complete: urb shutting down with status: %d\n", | 420 | urb->status); |
424 | urb->status); | ||
425 | return ATP_URB_STATUS_ERROR_FATAL; | 421 | return ATP_URB_STATUS_ERROR_FATAL; |
426 | 422 | ||
427 | default: | 423 | default: |
428 | dev_dbg(&intf->dev, | 424 | dbg("atp_complete: nonzero urb status received: %d", |
429 | "atp_complete: nonzero urb status received: %d\n", | 425 | urb->status); |
430 | urb->status); | ||
431 | return ATP_URB_STATUS_ERROR; | 426 | return ATP_URB_STATUS_ERROR; |
432 | } | 427 | } |
433 | 428 | ||
@@ -450,8 +445,7 @@ static void atp_detect_size(struct atp *dev) | |||
450 | for (i = dev->info->xsensors; i < ATP_XSENSORS; i++) { | 445 | for (i = dev->info->xsensors; i < ATP_XSENSORS; i++) { |
451 | if (dev->xy_cur[i]) { | 446 | if (dev->xy_cur[i]) { |
452 | 447 | ||
453 | dev_info(&dev->intf->dev, | 448 | printk(KERN_INFO "appletouch: 17\" model detected.\n"); |
454 | "appletouch: 17\" model detected.\n"); | ||
455 | 449 | ||
456 | input_set_abs_params(dev->input, ABS_X, 0, | 450 | input_set_abs_params(dev->input, ABS_X, 0, |
457 | (dev->info->xsensors_17 - 1) * | 451 | (dev->info->xsensors_17 - 1) * |
@@ -594,9 +588,8 @@ static void atp_complete_geyser_1_2(struct urb *urb) | |||
594 | exit: | 588 | exit: |
595 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | 589 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
596 | if (retval) | 590 | if (retval) |
597 | dev_err(&dev->intf->dev, | 591 | err("atp_complete: usb_submit_urb failed with result %d", |
598 | "atp_complete: usb_submit_urb failed with result %d\n", | 592 | retval); |
599 | retval); | ||
600 | } | 593 | } |
601 | 594 | ||
602 | /* Interrupt function for older touchpads: GEYSER3/GEYSER4 */ | 595 | /* Interrupt function for older touchpads: GEYSER3/GEYSER4 */ |
@@ -729,9 +722,8 @@ static void atp_complete_geyser_3_4(struct urb *urb) | |||
729 | exit: | 722 | exit: |
730 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | 723 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
731 | if (retval) | 724 | if (retval) |
732 | dev_err(&dev->intf->dev, | 725 | err("atp_complete: usb_submit_urb failed with result %d", |
733 | "atp_complete: usb_submit_urb failed with result %d\n", | 726 | retval); |
734 | retval); | ||
735 | } | 727 | } |
736 | 728 | ||
737 | static int atp_open(struct input_dev *input) | 729 | static int atp_open(struct input_dev *input) |
@@ -756,12 +748,14 @@ static void atp_close(struct input_dev *input) | |||
756 | 748 | ||
757 | static int atp_handle_geyser(struct atp *dev) | 749 | static int atp_handle_geyser(struct atp *dev) |
758 | { | 750 | { |
751 | struct usb_device *udev = dev->udev; | ||
752 | |||
759 | if (dev->info != &fountain_info) { | 753 | if (dev->info != &fountain_info) { |
760 | /* switch to raw sensor mode */ | 754 | /* switch to raw sensor mode */ |
761 | if (atp_geyser_init(dev)) | 755 | if (atp_geyser_init(udev)) |
762 | return -EIO; | 756 | return -EIO; |
763 | 757 | ||
764 | dev_info(&dev->intf->dev, "Geyser mode initialized.\n"); | 758 | printk(KERN_INFO "appletouch: Geyser mode initialized.\n"); |
765 | } | 759 | } |
766 | 760 | ||
767 | return 0; | 761 | return 0; |
@@ -791,7 +785,7 @@ static int atp_probe(struct usb_interface *iface, | |||
791 | } | 785 | } |
792 | } | 786 | } |
793 | if (!int_in_endpointAddr) { | 787 | if (!int_in_endpointAddr) { |
794 | dev_err(&iface->dev, "Could not find int-in endpoint\n"); | 788 | err("Could not find int-in endpoint"); |
795 | return -EIO; | 789 | return -EIO; |
796 | } | 790 | } |
797 | 791 | ||
@@ -799,12 +793,11 @@ static int atp_probe(struct usb_interface *iface, | |||
799 | dev = kzalloc(sizeof(struct atp), GFP_KERNEL); | 793 | dev = kzalloc(sizeof(struct atp), GFP_KERNEL); |
800 | input_dev = input_allocate_device(); | 794 | input_dev = input_allocate_device(); |
801 | if (!dev || !input_dev) { | 795 | if (!dev || !input_dev) { |
802 | dev_err(&iface->dev, "Out of memory\n"); | 796 | err("Out of memory"); |
803 | goto err_free_devs; | 797 | goto err_free_devs; |
804 | } | 798 | } |
805 | 799 | ||
806 | dev->udev = udev; | 800 | dev->udev = udev; |
807 | dev->intf = iface; | ||
808 | dev->input = input_dev; | 801 | dev->input = input_dev; |
809 | dev->info = info; | 802 | dev->info = info; |
810 | dev->overflow_warned = false; | 803 | dev->overflow_warned = false; |
@@ -893,7 +886,7 @@ static void atp_disconnect(struct usb_interface *iface) | |||
893 | usb_free_urb(dev->urb); | 886 | usb_free_urb(dev->urb); |
894 | kfree(dev); | 887 | kfree(dev); |
895 | } | 888 | } |
896 | dev_info(&iface->dev, "input: appletouch disconnected\n"); | 889 | printk(KERN_INFO "input: appletouch disconnected\n"); |
897 | } | 890 | } |
898 | 891 | ||
899 | static int atp_recover(struct atp *dev) | 892 | static int atp_recover(struct atp *dev) |
@@ -945,4 +938,15 @@ static struct usb_driver atp_driver = { | |||
945 | .id_table = atp_table, | 938 | .id_table = atp_table, |
946 | }; | 939 | }; |
947 | 940 | ||
948 | module_usb_driver(atp_driver); | 941 | static int __init atp_init(void) |
942 | { | ||
943 | return usb_register(&atp_driver); | ||
944 | } | ||
945 | |||
946 | static void __exit atp_exit(void) | ||
947 | { | ||
948 | usb_deregister(&atp_driver); | ||
949 | } | ||
950 | |||
951 | module_init(atp_init); | ||
952 | module_exit(atp_exit); | ||
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c index d1c43236b12..5c4a692bf73 100644 --- a/drivers/input/mouse/atarimouse.c +++ b/drivers/input/mouse/atarimouse.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
49 | #include <asm/setup.h> | 49 | #include <asm/setup.h> |
50 | #include <asm/system.h> | ||
50 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
51 | #include <asm/atarihw.h> | 52 | #include <asm/atarihw.h> |
52 | #include <asm/atarikb.h> | 53 | #include <asm/atarikb.h> |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2baff1b79a5..5ec617e28f7 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/usb/input.h> | 40 | #include <linux/usb/input.h> |
41 | #include <linux/hid.h> | 41 | #include <linux/hid.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/input/mt.h> | ||
44 | 43 | ||
45 | #define USB_VENDOR_ID_APPLE 0x05ac | 44 | #define USB_VENDOR_ID_APPLE 0x05ac |
46 | 45 | ||
@@ -80,14 +79,6 @@ | |||
80 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 | 79 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 |
81 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 | 80 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 |
82 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 | 81 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 |
83 | /* MacbookPro10,1 (unibody, June 2012) */ | ||
84 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 | ||
85 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 | ||
86 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 | ||
87 | /* MacbookPro10,2 (unibody, October 2012) */ | ||
88 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 | ||
89 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | ||
90 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | ||
91 | 82 | ||
92 | #define BCM5974_DEVICE(prod) { \ | 83 | #define BCM5974_DEVICE(prod) { \ |
93 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 84 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
@@ -137,14 +128,6 @@ static const struct usb_device_id bcm5974_table[] = { | |||
137 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), | 128 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), |
138 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), | 129 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), |
139 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), | 130 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), |
140 | /* MacbookPro10,1 */ | ||
141 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), | ||
142 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), | ||
143 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), | ||
144 | /* MacbookPro10,2 */ | ||
145 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), | ||
146 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), | ||
147 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), | ||
148 | /* Terminating entry */ | 131 | /* Terminating entry */ |
149 | {} | 132 | {} |
150 | }; | 133 | }; |
@@ -192,26 +175,26 @@ struct tp_finger { | |||
192 | __le16 abs_y; /* absolute y coodinate */ | 175 | __le16 abs_y; /* absolute y coodinate */ |
193 | __le16 rel_x; /* relative x coodinate */ | 176 | __le16 rel_x; /* relative x coodinate */ |
194 | __le16 rel_y; /* relative y coodinate */ | 177 | __le16 rel_y; /* relative y coodinate */ |
195 | __le16 tool_major; /* tool area, major axis */ | 178 | __le16 size_major; /* finger size, major axis? */ |
196 | __le16 tool_minor; /* tool area, minor axis */ | 179 | __le16 size_minor; /* finger size, minor axis? */ |
197 | __le16 orientation; /* 16384 when point, else 15 bit angle */ | 180 | __le16 orientation; /* 16384 when point, else 15 bit angle */ |
198 | __le16 touch_major; /* touch area, major axis */ | 181 | __le16 force_major; /* trackpad force, major axis? */ |
199 | __le16 touch_minor; /* touch area, minor axis */ | 182 | __le16 force_minor; /* trackpad force, minor axis? */ |
200 | __le16 unused[3]; /* zeros */ | 183 | __le16 unused[3]; /* zeros */ |
201 | __le16 multi; /* one finger: varies, more fingers: constant */ | 184 | __le16 multi; /* one finger: varies, more fingers: constant */ |
202 | } __attribute__((packed,aligned(2))); | 185 | } __attribute__((packed,aligned(2))); |
203 | 186 | ||
204 | /* trackpad finger data size, empirically at least ten fingers */ | 187 | /* trackpad finger data size, empirically at least ten fingers */ |
205 | #define MAX_FINGERS 16 | ||
206 | #define SIZEOF_FINGER sizeof(struct tp_finger) | 188 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
207 | #define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) | 189 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) |
208 | #define MAX_FINGER_ORIENTATION 16384 | 190 | #define MAX_FINGER_ORIENTATION 16384 |
209 | 191 | ||
210 | /* device-specific parameters */ | 192 | /* device-specific parameters */ |
211 | struct bcm5974_param { | 193 | struct bcm5974_param { |
212 | int snratio; /* signal-to-noise ratio */ | 194 | int dim; /* logical dimension */ |
213 | int min; /* device minimum reading */ | 195 | int fuzz; /* logical noise value */ |
214 | int max; /* device maximum reading */ | 196 | int devmin; /* device minimum reading */ |
197 | int devmax; /* device maximum reading */ | ||
215 | }; | 198 | }; |
216 | 199 | ||
217 | /* device-specific configuration */ | 200 | /* device-specific configuration */ |
@@ -228,7 +211,6 @@ struct bcm5974_config { | |||
228 | struct bcm5974_param w; /* finger width limits */ | 211 | struct bcm5974_param w; /* finger width limits */ |
229 | struct bcm5974_param x; /* horizontal limits */ | 212 | struct bcm5974_param x; /* horizontal limits */ |
230 | struct bcm5974_param y; /* vertical limits */ | 213 | struct bcm5974_param y; /* vertical limits */ |
231 | struct bcm5974_param o; /* orientation limits */ | ||
232 | }; | 214 | }; |
233 | 215 | ||
234 | /* logical device structure */ | 216 | /* logical device structure */ |
@@ -244,16 +226,23 @@ struct bcm5974 { | |||
244 | struct bt_data *bt_data; /* button transferred data */ | 226 | struct bt_data *bt_data; /* button transferred data */ |
245 | struct urb *tp_urb; /* trackpad usb request block */ | 227 | struct urb *tp_urb; /* trackpad usb request block */ |
246 | u8 *tp_data; /* trackpad transferred data */ | 228 | u8 *tp_data; /* trackpad transferred data */ |
247 | const struct tp_finger *index[MAX_FINGERS]; /* finger index data */ | 229 | int fingers; /* number of fingers on trackpad */ |
248 | struct input_mt_pos pos[MAX_FINGERS]; /* position array */ | ||
249 | int slots[MAX_FINGERS]; /* slot assignments */ | ||
250 | }; | 230 | }; |
251 | 231 | ||
232 | /* logical dimensions */ | ||
233 | #define DIM_PRESSURE 256 /* maximum finger pressure */ | ||
234 | #define DIM_WIDTH 16 /* maximum finger width */ | ||
235 | #define DIM_X 1280 /* maximum trackpad x value */ | ||
236 | #define DIM_Y 800 /* maximum trackpad y value */ | ||
237 | |||
252 | /* logical signal quality */ | 238 | /* logical signal quality */ |
253 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ | 239 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ |
254 | #define SN_WIDTH 25 /* width signal-to-noise ratio */ | 240 | #define SN_WIDTH 100 /* width signal-to-noise ratio */ |
255 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ | 241 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ |
256 | #define SN_ORIENT 10 /* orientation signal-to-noise ratio */ | 242 | |
243 | /* pressure thresholds */ | ||
244 | #define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE) | ||
245 | #define PRESSURE_HIGH (3 * PRESSURE_LOW) | ||
257 | 246 | ||
258 | /* device constants */ | 247 | /* device constants */ |
259 | static const struct bcm5974_config bcm5974_config_table[] = { | 248 | static const struct bcm5974_config bcm5974_config_table[] = { |
@@ -264,11 +253,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
264 | 0, | 253 | 0, |
265 | 0x84, sizeof(struct bt_data), | 254 | 0x84, sizeof(struct bt_data), |
266 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 255 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
267 | { SN_PRESSURE, 0, 256 }, | 256 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
268 | { SN_WIDTH, 0, 2048 }, | 257 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
269 | { SN_COORD, -4824, 5342 }, | 258 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, |
270 | { SN_COORD, -172, 5820 }, | 259 | { DIM_Y, DIM_Y / SN_COORD, -172, 5820 } |
271 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
272 | }, | 260 | }, |
273 | { | 261 | { |
274 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, | 262 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, |
@@ -277,11 +265,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
277 | 0, | 265 | 0, |
278 | 0x84, sizeof(struct bt_data), | 266 | 0x84, sizeof(struct bt_data), |
279 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 267 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
280 | { SN_PRESSURE, 0, 256 }, | 268 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
281 | { SN_WIDTH, 0, 2048 }, | 269 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
282 | { SN_COORD, -4824, 4824 }, | 270 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, |
283 | { SN_COORD, -172, 4290 }, | 271 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } |
284 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
285 | }, | 272 | }, |
286 | { | 273 | { |
287 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, | 274 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, |
@@ -290,11 +277,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
290 | HAS_INTEGRATED_BUTTON, | 277 | HAS_INTEGRATED_BUTTON, |
291 | 0x84, sizeof(struct bt_data), | 278 | 0x84, sizeof(struct bt_data), |
292 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 279 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
293 | { SN_PRESSURE, 0, 300 }, | 280 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
294 | { SN_WIDTH, 0, 2048 }, | 281 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
295 | { SN_COORD, -4460, 5166 }, | 282 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, |
296 | { SN_COORD, -75, 6700 }, | 283 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } |
297 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
298 | }, | 284 | }, |
299 | { | 285 | { |
300 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, | 286 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, |
@@ -303,11 +289,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
303 | HAS_INTEGRATED_BUTTON, | 289 | HAS_INTEGRATED_BUTTON, |
304 | 0x84, sizeof(struct bt_data), | 290 | 0x84, sizeof(struct bt_data), |
305 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 291 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
306 | { SN_PRESSURE, 0, 300 }, | 292 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
307 | { SN_WIDTH, 0, 2048 }, | 293 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
308 | { SN_COORD, -4620, 5140 }, | 294 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, |
309 | { SN_COORD, -150, 6600 }, | 295 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } |
310 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
311 | }, | 296 | }, |
312 | { | 297 | { |
313 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, | 298 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, |
@@ -316,11 +301,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
316 | HAS_INTEGRATED_BUTTON, | 301 | HAS_INTEGRATED_BUTTON, |
317 | 0x84, sizeof(struct bt_data), | 302 | 0x84, sizeof(struct bt_data), |
318 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 303 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
319 | { SN_PRESSURE, 0, 300 }, | 304 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
320 | { SN_WIDTH, 0, 2048 }, | 305 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
321 | { SN_COORD, -4616, 5112 }, | 306 | { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, |
322 | { SN_COORD, -142, 5234 }, | 307 | { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } |
323 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
324 | }, | 308 | }, |
325 | { | 309 | { |
326 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, | 310 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, |
@@ -329,11 +313,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
329 | HAS_INTEGRATED_BUTTON, | 313 | HAS_INTEGRATED_BUTTON, |
330 | 0x84, sizeof(struct bt_data), | 314 | 0x84, sizeof(struct bt_data), |
331 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 315 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
332 | { SN_PRESSURE, 0, 300 }, | 316 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
333 | { SN_WIDTH, 0, 2048 }, | 317 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
334 | { SN_COORD, -4415, 5050 }, | 318 | { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, |
335 | { SN_COORD, -55, 6680 }, | 319 | { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } |
336 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
337 | }, | 320 | }, |
338 | { | 321 | { |
339 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, | 322 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, |
@@ -342,11 +325,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
342 | HAS_INTEGRATED_BUTTON, | 325 | HAS_INTEGRATED_BUTTON, |
343 | 0x84, sizeof(struct bt_data), | 326 | 0x84, sizeof(struct bt_data), |
344 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 327 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
345 | { SN_PRESSURE, 0, 300 }, | 328 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
346 | { SN_WIDTH, 0, 2048 }, | 329 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
347 | { SN_COORD, -4620, 5140 }, | 330 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, |
348 | { SN_COORD, -150, 6600 }, | 331 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } |
349 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
350 | }, | 332 | }, |
351 | { | 333 | { |
352 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, | 334 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, |
@@ -355,11 +337,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
355 | HAS_INTEGRATED_BUTTON, | 337 | HAS_INTEGRATED_BUTTON, |
356 | 0x84, sizeof(struct bt_data), | 338 | 0x84, sizeof(struct bt_data), |
357 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 339 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
358 | { SN_PRESSURE, 0, 300 }, | 340 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
359 | { SN_WIDTH, 0, 2048 }, | 341 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
360 | { SN_COORD, -4750, 5280 }, | 342 | { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, |
361 | { SN_COORD, -150, 6730 }, | 343 | { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } |
362 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
363 | }, | 344 | }, |
364 | { | 345 | { |
365 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, | 346 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, |
@@ -368,37 +349,10 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
368 | HAS_INTEGRATED_BUTTON, | 349 | HAS_INTEGRATED_BUTTON, |
369 | 0x84, sizeof(struct bt_data), | 350 | 0x84, sizeof(struct bt_data), |
370 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 351 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
371 | { SN_PRESSURE, 0, 300 }, | 352 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, |
372 | { SN_WIDTH, 0, 2048 }, | 353 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
373 | { SN_COORD, -4620, 5140 }, | 354 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, |
374 | { SN_COORD, -150, 6600 }, | 355 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } |
375 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
376 | }, | ||
377 | { | ||
378 | USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, | ||
379 | USB_DEVICE_ID_APPLE_WELLSPRING7_ISO, | ||
380 | USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, | ||
381 | HAS_INTEGRATED_BUTTON, | ||
382 | 0x84, sizeof(struct bt_data), | ||
383 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
384 | { SN_PRESSURE, 0, 300 }, | ||
385 | { SN_WIDTH, 0, 2048 }, | ||
386 | { SN_COORD, -4750, 5280 }, | ||
387 | { SN_COORD, -150, 6730 }, | ||
388 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
389 | }, | ||
390 | { | ||
391 | USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI, | ||
392 | USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO, | ||
393 | USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, | ||
394 | HAS_INTEGRATED_BUTTON, | ||
395 | 0x84, sizeof(struct bt_data), | ||
396 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
397 | { SN_PRESSURE, 0, 300 }, | ||
398 | { SN_WIDTH, 0, 2048 }, | ||
399 | { SN_COORD, -4750, 5280 }, | ||
400 | { SN_COORD, -150, 6730 }, | ||
401 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
402 | }, | 356 | }, |
403 | {} | 357 | {} |
404 | }; | 358 | }; |
@@ -422,11 +376,18 @@ static inline int raw2int(__le16 x) | |||
422 | return (signed short)le16_to_cpu(x); | 376 | return (signed short)le16_to_cpu(x); |
423 | } | 377 | } |
424 | 378 | ||
425 | static void set_abs(struct input_dev *input, unsigned int code, | 379 | /* scale device data to logical dimensions (asserts devmin < devmax) */ |
426 | const struct bcm5974_param *p) | 380 | static inline int int2scale(const struct bcm5974_param *p, int x) |
427 | { | 381 | { |
428 | int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0; | 382 | return x * p->dim / (p->devmax - p->devmin); |
429 | input_set_abs_params(input, code, p->min, p->max, fuzz, 0); | 383 | } |
384 | |||
385 | /* all logical value ranges are [0,dim). */ | ||
386 | static inline int int2bound(const struct bcm5974_param *p, int x) | ||
387 | { | ||
388 | int s = int2scale(p, x); | ||
389 | |||
390 | return clamp_val(s, 0, p->dim - 1); | ||
430 | } | 391 | } |
431 | 392 | ||
432 | /* setup which logical events to report */ | 393 | /* setup which logical events to report */ |
@@ -435,30 +396,44 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
435 | { | 396 | { |
436 | __set_bit(EV_ABS, input_dev->evbit); | 397 | __set_bit(EV_ABS, input_dev->evbit); |
437 | 398 | ||
438 | /* for synaptics only */ | 399 | input_set_abs_params(input_dev, ABS_PRESSURE, |
439 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0); | 400 | 0, cfg->p.dim, cfg->p.fuzz, 0); |
440 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0); | 401 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, |
402 | 0, cfg->w.dim, cfg->w.fuzz, 0); | ||
403 | input_set_abs_params(input_dev, ABS_X, | ||
404 | 0, cfg->x.dim, cfg->x.fuzz, 0); | ||
405 | input_set_abs_params(input_dev, ABS_Y, | ||
406 | 0, cfg->y.dim, cfg->y.fuzz, 0); | ||
441 | 407 | ||
442 | /* finger touch area */ | 408 | /* finger touch area */ |
443 | set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); | 409 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
444 | set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); | 410 | cfg->w.devmin, cfg->w.devmax, 0, 0); |
411 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
412 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
445 | /* finger approach area */ | 413 | /* finger approach area */ |
446 | set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w); | 414 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, |
447 | set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w); | 415 | cfg->w.devmin, cfg->w.devmax, 0, 0); |
416 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, | ||
417 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
448 | /* finger orientation */ | 418 | /* finger orientation */ |
449 | set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o); | 419 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, |
420 | -MAX_FINGER_ORIENTATION, | ||
421 | MAX_FINGER_ORIENTATION, 0, 0); | ||
450 | /* finger position */ | 422 | /* finger position */ |
451 | set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x); | 423 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
452 | set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); | 424 | cfg->x.devmin, cfg->x.devmax, 0, 0); |
425 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
426 | cfg->y.devmin, cfg->y.devmax, 0, 0); | ||
453 | 427 | ||
454 | __set_bit(EV_KEY, input_dev->evbit); | 428 | __set_bit(EV_KEY, input_dev->evbit); |
429 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
430 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
431 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
432 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
433 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
455 | __set_bit(BTN_LEFT, input_dev->keybit); | 434 | __set_bit(BTN_LEFT, input_dev->keybit); |
456 | 435 | ||
457 | if (cfg->caps & HAS_INTEGRATED_BUTTON) | 436 | input_set_events_per_packet(input_dev, 60); |
458 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | ||
459 | |||
460 | input_mt_init_slots(input_dev, MAX_FINGERS, | ||
461 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); | ||
462 | } | 437 | } |
463 | 438 | ||
464 | /* report button data as logical button state */ | 439 | /* report button data as logical button state */ |
@@ -478,44 +453,24 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
478 | return 0; | 453 | return 0; |
479 | } | 454 | } |
480 | 455 | ||
481 | static void report_finger_data(struct input_dev *input, int slot, | 456 | static void report_finger_data(struct input_dev *input, |
482 | const struct input_mt_pos *pos, | 457 | const struct bcm5974_config *cfg, |
483 | const struct tp_finger *f) | 458 | const struct tp_finger *f) |
484 | { | 459 | { |
485 | input_mt_slot(input, slot); | ||
486 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
487 | |||
488 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, | 460 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, |
489 | raw2int(f->touch_major) << 1); | 461 | raw2int(f->force_major) << 1); |
490 | input_report_abs(input, ABS_MT_TOUCH_MINOR, | 462 | input_report_abs(input, ABS_MT_TOUCH_MINOR, |
491 | raw2int(f->touch_minor) << 1); | 463 | raw2int(f->force_minor) << 1); |
492 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | 464 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, |
493 | raw2int(f->tool_major) << 1); | 465 | raw2int(f->size_major) << 1); |
494 | input_report_abs(input, ABS_MT_WIDTH_MINOR, | 466 | input_report_abs(input, ABS_MT_WIDTH_MINOR, |
495 | raw2int(f->tool_minor) << 1); | 467 | raw2int(f->size_minor) << 1); |
496 | input_report_abs(input, ABS_MT_ORIENTATION, | 468 | input_report_abs(input, ABS_MT_ORIENTATION, |
497 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | 469 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); |
498 | input_report_abs(input, ABS_MT_POSITION_X, pos->x); | 470 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); |
499 | input_report_abs(input, ABS_MT_POSITION_Y, pos->y); | 471 | input_report_abs(input, ABS_MT_POSITION_Y, |
500 | } | 472 | cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); |
501 | 473 | input_mt_sync(input); | |
502 | static void report_synaptics_data(struct input_dev *input, | ||
503 | const struct bcm5974_config *cfg, | ||
504 | const struct tp_finger *f, int raw_n) | ||
505 | { | ||
506 | int abs_p = 0, abs_w = 0; | ||
507 | |||
508 | if (raw_n) { | ||
509 | int p = raw2int(f->touch_major); | ||
510 | int w = raw2int(f->tool_major); | ||
511 | if (p > 0 && raw2int(f->origin)) { | ||
512 | abs_p = clamp_val(256 * p / cfg->p.max, 0, 255); | ||
513 | abs_w = clamp_val(16 * w / cfg->w.max, 0, 15); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | input_report_abs(input, ABS_PRESSURE, abs_p); | ||
518 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | ||
519 | } | 474 | } |
520 | 475 | ||
521 | /* report trackpad data as logical trackpad state */ | 476 | /* report trackpad data as logical trackpad state */ |
@@ -524,7 +479,9 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
524 | const struct bcm5974_config *c = &dev->cfg; | 479 | const struct bcm5974_config *c = &dev->cfg; |
525 | const struct tp_finger *f; | 480 | const struct tp_finger *f; |
526 | struct input_dev *input = dev->input; | 481 | struct input_dev *input = dev->input; |
527 | int raw_n, i, n = 0; | 482 | int raw_p, raw_w, raw_x, raw_y, raw_n, i; |
483 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; | ||
484 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | ||
528 | 485 | ||
529 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) | 486 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
530 | return -EIO; | 487 | return -EIO; |
@@ -533,29 +490,76 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
533 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); | 490 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); |
534 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; | 491 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; |
535 | 492 | ||
536 | for (i = 0; i < raw_n; i++) { | 493 | /* always track the first finger; when detached, start over */ |
537 | if (raw2int(f[i].touch_major) == 0) | 494 | if (raw_n) { |
538 | continue; | 495 | |
539 | dev->pos[n].x = raw2int(f[i].abs_x); | 496 | /* report raw trackpad data */ |
540 | dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); | 497 | for (i = 0; i < raw_n; i++) |
541 | dev->index[n++] = &f[i]; | 498 | report_finger_data(input, c, &f[i]); |
499 | |||
500 | raw_p = raw2int(f->force_major); | ||
501 | raw_w = raw2int(f->size_major); | ||
502 | raw_x = raw2int(f->abs_x); | ||
503 | raw_y = raw2int(f->abs_y); | ||
504 | |||
505 | dprintk(9, | ||
506 | "bcm5974: " | ||
507 | "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", | ||
508 | raw_p, raw_w, raw_x, raw_y, raw_n); | ||
509 | |||
510 | ptest = int2bound(&c->p, raw_p); | ||
511 | origin = raw2int(f->origin); | ||
512 | |||
513 | /* while tracking finger still valid, count all fingers */ | ||
514 | if (ptest > PRESSURE_LOW && origin) { | ||
515 | abs_p = ptest; | ||
516 | abs_w = int2bound(&c->w, raw_w); | ||
517 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | ||
518 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | ||
519 | while (raw_n--) { | ||
520 | ptest = int2bound(&c->p, | ||
521 | raw2int(f->force_major)); | ||
522 | if (ptest > PRESSURE_LOW) | ||
523 | nmax++; | ||
524 | if (ptest > PRESSURE_HIGH) | ||
525 | nmin++; | ||
526 | f++; | ||
527 | } | ||
528 | } | ||
542 | } | 529 | } |
543 | 530 | ||
544 | input_mt_assign_slots(input, dev->slots, dev->pos, n); | 531 | /* set the integrated button if applicable */ |
532 | if (c->tp_type == TYPE2) | ||
533 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
545 | 534 | ||
546 | for (i = 0; i < n; i++) | 535 | if (dev->fingers < nmin) |
547 | report_finger_data(input, dev->slots[i], | 536 | dev->fingers = nmin; |
548 | &dev->pos[i], dev->index[i]); | 537 | if (dev->fingers > nmax) |
538 | dev->fingers = nmax; | ||
549 | 539 | ||
550 | input_mt_sync_frame(input); | 540 | input_report_key(input, BTN_TOUCH, dev->fingers > 0); |
541 | input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); | ||
542 | input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); | ||
543 | input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); | ||
544 | input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); | ||
551 | 545 | ||
552 | report_synaptics_data(input, c, f, raw_n); | 546 | input_report_abs(input, ABS_PRESSURE, abs_p); |
547 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | ||
548 | |||
549 | if (abs_p) { | ||
550 | input_report_abs(input, ABS_X, abs_x); | ||
551 | input_report_abs(input, ABS_Y, abs_y); | ||
552 | |||
553 | dprintk(8, | ||
554 | "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " | ||
555 | "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, | ||
556 | abs_x, abs_y, nmin, nmax, dev->fingers, ibt); | ||
557 | |||
558 | } | ||
553 | 559 | ||
554 | /* type 2 reports button events via ibt only */ | 560 | /* type 2 reports button events via ibt only */ |
555 | if (c->tp_type == TYPE2) { | 561 | if (c->tp_type == TYPE2) |
556 | int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
557 | input_report_key(input, BTN_LEFT, ibt); | 562 | input_report_key(input, BTN_LEFT, ibt); |
558 | } | ||
559 | 563 | ||
560 | input_sync(input); | 564 | input_sync(input); |
561 | 565 | ||
@@ -576,7 +580,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) | |||
576 | int retval = 0, size; | 580 | int retval = 0, size; |
577 | 581 | ||
578 | if (!data) { | 582 | if (!data) { |
579 | dev_err(&dev->intf->dev, "out of memory\n"); | 583 | err("bcm5974: out of memory"); |
580 | retval = -ENOMEM; | 584 | retval = -ENOMEM; |
581 | goto out; | 585 | goto out; |
582 | } | 586 | } |
@@ -589,7 +593,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) | |||
589 | BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); | 593 | BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); |
590 | 594 | ||
591 | if (size != 8) { | 595 | if (size != 8) { |
592 | dev_err(&dev->intf->dev, "could not read from device\n"); | 596 | err("bcm5974: could not read from device"); |
593 | retval = -EIO; | 597 | retval = -EIO; |
594 | goto out; | 598 | goto out; |
595 | } | 599 | } |
@@ -607,7 +611,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) | |||
607 | BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); | 611 | BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); |
608 | 612 | ||
609 | if (size != 8) { | 613 | if (size != 8) { |
610 | dev_err(&dev->intf->dev, "could not write to device\n"); | 614 | err("bcm5974: could not write to device"); |
611 | retval = -EIO; | 615 | retval = -EIO; |
612 | goto out; | 616 | goto out; |
613 | } | 617 | } |
@@ -623,7 +627,6 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) | |||
623 | static void bcm5974_irq_button(struct urb *urb) | 627 | static void bcm5974_irq_button(struct urb *urb) |
624 | { | 628 | { |
625 | struct bcm5974 *dev = urb->context; | 629 | struct bcm5974 *dev = urb->context; |
626 | struct usb_interface *intf = dev->intf; | ||
627 | int error; | 630 | int error; |
628 | 631 | ||
629 | switch (urb->status) { | 632 | switch (urb->status) { |
@@ -633,11 +636,10 @@ static void bcm5974_irq_button(struct urb *urb) | |||
633 | case -ECONNRESET: | 636 | case -ECONNRESET: |
634 | case -ENOENT: | 637 | case -ENOENT: |
635 | case -ESHUTDOWN: | 638 | case -ESHUTDOWN: |
636 | dev_dbg(&intf->dev, "button urb shutting down: %d\n", | 639 | dbg("bcm5974: button urb shutting down: %d", urb->status); |
637 | urb->status); | ||
638 | return; | 640 | return; |
639 | default: | 641 | default: |
640 | dev_dbg(&intf->dev, "button urb status: %d\n", urb->status); | 642 | dbg("bcm5974: button urb status: %d", urb->status); |
641 | goto exit; | 643 | goto exit; |
642 | } | 644 | } |
643 | 645 | ||
@@ -648,13 +650,12 @@ static void bcm5974_irq_button(struct urb *urb) | |||
648 | exit: | 650 | exit: |
649 | error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); | 651 | error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); |
650 | if (error) | 652 | if (error) |
651 | dev_err(&intf->dev, "button urb failed: %d\n", error); | 653 | err("bcm5974: button urb failed: %d", error); |
652 | } | 654 | } |
653 | 655 | ||
654 | static void bcm5974_irq_trackpad(struct urb *urb) | 656 | static void bcm5974_irq_trackpad(struct urb *urb) |
655 | { | 657 | { |
656 | struct bcm5974 *dev = urb->context; | 658 | struct bcm5974 *dev = urb->context; |
657 | struct usb_interface *intf = dev->intf; | ||
658 | int error; | 659 | int error; |
659 | 660 | ||
660 | switch (urb->status) { | 661 | switch (urb->status) { |
@@ -664,11 +665,10 @@ static void bcm5974_irq_trackpad(struct urb *urb) | |||
664 | case -ECONNRESET: | 665 | case -ECONNRESET: |
665 | case -ENOENT: | 666 | case -ENOENT: |
666 | case -ESHUTDOWN: | 667 | case -ESHUTDOWN: |
667 | dev_dbg(&intf->dev, "trackpad urb shutting down: %d\n", | 668 | dbg("bcm5974: trackpad urb shutting down: %d", urb->status); |
668 | urb->status); | ||
669 | return; | 669 | return; |
670 | default: | 670 | default: |
671 | dev_dbg(&intf->dev, "trackpad urb status: %d\n", urb->status); | 671 | dbg("bcm5974: trackpad urb status: %d", urb->status); |
672 | goto exit; | 672 | goto exit; |
673 | } | 673 | } |
674 | 674 | ||
@@ -683,7 +683,7 @@ static void bcm5974_irq_trackpad(struct urb *urb) | |||
683 | exit: | 683 | exit: |
684 | error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC); | 684 | error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC); |
685 | if (error) | 685 | if (error) |
686 | dev_err(&intf->dev, "trackpad urb failed: %d\n", error); | 686 | err("bcm5974: trackpad urb failed: %d", error); |
687 | } | 687 | } |
688 | 688 | ||
689 | /* | 689 | /* |
@@ -714,11 +714,9 @@ static int bcm5974_start_traffic(struct bcm5974 *dev) | |||
714 | goto err_out; | 714 | goto err_out; |
715 | } | 715 | } |
716 | 716 | ||
717 | if (dev->bt_urb) { | 717 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); |
718 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); | 718 | if (error) |
719 | if (error) | 719 | goto err_reset_mode; |
720 | goto err_reset_mode; | ||
721 | } | ||
722 | 720 | ||
723 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); | 721 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); |
724 | if (error) | 722 | if (error) |
@@ -831,7 +829,7 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
831 | dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); | 829 | dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); |
832 | input_dev = input_allocate_device(); | 830 | input_dev = input_allocate_device(); |
833 | if (!dev || !input_dev) { | 831 | if (!dev || !input_dev) { |
834 | dev_err(&iface->dev, "out of memory\n"); | 832 | err("bcm5974: out of memory"); |
835 | goto err_free_devs; | 833 | goto err_free_devs; |
836 | } | 834 | } |
837 | 835 | ||
@@ -842,23 +840,19 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
842 | mutex_init(&dev->pm_mutex); | 840 | mutex_init(&dev->pm_mutex); |
843 | 841 | ||
844 | /* setup urbs */ | 842 | /* setup urbs */ |
845 | if (cfg->tp_type == TYPE1) { | 843 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); |
846 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); | 844 | if (!dev->bt_urb) |
847 | if (!dev->bt_urb) | 845 | goto err_free_devs; |
848 | goto err_free_devs; | ||
849 | } | ||
850 | 846 | ||
851 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); | 847 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); |
852 | if (!dev->tp_urb) | 848 | if (!dev->tp_urb) |
853 | goto err_free_bt_urb; | 849 | goto err_free_bt_urb; |
854 | 850 | ||
855 | if (dev->bt_urb) { | 851 | dev->bt_data = usb_alloc_coherent(dev->udev, |
856 | dev->bt_data = usb_alloc_coherent(dev->udev, | ||
857 | dev->cfg.bt_datalen, GFP_KERNEL, | 852 | dev->cfg.bt_datalen, GFP_KERNEL, |
858 | &dev->bt_urb->transfer_dma); | 853 | &dev->bt_urb->transfer_dma); |
859 | if (!dev->bt_data) | 854 | if (!dev->bt_data) |
860 | goto err_free_urb; | 855 | goto err_free_urb; |
861 | } | ||
862 | 856 | ||
863 | dev->tp_data = usb_alloc_coherent(dev->udev, | 857 | dev->tp_data = usb_alloc_coherent(dev->udev, |
864 | dev->cfg.tp_datalen, GFP_KERNEL, | 858 | dev->cfg.tp_datalen, GFP_KERNEL, |
@@ -866,11 +860,10 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
866 | if (!dev->tp_data) | 860 | if (!dev->tp_data) |
867 | goto err_free_bt_buffer; | 861 | goto err_free_bt_buffer; |
868 | 862 | ||
869 | if (dev->bt_urb) | 863 | usb_fill_int_urb(dev->bt_urb, udev, |
870 | usb_fill_int_urb(dev->bt_urb, udev, | 864 | usb_rcvintpipe(udev, cfg->bt_ep), |
871 | usb_rcvintpipe(udev, cfg->bt_ep), | 865 | dev->bt_data, dev->cfg.bt_datalen, |
872 | dev->bt_data, dev->cfg.bt_datalen, | 866 | bcm5974_irq_button, dev, 1); |
873 | bcm5974_irq_button, dev, 1); | ||
874 | 867 | ||
875 | usb_fill_int_urb(dev->tp_urb, udev, | 868 | usb_fill_int_urb(dev->tp_urb, udev, |
876 | usb_rcvintpipe(udev, cfg->tp_ep), | 869 | usb_rcvintpipe(udev, cfg->tp_ep), |
@@ -908,9 +901,8 @@ err_free_buffer: | |||
908 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, | 901 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
909 | dev->tp_data, dev->tp_urb->transfer_dma); | 902 | dev->tp_data, dev->tp_urb->transfer_dma); |
910 | err_free_bt_buffer: | 903 | err_free_bt_buffer: |
911 | if (dev->bt_urb) | 904 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
912 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, | 905 | dev->bt_data, dev->bt_urb->transfer_dma); |
913 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
914 | err_free_urb: | 906 | err_free_urb: |
915 | usb_free_urb(dev->tp_urb); | 907 | usb_free_urb(dev->tp_urb); |
916 | err_free_bt_urb: | 908 | err_free_bt_urb: |
@@ -931,9 +923,8 @@ static void bcm5974_disconnect(struct usb_interface *iface) | |||
931 | input_unregister_device(dev->input); | 923 | input_unregister_device(dev->input); |
932 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, | 924 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
933 | dev->tp_data, dev->tp_urb->transfer_dma); | 925 | dev->tp_data, dev->tp_urb->transfer_dma); |
934 | if (dev->bt_urb) | 926 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
935 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, | 927 | dev->bt_data, dev->bt_urb->transfer_dma); |
936 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
937 | usb_free_urb(dev->tp_urb); | 928 | usb_free_urb(dev->tp_urb); |
938 | usb_free_urb(dev->bt_urb); | 929 | usb_free_urb(dev->bt_urb); |
939 | kfree(dev); | 930 | kfree(dev); |
@@ -949,4 +940,16 @@ static struct usb_driver bcm5974_driver = { | |||
949 | .supports_autosuspend = 1, | 940 | .supports_autosuspend = 1, |
950 | }; | 941 | }; |
951 | 942 | ||
952 | module_usb_driver(bcm5974_driver); | 943 | static int __init bcm5974_init(void) |
944 | { | ||
945 | return usb_register(&bcm5974_driver); | ||
946 | } | ||
947 | |||
948 | static void __exit bcm5974_exit(void) | ||
949 | { | ||
950 | usb_deregister(&bcm5974_driver); | ||
951 | } | ||
952 | |||
953 | module_init(bcm5974_init); | ||
954 | module_exit(bcm5974_exit); | ||
955 | |||
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 1e8e42fb03a..32503565faf 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> |
@@ -23,10 +25,13 @@ | |||
23 | #define elantech_debug(fmt, ...) \ | 25 | #define elantech_debug(fmt, ...) \ |
24 | do { \ | 26 | do { \ |
25 | if (etd->debug) \ | 27 | if (etd->debug) \ |
26 | psmouse_printk(KERN_DEBUG, psmouse, \ | 28 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ |
27 | fmt, ##__VA_ARGS__); \ | ||
28 | } while (0) | 29 | } while (0) |
29 | 30 | ||
31 | static bool force_elantech; | ||
32 | module_param_named(force_elantech, force_elantech, bool, 0644); | ||
33 | MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default)."); | ||
34 | |||
30 | /* | 35 | /* |
31 | * Send a Synaptics style sliced query command | 36 | * Send a Synaptics style sliced query command |
32 | */ | 37 | */ |
@@ -35,25 +40,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, | |||
35 | { | 40 | { |
36 | if (psmouse_sliced_command(psmouse, c) || | 41 | if (psmouse_sliced_command(psmouse, c) || |
37 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 42 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
38 | psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c); | 43 | pr_err("synaptics_send_cmd query 0x%02x failed.\n", c); |
39 | return -1; | ||
40 | } | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * V3 and later support this fast command | ||
47 | */ | ||
48 | static int elantech_send_cmd(struct psmouse *psmouse, unsigned char c, | ||
49 | unsigned char *param) | ||
50 | { | ||
51 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
52 | |||
53 | if (ps2_command(ps2dev, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
54 | ps2_command(ps2dev, NULL, c) || | ||
55 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | ||
56 | psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c); | ||
57 | return -1; | 44 | return -1; |
58 | } | 45 | } |
59 | 46 | ||
@@ -82,7 +69,7 @@ static int elantech_ps2_command(struct psmouse *psmouse, | |||
82 | } while (tries > 0); | 69 | } while (tries > 0); |
83 | 70 | ||
84 | if (rc) | 71 | if (rc) |
85 | psmouse_err(psmouse, "ps2 command 0x%02x failed.\n", command); | 72 | pr_err("ps2 command 0x%02x failed.\n", command); |
86 | 73 | ||
87 | return rc; | 74 | return rc; |
88 | } | 75 | } |
@@ -97,7 +84,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
97 | unsigned char param[3]; | 84 | unsigned char param[3]; |
98 | int rc = 0; | 85 | int rc = 0; |
99 | 86 | ||
100 | if (reg < 0x07 || reg > 0x26) | 87 | if (reg < 0x10 || reg > 0x26) |
101 | return -1; | 88 | return -1; |
102 | 89 | ||
103 | if (reg > 0x11 && reg < 0x20) | 90 | if (reg > 0x11 && reg < 0x20) |
@@ -121,24 +108,12 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
121 | rc = -1; | 108 | rc = -1; |
122 | } | 109 | } |
123 | break; | 110 | break; |
124 | |||
125 | case 3 ... 4: | ||
126 | if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
127 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
128 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
129 | elantech_ps2_command(psmouse, NULL, reg) || | ||
130 | elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) { | ||
131 | rc = -1; | ||
132 | } | ||
133 | break; | ||
134 | } | 111 | } |
135 | 112 | ||
136 | if (rc) | 113 | if (rc) |
137 | psmouse_err(psmouse, "failed to read register 0x%02x.\n", reg); | 114 | pr_err("failed to read register 0x%02x.\n", reg); |
138 | else if (etd->hw_version != 4) | ||
139 | *val = param[0]; | ||
140 | else | 115 | else |
141 | *val = param[1]; | 116 | *val = param[0]; |
142 | 117 | ||
143 | return rc; | 118 | return rc; |
144 | } | 119 | } |
@@ -152,7 +127,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
152 | struct elantech_data *etd = psmouse->private; | 127 | struct elantech_data *etd = psmouse->private; |
153 | int rc = 0; | 128 | int rc = 0; |
154 | 129 | ||
155 | if (reg < 0x07 || reg > 0x26) | 130 | if (reg < 0x10 || reg > 0x26) |
156 | return -1; | 131 | return -1; |
157 | 132 | ||
158 | if (reg > 0x11 && reg < 0x20) | 133 | if (reg > 0x11 && reg < 0x20) |
@@ -179,38 +154,11 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
179 | rc = -1; | 154 | rc = -1; |
180 | } | 155 | } |
181 | break; | 156 | break; |
182 | |||
183 | case 3: | ||
184 | if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
185 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
186 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
187 | elantech_ps2_command(psmouse, NULL, reg) || | ||
188 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
189 | elantech_ps2_command(psmouse, NULL, val) || | ||
190 | elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) { | ||
191 | rc = -1; | ||
192 | } | ||
193 | break; | ||
194 | |||
195 | case 4: | ||
196 | if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
197 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
198 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
199 | elantech_ps2_command(psmouse, NULL, reg) || | ||
200 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
201 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
202 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
203 | elantech_ps2_command(psmouse, NULL, val) || | ||
204 | elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) { | ||
205 | rc = -1; | ||
206 | } | ||
207 | break; | ||
208 | } | 157 | } |
209 | 158 | ||
210 | if (rc) | 159 | if (rc) |
211 | psmouse_err(psmouse, | 160 | pr_err("failed to write register 0x%02x with value 0x%02x.\n", |
212 | "failed to write register 0x%02x with value 0x%02x.\n", | 161 | reg, val); |
213 | reg, val); | ||
214 | 162 | ||
215 | return rc; | 163 | return rc; |
216 | } | 164 | } |
@@ -218,13 +166,13 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
218 | /* | 166 | /* |
219 | * Dump a complete mouse movement packet to the syslog | 167 | * Dump a complete mouse movement packet to the syslog |
220 | */ | 168 | */ |
221 | static void elantech_packet_dump(struct psmouse *psmouse) | 169 | static void elantech_packet_dump(unsigned char *packet, int size) |
222 | { | 170 | { |
223 | int i; | 171 | int i; |
224 | 172 | ||
225 | psmouse_printk(KERN_DEBUG, psmouse, "PS/2 packet ["); | 173 | printk(KERN_DEBUG pr_fmt("PS/2 packet [")); |
226 | for (i = 0; i < psmouse->pktsize; i++) | 174 | for (i = 0; i < size; i++) |
227 | printk("%s0x%02x ", i ? ", " : " ", psmouse->packet[i]); | 175 | printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); |
228 | printk("]\n"); | 176 | printk("]\n"); |
229 | } | 177 | } |
230 | 178 | ||
@@ -275,7 +223,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
275 | input_report_abs(dev, ABS_X, | 223 | input_report_abs(dev, ABS_X, |
276 | ((packet[1] & 0x0c) << 6) | packet[2]); | 224 | ((packet[1] & 0x0c) << 6) | packet[2]); |
277 | input_report_abs(dev, ABS_Y, | 225 | input_report_abs(dev, ABS_Y, |
278 | etd->y_max - (((packet[1] & 0x03) << 8) | packet[3])); | 226 | ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); |
279 | } | 227 | } |
280 | 228 | ||
281 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 229 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
@@ -285,7 +233,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
285 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 233 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
286 | 234 | ||
287 | if (etd->fw_version < 0x020000 && | 235 | if (etd->fw_version < 0x020000 && |
288 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { | 236 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
289 | /* rocker up */ | 237 | /* rocker up */ |
290 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 238 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
291 | /* rocker down */ | 239 | /* rocker down */ |
@@ -325,11 +273,11 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
325 | struct elantech_data *etd = psmouse->private; | 273 | struct elantech_data *etd = psmouse->private; |
326 | struct input_dev *dev = psmouse->dev; | 274 | struct input_dev *dev = psmouse->dev; |
327 | unsigned char *packet = psmouse->packet; | 275 | unsigned char *packet = psmouse->packet; |
328 | unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0; | 276 | unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, pres = 0; |
329 | unsigned int width = 0, pres = 0; | ||
330 | 277 | ||
331 | /* byte 0: n1 n0 . . . . R L */ | 278 | /* byte 0: n1 n0 . . . . R L */ |
332 | fingers = (packet[0] & 0xc0) >> 6; | 279 | fingers = (packet[0] & 0xc0) >> 6; |
280 | input_report_key(dev, BTN_TOUCH, fingers != 0); | ||
333 | 281 | ||
334 | switch (fingers) { | 282 | switch (fingers) { |
335 | case 3: | 283 | case 3: |
@@ -342,15 +290,18 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
342 | /* pass through... */ | 290 | /* pass through... */ |
343 | case 1: | 291 | case 1: |
344 | /* | 292 | /* |
345 | * byte 1: . . . . x11 x10 x9 x8 | 293 | * byte 1: . . . . . x10 x9 x8 |
346 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 | 294 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
347 | */ | 295 | */ |
348 | x1 = ((packet[1] & 0x0f) << 8) | packet[2]; | 296 | x1 = ((packet[1] & 0x07) << 8) | packet[2]; |
349 | /* | 297 | /* |
350 | * byte 4: . . . . y11 y10 y9 y8 | 298 | * byte 4: . . . . . . y9 y8 |
351 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | 299 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 |
352 | */ | 300 | */ |
353 | y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | 301 | y1 = ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]); |
302 | |||
303 | input_report_abs(dev, ABS_X, x1); | ||
304 | input_report_abs(dev, ABS_Y, y1); | ||
354 | 305 | ||
355 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | 306 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); |
356 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); | 307 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); |
@@ -363,18 +314,22 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
363 | * byte 0: . . ay8 ax8 . . . . | 314 | * byte 0: . . ay8 ax8 . . . . |
364 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | 315 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 |
365 | */ | 316 | */ |
366 | x1 = (((packet[0] & 0x10) << 4) | packet[1]) << 2; | 317 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; |
367 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ | 318 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ |
368 | y1 = etd->y_max - | 319 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); |
369 | ((((packet[0] & 0x20) << 3) | packet[2]) << 2); | ||
370 | /* | 320 | /* |
371 | * byte 3: . . by8 bx8 . . . . | 321 | * byte 3: . . by8 bx8 . . . . |
372 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | 322 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 |
373 | */ | 323 | */ |
374 | x2 = (((packet[3] & 0x10) << 4) | packet[4]) << 2; | 324 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; |
375 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ | 325 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ |
376 | y2 = etd->y_max - | 326 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); |
377 | ((((packet[3] & 0x20) << 3) | packet[5]) << 2); | 327 | /* |
328 | * For compatibility with the X Synaptics driver scale up | ||
329 | * one coordinate and report as ordinary mouse movent | ||
330 | */ | ||
331 | input_report_abs(dev, ABS_X, x1 << 2); | ||
332 | input_report_abs(dev, ABS_Y, y1 << 2); | ||
378 | 333 | ||
379 | /* Unknown so just report sensible values */ | 334 | /* Unknown so just report sensible values */ |
380 | pres = 127; | 335 | pres = 127; |
@@ -382,11 +337,6 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
382 | break; | 337 | break; |
383 | } | 338 | } |
384 | 339 | ||
385 | input_report_key(dev, BTN_TOUCH, fingers != 0); | ||
386 | if (fingers != 0) { | ||
387 | input_report_abs(dev, ABS_X, x1); | ||
388 | input_report_abs(dev, ABS_Y, y1); | ||
389 | } | ||
390 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | 340 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); |
391 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 341 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
392 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 342 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
@@ -402,207 +352,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
402 | input_sync(dev); | 352 | input_sync(dev); |
403 | } | 353 | } |
404 | 354 | ||
405 | /* | 355 | static int elantech_check_parity_v1(struct psmouse *psmouse) |
406 | * Interpret complete data packets and report absolute mode input events for | ||
407 | * hardware version 3. (12 byte packets for two fingers) | ||
408 | */ | ||
409 | static void elantech_report_absolute_v3(struct psmouse *psmouse, | ||
410 | int packet_type) | ||
411 | { | ||
412 | struct input_dev *dev = psmouse->dev; | ||
413 | struct elantech_data *etd = psmouse->private; | ||
414 | unsigned char *packet = psmouse->packet; | ||
415 | unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0; | ||
416 | unsigned int width = 0, pres = 0; | ||
417 | |||
418 | /* byte 0: n1 n0 . . . . R L */ | ||
419 | fingers = (packet[0] & 0xc0) >> 6; | ||
420 | |||
421 | switch (fingers) { | ||
422 | case 3: | ||
423 | case 1: | ||
424 | /* | ||
425 | * byte 1: . . . . x11 x10 x9 x8 | ||
426 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 | ||
427 | */ | ||
428 | x1 = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
429 | /* | ||
430 | * byte 4: . . . . y11 y10 y9 y8 | ||
431 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
432 | */ | ||
433 | y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | ||
434 | break; | ||
435 | |||
436 | case 2: | ||
437 | if (packet_type == PACKET_V3_HEAD) { | ||
438 | /* | ||
439 | * byte 1: . . . . ax11 ax10 ax9 ax8 | ||
440 | * byte 2: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | ||
441 | */ | ||
442 | etd->mt[0].x = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
443 | /* | ||
444 | * byte 4: . . . . ay11 ay10 ay9 ay8 | ||
445 | * byte 5: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 | ||
446 | */ | ||
447 | etd->mt[0].y = etd->y_max - | ||
448 | (((packet[4] & 0x0f) << 8) | packet[5]); | ||
449 | /* | ||
450 | * wait for next packet | ||
451 | */ | ||
452 | return; | ||
453 | } | ||
454 | |||
455 | /* packet_type == PACKET_V3_TAIL */ | ||
456 | x1 = etd->mt[0].x; | ||
457 | y1 = etd->mt[0].y; | ||
458 | x2 = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
459 | y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | ||
464 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); | ||
465 | |||
466 | input_report_key(dev, BTN_TOUCH, fingers != 0); | ||
467 | if (fingers != 0) { | ||
468 | input_report_abs(dev, ABS_X, x1); | ||
469 | input_report_abs(dev, ABS_Y, y1); | ||
470 | } | ||
471 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
472 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | ||
473 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | ||
474 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | ||
475 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
476 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
477 | input_report_abs(dev, ABS_PRESSURE, pres); | ||
478 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | ||
479 | |||
480 | input_sync(dev); | ||
481 | } | ||
482 | |||
483 | static void elantech_input_sync_v4(struct psmouse *psmouse) | ||
484 | { | ||
485 | struct input_dev *dev = psmouse->dev; | ||
486 | unsigned char *packet = psmouse->packet; | ||
487 | |||
488 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
489 | input_mt_report_pointer_emulation(dev, true); | ||
490 | input_sync(dev); | ||
491 | } | ||
492 | |||
493 | static void process_packet_status_v4(struct psmouse *psmouse) | ||
494 | { | ||
495 | struct input_dev *dev = psmouse->dev; | ||
496 | unsigned char *packet = psmouse->packet; | ||
497 | unsigned fingers; | ||
498 | int i; | ||
499 | |||
500 | /* notify finger state change */ | ||
501 | fingers = packet[1] & 0x1f; | ||
502 | for (i = 0; i < ETP_MAX_FINGERS; i++) { | ||
503 | if ((fingers & (1 << i)) == 0) { | ||
504 | input_mt_slot(dev, i); | ||
505 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, false); | ||
506 | } | ||
507 | } | ||
508 | |||
509 | elantech_input_sync_v4(psmouse); | ||
510 | } | ||
511 | |||
512 | static void process_packet_head_v4(struct psmouse *psmouse) | ||
513 | { | ||
514 | struct input_dev *dev = psmouse->dev; | ||
515 | struct elantech_data *etd = psmouse->private; | ||
516 | unsigned char *packet = psmouse->packet; | ||
517 | int id = ((packet[3] & 0xe0) >> 5) - 1; | ||
518 | int pres, traces; | ||
519 | |||
520 | if (id < 0) | ||
521 | return; | ||
522 | |||
523 | etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
524 | etd->mt[id].y = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | ||
525 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | ||
526 | traces = (packet[0] & 0xf0) >> 4; | ||
527 | |||
528 | input_mt_slot(dev, id); | ||
529 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, true); | ||
530 | |||
531 | input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x); | ||
532 | input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y); | ||
533 | input_report_abs(dev, ABS_MT_PRESSURE, pres); | ||
534 | input_report_abs(dev, ABS_MT_TOUCH_MAJOR, traces * etd->width); | ||
535 | /* report this for backwards compatibility */ | ||
536 | input_report_abs(dev, ABS_TOOL_WIDTH, traces); | ||
537 | |||
538 | elantech_input_sync_v4(psmouse); | ||
539 | } | ||
540 | |||
541 | static void process_packet_motion_v4(struct psmouse *psmouse) | ||
542 | { | ||
543 | struct input_dev *dev = psmouse->dev; | ||
544 | struct elantech_data *etd = psmouse->private; | ||
545 | unsigned char *packet = psmouse->packet; | ||
546 | int weight, delta_x1 = 0, delta_y1 = 0, delta_x2 = 0, delta_y2 = 0; | ||
547 | int id, sid; | ||
548 | |||
549 | id = ((packet[0] & 0xe0) >> 5) - 1; | ||
550 | if (id < 0) | ||
551 | return; | ||
552 | |||
553 | sid = ((packet[3] & 0xe0) >> 5) - 1; | ||
554 | weight = (packet[0] & 0x10) ? ETP_WEIGHT_VALUE : 1; | ||
555 | /* | ||
556 | * Motion packets give us the delta of x, y values of specific fingers, | ||
557 | * but in two's complement. Let the compiler do the conversion for us. | ||
558 | * Also _enlarge_ the numbers to int, in case of overflow. | ||
559 | */ | ||
560 | delta_x1 = (signed char)packet[1]; | ||
561 | delta_y1 = (signed char)packet[2]; | ||
562 | delta_x2 = (signed char)packet[4]; | ||
563 | delta_y2 = (signed char)packet[5]; | ||
564 | |||
565 | etd->mt[id].x += delta_x1 * weight; | ||
566 | etd->mt[id].y -= delta_y1 * weight; | ||
567 | input_mt_slot(dev, id); | ||
568 | input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x); | ||
569 | input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y); | ||
570 | |||
571 | if (sid >= 0) { | ||
572 | etd->mt[sid].x += delta_x2 * weight; | ||
573 | etd->mt[sid].y -= delta_y2 * weight; | ||
574 | input_mt_slot(dev, sid); | ||
575 | input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[sid].x); | ||
576 | input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[sid].y); | ||
577 | } | ||
578 | |||
579 | elantech_input_sync_v4(psmouse); | ||
580 | } | ||
581 | |||
582 | static void elantech_report_absolute_v4(struct psmouse *psmouse, | ||
583 | int packet_type) | ||
584 | { | ||
585 | switch (packet_type) { | ||
586 | case PACKET_V4_STATUS: | ||
587 | process_packet_status_v4(psmouse); | ||
588 | break; | ||
589 | |||
590 | case PACKET_V4_HEAD: | ||
591 | process_packet_head_v4(psmouse); | ||
592 | break; | ||
593 | |||
594 | case PACKET_V4_MOTION: | ||
595 | process_packet_motion_v4(psmouse); | ||
596 | break; | ||
597 | |||
598 | case PACKET_UNKNOWN: | ||
599 | default: | ||
600 | /* impossible to get here */ | ||
601 | break; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static int elantech_packet_check_v1(struct psmouse *psmouse) | ||
606 | { | 356 | { |
607 | struct elantech_data *etd = psmouse->private; | 357 | struct elantech_data *etd = psmouse->private; |
608 | unsigned char *packet = psmouse->packet; | 358 | unsigned char *packet = psmouse->packet; |
@@ -626,142 +376,31 @@ static int elantech_packet_check_v1(struct psmouse *psmouse) | |||
626 | etd->parity[packet[3]] == p3; | 376 | etd->parity[packet[3]] == p3; |
627 | } | 377 | } |
628 | 378 | ||
629 | static int elantech_debounce_check_v2(struct psmouse *psmouse) | ||
630 | { | ||
631 | /* | ||
632 | * When we encounter packet that matches this exactly, it means the | ||
633 | * hardware is in debounce status. Just ignore the whole packet. | ||
634 | */ | ||
635 | const u8 debounce_packet[] = { 0x84, 0xff, 0xff, 0x02, 0xff, 0xff }; | ||
636 | unsigned char *packet = psmouse->packet; | ||
637 | |||
638 | return !memcmp(packet, debounce_packet, sizeof(debounce_packet)); | ||
639 | } | ||
640 | |||
641 | static int elantech_packet_check_v2(struct psmouse *psmouse) | ||
642 | { | ||
643 | struct elantech_data *etd = psmouse->private; | ||
644 | unsigned char *packet = psmouse->packet; | ||
645 | |||
646 | /* | ||
647 | * V2 hardware has two flavors. Older ones that do not report pressure, | ||
648 | * and newer ones that reports pressure and width. With newer ones, all | ||
649 | * packets (1, 2, 3 finger touch) have the same constant bits. With | ||
650 | * older ones, 1/3 finger touch packets and 2 finger touch packets | ||
651 | * have different constant bits. | ||
652 | * With all three cases, if the constant bits are not exactly what I | ||
653 | * expected, I consider them invalid. | ||
654 | */ | ||
655 | if (etd->reports_pressure) | ||
656 | return (packet[0] & 0x0c) == 0x04 && | ||
657 | (packet[3] & 0x0f) == 0x02; | ||
658 | |||
659 | if ((packet[0] & 0xc0) == 0x80) | ||
660 | return (packet[0] & 0x0c) == 0x0c && | ||
661 | (packet[3] & 0x0e) == 0x08; | ||
662 | |||
663 | return (packet[0] & 0x3c) == 0x3c && | ||
664 | (packet[1] & 0xf0) == 0x00 && | ||
665 | (packet[3] & 0x3e) == 0x38 && | ||
666 | (packet[4] & 0xf0) == 0x00; | ||
667 | } | ||
668 | |||
669 | /* | ||
670 | * We check the constant bits to determine what packet type we get, | ||
671 | * so packet checking is mandatory for v3 and later hardware. | ||
672 | */ | ||
673 | static int elantech_packet_check_v3(struct psmouse *psmouse) | ||
674 | { | ||
675 | const u8 debounce_packet[] = { 0xc4, 0xff, 0xff, 0x02, 0xff, 0xff }; | ||
676 | unsigned char *packet = psmouse->packet; | ||
677 | |||
678 | /* | ||
679 | * check debounce first, it has the same signature in byte 0 | ||
680 | * and byte 3 as PACKET_V3_HEAD. | ||
681 | */ | ||
682 | if (!memcmp(packet, debounce_packet, sizeof(debounce_packet))) | ||
683 | return PACKET_DEBOUNCE; | ||
684 | |||
685 | if ((packet[0] & 0x0c) == 0x04 && (packet[3] & 0xcf) == 0x02) | ||
686 | return PACKET_V3_HEAD; | ||
687 | |||
688 | if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) | ||
689 | return PACKET_V3_TAIL; | ||
690 | |||
691 | return PACKET_UNKNOWN; | ||
692 | } | ||
693 | |||
694 | static int elantech_packet_check_v4(struct psmouse *psmouse) | ||
695 | { | ||
696 | unsigned char *packet = psmouse->packet; | ||
697 | |||
698 | if ((packet[0] & 0x0c) == 0x04 && | ||
699 | (packet[3] & 0x1f) == 0x11) | ||
700 | return PACKET_V4_HEAD; | ||
701 | |||
702 | if ((packet[0] & 0x0c) == 0x04 && | ||
703 | (packet[3] & 0x1f) == 0x12) | ||
704 | return PACKET_V4_MOTION; | ||
705 | |||
706 | if ((packet[0] & 0x0c) == 0x04 && | ||
707 | (packet[3] & 0x1f) == 0x10) | ||
708 | return PACKET_V4_STATUS; | ||
709 | |||
710 | return PACKET_UNKNOWN; | ||
711 | } | ||
712 | |||
713 | /* | 379 | /* |
714 | * Process byte stream from mouse and handle complete packets | 380 | * Process byte stream from mouse and handle complete packets |
715 | */ | 381 | */ |
716 | static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | 382 | static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) |
717 | { | 383 | { |
718 | struct elantech_data *etd = psmouse->private; | 384 | struct elantech_data *etd = psmouse->private; |
719 | int packet_type; | ||
720 | 385 | ||
721 | if (psmouse->pktcnt < psmouse->pktsize) | 386 | if (psmouse->pktcnt < psmouse->pktsize) |
722 | return PSMOUSE_GOOD_DATA; | 387 | return PSMOUSE_GOOD_DATA; |
723 | 388 | ||
724 | if (etd->debug > 1) | 389 | if (etd->debug > 1) |
725 | elantech_packet_dump(psmouse); | 390 | elantech_packet_dump(psmouse->packet, psmouse->pktsize); |
726 | 391 | ||
727 | switch (etd->hw_version) { | 392 | switch (etd->hw_version) { |
728 | case 1: | 393 | case 1: |
729 | if (etd->paritycheck && !elantech_packet_check_v1(psmouse)) | 394 | if (etd->paritycheck && !elantech_check_parity_v1(psmouse)) |
730 | return PSMOUSE_BAD_DATA; | 395 | return PSMOUSE_BAD_DATA; |
731 | 396 | ||
732 | elantech_report_absolute_v1(psmouse); | 397 | elantech_report_absolute_v1(psmouse); |
733 | break; | 398 | break; |
734 | 399 | ||
735 | case 2: | 400 | case 2: |
736 | /* ignore debounce */ | 401 | /* We don't know how to check parity in protocol v2 */ |
737 | if (elantech_debounce_check_v2(psmouse)) | ||
738 | return PSMOUSE_FULL_PACKET; | ||
739 | |||
740 | if (etd->paritycheck && !elantech_packet_check_v2(psmouse)) | ||
741 | return PSMOUSE_BAD_DATA; | ||
742 | |||
743 | elantech_report_absolute_v2(psmouse); | 402 | elantech_report_absolute_v2(psmouse); |
744 | break; | 403 | break; |
745 | |||
746 | case 3: | ||
747 | packet_type = elantech_packet_check_v3(psmouse); | ||
748 | /* ignore debounce */ | ||
749 | if (packet_type == PACKET_DEBOUNCE) | ||
750 | return PSMOUSE_FULL_PACKET; | ||
751 | |||
752 | if (packet_type == PACKET_UNKNOWN) | ||
753 | return PSMOUSE_BAD_DATA; | ||
754 | |||
755 | elantech_report_absolute_v3(psmouse, packet_type); | ||
756 | break; | ||
757 | |||
758 | case 4: | ||
759 | packet_type = elantech_packet_check_v4(psmouse); | ||
760 | if (packet_type == PACKET_UNKNOWN) | ||
761 | return PSMOUSE_BAD_DATA; | ||
762 | |||
763 | elantech_report_absolute_v4(psmouse, packet_type); | ||
764 | break; | ||
765 | } | 404 | } |
766 | 405 | ||
767 | return PSMOUSE_FULL_PACKET; | 406 | return PSMOUSE_FULL_PACKET; |
@@ -796,29 +435,15 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
796 | elantech_write_reg(psmouse, 0x11, etd->reg_11) || | 435 | elantech_write_reg(psmouse, 0x11, etd->reg_11) || |
797 | elantech_write_reg(psmouse, 0x21, etd->reg_21)) { | 436 | elantech_write_reg(psmouse, 0x21, etd->reg_21)) { |
798 | rc = -1; | 437 | rc = -1; |
438 | break; | ||
799 | } | 439 | } |
800 | break; | ||
801 | |||
802 | case 3: | ||
803 | etd->reg_10 = 0x0b; | ||
804 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) | ||
805 | rc = -1; | ||
806 | |||
807 | break; | ||
808 | |||
809 | case 4: | ||
810 | etd->reg_07 = 0x01; | ||
811 | if (elantech_write_reg(psmouse, 0x07, etd->reg_07)) | ||
812 | rc = -1; | ||
813 | |||
814 | goto skip_readback_reg_10; /* v4 has no reg 0x10 to read */ | ||
815 | } | 440 | } |
816 | 441 | ||
817 | if (rc == 0) { | 442 | if (rc == 0) { |
818 | /* | 443 | /* |
819 | * Read back reg 0x10. For hardware version 1 we must make | 444 | * Read back reg 0x10. For hardware version 1 we must make |
820 | * sure the absolute mode bit is set. For hardware version 2 | 445 | * sure the absolute mode bit is set. For hardware version 2 |
821 | * the touchpad is probably initializing and not ready until | 446 | * the touchpad is probably initalising and not ready until |
822 | * we read back the value we just wrote. | 447 | * we read back the value we just wrote. |
823 | */ | 448 | */ |
824 | do { | 449 | do { |
@@ -831,142 +456,28 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
831 | } while (tries > 0); | 456 | } while (tries > 0); |
832 | 457 | ||
833 | if (rc) { | 458 | if (rc) { |
834 | psmouse_err(psmouse, | 459 | pr_err("failed to read back register 0x10.\n"); |
835 | "failed to read back register 0x10.\n"); | ||
836 | } else if (etd->hw_version == 1 && | 460 | } else if (etd->hw_version == 1 && |
837 | !(val & ETP_R10_ABSOLUTE_MODE)) { | 461 | !(val & ETP_R10_ABSOLUTE_MODE)) { |
838 | psmouse_err(psmouse, | 462 | pr_err("touchpad refuses to switch to absolute mode.\n"); |
839 | "touchpad refuses to switch to absolute mode.\n"); | ||
840 | rc = -1; | 463 | rc = -1; |
841 | } | 464 | } |
842 | } | 465 | } |
843 | 466 | ||
844 | skip_readback_reg_10: | ||
845 | if (rc) | 467 | if (rc) |
846 | psmouse_err(psmouse, "failed to initialise registers.\n"); | 468 | pr_err("failed to initialise registers.\n"); |
847 | 469 | ||
848 | return rc; | 470 | return rc; |
849 | } | 471 | } |
850 | 472 | ||
851 | static int elantech_set_range(struct psmouse *psmouse, | ||
852 | unsigned int *x_min, unsigned int *y_min, | ||
853 | unsigned int *x_max, unsigned int *y_max, | ||
854 | unsigned int *width) | ||
855 | { | ||
856 | struct elantech_data *etd = psmouse->private; | ||
857 | unsigned char param[3]; | ||
858 | unsigned char traces; | ||
859 | |||
860 | switch (etd->hw_version) { | ||
861 | case 1: | ||
862 | *x_min = ETP_XMIN_V1; | ||
863 | *y_min = ETP_YMIN_V1; | ||
864 | *x_max = ETP_XMAX_V1; | ||
865 | *y_max = ETP_YMAX_V1; | ||
866 | break; | ||
867 | |||
868 | case 2: | ||
869 | if (etd->fw_version == 0x020800 || | ||
870 | etd->fw_version == 0x020b00 || | ||
871 | etd->fw_version == 0x020030) { | ||
872 | *x_min = ETP_XMIN_V2; | ||
873 | *y_min = ETP_YMIN_V2; | ||
874 | *x_max = ETP_XMAX_V2; | ||
875 | *y_max = ETP_YMAX_V2; | ||
876 | } else { | ||
877 | int i; | ||
878 | int fixed_dpi; | ||
879 | |||
880 | i = (etd->fw_version > 0x020800 && | ||
881 | etd->fw_version < 0x020900) ? 1 : 2; | ||
882 | |||
883 | if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | ||
884 | return -1; | ||
885 | |||
886 | fixed_dpi = param[1] & 0x10; | ||
887 | |||
888 | if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) { | ||
889 | if (etd->send_cmd(psmouse, ETP_SAMPLE_QUERY, param)) | ||
890 | return -1; | ||
891 | |||
892 | *x_max = (etd->capabilities[1] - i) * param[1] / 2; | ||
893 | *y_max = (etd->capabilities[2] - i) * param[2] / 2; | ||
894 | } else if (etd->fw_version == 0x040216) { | ||
895 | *x_max = 819; | ||
896 | *y_max = 405; | ||
897 | } else if (etd->fw_version == 0x040219 || etd->fw_version == 0x040215) { | ||
898 | *x_max = 900; | ||
899 | *y_max = 500; | ||
900 | } else { | ||
901 | *x_max = (etd->capabilities[1] - i) * 64; | ||
902 | *y_max = (etd->capabilities[2] - i) * 64; | ||
903 | } | ||
904 | } | ||
905 | break; | ||
906 | |||
907 | case 3: | ||
908 | if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | ||
909 | return -1; | ||
910 | |||
911 | *x_max = (0x0f & param[0]) << 8 | param[1]; | ||
912 | *y_max = (0xf0 & param[0]) << 4 | param[2]; | ||
913 | break; | ||
914 | |||
915 | case 4: | ||
916 | if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | ||
917 | return -1; | ||
918 | |||
919 | *x_max = (0x0f & param[0]) << 8 | param[1]; | ||
920 | *y_max = (0xf0 & param[0]) << 4 | param[2]; | ||
921 | traces = etd->capabilities[1]; | ||
922 | if ((traces < 2) || (traces > *x_max)) | ||
923 | return -1; | ||
924 | |||
925 | *width = *x_max / (traces - 1); | ||
926 | break; | ||
927 | } | ||
928 | |||
929 | return 0; | ||
930 | } | ||
931 | |||
932 | /* | ||
933 | * (value from firmware) * 10 + 790 = dpi | ||
934 | * we also have to convert dpi to dots/mm (*10/254 to avoid floating point) | ||
935 | */ | ||
936 | static unsigned int elantech_convert_res(unsigned int val) | ||
937 | { | ||
938 | return (val * 10 + 790) * 10 / 254; | ||
939 | } | ||
940 | |||
941 | static int elantech_get_resolution_v4(struct psmouse *psmouse, | ||
942 | unsigned int *x_res, | ||
943 | unsigned int *y_res) | ||
944 | { | ||
945 | unsigned char param[3]; | ||
946 | |||
947 | if (elantech_send_cmd(psmouse, ETP_RESOLUTION_QUERY, param)) | ||
948 | return -1; | ||
949 | |||
950 | *x_res = elantech_convert_res(param[1] & 0x0f); | ||
951 | *y_res = elantech_convert_res((param[1] & 0xf0) >> 4); | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | /* | 473 | /* |
957 | * Set the appropriate event bits for the input subsystem | 474 | * Set the appropriate event bits for the input subsystem |
958 | */ | 475 | */ |
959 | static int elantech_set_input_params(struct psmouse *psmouse) | 476 | static void elantech_set_input_params(struct psmouse *psmouse) |
960 | { | 477 | { |
961 | struct input_dev *dev = psmouse->dev; | 478 | struct input_dev *dev = psmouse->dev; |
962 | struct elantech_data *etd = psmouse->private; | 479 | struct elantech_data *etd = psmouse->private; |
963 | unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; | ||
964 | unsigned int x_res = 0, y_res = 0; | ||
965 | 480 | ||
966 | if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) | ||
967 | return -1; | ||
968 | |||
969 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | ||
970 | __set_bit(EV_KEY, dev->evbit); | 481 | __set_bit(EV_KEY, dev->evbit); |
971 | __set_bit(EV_ABS, dev->evbit); | 482 | __set_bit(EV_ABS, dev->evbit); |
972 | __clear_bit(EV_REL, dev->evbit); | 483 | __clear_bit(EV_REL, dev->evbit); |
@@ -983,78 +494,30 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
983 | case 1: | 494 | case 1: |
984 | /* Rocker button */ | 495 | /* Rocker button */ |
985 | if (etd->fw_version < 0x020000 && | 496 | if (etd->fw_version < 0x020000 && |
986 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { | 497 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
987 | __set_bit(BTN_FORWARD, dev->keybit); | 498 | __set_bit(BTN_FORWARD, dev->keybit); |
988 | __set_bit(BTN_BACK, dev->keybit); | 499 | __set_bit(BTN_BACK, dev->keybit); |
989 | } | 500 | } |
990 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); | 501 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0); |
991 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); | 502 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0); |
992 | break; | 503 | break; |
993 | 504 | ||
994 | case 2: | 505 | case 2: |
995 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 506 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
996 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 507 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); |
997 | /* fall through */ | 508 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); |
998 | case 3: | ||
999 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); | ||
1000 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); | ||
1001 | if (etd->reports_pressure) { | 509 | if (etd->reports_pressure) { |
1002 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, | 510 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, |
1003 | ETP_PMAX_V2, 0, 0); | 511 | ETP_PMAX_V2, 0, 0); |
1004 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 512 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
1005 | ETP_WMAX_V2, 0, 0); | 513 | ETP_WMAX_V2, 0, 0); |
1006 | } | 514 | } |
1007 | input_mt_init_slots(dev, 2, 0); | 515 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
1008 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | 516 | input_mt_init_slots(dev, 2); |
1009 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | 517 | input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); |
1010 | break; | 518 | input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); |
1011 | |||
1012 | case 4: | ||
1013 | if (elantech_get_resolution_v4(psmouse, &x_res, &y_res)) { | ||
1014 | /* | ||
1015 | * if query failed, print a warning and leave the values | ||
1016 | * zero to resemble synaptics.c behavior. | ||
1017 | */ | ||
1018 | psmouse_warn(psmouse, "couldn't query resolution data.\n"); | ||
1019 | } | ||
1020 | /* v4 is clickpad, with only one button. */ | ||
1021 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | ||
1022 | __clear_bit(BTN_RIGHT, dev->keybit); | ||
1023 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
1024 | /* For X to recognize me as touchpad. */ | ||
1025 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); | ||
1026 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); | ||
1027 | input_abs_set_res(dev, ABS_X, x_res); | ||
1028 | input_abs_set_res(dev, ABS_Y, y_res); | ||
1029 | /* | ||
1030 | * range of pressure and width is the same as v2, | ||
1031 | * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility. | ||
1032 | */ | ||
1033 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, | ||
1034 | ETP_PMAX_V2, 0, 0); | ||
1035 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | ||
1036 | ETP_WMAX_V2, 0, 0); | ||
1037 | /* Multitouch capable pad, up to 5 fingers. */ | ||
1038 | input_mt_init_slots(dev, ETP_MAX_FINGERS, 0); | ||
1039 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | ||
1040 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | ||
1041 | input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); | ||
1042 | input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res); | ||
1043 | input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2, | ||
1044 | ETP_PMAX_V2, 0, 0); | ||
1045 | /* | ||
1046 | * The firmware reports how many trace lines the finger spans, | ||
1047 | * convert to surface unit as Protocol-B requires. | ||
1048 | */ | ||
1049 | input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0, | ||
1050 | ETP_WMAX_V2 * width, 0, 0); | ||
1051 | break; | 519 | break; |
1052 | } | 520 | } |
1053 | |||
1054 | etd->y_max = y_max; | ||
1055 | etd->width = width; | ||
1056 | |||
1057 | return 0; | ||
1058 | } | 521 | } |
1059 | 522 | ||
1060 | struct elantech_attr_data { | 523 | struct elantech_attr_data { |
@@ -1088,13 +551,16 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse, | |||
1088 | struct elantech_data *etd = psmouse->private; | 551 | struct elantech_data *etd = psmouse->private; |
1089 | struct elantech_attr_data *attr = data; | 552 | struct elantech_attr_data *attr = data; |
1090 | unsigned char *reg = (unsigned char *) etd + attr->field_offset; | 553 | unsigned char *reg = (unsigned char *) etd + attr->field_offset; |
1091 | unsigned char value; | 554 | unsigned long value; |
1092 | int err; | 555 | int err; |
1093 | 556 | ||
1094 | err = kstrtou8(buf, 16, &value); | 557 | err = strict_strtoul(buf, 16, &value); |
1095 | if (err) | 558 | if (err) |
1096 | return err; | 559 | return err; |
1097 | 560 | ||
561 | if (value > 0xff) | ||
562 | return -EINVAL; | ||
563 | |||
1098 | /* Do we need to preserve some bits for version 2 hardware too? */ | 564 | /* Do we need to preserve some bits for version 2 hardware too? */ |
1099 | if (etd->hw_version == 1) { | 565 | if (etd->hw_version == 1) { |
1100 | if (attr->reg == 0x10) | 566 | if (attr->reg == 0x10) |
@@ -1121,7 +587,6 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse, | |||
1121 | elantech_show_int_attr, \ | 587 | elantech_show_int_attr, \ |
1122 | elantech_set_int_attr) | 588 | elantech_set_int_attr) |
1123 | 589 | ||
1124 | ELANTECH_INT_ATTR(reg_07, 0x07); | ||
1125 | ELANTECH_INT_ATTR(reg_10, 0x10); | 590 | ELANTECH_INT_ATTR(reg_10, 0x10); |
1126 | ELANTECH_INT_ATTR(reg_11, 0x11); | 591 | ELANTECH_INT_ATTR(reg_11, 0x11); |
1127 | ELANTECH_INT_ATTR(reg_20, 0x20); | 592 | ELANTECH_INT_ATTR(reg_20, 0x20); |
@@ -1135,7 +600,6 @@ ELANTECH_INT_ATTR(debug, 0); | |||
1135 | ELANTECH_INT_ATTR(paritycheck, 0); | 600 | ELANTECH_INT_ATTR(paritycheck, 0); |
1136 | 601 | ||
1137 | static struct attribute *elantech_attrs[] = { | 602 | static struct attribute *elantech_attrs[] = { |
1138 | &psmouse_attr_reg_07.dattr.attr, | ||
1139 | &psmouse_attr_reg_10.dattr.attr, | 603 | &psmouse_attr_reg_10.dattr.attr, |
1140 | &psmouse_attr_reg_11.dattr.attr, | 604 | &psmouse_attr_reg_11.dattr.attr, |
1141 | &psmouse_attr_reg_20.dattr.attr, | 605 | &psmouse_attr_reg_20.dattr.attr, |
@@ -1187,7 +651,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
1187 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 651 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
1188 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 652 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
1189 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 653 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
1190 | psmouse_dbg(psmouse, "sending Elantech magic knock failed.\n"); | 654 | pr_debug("sending Elantech magic knock failed.\n"); |
1191 | return -1; | 655 | return -1; |
1192 | } | 656 | } |
1193 | 657 | ||
@@ -1195,11 +659,9 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
1195 | * Report this in case there are Elantech models that use a different | 659 | * Report this in case there are Elantech models that use a different |
1196 | * set of magic numbers | 660 | * set of magic numbers |
1197 | */ | 661 | */ |
1198 | if (param[0] != 0x3c || param[1] != 0x03 || | 662 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { |
1199 | (param[2] != 0xc8 && param[2] != 0x00)) { | 663 | pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", |
1200 | psmouse_dbg(psmouse, | 664 | param[0], param[1], param[2]); |
1201 | "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", | ||
1202 | param[0], param[1], param[2]); | ||
1203 | return -1; | 665 | return -1; |
1204 | } | 666 | } |
1205 | 667 | ||
@@ -1209,18 +671,20 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
1209 | * to Elantech magic knock and there might be more. | 671 | * to Elantech magic knock and there might be more. |
1210 | */ | 672 | */ |
1211 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 673 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
1212 | psmouse_dbg(psmouse, "failed to query firmware version.\n"); | 674 | pr_debug("failed to query firmware version.\n"); |
1213 | return -1; | 675 | return -1; |
1214 | } | 676 | } |
1215 | 677 | ||
1216 | psmouse_dbg(psmouse, | 678 | pr_debug("Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", |
1217 | "Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", | 679 | param[0], param[1], param[2]); |
1218 | param[0], param[1], param[2]); | ||
1219 | 680 | ||
1220 | if (!elantech_is_signature_valid(param)) { | 681 | if (!elantech_is_signature_valid(param)) { |
1221 | psmouse_dbg(psmouse, | 682 | if (!force_elantech) { |
1222 | "Probably not a real Elantech touchpad. Aborting.\n"); | 683 | pr_debug("Probably not a real Elantech touchpad. Aborting.\n"); |
1223 | return -1; | 684 | return -1; |
685 | } | ||
686 | |||
687 | pr_debug("Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); | ||
1224 | } | 688 | } |
1225 | 689 | ||
1226 | if (set_properties) { | 690 | if (set_properties) { |
@@ -1247,14 +711,11 @@ static void elantech_disconnect(struct psmouse *psmouse) | |||
1247 | */ | 711 | */ |
1248 | static int elantech_reconnect(struct psmouse *psmouse) | 712 | static int elantech_reconnect(struct psmouse *psmouse) |
1249 | { | 713 | { |
1250 | psmouse_reset(psmouse); | ||
1251 | |||
1252 | if (elantech_detect(psmouse, 0)) | 714 | if (elantech_detect(psmouse, 0)) |
1253 | return -1; | 715 | return -1; |
1254 | 716 | ||
1255 | if (elantech_set_absolute_mode(psmouse)) { | 717 | if (elantech_set_absolute_mode(psmouse)) { |
1256 | psmouse_err(psmouse, | 718 | pr_err("failed to put touchpad back into absolute mode.\n"); |
1257 | "failed to put touchpad back into absolute mode.\n"); | ||
1258 | return -1; | 719 | return -1; |
1259 | } | 720 | } |
1260 | 721 | ||
@@ -1262,60 +723,6 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
1262 | } | 723 | } |
1263 | 724 | ||
1264 | /* | 725 | /* |
1265 | * determine hardware version and set some properties according to it. | ||
1266 | */ | ||
1267 | static int elantech_set_properties(struct elantech_data *etd) | ||
1268 | { | ||
1269 | /* This represents the version of IC body. */ | ||
1270 | int ver = (etd->fw_version & 0x0f0000) >> 16; | ||
1271 | |||
1272 | /* Early version of Elan touchpads doesn't obey the rule. */ | ||
1273 | if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) | ||
1274 | etd->hw_version = 1; | ||
1275 | else { | ||
1276 | switch (ver) { | ||
1277 | case 2: | ||
1278 | case 4: | ||
1279 | etd->hw_version = 2; | ||
1280 | break; | ||
1281 | case 5: | ||
1282 | etd->hw_version = 3; | ||
1283 | break; | ||
1284 | case 6: | ||
1285 | etd->hw_version = 4; | ||
1286 | break; | ||
1287 | default: | ||
1288 | return -1; | ||
1289 | } | ||
1290 | } | ||
1291 | |||
1292 | /* decide which send_cmd we're gonna use early */ | ||
1293 | etd->send_cmd = etd->hw_version >= 3 ? elantech_send_cmd : | ||
1294 | synaptics_send_cmd; | ||
1295 | |||
1296 | /* Turn on packet checking by default */ | ||
1297 | etd->paritycheck = 1; | ||
1298 | |||
1299 | /* | ||
1300 | * This firmware suffers from misreporting coordinates when | ||
1301 | * a touch action starts causing the mouse cursor or scrolled page | ||
1302 | * to jump. Enable a workaround. | ||
1303 | */ | ||
1304 | etd->jumpy_cursor = | ||
1305 | (etd->fw_version == 0x020022 || etd->fw_version == 0x020600); | ||
1306 | |||
1307 | if (etd->hw_version > 1) { | ||
1308 | /* For now show extra debug information */ | ||
1309 | etd->debug = 1; | ||
1310 | |||
1311 | if (etd->fw_version >= 0x020800) | ||
1312 | etd->reports_pressure = true; | ||
1313 | } | ||
1314 | |||
1315 | return 0; | ||
1316 | } | ||
1317 | |||
1318 | /* | ||
1319 | * Initialize the touchpad and create sysfs entries | 726 | * Initialize the touchpad and create sysfs entries |
1320 | */ | 727 | */ |
1321 | int elantech_init(struct psmouse *psmouse) | 728 | int elantech_init(struct psmouse *psmouse) |
@@ -1328,8 +735,6 @@ int elantech_init(struct psmouse *psmouse) | |||
1328 | if (!etd) | 735 | if (!etd) |
1329 | return -ENOMEM; | 736 | return -ENOMEM; |
1330 | 737 | ||
1331 | psmouse_reset(psmouse); | ||
1332 | |||
1333 | etd->parity[0] = 1; | 738 | etd->parity[0] = 1; |
1334 | for (i = 1; i < 256; i++) | 739 | for (i = 1; i < 256; i++) |
1335 | etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; | 740 | etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; |
@@ -1338,53 +743,70 @@ int elantech_init(struct psmouse *psmouse) | |||
1338 | * Do the version query again so we can store the result | 743 | * Do the version query again so we can store the result |
1339 | */ | 744 | */ |
1340 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 745 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
1341 | psmouse_err(psmouse, "failed to query firmware version.\n"); | 746 | pr_err("failed to query firmware version.\n"); |
1342 | goto init_fail; | 747 | goto init_fail; |
1343 | } | 748 | } |
749 | |||
1344 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; | 750 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
1345 | 751 | ||
1346 | if (elantech_set_properties(etd)) { | 752 | /* |
1347 | psmouse_err(psmouse, "unknown hardware version, aborting...\n"); | 753 | * Assume every version greater than this is new EeePC style |
1348 | goto init_fail; | 754 | * hardware with 6 byte packets |
755 | */ | ||
756 | if (etd->fw_version >= 0x020030) { | ||
757 | etd->hw_version = 2; | ||
758 | /* For now show extra debug information */ | ||
759 | etd->debug = 1; | ||
760 | /* Don't know how to do parity checking for version 2 */ | ||
761 | etd->paritycheck = 0; | ||
762 | |||
763 | if (etd->fw_version >= 0x020800) | ||
764 | etd->reports_pressure = true; | ||
765 | |||
766 | } else { | ||
767 | etd->hw_version = 1; | ||
768 | etd->paritycheck = 1; | ||
1349 | } | 769 | } |
1350 | psmouse_info(psmouse, | ||
1351 | "assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n", | ||
1352 | etd->hw_version, param[0], param[1], param[2]); | ||
1353 | 770 | ||
1354 | if (etd->send_cmd(psmouse, ETP_CAPABILITIES_QUERY, | 771 | pr_info("assuming hardware version %d, firmware version %d.%d.%d\n", |
1355 | etd->capabilities)) { | 772 | etd->hw_version, param[0], param[1], param[2]); |
1356 | psmouse_err(psmouse, "failed to query capabilities.\n"); | 773 | |
774 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | ||
775 | pr_err("failed to query capabilities.\n"); | ||
1357 | goto init_fail; | 776 | goto init_fail; |
1358 | } | 777 | } |
1359 | psmouse_info(psmouse, | 778 | pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", |
1360 | "Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", | 779 | param[0], param[1], param[2]); |
1361 | etd->capabilities[0], etd->capabilities[1], | 780 | etd->capabilities = param[0]; |
1362 | etd->capabilities[2]); | ||
1363 | 781 | ||
1364 | if (elantech_set_absolute_mode(psmouse)) { | 782 | /* |
1365 | psmouse_err(psmouse, | 783 | * This firmware suffers from misreporting coordinates when |
1366 | "failed to put touchpad into absolute mode.\n"); | 784 | * a touch action starts causing the mouse cursor or scrolled page |
1367 | goto init_fail; | 785 | * to jump. Enable a workaround. |
786 | */ | ||
787 | if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) { | ||
788 | pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n"); | ||
789 | etd->jumpy_cursor = true; | ||
1368 | } | 790 | } |
1369 | 791 | ||
1370 | if (elantech_set_input_params(psmouse)) { | 792 | if (elantech_set_absolute_mode(psmouse)) { |
1371 | psmouse_err(psmouse, "failed to query touchpad range.\n"); | 793 | pr_err("failed to put touchpad into absolute mode.\n"); |
1372 | goto init_fail; | 794 | goto init_fail; |
1373 | } | 795 | } |
1374 | 796 | ||
797 | elantech_set_input_params(psmouse); | ||
798 | |||
1375 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, | 799 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, |
1376 | &elantech_attr_group); | 800 | &elantech_attr_group); |
1377 | if (error) { | 801 | if (error) { |
1378 | psmouse_err(psmouse, | 802 | pr_err("failed to create sysfs attributes, error: %d.\n", error); |
1379 | "failed to create sysfs attributes, error: %d.\n", | ||
1380 | error); | ||
1381 | goto init_fail; | 803 | goto init_fail; |
1382 | } | 804 | } |
1383 | 805 | ||
1384 | psmouse->protocol_handler = elantech_process_byte; | 806 | psmouse->protocol_handler = elantech_process_byte; |
1385 | psmouse->disconnect = elantech_disconnect; | 807 | psmouse->disconnect = elantech_disconnect; |
1386 | psmouse->reconnect = elantech_reconnect; | 808 | psmouse->reconnect = elantech_reconnect; |
1387 | psmouse->pktsize = etd->hw_version > 1 ? 6 : 4; | 809 | psmouse->pktsize = etd->hw_version == 2 ? 6 : 4; |
1388 | 810 | ||
1389 | return 0; | 811 | return 0; |
1390 | 812 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 46db3be45ac..fabb2b99615 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -16,18 +16,14 @@ | |||
16 | /* | 16 | /* |
17 | * Command values for Synaptics style queries | 17 | * Command values for Synaptics style queries |
18 | */ | 18 | */ |
19 | #define ETP_FW_ID_QUERY 0x00 | ||
20 | #define ETP_FW_VERSION_QUERY 0x01 | 19 | #define ETP_FW_VERSION_QUERY 0x01 |
21 | #define ETP_CAPABILITIES_QUERY 0x02 | 20 | #define ETP_CAPABILITIES_QUERY 0x02 |
22 | #define ETP_SAMPLE_QUERY 0x03 | ||
23 | #define ETP_RESOLUTION_QUERY 0x04 | ||
24 | 21 | ||
25 | /* | 22 | /* |
26 | * Command values for register reading or writing | 23 | * Command values for register reading or writing |
27 | */ | 24 | */ |
28 | #define ETP_REGISTER_READ 0x10 | 25 | #define ETP_REGISTER_READ 0x10 |
29 | #define ETP_REGISTER_WRITE 0x11 | 26 | #define ETP_REGISTER_WRITE 0x11 |
30 | #define ETP_REGISTER_READWRITE 0x00 | ||
31 | 27 | ||
32 | /* | 28 | /* |
33 | * Hardware version 2 custom PS/2 command value | 29 | * Hardware version 2 custom PS/2 command value |
@@ -70,13 +66,16 @@ | |||
70 | #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1) | 66 | #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1) |
71 | 67 | ||
72 | /* | 68 | /* |
73 | * The resolution for older v2 hardware doubled. | 69 | * It seems the resolution for hardware version 2 doubled. |
74 | * (newer v2's firmware provides command so we can query) | 70 | * Hence the X and Y ranges are doubled too. |
71 | * The bezel around the pad also appears to be smaller | ||
75 | */ | 72 | */ |
76 | #define ETP_XMIN_V2 0 | 73 | #define ETP_EDGE_FUZZ_V2 8 |
77 | #define ETP_XMAX_V2 1152 | 74 | |
78 | #define ETP_YMIN_V2 0 | 75 | #define ETP_XMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) |
79 | #define ETP_YMAX_V2 768 | 76 | #define ETP_XMAX_V2 (1152 - ETP_EDGE_FUZZ_V2) |
77 | #define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) | ||
78 | #define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2) | ||
80 | 79 | ||
81 | #define ETP_PMIN_V2 0 | 80 | #define ETP_PMIN_V2 0 |
82 | #define ETP_PMAX_V2 255 | 81 | #define ETP_PMAX_V2 255 |
@@ -84,37 +83,17 @@ | |||
84 | #define ETP_WMAX_V2 15 | 83 | #define ETP_WMAX_V2 15 |
85 | 84 | ||
86 | /* | 85 | /* |
87 | * v3 hardware has 2 kinds of packet types, | 86 | * For two finger touches the coordinate of each finger gets reported |
88 | * v4 hardware has 3. | 87 | * separately but with reduced resolution. |
89 | */ | ||
90 | #define PACKET_UNKNOWN 0x01 | ||
91 | #define PACKET_DEBOUNCE 0x02 | ||
92 | #define PACKET_V3_HEAD 0x03 | ||
93 | #define PACKET_V3_TAIL 0x04 | ||
94 | #define PACKET_V4_HEAD 0x05 | ||
95 | #define PACKET_V4_MOTION 0x06 | ||
96 | #define PACKET_V4_STATUS 0x07 | ||
97 | |||
98 | /* | ||
99 | * track up to 5 fingers for v4 hardware | ||
100 | */ | ||
101 | #define ETP_MAX_FINGERS 5 | ||
102 | |||
103 | /* | ||
104 | * weight value for v4 hardware | ||
105 | */ | 88 | */ |
106 | #define ETP_WEIGHT_VALUE 5 | 89 | #define ETP_2FT_FUZZ 4 |
107 | 90 | ||
108 | /* | 91 | #define ETP_2FT_XMIN ( 0 + ETP_2FT_FUZZ) |
109 | * The base position for one finger, v4 hardware | 92 | #define ETP_2FT_XMAX (288 - ETP_2FT_FUZZ) |
110 | */ | 93 | #define ETP_2FT_YMIN ( 0 + ETP_2FT_FUZZ) |
111 | struct finger_pos { | 94 | #define ETP_2FT_YMAX (192 - ETP_2FT_FUZZ) |
112 | unsigned int x; | ||
113 | unsigned int y; | ||
114 | }; | ||
115 | 95 | ||
116 | struct elantech_data { | 96 | struct elantech_data { |
117 | unsigned char reg_07; | ||
118 | unsigned char reg_10; | 97 | unsigned char reg_10; |
119 | unsigned char reg_11; | 98 | unsigned char reg_11; |
120 | unsigned char reg_20; | 99 | unsigned char reg_20; |
@@ -125,18 +104,14 @@ struct elantech_data { | |||
125 | unsigned char reg_25; | 104 | unsigned char reg_25; |
126 | unsigned char reg_26; | 105 | unsigned char reg_26; |
127 | unsigned char debug; | 106 | unsigned char debug; |
128 | unsigned char capabilities[3]; | 107 | unsigned char capabilities; |
129 | bool paritycheck; | 108 | bool paritycheck; |
130 | bool jumpy_cursor; | 109 | bool jumpy_cursor; |
131 | bool reports_pressure; | 110 | bool reports_pressure; |
132 | unsigned char hw_version; | 111 | unsigned char hw_version; |
133 | unsigned int fw_version; | 112 | unsigned int fw_version; |
134 | unsigned int single_finger_reports; | 113 | unsigned int single_finger_reports; |
135 | unsigned int y_max; | ||
136 | unsigned int width; | ||
137 | struct finger_pos mt[ETP_MAX_FINGERS]; | ||
138 | unsigned char parity[256]; | 114 | unsigned char parity[256]; |
139 | int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param); | ||
140 | }; | 115 | }; |
141 | 116 | ||
142 | #ifdef CONFIG_MOUSE_PS2_ELANTECH | 117 | #ifdef CONFIG_MOUSE_PS2_ELANTECH |
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 532eaca4cc5..58902fbb989 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c | |||
@@ -12,9 +12,9 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/input-polldev.h> | 14 | #include <linux/input-polldev.h> |
15 | #include <linux/gpio.h> | ||
16 | #include <linux/gpio_mouse.h> | 15 | #include <linux/gpio_mouse.h> |
17 | 16 | ||
17 | #include <asm/gpio.h> | ||
18 | 18 | ||
19 | /* | 19 | /* |
20 | * Timer function which is run every scan_ms ms when the device is opened. | 20 | * Timer function which is run every scan_ms ms when the device is opened. |
@@ -46,7 +46,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev) | |||
46 | input_sync(input); | 46 | input_sync(input); |
47 | } | 47 | } |
48 | 48 | ||
49 | static int gpio_mouse_probe(struct platform_device *pdev) | 49 | static int __devinit gpio_mouse_probe(struct platform_device *pdev) |
50 | { | 50 | { |
51 | struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; | 51 | struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; |
52 | struct input_polled_dev *input_poll; | 52 | struct input_polled_dev *input_poll; |
@@ -150,7 +150,7 @@ static int gpio_mouse_probe(struct platform_device *pdev) | |||
150 | return error; | 150 | return error; |
151 | } | 151 | } |
152 | 152 | ||
153 | static int gpio_mouse_remove(struct platform_device *pdev) | 153 | static int __devexit gpio_mouse_remove(struct platform_device *pdev) |
154 | { | 154 | { |
155 | struct input_polled_dev *input = platform_get_drvdata(pdev); | 155 | struct input_polled_dev *input = platform_get_drvdata(pdev); |
156 | struct gpio_mouse_platform_data *pdata = input->private; | 156 | struct gpio_mouse_platform_data *pdata = input->private; |
@@ -172,13 +172,24 @@ static int gpio_mouse_remove(struct platform_device *pdev) | |||
172 | 172 | ||
173 | static struct platform_driver gpio_mouse_device_driver = { | 173 | static struct platform_driver gpio_mouse_device_driver = { |
174 | .probe = gpio_mouse_probe, | 174 | .probe = gpio_mouse_probe, |
175 | .remove = gpio_mouse_remove, | 175 | .remove = __devexit_p(gpio_mouse_remove), |
176 | .driver = { | 176 | .driver = { |
177 | .name = "gpio_mouse", | 177 | .name = "gpio_mouse", |
178 | .owner = THIS_MODULE, | 178 | .owner = THIS_MODULE, |
179 | } | 179 | } |
180 | }; | 180 | }; |
181 | module_platform_driver(gpio_mouse_device_driver); | 181 | |
182 | static int __init gpio_mouse_init(void) | ||
183 | { | ||
184 | return platform_driver_register(&gpio_mouse_device_driver); | ||
185 | } | ||
186 | module_init(gpio_mouse_init); | ||
187 | |||
188 | static void __exit gpio_mouse_exit(void) | ||
189 | { | ||
190 | platform_driver_unregister(&gpio_mouse_device_driver); | ||
191 | } | ||
192 | module_exit(gpio_mouse_exit); | ||
182 | 193 | ||
183 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); | 194 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); |
184 | MODULE_DESCRIPTION("GPIO mouse driver"); | 195 | MODULE_DESCRIPTION("GPIO mouse driver"); |
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 62be888e83d..4d17d9f3320 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -136,10 +136,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) | |||
136 | /* discard if too big, or half that but > 4 times the prev delta */ | 136 | /* discard if too big, or half that but > 4 times the prev delta */ |
137 | if (avx > recalib_delta || | 137 | if (avx > recalib_delta || |
138 | (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { | 138 | (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { |
139 | psmouse_warn(psmouse, "detected %dpx jump in x\n", x); | 139 | hgpk_err(psmouse, "detected %dpx jump in x\n", x); |
140 | priv->xbigj = avx; | 140 | priv->xbigj = avx; |
141 | } else if (approx_half(avx, priv->xbigj)) { | 141 | } else if (approx_half(avx, priv->xbigj)) { |
142 | psmouse_warn(psmouse, "detected secondary %dpx jump in x\n", x); | 142 | hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x); |
143 | priv->xbigj = avx; | 143 | priv->xbigj = avx; |
144 | priv->xsaw_secondary++; | 144 | priv->xsaw_secondary++; |
145 | } else { | 145 | } else { |
@@ -151,10 +151,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) | |||
151 | 151 | ||
152 | if (avy > recalib_delta || | 152 | if (avy > recalib_delta || |
153 | (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { | 153 | (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { |
154 | psmouse_warn(psmouse, "detected %dpx jump in y\n", y); | 154 | hgpk_err(psmouse, "detected %dpx jump in y\n", y); |
155 | priv->ybigj = avy; | 155 | priv->ybigj = avy; |
156 | } else if (approx_half(avy, priv->ybigj)) { | 156 | } else if (approx_half(avy, priv->ybigj)) { |
157 | psmouse_warn(psmouse, "detected secondary %dpx jump in y\n", y); | 157 | hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y); |
158 | priv->ybigj = avy; | 158 | priv->ybigj = avy; |
159 | priv->ysaw_secondary++; | 159 | priv->ysaw_secondary++; |
160 | } else { | 160 | } else { |
@@ -168,7 +168,7 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) | |||
168 | priv->ylast = avy; | 168 | priv->ylast = avy; |
169 | 169 | ||
170 | if (do_recal && jumpy_delay) { | 170 | if (do_recal && jumpy_delay) { |
171 | psmouse_warn(psmouse, "scheduling recalibration\n"); | 171 | hgpk_err(psmouse, "scheduling recalibration\n"); |
172 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 172 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
173 | msecs_to_jiffies(jumpy_delay)); | 173 | msecs_to_jiffies(jumpy_delay)); |
174 | } | 174 | } |
@@ -260,8 +260,8 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
260 | * movement, it is probably a case of the user moving the | 260 | * movement, it is probably a case of the user moving the |
261 | * cursor very slowly across the screen. */ | 261 | * cursor very slowly across the screen. */ |
262 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { | 262 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { |
263 | psmouse_warn(psmouse, "packet spew detected (%d,%d)\n", | 263 | hgpk_err(psmouse, "packet spew detected (%d,%d)\n", |
264 | priv->x_tally, priv->y_tally); | 264 | priv->x_tally, priv->y_tally); |
265 | priv->spew_flag = RECALIBRATING; | 265 | priv->spew_flag = RECALIBRATING; |
266 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 266 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
267 | msecs_to_jiffies(spew_delay)); | 267 | msecs_to_jiffies(spew_delay)); |
@@ -333,9 +333,12 @@ static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) | |||
333 | } | 333 | } |
334 | 334 | ||
335 | if (!valid) | 335 | if (!valid) |
336 | psmouse_dbg(psmouse, | 336 | hgpk_dbg(psmouse, |
337 | "bad data, mode %d (%d) %*ph\n", | 337 | "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", |
338 | priv->mode, pktcnt, 6, psmouse->packet); | 338 | priv->mode, pktcnt, |
339 | psmouse->packet[0], psmouse->packet[1], | ||
340 | psmouse->packet[2], psmouse->packet[3], | ||
341 | psmouse->packet[4], psmouse->packet[5]); | ||
339 | 342 | ||
340 | return valid; | 343 | return valid; |
341 | } | 344 | } |
@@ -358,20 +361,19 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) | |||
358 | 361 | ||
359 | input_report_abs(idev, ABS_PRESSURE, z); | 362 | input_report_abs(idev, ABS_PRESSURE, z); |
360 | if (tpdebug) | 363 | if (tpdebug) |
361 | psmouse_dbg(psmouse, "pd=%d fd=%d z=%d", | 364 | hgpk_dbg(psmouse, "pd=%d fd=%d z=%d", |
362 | pt_down, finger_down, z); | 365 | pt_down, finger_down, z); |
363 | } else { | 366 | } else { |
364 | /* | 367 | /* |
365 | * PenTablet mode does not report pressure, so we don't | 368 | * PenTablet mode does not report pressure, so we don't |
366 | * report it here | 369 | * report it here |
367 | */ | 370 | */ |
368 | if (tpdebug) | 371 | if (tpdebug) |
369 | psmouse_dbg(psmouse, "pd=%d ", down); | 372 | hgpk_dbg(psmouse, "pd=%d ", down); |
370 | } | 373 | } |
371 | 374 | ||
372 | if (tpdebug) | 375 | if (tpdebug) |
373 | psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", | 376 | hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); |
374 | left, right, x, y); | ||
375 | 377 | ||
376 | input_report_key(idev, BTN_TOUCH, down); | 378 | input_report_key(idev, BTN_TOUCH, down); |
377 | input_report_key(idev, BTN_LEFT, left); | 379 | input_report_key(idev, BTN_LEFT, left); |
@@ -393,7 +395,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) | |||
393 | if (x == priv->abs_x && y == priv->abs_y) { | 395 | if (x == priv->abs_x && y == priv->abs_y) { |
394 | if (++priv->dupe_count > SPEW_WATCH_COUNT) { | 396 | if (++priv->dupe_count > SPEW_WATCH_COUNT) { |
395 | if (tpdebug) | 397 | if (tpdebug) |
396 | psmouse_dbg(psmouse, "hard spew detected\n"); | 398 | hgpk_dbg(psmouse, "hard spew detected\n"); |
397 | priv->spew_flag = RECALIBRATING; | 399 | priv->spew_flag = RECALIBRATING; |
398 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 400 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
399 | msecs_to_jiffies(spew_delay)); | 401 | msecs_to_jiffies(spew_delay)); |
@@ -410,7 +412,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) | |||
410 | int y_diff = priv->abs_y - y; | 412 | int y_diff = priv->abs_y - y; |
411 | if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { | 413 | if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { |
412 | if (tpdebug) | 414 | if (tpdebug) |
413 | psmouse_dbg(psmouse, "discarding\n"); | 415 | hgpk_dbg(psmouse, "discarding\n"); |
414 | goto done; | 416 | goto done; |
415 | } | 417 | } |
416 | hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); | 418 | hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); |
@@ -435,21 +437,20 @@ static void hgpk_process_simple_packet(struct psmouse *psmouse) | |||
435 | int y = ((packet[0] << 3) & 0x100) - packet[2]; | 437 | int y = ((packet[0] << 3) & 0x100) - packet[2]; |
436 | 438 | ||
437 | if (packet[0] & 0xc0) | 439 | if (packet[0] & 0xc0) |
438 | psmouse_dbg(psmouse, | 440 | hgpk_dbg(psmouse, |
439 | "overflow -- 0x%02x 0x%02x 0x%02x\n", | 441 | "overflow -- 0x%02x 0x%02x 0x%02x\n", |
440 | packet[0], packet[1], packet[2]); | 442 | packet[0], packet[1], packet[2]); |
441 | 443 | ||
442 | if (hgpk_discard_decay_hack(psmouse, x, y)) { | 444 | if (hgpk_discard_decay_hack(psmouse, x, y)) { |
443 | if (tpdebug) | 445 | if (tpdebug) |
444 | psmouse_dbg(psmouse, "discarding\n"); | 446 | hgpk_dbg(psmouse, "discarding\n"); |
445 | return; | 447 | return; |
446 | } | 448 | } |
447 | 449 | ||
448 | hgpk_spewing_hack(psmouse, left, right, x, y); | 450 | hgpk_spewing_hack(psmouse, left, right, x, y); |
449 | 451 | ||
450 | if (tpdebug) | 452 | if (tpdebug) |
451 | psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", | 453 | hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); |
452 | left, right, x, y); | ||
453 | 454 | ||
454 | input_report_key(dev, BTN_LEFT, left); | 455 | input_report_key(dev, BTN_LEFT, left); |
455 | input_report_key(dev, BTN_RIGHT, right); | 456 | input_report_key(dev, BTN_RIGHT, right); |
@@ -481,8 +482,9 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) | |||
481 | * ugh, got a packet inside our recalibration | 482 | * ugh, got a packet inside our recalibration |
482 | * window, schedule another recalibration. | 483 | * window, schedule another recalibration. |
483 | */ | 484 | */ |
484 | psmouse_dbg(psmouse, | 485 | hgpk_dbg(psmouse, |
485 | "packet inside calibration window, queueing another recalibration\n"); | 486 | "packet inside calibration window, " |
487 | "queueing another recalibration\n"); | ||
486 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 488 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
487 | msecs_to_jiffies(post_interrupt_delay)); | 489 | msecs_to_jiffies(post_interrupt_delay)); |
488 | } | 490 | } |
@@ -626,7 +628,7 @@ static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate) | |||
626 | 628 | ||
627 | err = hgpk_select_mode(psmouse); | 629 | err = hgpk_select_mode(psmouse); |
628 | if (err) { | 630 | if (err) { |
629 | psmouse_err(psmouse, "failed to select mode\n"); | 631 | hgpk_err(psmouse, "failed to select mode\n"); |
630 | return err; | 632 | return err; |
631 | } | 633 | } |
632 | 634 | ||
@@ -637,6 +639,7 @@ static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate) | |||
637 | 639 | ||
638 | static int hgpk_force_recalibrate(struct psmouse *psmouse) | 640 | static int hgpk_force_recalibrate(struct psmouse *psmouse) |
639 | { | 641 | { |
642 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
640 | struct hgpk_data *priv = psmouse->private; | 643 | struct hgpk_data *priv = psmouse->private; |
641 | int err; | 644 | int err; |
642 | 645 | ||
@@ -645,11 +648,11 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
645 | return 0; | 648 | return 0; |
646 | 649 | ||
647 | if (!autorecal) { | 650 | if (!autorecal) { |
648 | psmouse_dbg(psmouse, "recalibration disabled, ignoring\n"); | 651 | hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n"); |
649 | return 0; | 652 | return 0; |
650 | } | 653 | } |
651 | 654 | ||
652 | psmouse_dbg(psmouse, "recalibrating touchpad..\n"); | 655 | hgpk_dbg(psmouse, "recalibrating touchpad..\n"); |
653 | 656 | ||
654 | /* we don't want to race with the irq handler, nor with resyncs */ | 657 | /* we don't want to race with the irq handler, nor with resyncs */ |
655 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 658 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
@@ -665,11 +668,14 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
665 | * we don't have a good way to deal with it. The 2s window stuff | 668 | * we don't have a good way to deal with it. The 2s window stuff |
666 | * (below) is our best option for now. | 669 | * (below) is our best option for now. |
667 | */ | 670 | */ |
668 | if (psmouse_activate(psmouse)) | 671 | |
672 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) | ||
669 | return -1; | 673 | return -1; |
670 | 674 | ||
675 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | ||
676 | |||
671 | if (tpdebug) | 677 | if (tpdebug) |
672 | psmouse_dbg(psmouse, "touchpad reactivated\n"); | 678 | hgpk_dbg(psmouse, "touchpad reactivated\n"); |
673 | 679 | ||
674 | /* | 680 | /* |
675 | * If we get packets right away after recalibrating, it's likely | 681 | * If we get packets right away after recalibrating, it's likely |
@@ -721,15 +727,16 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) | |||
721 | 727 | ||
722 | err = hgpk_reset_device(psmouse, false); | 728 | err = hgpk_reset_device(psmouse, false); |
723 | if (err) { | 729 | if (err) { |
724 | psmouse_err(psmouse, "Failed to reset device!\n"); | 730 | hgpk_err(psmouse, "Failed to reset device!\n"); |
725 | return err; | 731 | return err; |
726 | } | 732 | } |
727 | 733 | ||
728 | /* should be all set, enable the touchpad */ | 734 | /* should be all set, enable the touchpad */ |
729 | psmouse_activate(psmouse); | 735 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
730 | psmouse_dbg(psmouse, "Touchpad powered up.\n"); | 736 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
737 | hgpk_dbg(psmouse, "Touchpad powered up.\n"); | ||
731 | } else { | 738 | } else { |
732 | psmouse_dbg(psmouse, "Powering off touchpad.\n"); | 739 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); |
733 | 740 | ||
734 | if (ps2_command(ps2dev, NULL, 0xec) || | 741 | if (ps2_command(ps2dev, NULL, 0xec) || |
735 | ps2_command(ps2dev, NULL, 0xec) || | 742 | ps2_command(ps2dev, NULL, 0xec) || |
@@ -781,14 +788,11 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
781 | const char *buf, size_t count) | 788 | const char *buf, size_t count) |
782 | { | 789 | { |
783 | struct hgpk_data *priv = psmouse->private; | 790 | struct hgpk_data *priv = psmouse->private; |
784 | unsigned int value; | 791 | unsigned long value; |
785 | int err; | 792 | int err; |
786 | 793 | ||
787 | err = kstrtouint(buf, 10, &value); | 794 | err = strict_strtoul(buf, 10, &value); |
788 | if (err) | 795 | if (err || value > 1) |
789 | return err; | ||
790 | |||
791 | if (value > 1) | ||
792 | return -EINVAL; | 796 | return -EINVAL; |
793 | 797 | ||
794 | if (value != priv->powered) { | 798 | if (value != priv->powered) { |
@@ -876,14 +880,11 @@ static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data, | |||
876 | const char *buf, size_t count) | 880 | const char *buf, size_t count) |
877 | { | 881 | { |
878 | struct hgpk_data *priv = psmouse->private; | 882 | struct hgpk_data *priv = psmouse->private; |
879 | unsigned int value; | 883 | unsigned long value; |
880 | int err; | 884 | int err; |
881 | 885 | ||
882 | err = kstrtouint(buf, 10, &value); | 886 | err = strict_strtoul(buf, 10, &value); |
883 | if (err) | 887 | if (err || value != 1) |
884 | return err; | ||
885 | |||
886 | if (value != 1) | ||
887 | return -EINVAL; | 888 | return -EINVAL; |
888 | 889 | ||
889 | /* | 890 | /* |
@@ -922,7 +923,7 @@ static void hgpk_recalib_work(struct work_struct *work) | |||
922 | struct psmouse *psmouse = priv->psmouse; | 923 | struct psmouse *psmouse = priv->psmouse; |
923 | 924 | ||
924 | if (hgpk_force_recalibrate(psmouse)) | 925 | if (hgpk_force_recalibrate(psmouse)) |
925 | psmouse_err(psmouse, "recalibration failed!\n"); | 926 | hgpk_err(psmouse, "recalibration failed!\n"); |
926 | } | 927 | } |
927 | 928 | ||
928 | static int hgpk_register(struct psmouse *psmouse) | 929 | static int hgpk_register(struct psmouse *psmouse) |
@@ -946,15 +947,14 @@ static int hgpk_register(struct psmouse *psmouse) | |||
946 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 947 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
947 | &psmouse_attr_powered.dattr); | 948 | &psmouse_attr_powered.dattr); |
948 | if (err) { | 949 | if (err) { |
949 | psmouse_err(psmouse, "Failed creating 'powered' sysfs node\n"); | 950 | hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n"); |
950 | return err; | 951 | return err; |
951 | } | 952 | } |
952 | 953 | ||
953 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 954 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
954 | &psmouse_attr_hgpk_mode.dattr); | 955 | &psmouse_attr_hgpk_mode.dattr); |
955 | if (err) { | 956 | if (err) { |
956 | psmouse_err(psmouse, | 957 | hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n"); |
957 | "Failed creating 'hgpk_mode' sysfs node\n"); | ||
958 | goto err_remove_powered; | 958 | goto err_remove_powered; |
959 | } | 959 | } |
960 | 960 | ||
@@ -963,8 +963,8 @@ static int hgpk_register(struct psmouse *psmouse) | |||
963 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 963 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
964 | &psmouse_attr_recalibrate.dattr); | 964 | &psmouse_attr_recalibrate.dattr); |
965 | if (err) { | 965 | if (err) { |
966 | psmouse_err(psmouse, | 966 | hgpk_err(psmouse, |
967 | "Failed creating 'recalibrate' sysfs node\n"); | 967 | "Failed creating 'recalibrate' sysfs node\n"); |
968 | goto err_remove_mode; | 968 | goto err_remove_mode; |
969 | } | 969 | } |
970 | } | 970 | } |
@@ -1027,13 +1027,13 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) | |||
1027 | return -EIO; | 1027 | return -EIO; |
1028 | } | 1028 | } |
1029 | 1029 | ||
1030 | psmouse_dbg(psmouse, "ID: %*ph\n", 3, param); | 1030 | hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); |
1031 | 1031 | ||
1032 | /* HGPK signature: 0x67, 0x00, 0x<model> */ | 1032 | /* HGPK signature: 0x67, 0x00, 0x<model> */ |
1033 | if (param[0] != 0x67 || param[1] != 0x00) | 1033 | if (param[0] != 0x67 || param[1] != 0x00) |
1034 | return -ENODEV; | 1034 | return -ENODEV; |
1035 | 1035 | ||
1036 | psmouse_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]); | 1036 | hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]); |
1037 | 1037 | ||
1038 | return param[2]; | 1038 | return param[2]; |
1039 | } | 1039 | } |
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h index dd686771cfe..311c0e87fcb 100644 --- a/drivers/input/mouse/hgpk.h +++ b/drivers/input/mouse/hgpk.h | |||
@@ -46,6 +46,17 @@ struct hgpk_data { | |||
46 | int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ | 46 | int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #define hgpk_dbg(psmouse, format, arg...) \ | ||
50 | dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
51 | #define hgpk_err(psmouse, format, arg...) \ | ||
52 | dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
53 | #define hgpk_info(psmouse, format, arg...) \ | ||
54 | dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
55 | #define hgpk_warn(psmouse, format, arg...) \ | ||
56 | dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
57 | #define hgpk_notice(psmouse, format, arg...) \ | ||
58 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
59 | |||
49 | #ifdef CONFIG_MOUSE_PS2_OLPC | 60 | #ifdef CONFIG_MOUSE_PS2_OLPC |
50 | void hgpk_module_init(void); | 61 | void hgpk_module_init(void); |
51 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); | 62 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 2c4db636de6..83bcaba96b8 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -169,8 +169,8 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
169 | 169 | ||
170 | if (relative_packet) { | 170 | if (relative_packet) { |
171 | if (!dev2) | 171 | if (!dev2) |
172 | psmouse_warn(psmouse, | 172 | printk(KERN_WARNING "lifebook.c: got relative packet " |
173 | "got relative packet but no relative device set up\n"); | 173 | "but no relative device set up\n"); |
174 | } else { | 174 | } else { |
175 | if (lifebook_use_6byte_proto) { | 175 | if (lifebook_use_6byte_proto) { |
176 | input_report_abs(dev1, ABS_X, | 176 | input_report_abs(dev1, ABS_X, |
@@ -212,7 +212,7 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Enable absolute output -- ps2_command fails always but if | 214 | * Enable absolute output -- ps2_command fails always but if |
215 | * you leave this call out the touchscreen will never send | 215 | * you leave this call out the touchsreen will never send |
216 | * absolute coordinates | 216 | * absolute coordinates |
217 | */ | 217 | */ |
218 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; | 218 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 84de2fc6acc..c9983aee908 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -82,11 +82,11 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
82 | packet[0] = packet[2] | 0x08; | 82 | packet[0] = packet[2] | 0x08; |
83 | break; | 83 | break; |
84 | 84 | ||
85 | #ifdef DEBUG | ||
85 | default: | 86 | default: |
86 | psmouse_dbg(psmouse, | 87 | printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", |
87 | "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 | break; | ||
90 | } | 90 | } |
91 | } else { | 91 | } else { |
92 | /* Standard PS/2 motion data */ | 92 | /* Standard PS/2 motion data */ |
@@ -155,14 +155,9 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, | |||
155 | static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, | 155 | static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, |
156 | const char *buf, size_t count) | 156 | const char *buf, size_t count) |
157 | { | 157 | { |
158 | unsigned int value; | 158 | unsigned long value; |
159 | int err; | ||
160 | |||
161 | err = kstrtouint(buf, 10, &value); | ||
162 | if (err) | ||
163 | return err; | ||
164 | 159 | ||
165 | if (value > 1) | 160 | if (strict_strtoul(buf, 10, &value) || value > 1) |
166 | return -EINVAL; | 161 | return -EINVAL; |
167 | 162 | ||
168 | ps2pp_set_smartscroll(psmouse, value); | 163 | ps2pp_set_smartscroll(psmouse, value); |
@@ -387,7 +382,7 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
387 | } | 382 | } |
388 | 383 | ||
389 | } else { | 384 | } else { |
390 | psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model); | 385 | printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); |
391 | } | 386 | } |
392 | 387 | ||
393 | if (set_properties) { | 388 | if (set_properties) { |
@@ -405,9 +400,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
405 | error = device_create_file(&psmouse->ps2dev.serio->dev, | 400 | error = device_create_file(&psmouse->ps2dev.serio->dev, |
406 | &psmouse_attr_smartscroll.dattr); | 401 | &psmouse_attr_smartscroll.dattr); |
407 | if (error) { | 402 | if (error) { |
408 | psmouse_err(psmouse, | 403 | printk(KERN_ERR |
409 | "failed to create smartscroll sysfs attribute, error: %d\n", | 404 | "logips2pp.c: failed to create smartscroll " |
410 | error); | 405 | "sysfs attribute, error: %d\n", error); |
411 | return -1; | 406 | return -1; |
412 | } | 407 | } |
413 | } | 408 | } |
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index 0a60717b91c..5f278176eb9 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c | |||
@@ -64,7 +64,7 @@ static void dc_mouse_close(struct input_dev *dev) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | /* allow the mouse to be used */ | 66 | /* allow the mouse to be used */ |
67 | static int probe_maple_mouse(struct device *dev) | 67 | static int __devinit probe_maple_mouse(struct device *dev) |
68 | { | 68 | { |
69 | struct maple_device *mdev = to_maple_dev(dev); | 69 | struct maple_device *mdev = to_maple_dev(dev); |
70 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | 70 | struct maple_driver *mdrv = to_maple_driver(dev->driver); |
@@ -114,7 +114,7 @@ fail: | |||
114 | return error; | 114 | return error; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int remove_maple_mouse(struct device *dev) | 117 | static int __devexit remove_maple_mouse(struct device *dev) |
118 | { | 118 | { |
119 | struct maple_device *mdev = to_maple_dev(dev); | 119 | struct maple_device *mdev = to_maple_dev(dev); |
120 | struct dc_mouse *mse = maple_get_drvdata(mdev); | 120 | struct dc_mouse *mse = maple_get_drvdata(mdev); |
@@ -132,7 +132,7 @@ static struct maple_driver dc_mouse_driver = { | |||
132 | .drv = { | 132 | .drv = { |
133 | .name = "Dreamcast_mouse", | 133 | .name = "Dreamcast_mouse", |
134 | .probe = probe_maple_mouse, | 134 | .probe = probe_maple_mouse, |
135 | .remove = remove_maple_mouse, | 135 | .remove = __devexit_p(remove_maple_mouse), |
136 | }, | 136 | }, |
137 | }; | 137 | }; |
138 | 138 | ||
diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c deleted file mode 100644 index 8e1b98ea564..00000000000 --- a/drivers/input/mouse/navpoint.c +++ /dev/null | |||
@@ -1,369 +0,0 @@ | |||
1 | /* | ||
2 | * Synaptics NavPoint (PXA27x SSP/SPI) driver. | ||
3 | * | ||
4 | * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/input/navpoint.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/pxa2xx_ssp.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | /* | ||
26 | * Synaptics Modular Embedded Protocol: Module Packet Format. | ||
27 | * Module header byte 2:0 = Length (# bytes that follow) | ||
28 | * Module header byte 4:3 = Control | ||
29 | * Module header byte 7:5 = Module Address | ||
30 | */ | ||
31 | #define HEADER_LENGTH(byte) ((byte) & 0x07) | ||
32 | #define HEADER_CONTROL(byte) (((byte) >> 3) & 0x03) | ||
33 | #define HEADER_ADDRESS(byte) ((byte) >> 5) | ||
34 | |||
35 | struct navpoint { | ||
36 | struct ssp_device *ssp; | ||
37 | struct input_dev *input; | ||
38 | struct device *dev; | ||
39 | int gpio; | ||
40 | int index; | ||
41 | u8 data[1 + HEADER_LENGTH(0xff)]; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * Initialization values for SSCR0_x, SSCR1_x, SSSR_x. | ||
46 | */ | ||
47 | static const u32 sscr0 = 0 | ||
48 | | SSCR0_TUM /* TIM = 1; No TUR interrupts */ | ||
49 | | SSCR0_RIM /* RIM = 1; No ROR interrupts */ | ||
50 | | SSCR0_SSE /* SSE = 1; SSP enabled */ | ||
51 | | SSCR0_Motorola /* FRF = 0; Motorola SPI */ | ||
52 | | SSCR0_DataSize(16) /* DSS = 15; Data size = 16-bit */ | ||
53 | ; | ||
54 | static const u32 sscr1 = 0 | ||
55 | | SSCR1_SCFR /* SCFR = 1; SSPSCLK only during transfers */ | ||
56 | | SSCR1_SCLKDIR /* SCLKDIR = 1; Slave mode */ | ||
57 | | SSCR1_SFRMDIR /* SFRMDIR = 1; Slave mode */ | ||
58 | | SSCR1_RWOT /* RWOT = 1; Receive without transmit mode */ | ||
59 | | SSCR1_RxTresh(1) /* RFT = 0; Receive FIFO threshold = 1 */ | ||
60 | | SSCR1_SPH /* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */ | ||
61 | | SSCR1_RIE /* RIE = 1; Receive FIFO interrupt enabled */ | ||
62 | ; | ||
63 | static const u32 sssr = 0 | ||
64 | | SSSR_BCE /* BCE = 1; Clear BCE */ | ||
65 | | SSSR_TUR /* TUR = 1; Clear TUR */ | ||
66 | | SSSR_EOC /* EOC = 1; Clear EOC */ | ||
67 | | SSSR_TINT /* TINT = 1; Clear TINT */ | ||
68 | | SSSR_PINT /* PINT = 1; Clear PINT */ | ||
69 | | SSSR_ROR /* ROR = 1; Clear ROR */ | ||
70 | ; | ||
71 | |||
72 | /* | ||
73 | * MEP Query $22: Touchpad Coordinate Range Query is not supported by | ||
74 | * the NavPoint module, so sampled values provide the default limits. | ||
75 | */ | ||
76 | #define NAVPOINT_X_MIN 1278 | ||
77 | #define NAVPOINT_X_MAX 5340 | ||
78 | #define NAVPOINT_Y_MIN 1572 | ||
79 | #define NAVPOINT_Y_MAX 4396 | ||
80 | #define NAVPOINT_PRESSURE_MIN 0 | ||
81 | #define NAVPOINT_PRESSURE_MAX 255 | ||
82 | |||
83 | static void navpoint_packet(struct navpoint *navpoint) | ||
84 | { | ||
85 | int finger; | ||
86 | int gesture; | ||
87 | int x, y, z; | ||
88 | |||
89 | switch (navpoint->data[0]) { | ||
90 | case 0xff: /* Garbage (packet?) between reset and Hello packet */ | ||
91 | case 0x00: /* Module 0, NULL packet */ | ||
92 | break; | ||
93 | |||
94 | case 0x0e: /* Module 0, Absolute packet */ | ||
95 | finger = (navpoint->data[1] & 0x01); | ||
96 | gesture = (navpoint->data[1] & 0x02); | ||
97 | x = ((navpoint->data[2] & 0x1f) << 8) | navpoint->data[3]; | ||
98 | y = ((navpoint->data[4] & 0x1f) << 8) | navpoint->data[5]; | ||
99 | z = navpoint->data[6]; | ||
100 | input_report_key(navpoint->input, BTN_TOUCH, finger); | ||
101 | input_report_abs(navpoint->input, ABS_X, x); | ||
102 | input_report_abs(navpoint->input, ABS_Y, y); | ||
103 | input_report_abs(navpoint->input, ABS_PRESSURE, z); | ||
104 | input_report_key(navpoint->input, BTN_TOOL_FINGER, finger); | ||
105 | input_report_key(navpoint->input, BTN_LEFT, gesture); | ||
106 | input_sync(navpoint->input); | ||
107 | break; | ||
108 | |||
109 | case 0x19: /* Module 0, Hello packet */ | ||
110 | if ((navpoint->data[1] & 0xf0) == 0x10) | ||
111 | break; | ||
112 | /* FALLTHROUGH */ | ||
113 | default: | ||
114 | dev_warn(navpoint->dev, | ||
115 | "spurious packet: data=0x%02x,0x%02x,...\n", | ||
116 | navpoint->data[0], navpoint->data[1]); | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static irqreturn_t navpoint_irq(int irq, void *dev_id) | ||
122 | { | ||
123 | struct navpoint *navpoint = dev_id; | ||
124 | struct ssp_device *ssp = navpoint->ssp; | ||
125 | irqreturn_t ret = IRQ_NONE; | ||
126 | u32 status; | ||
127 | |||
128 | status = pxa_ssp_read_reg(ssp, SSSR); | ||
129 | if (status & sssr) { | ||
130 | dev_warn(navpoint->dev, | ||
131 | "unexpected interrupt: status=0x%08x\n", status); | ||
132 | pxa_ssp_write_reg(ssp, SSSR, (status & sssr)); | ||
133 | ret = IRQ_HANDLED; | ||
134 | } | ||
135 | |||
136 | while (status & SSSR_RNE) { | ||
137 | u32 data; | ||
138 | |||
139 | data = pxa_ssp_read_reg(ssp, SSDR); | ||
140 | navpoint->data[navpoint->index + 0] = (data >> 8); | ||
141 | navpoint->data[navpoint->index + 1] = data; | ||
142 | navpoint->index += 2; | ||
143 | if (HEADER_LENGTH(navpoint->data[0]) < navpoint->index) { | ||
144 | navpoint_packet(navpoint); | ||
145 | navpoint->index = 0; | ||
146 | } | ||
147 | status = pxa_ssp_read_reg(ssp, SSSR); | ||
148 | ret = IRQ_HANDLED; | ||
149 | } | ||
150 | |||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | static void navpoint_up(struct navpoint *navpoint) | ||
155 | { | ||
156 | struct ssp_device *ssp = navpoint->ssp; | ||
157 | int timeout; | ||
158 | |||
159 | clk_prepare_enable(ssp->clk); | ||
160 | |||
161 | pxa_ssp_write_reg(ssp, SSCR1, sscr1); | ||
162 | pxa_ssp_write_reg(ssp, SSSR, sssr); | ||
163 | pxa_ssp_write_reg(ssp, SSTO, 0); | ||
164 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */ | ||
165 | |||
166 | /* Wait until SSP port is ready for slave clock operations */ | ||
167 | for (timeout = 100; timeout != 0; --timeout) { | ||
168 | if (!(pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS)) | ||
169 | break; | ||
170 | msleep(1); | ||
171 | } | ||
172 | |||
173 | if (timeout == 0) | ||
174 | dev_err(navpoint->dev, | ||
175 | "timeout waiting for SSSR[CSS] to clear\n"); | ||
176 | |||
177 | if (gpio_is_valid(navpoint->gpio)) | ||
178 | gpio_set_value(navpoint->gpio, 1); | ||
179 | } | ||
180 | |||
181 | static void navpoint_down(struct navpoint *navpoint) | ||
182 | { | ||
183 | struct ssp_device *ssp = navpoint->ssp; | ||
184 | |||
185 | if (gpio_is_valid(navpoint->gpio)) | ||
186 | gpio_set_value(navpoint->gpio, 0); | ||
187 | |||
188 | pxa_ssp_write_reg(ssp, SSCR0, 0); | ||
189 | |||
190 | clk_disable_unprepare(ssp->clk); | ||
191 | } | ||
192 | |||
193 | static int navpoint_open(struct input_dev *input) | ||
194 | { | ||
195 | struct navpoint *navpoint = input_get_drvdata(input); | ||
196 | |||
197 | navpoint_up(navpoint); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static void navpoint_close(struct input_dev *input) | ||
203 | { | ||
204 | struct navpoint *navpoint = input_get_drvdata(input); | ||
205 | |||
206 | navpoint_down(navpoint); | ||
207 | } | ||
208 | |||
209 | static int navpoint_probe(struct platform_device *pdev) | ||
210 | { | ||
211 | const struct navpoint_platform_data *pdata = | ||
212 | dev_get_platdata(&pdev->dev); | ||
213 | struct ssp_device *ssp; | ||
214 | struct input_dev *input; | ||
215 | struct navpoint *navpoint; | ||
216 | int error; | ||
217 | |||
218 | if (!pdata) { | ||
219 | dev_err(&pdev->dev, "no platform data\n"); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | if (gpio_is_valid(pdata->gpio)) { | ||
224 | error = gpio_request_one(pdata->gpio, GPIOF_OUT_INIT_LOW, | ||
225 | "SYNAPTICS_ON"); | ||
226 | if (error) | ||
227 | return error; | ||
228 | } | ||
229 | |||
230 | ssp = pxa_ssp_request(pdata->port, pdev->name); | ||
231 | if (!ssp) { | ||
232 | error = -ENODEV; | ||
233 | goto err_free_gpio; | ||
234 | } | ||
235 | |||
236 | /* HaRET does not disable devices before jumping into Linux */ | ||
237 | if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { | ||
238 | pxa_ssp_write_reg(ssp, SSCR0, 0); | ||
239 | dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port); | ||
240 | } | ||
241 | |||
242 | navpoint = kzalloc(sizeof(*navpoint), GFP_KERNEL); | ||
243 | input = input_allocate_device(); | ||
244 | if (!navpoint || !input) { | ||
245 | error = -ENOMEM; | ||
246 | goto err_free_mem; | ||
247 | } | ||
248 | |||
249 | navpoint->ssp = ssp; | ||
250 | navpoint->input = input; | ||
251 | navpoint->dev = &pdev->dev; | ||
252 | navpoint->gpio = pdata->gpio; | ||
253 | |||
254 | input->name = pdev->name; | ||
255 | input->dev.parent = &pdev->dev; | ||
256 | |||
257 | __set_bit(EV_KEY, input->evbit); | ||
258 | __set_bit(EV_ABS, input->evbit); | ||
259 | __set_bit(BTN_LEFT, input->keybit); | ||
260 | __set_bit(BTN_TOUCH, input->keybit); | ||
261 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
262 | |||
263 | input_set_abs_params(input, ABS_X, | ||
264 | NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0); | ||
265 | input_set_abs_params(input, ABS_Y, | ||
266 | NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0); | ||
267 | input_set_abs_params(input, ABS_PRESSURE, | ||
268 | NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX, | ||
269 | 0, 0); | ||
270 | |||
271 | input->open = navpoint_open; | ||
272 | input->close = navpoint_close; | ||
273 | |||
274 | input_set_drvdata(input, navpoint); | ||
275 | |||
276 | error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint); | ||
277 | if (error) | ||
278 | goto err_free_mem; | ||
279 | |||
280 | error = input_register_device(input); | ||
281 | if (error) | ||
282 | goto err_free_irq; | ||
283 | |||
284 | platform_set_drvdata(pdev, navpoint); | ||
285 | dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq); | ||
286 | |||
287 | return 0; | ||
288 | |||
289 | err_free_irq: | ||
290 | free_irq(ssp->irq, &pdev->dev); | ||
291 | err_free_mem: | ||
292 | input_free_device(input); | ||
293 | kfree(navpoint); | ||
294 | pxa_ssp_free(ssp); | ||
295 | err_free_gpio: | ||
296 | if (gpio_is_valid(pdata->gpio)) | ||
297 | gpio_free(pdata->gpio); | ||
298 | |||
299 | return error; | ||
300 | } | ||
301 | |||
302 | static int navpoint_remove(struct platform_device *pdev) | ||
303 | { | ||
304 | const struct navpoint_platform_data *pdata = | ||
305 | dev_get_platdata(&pdev->dev); | ||
306 | struct navpoint *navpoint = platform_get_drvdata(pdev); | ||
307 | struct ssp_device *ssp = navpoint->ssp; | ||
308 | |||
309 | free_irq(ssp->irq, navpoint); | ||
310 | |||
311 | input_unregister_device(navpoint->input); | ||
312 | kfree(navpoint); | ||
313 | |||
314 | pxa_ssp_free(ssp); | ||
315 | |||
316 | if (gpio_is_valid(pdata->gpio)) | ||
317 | gpio_free(pdata->gpio); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | #ifdef CONFIG_PM_SLEEP | ||
323 | static int navpoint_suspend(struct device *dev) | ||
324 | { | ||
325 | struct platform_device *pdev = to_platform_device(dev); | ||
326 | struct navpoint *navpoint = platform_get_drvdata(pdev); | ||
327 | struct input_dev *input = navpoint->input; | ||
328 | |||
329 | mutex_lock(&input->mutex); | ||
330 | if (input->users) | ||
331 | navpoint_down(navpoint); | ||
332 | mutex_unlock(&input->mutex); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int navpoint_resume(struct device *dev) | ||
338 | { | ||
339 | struct platform_device *pdev = to_platform_device(dev); | ||
340 | struct navpoint *navpoint = platform_get_drvdata(pdev); | ||
341 | struct input_dev *input = navpoint->input; | ||
342 | |||
343 | mutex_lock(&input->mutex); | ||
344 | if (input->users) | ||
345 | navpoint_up(navpoint); | ||
346 | mutex_unlock(&input->mutex); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | #endif | ||
351 | |||
352 | static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); | ||
353 | |||
354 | static struct platform_driver navpoint_driver = { | ||
355 | .probe = navpoint_probe, | ||
356 | .remove = navpoint_remove, | ||
357 | .driver = { | ||
358 | .name = "navpoint", | ||
359 | .owner = THIS_MODULE, | ||
360 | .pm = &navpoint_pm_ops, | ||
361 | }, | ||
362 | }; | ||
363 | |||
364 | module_platform_driver(navpoint_driver); | ||
365 | |||
366 | MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); | ||
367 | MODULE_DESCRIPTION("Synaptics NavPoint (PXA27x SSP/SPI) driver"); | ||
368 | MODULE_LICENSE("GPL"); | ||
369 | MODULE_ALIAS("platform:navpoint"); | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 22fe2547e16..3f74baee102 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -11,9 +11,6 @@ | |||
11 | * the Free Software Foundation. | 11 | * the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | #define psmouse_fmt(fmt) fmt | ||
16 | |||
17 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
18 | #include <linux/module.h> | 15 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -60,7 +57,7 @@ static unsigned int psmouse_rate = 100; | |||
60 | module_param_named(rate, psmouse_rate, uint, 0644); | 57 | module_param_named(rate, psmouse_rate, uint, 0644); |
61 | MODULE_PARM_DESC(rate, "Report rate, in reports per second."); | 58 | MODULE_PARM_DESC(rate, "Report rate, in reports per second."); |
62 | 59 | ||
63 | static bool psmouse_smartscroll = 1; | 60 | static unsigned int psmouse_smartscroll = 1; |
64 | module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); | 61 | module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); |
65 | MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); | 62 | MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); |
66 | 63 | ||
@@ -127,7 +124,7 @@ struct psmouse_protocol { | |||
127 | * relevant events to the input module once full packet has arrived. | 124 | * relevant events to the input module once full packet has arrived. |
128 | */ | 125 | */ |
129 | 126 | ||
130 | psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | 127 | static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) |
131 | { | 128 | { |
132 | struct input_dev *dev = psmouse->dev; | 129 | struct input_dev *dev = psmouse->dev; |
133 | unsigned char *packet = psmouse->packet; | 130 | unsigned char *packet = psmouse->packet; |
@@ -254,14 +251,11 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
254 | switch (rc) { | 251 | switch (rc) { |
255 | case PSMOUSE_BAD_DATA: | 252 | case PSMOUSE_BAD_DATA: |
256 | if (psmouse->state == PSMOUSE_ACTIVATED) { | 253 | if (psmouse->state == PSMOUSE_ACTIVATED) { |
257 | psmouse_warn(psmouse, | 254 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", |
258 | "%s at %s lost sync at byte %d\n", | 255 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
259 | psmouse->name, psmouse->phys, | ||
260 | psmouse->pktcnt); | ||
261 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { | 256 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { |
262 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 257 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
263 | psmouse_notice(psmouse, | 258 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); |
264 | "issuing reconnect request\n"); | ||
265 | serio_reconnect(psmouse->ps2dev.serio); | 259 | serio_reconnect(psmouse->ps2dev.serio); |
266 | return -1; | 260 | return -1; |
267 | } | 261 | } |
@@ -273,9 +267,8 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
273 | psmouse->pktcnt = 0; | 267 | psmouse->pktcnt = 0; |
274 | if (psmouse->out_of_sync_cnt) { | 268 | if (psmouse->out_of_sync_cnt) { |
275 | psmouse->out_of_sync_cnt = 0; | 269 | psmouse->out_of_sync_cnt = 0; |
276 | psmouse_notice(psmouse, | 270 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", |
277 | "%s at %s - driver resynced.\n", | 271 | psmouse->name, psmouse->phys); |
278 | psmouse->name, psmouse->phys); | ||
279 | } | 272 | } |
280 | break; | 273 | break; |
281 | 274 | ||
@@ -302,10 +295,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
302 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { | 295 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { |
303 | 296 | ||
304 | if (psmouse->state == PSMOUSE_ACTIVATED) | 297 | if (psmouse->state == PSMOUSE_ACTIVATED) |
305 | psmouse_warn(psmouse, | 298 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", |
306 | "bad data from KBC -%s%s\n", | 299 | flags & SERIO_TIMEOUT ? " timeout" : "", |
307 | flags & SERIO_TIMEOUT ? " timeout" : "", | 300 | flags & SERIO_PARITY ? " bad parity" : ""); |
308 | flags & SERIO_PARITY ? " bad parity" : ""); | ||
309 | ps2_cmd_aborted(&psmouse->ps2dev); | 301 | ps2_cmd_aborted(&psmouse->ps2dev); |
310 | goto out; | 302 | goto out; |
311 | } | 303 | } |
@@ -323,8 +315,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
323 | 315 | ||
324 | if (psmouse->state == PSMOUSE_ACTIVATED && | 316 | if (psmouse->state == PSMOUSE_ACTIVATED && |
325 | psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { | 317 | psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { |
326 | psmouse_info(psmouse, "%s at %s lost synchronization, throwing %d bytes away.\n", | 318 | printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", |
327 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 319 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
328 | psmouse->badbyte = psmouse->packet[0]; | 320 | psmouse->badbyte = psmouse->packet[0]; |
329 | __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); | 321 | __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); |
330 | psmouse_queue_work(psmouse, &psmouse->resync_work, 0); | 322 | psmouse_queue_work(psmouse, &psmouse->resync_work, 0); |
@@ -418,49 +410,6 @@ int psmouse_reset(struct psmouse *psmouse) | |||
418 | return 0; | 410 | return 0; |
419 | } | 411 | } |
420 | 412 | ||
421 | /* | ||
422 | * Here we set the mouse resolution. | ||
423 | */ | ||
424 | |||
425 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) | ||
426 | { | ||
427 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; | ||
428 | unsigned char p; | ||
429 | |||
430 | if (resolution == 0 || resolution > 200) | ||
431 | resolution = 200; | ||
432 | |||
433 | p = params[resolution / 50]; | ||
434 | ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES); | ||
435 | psmouse->resolution = 25 << p; | ||
436 | } | ||
437 | |||
438 | /* | ||
439 | * Here we set the mouse report rate. | ||
440 | */ | ||
441 | |||
442 | static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) | ||
443 | { | ||
444 | static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; | ||
445 | unsigned char r; | ||
446 | int i = 0; | ||
447 | |||
448 | while (rates[i] > rate) i++; | ||
449 | r = rates[i]; | ||
450 | ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE); | ||
451 | psmouse->rate = r; | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. | ||
456 | */ | ||
457 | |||
458 | static int psmouse_poll(struct psmouse *psmouse) | ||
459 | { | ||
460 | return ps2_command(&psmouse->ps2dev, psmouse->packet, | ||
461 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)); | ||
462 | } | ||
463 | |||
464 | 413 | ||
465 | /* | 414 | /* |
466 | * Genius NetMouse magic init. | 415 | * Genius NetMouse magic init. |
@@ -646,56 +595,6 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) | |||
646 | } | 595 | } |
647 | 596 | ||
648 | /* | 597 | /* |
649 | * Apply default settings to the psmouse structure. Most of them will | ||
650 | * be overridden by individual protocol initialization routines. | ||
651 | */ | ||
652 | |||
653 | static void psmouse_apply_defaults(struct psmouse *psmouse) | ||
654 | { | ||
655 | struct input_dev *input_dev = psmouse->dev; | ||
656 | |||
657 | memset(input_dev->evbit, 0, sizeof(input_dev->evbit)); | ||
658 | memset(input_dev->keybit, 0, sizeof(input_dev->keybit)); | ||
659 | memset(input_dev->relbit, 0, sizeof(input_dev->relbit)); | ||
660 | memset(input_dev->absbit, 0, sizeof(input_dev->absbit)); | ||
661 | memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit)); | ||
662 | |||
663 | __set_bit(EV_KEY, input_dev->evbit); | ||
664 | __set_bit(EV_REL, input_dev->evbit); | ||
665 | |||
666 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
667 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
668 | |||
669 | __set_bit(REL_X, input_dev->relbit); | ||
670 | __set_bit(REL_Y, input_dev->relbit); | ||
671 | |||
672 | psmouse->set_rate = psmouse_set_rate; | ||
673 | psmouse->set_resolution = psmouse_set_resolution; | ||
674 | psmouse->poll = psmouse_poll; | ||
675 | psmouse->protocol_handler = psmouse_process_byte; | ||
676 | psmouse->pktsize = 3; | ||
677 | psmouse->reconnect = NULL; | ||
678 | psmouse->disconnect = NULL; | ||
679 | psmouse->cleanup = NULL; | ||
680 | psmouse->pt_activate = NULL; | ||
681 | psmouse->pt_deactivate = NULL; | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * Apply default settings to the psmouse structure and call specified | ||
686 | * protocol detection or initialization routine. | ||
687 | */ | ||
688 | static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse, | ||
689 | bool set_properties), | ||
690 | struct psmouse *psmouse, bool set_properties) | ||
691 | { | ||
692 | if (set_properties) | ||
693 | psmouse_apply_defaults(psmouse); | ||
694 | |||
695 | return detect(psmouse, set_properties); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * psmouse_extensions() probes for any extensions to the basic PS/2 protocol | 598 | * psmouse_extensions() probes for any extensions to the basic PS/2 protocol |
700 | * the mouse may have. | 599 | * the mouse may have. |
701 | */ | 600 | */ |
@@ -709,7 +608,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
709 | * We always check for lifebook because it does not disturb mouse | 608 | * We always check for lifebook because it does not disturb mouse |
710 | * (it only checks DMI information). | 609 | * (it only checks DMI information). |
711 | */ | 610 | */ |
712 | if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) { | 611 | if (lifebook_detect(psmouse, set_properties) == 0) { |
713 | if (max_proto > PSMOUSE_IMEX) { | 612 | if (max_proto > PSMOUSE_IMEX) { |
714 | if (!set_properties || lifebook_init(psmouse) == 0) | 613 | if (!set_properties || lifebook_init(psmouse) == 0) |
715 | return PSMOUSE_LIFEBOOK; | 614 | return PSMOUSE_LIFEBOOK; |
@@ -721,18 +620,15 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
721 | * upsets the thinkingmouse). | 620 | * upsets the thinkingmouse). |
722 | */ | 621 | */ |
723 | 622 | ||
724 | if (max_proto > PSMOUSE_IMEX && | 623 | if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0) |
725 | psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) { | ||
726 | return PSMOUSE_THINKPS; | 624 | return PSMOUSE_THINKPS; |
727 | } | ||
728 | 625 | ||
729 | /* | 626 | /* |
730 | * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol | 627 | * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol |
731 | * support is disabled in config - we need to know if it is synaptics so we | 628 | * support is disabled in config - we need to know if it is synaptics so we |
732 | * can reset it properly after probing for intellimouse. | 629 | * can reset it properly after probing for intellimouse. |
733 | */ | 630 | */ |
734 | if (max_proto > PSMOUSE_PS2 && | 631 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { |
735 | psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) { | ||
736 | synaptics_hardware = true; | 632 | synaptics_hardware = true; |
737 | 633 | ||
738 | if (max_proto > PSMOUSE_IMEX) { | 634 | if (max_proto > PSMOUSE_IMEX) { |
@@ -763,8 +659,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
763 | */ | 659 | */ |
764 | if (max_proto > PSMOUSE_IMEX) { | 660 | if (max_proto > PSMOUSE_IMEX) { |
765 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); | 661 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); |
766 | if (psmouse_do_detect(alps_detect, | 662 | if (alps_detect(psmouse, set_properties) == 0) { |
767 | psmouse, set_properties) == 0) { | ||
768 | if (!set_properties || alps_init(psmouse) == 0) | 663 | if (!set_properties || alps_init(psmouse) == 0) |
769 | return PSMOUSE_ALPS; | 664 | return PSMOUSE_ALPS; |
770 | /* | 665 | /* |
@@ -778,7 +673,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
778 | * Try OLPC HGPK touchpad. | 673 | * Try OLPC HGPK touchpad. |
779 | */ | 674 | */ |
780 | if (max_proto > PSMOUSE_IMEX && | 675 | if (max_proto > PSMOUSE_IMEX && |
781 | psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) { | 676 | hgpk_detect(psmouse, set_properties) == 0) { |
782 | if (!set_properties || hgpk_init(psmouse) == 0) | 677 | if (!set_properties || hgpk_init(psmouse) == 0) |
783 | return PSMOUSE_HGPK; | 678 | return PSMOUSE_HGPK; |
784 | /* | 679 | /* |
@@ -791,7 +686,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
791 | * Try Elantech touchpad. | 686 | * Try Elantech touchpad. |
792 | */ | 687 | */ |
793 | if (max_proto > PSMOUSE_IMEX && | 688 | if (max_proto > PSMOUSE_IMEX && |
794 | psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) { | 689 | elantech_detect(psmouse, set_properties) == 0) { |
795 | if (!set_properties || elantech_init(psmouse) == 0) | 690 | if (!set_properties || elantech_init(psmouse) == 0) |
796 | return PSMOUSE_ELANTECH; | 691 | return PSMOUSE_ELANTECH; |
797 | /* | 692 | /* |
@@ -800,21 +695,18 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
800 | max_proto = PSMOUSE_IMEX; | 695 | max_proto = PSMOUSE_IMEX; |
801 | } | 696 | } |
802 | 697 | ||
698 | |||
803 | if (max_proto > PSMOUSE_IMEX) { | 699 | if (max_proto > PSMOUSE_IMEX) { |
804 | if (psmouse_do_detect(genius_detect, | 700 | if (genius_detect(psmouse, set_properties) == 0) |
805 | psmouse, set_properties) == 0) | ||
806 | return PSMOUSE_GENPS; | 701 | return PSMOUSE_GENPS; |
807 | 702 | ||
808 | if (psmouse_do_detect(ps2pp_init, | 703 | if (ps2pp_init(psmouse, set_properties) == 0) |
809 | psmouse, set_properties) == 0) | ||
810 | return PSMOUSE_PS2PP; | 704 | return PSMOUSE_PS2PP; |
811 | 705 | ||
812 | if (psmouse_do_detect(trackpoint_detect, | 706 | if (trackpoint_detect(psmouse, set_properties) == 0) |
813 | psmouse, set_properties) == 0) | ||
814 | return PSMOUSE_TRACKPOINT; | 707 | return PSMOUSE_TRACKPOINT; |
815 | 708 | ||
816 | if (psmouse_do_detect(touchkit_ps2_detect, | 709 | if (touchkit_ps2_detect(psmouse, set_properties) == 0) |
817 | psmouse, set_properties) == 0) | ||
818 | return PSMOUSE_TOUCHKIT_PS2; | 710 | return PSMOUSE_TOUCHKIT_PS2; |
819 | } | 711 | } |
820 | 712 | ||
@@ -823,8 +715,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
823 | * Trackpoint devices (causing TP_READ_ID command to time out). | 715 | * Trackpoint devices (causing TP_READ_ID command to time out). |
824 | */ | 716 | */ |
825 | if (max_proto > PSMOUSE_IMEX) { | 717 | if (max_proto > PSMOUSE_IMEX) { |
826 | if (psmouse_do_detect(fsp_detect, | 718 | if (fsp_detect(psmouse, set_properties) == 0) { |
827 | psmouse, set_properties) == 0) { | ||
828 | if (!set_properties || fsp_init(psmouse) == 0) | 719 | if (!set_properties || fsp_init(psmouse) == 0) |
829 | return PSMOUSE_FSP; | 720 | return PSMOUSE_FSP; |
830 | /* | 721 | /* |
@@ -842,23 +733,17 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
842 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); | 733 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); |
843 | psmouse_reset(psmouse); | 734 | psmouse_reset(psmouse); |
844 | 735 | ||
845 | if (max_proto >= PSMOUSE_IMEX && | 736 | if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0) |
846 | psmouse_do_detect(im_explorer_detect, | ||
847 | psmouse, set_properties) == 0) { | ||
848 | return PSMOUSE_IMEX; | 737 | return PSMOUSE_IMEX; |
849 | } | ||
850 | 738 | ||
851 | if (max_proto >= PSMOUSE_IMPS && | 739 | if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse, set_properties) == 0) |
852 | psmouse_do_detect(intellimouse_detect, | ||
853 | psmouse, set_properties) == 0) { | ||
854 | return PSMOUSE_IMPS; | 740 | return PSMOUSE_IMPS; |
855 | } | ||
856 | 741 | ||
857 | /* | 742 | /* |
858 | * Okay, all failed, we have a standard mouse here. The number of the buttons | 743 | * Okay, all failed, we have a standard mouse here. The number of the buttons |
859 | * is still a question, though. We assume 3. | 744 | * is still a question, though. We assume 3. |
860 | */ | 745 | */ |
861 | psmouse_do_detect(ps2bare_detect, psmouse, set_properties); | 746 | ps2bare_detect(psmouse, set_properties); |
862 | 747 | ||
863 | if (synaptics_hardware) { | 748 | if (synaptics_hardware) { |
864 | /* | 749 | /* |
@@ -926,13 +811,6 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
926 | .detect = synaptics_detect, | 811 | .detect = synaptics_detect, |
927 | .init = synaptics_init, | 812 | .init = synaptics_init, |
928 | }, | 813 | }, |
929 | { | ||
930 | .type = PSMOUSE_SYNAPTICS_RELATIVE, | ||
931 | .name = "SynRelPS/2", | ||
932 | .alias = "synaptics-relative", | ||
933 | .detect = synaptics_detect, | ||
934 | .init = synaptics_init_relative, | ||
935 | }, | ||
936 | #endif | 814 | #endif |
937 | #ifdef CONFIG_MOUSE_PS2_ALPS | 815 | #ifdef CONFIG_MOUSE_PS2_ALPS |
938 | { | 816 | { |
@@ -1065,13 +943,45 @@ static int psmouse_probe(struct psmouse *psmouse) | |||
1065 | */ | 943 | */ |
1066 | 944 | ||
1067 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) | 945 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) |
1068 | psmouse_warn(psmouse, "Failed to reset mouse on %s\n", | 946 | printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", ps2dev->serio->phys); |
1069 | ps2dev->serio->phys); | ||
1070 | 947 | ||
1071 | return 0; | 948 | return 0; |
1072 | } | 949 | } |
1073 | 950 | ||
1074 | /* | 951 | /* |
952 | * Here we set the mouse resolution. | ||
953 | */ | ||
954 | |||
955 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) | ||
956 | { | ||
957 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; | ||
958 | unsigned char p; | ||
959 | |||
960 | if (resolution == 0 || resolution > 200) | ||
961 | resolution = 200; | ||
962 | |||
963 | p = params[resolution / 50]; | ||
964 | ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES); | ||
965 | psmouse->resolution = 25 << p; | ||
966 | } | ||
967 | |||
968 | /* | ||
969 | * Here we set the mouse report rate. | ||
970 | */ | ||
971 | |||
972 | static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) | ||
973 | { | ||
974 | static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; | ||
975 | unsigned char r; | ||
976 | int i = 0; | ||
977 | |||
978 | while (rates[i] > rate) i++; | ||
979 | r = rates[i]; | ||
980 | ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE); | ||
981 | psmouse->rate = r; | ||
982 | } | ||
983 | |||
984 | /* | ||
1075 | * psmouse_initialize() initializes the mouse to a sane state. | 985 | * psmouse_initialize() initializes the mouse to a sane state. |
1076 | */ | 986 | */ |
1077 | 987 | ||
@@ -1092,33 +1002,38 @@ static void psmouse_initialize(struct psmouse *psmouse) | |||
1092 | * psmouse_activate() enables the mouse so that we get motion reports from it. | 1002 | * psmouse_activate() enables the mouse so that we get motion reports from it. |
1093 | */ | 1003 | */ |
1094 | 1004 | ||
1095 | int psmouse_activate(struct psmouse *psmouse) | 1005 | static void psmouse_activate(struct psmouse *psmouse) |
1096 | { | 1006 | { |
1097 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { | 1007 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) |
1098 | psmouse_warn(psmouse, "Failed to enable mouse on %s\n", | 1008 | printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", |
1099 | psmouse->ps2dev.serio->phys); | 1009 | psmouse->ps2dev.serio->phys); |
1100 | return -1; | ||
1101 | } | ||
1102 | 1010 | ||
1103 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 1011 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
1104 | return 0; | ||
1105 | } | 1012 | } |
1106 | 1013 | ||
1014 | |||
1107 | /* | 1015 | /* |
1108 | * psmouse_deactivate() puts the mouse into poll mode so that we don't get motion | 1016 | * psmouse_deactivate() puts the mouse into poll mode so that we don't get motion |
1109 | * reports from it unless we explicitly request it. | 1017 | * reports from it unless we explicitly request it. |
1110 | */ | 1018 | */ |
1111 | 1019 | ||
1112 | int psmouse_deactivate(struct psmouse *psmouse) | 1020 | static void psmouse_deactivate(struct psmouse *psmouse) |
1113 | { | 1021 | { |
1114 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) { | 1022 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) |
1115 | psmouse_warn(psmouse, "Failed to deactivate mouse on %s\n", | 1023 | printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", |
1116 | psmouse->ps2dev.serio->phys); | 1024 | psmouse->ps2dev.serio->phys); |
1117 | return -1; | ||
1118 | } | ||
1119 | 1025 | ||
1120 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1026 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
1121 | return 0; | 1027 | } |
1028 | |||
1029 | /* | ||
1030 | * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it. | ||
1031 | */ | ||
1032 | |||
1033 | static int psmouse_poll(struct psmouse *psmouse) | ||
1034 | { | ||
1035 | return ps2_command(&psmouse->ps2dev, psmouse->packet, | ||
1036 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)); | ||
1122 | } | 1037 | } |
1123 | 1038 | ||
1124 | 1039 | ||
@@ -1200,15 +1115,14 @@ static void psmouse_resync(struct work_struct *work) | |||
1200 | } | 1115 | } |
1201 | 1116 | ||
1202 | if (!enabled) { | 1117 | if (!enabled) { |
1203 | psmouse_warn(psmouse, "failed to re-enable mouse on %s\n", | 1118 | printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", |
1204 | psmouse->ps2dev.serio->phys); | 1119 | psmouse->ps2dev.serio->phys); |
1205 | failed = true; | 1120 | failed = true; |
1206 | } | 1121 | } |
1207 | 1122 | ||
1208 | if (failed) { | 1123 | if (failed) { |
1209 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 1124 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
1210 | psmouse_info(psmouse, | 1125 | printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n"); |
1211 | "resync failed, issuing reconnect request\n"); | ||
1212 | serio_reconnect(serio); | 1126 | serio_reconnect(serio); |
1213 | } else | 1127 | } else |
1214 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 1128 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
@@ -1241,8 +1155,8 @@ static void psmouse_cleanup(struct serio *serio) | |||
1241 | * Disable stream mode so cleanup routine can proceed undisturbed. | 1155 | * Disable stream mode so cleanup routine can proceed undisturbed. |
1242 | */ | 1156 | */ |
1243 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | 1157 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) |
1244 | psmouse_warn(psmouse, "Failed to disable mouse on %s\n", | 1158 | printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", |
1245 | psmouse->ps2dev.serio->phys); | 1159 | psmouse->ps2dev.serio->phys); |
1246 | 1160 | ||
1247 | if (psmouse->cleanup) | 1161 | if (psmouse->cleanup) |
1248 | psmouse->cleanup(psmouse); | 1162 | psmouse->cleanup(psmouse); |
@@ -1321,9 +1235,18 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1321 | 1235 | ||
1322 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; | 1236 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
1323 | 1237 | ||
1324 | if (proto && (proto->detect || proto->init)) { | 1238 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
1325 | psmouse_apply_defaults(psmouse); | 1239 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] = |
1240 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); | ||
1241 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | ||
1242 | |||
1243 | psmouse->set_rate = psmouse_set_rate; | ||
1244 | psmouse->set_resolution = psmouse_set_resolution; | ||
1245 | psmouse->poll = psmouse_poll; | ||
1246 | psmouse->protocol_handler = psmouse_process_byte; | ||
1247 | psmouse->pktsize = 3; | ||
1326 | 1248 | ||
1249 | if (proto && (proto->detect || proto->init)) { | ||
1327 | if (proto->detect && proto->detect(psmouse, true) < 0) | 1250 | if (proto->detect && proto->detect(psmouse, true) < 0) |
1328 | return -1; | 1251 | return -1; |
1329 | 1252 | ||
@@ -1477,8 +1400,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1477 | int rc = -1; | 1400 | int rc = -1; |
1478 | 1401 | ||
1479 | if (!drv || !psmouse) { | 1402 | if (!drv || !psmouse) { |
1480 | psmouse_dbg(psmouse, | 1403 | printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); |
1481 | "reconnect request, but serio is disconnected, ignoring...\n"); | ||
1482 | return -1; | 1404 | return -1; |
1483 | } | 1405 | } |
1484 | 1406 | ||
@@ -1505,9 +1427,8 @@ static int psmouse_reconnect(struct serio *serio) | |||
1505 | goto out; | 1427 | goto out; |
1506 | } | 1428 | } |
1507 | 1429 | ||
1508 | /* | 1430 | /* ok, the device type (and capabilities) match the old one, |
1509 | * OK, the device type (and capabilities) match the old one, | 1431 | * we can continue using it, complete intialization |
1510 | * we can continue using it, complete initialization | ||
1511 | */ | 1432 | */ |
1512 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1433 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
1513 | 1434 | ||
@@ -1625,12 +1546,13 @@ static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char | |||
1625 | static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count) | 1546 | static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count) |
1626 | { | 1547 | { |
1627 | unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); | 1548 | unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); |
1628 | unsigned int value; | 1549 | unsigned long value; |
1629 | int err; | ||
1630 | 1550 | ||
1631 | err = kstrtouint(buf, 10, &value); | 1551 | if (strict_strtoul(buf, 10, &value)) |
1632 | if (err) | 1552 | return -EINVAL; |
1633 | return err; | 1553 | |
1554 | if ((unsigned int)value != value) | ||
1555 | return -EINVAL; | ||
1634 | 1556 | ||
1635 | *field = value; | 1557 | *field = value; |
1636 | 1558 | ||
@@ -1664,8 +1586,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1664 | 1586 | ||
1665 | while (!list_empty(&serio->children)) { | 1587 | while (!list_empty(&serio->children)) { |
1666 | if (++retry > 3) { | 1588 | if (++retry > 3) { |
1667 | psmouse_warn(psmouse, | 1589 | printk(KERN_WARNING |
1668 | "failed to destroy children ports, protocol change aborted.\n"); | 1590 | "psmouse: failed to destroy children ports, " |
1591 | "protocol change aborted.\n"); | ||
1669 | input_free_device(new_dev); | 1592 | input_free_device(new_dev); |
1670 | return -EIO; | 1593 | return -EIO; |
1671 | } | 1594 | } |
@@ -1737,12 +1660,10 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1737 | 1660 | ||
1738 | static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count) | 1661 | static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count) |
1739 | { | 1662 | { |
1740 | unsigned int value; | 1663 | unsigned long value; |
1741 | int err; | ||
1742 | 1664 | ||
1743 | err = kstrtouint(buf, 10, &value); | 1665 | if (strict_strtoul(buf, 10, &value)) |
1744 | if (err) | 1666 | return -EINVAL; |
1745 | return err; | ||
1746 | 1667 | ||
1747 | psmouse->set_rate(psmouse, value); | 1668 | psmouse->set_rate(psmouse, value); |
1748 | return count; | 1669 | return count; |
@@ -1750,12 +1671,10 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const | |||
1750 | 1671 | ||
1751 | static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count) | 1672 | static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count) |
1752 | { | 1673 | { |
1753 | unsigned int value; | 1674 | unsigned long value; |
1754 | int err; | ||
1755 | 1675 | ||
1756 | err = kstrtouint(buf, 10, &value); | 1676 | if (strict_strtoul(buf, 10, &value)) |
1757 | if (err) | 1677 | return -EINVAL; |
1758 | return err; | ||
1759 | 1678 | ||
1760 | psmouse->set_resolution(psmouse, value); | 1679 | psmouse->set_resolution(psmouse, value); |
1761 | return count; | 1680 | return count; |
@@ -1796,7 +1715,7 @@ static int __init psmouse_init(void) | |||
1796 | 1715 | ||
1797 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1716 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1798 | if (!kpsmoused_wq) { | 1717 | if (!kpsmoused_wq) { |
1799 | pr_err("failed to create kpsmoused workqueue\n"); | 1718 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); |
1800 | return -ENOMEM; | 1719 | return -ENOMEM; |
1801 | } | 1720 | } |
1802 | 1721 | ||
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index fe1df231ba4..593e910bfc7 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -8,7 +8,6 @@ | |||
8 | #define PSMOUSE_CMD_SETSTREAM 0x00ea | 8 | #define PSMOUSE_CMD_SETSTREAM 0x00ea |
9 | #define PSMOUSE_CMD_SETPOLL 0x00f0 | 9 | #define PSMOUSE_CMD_SETPOLL 0x00f0 |
10 | #define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */ | 10 | #define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */ |
11 | #define PSMOUSE_CMD_RESET_WRAP 0x00ec | ||
12 | #define PSMOUSE_CMD_GETID 0x02f2 | 11 | #define PSMOUSE_CMD_GETID 0x02f2 |
13 | #define PSMOUSE_CMD_SETRATE 0x10f3 | 12 | #define PSMOUSE_CMD_SETRATE 0x10f3 |
14 | #define PSMOUSE_CMD_ENABLE 0x00f4 | 13 | #define PSMOUSE_CMD_ENABLE 0x00f4 |
@@ -94,7 +93,6 @@ enum psmouse_type { | |||
94 | PSMOUSE_HGPK, | 93 | PSMOUSE_HGPK, |
95 | PSMOUSE_ELANTECH, | 94 | PSMOUSE_ELANTECH, |
96 | PSMOUSE_FSP, | 95 | PSMOUSE_FSP, |
97 | PSMOUSE_SYNAPTICS_RELATIVE, | ||
98 | PSMOUSE_AUTO /* This one should always be last */ | 96 | PSMOUSE_AUTO /* This one should always be last */ |
99 | }; | 97 | }; |
100 | 98 | ||
@@ -104,9 +102,6 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); | |||
104 | int psmouse_reset(struct psmouse *psmouse); | 102 | int psmouse_reset(struct psmouse *psmouse); |
105 | void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state); | 103 | void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state); |
106 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); | 104 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); |
107 | psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse); | ||
108 | int psmouse_activate(struct psmouse *psmouse); | ||
109 | int psmouse_deactivate(struct psmouse *psmouse); | ||
110 | 105 | ||
111 | struct psmouse_attribute { | 106 | struct psmouse_attribute { |
112 | struct device_attribute dattr; | 107 | struct device_attribute dattr; |
@@ -155,29 +150,4 @@ static struct psmouse_attribute psmouse_attr_##_name = { \ | |||
155 | static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ | 150 | static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ |
156 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) | 151 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) |
157 | 152 | ||
158 | #ifndef psmouse_fmt | ||
159 | #define psmouse_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
160 | #endif | ||
161 | |||
162 | #define psmouse_dbg(psmouse, format, ...) \ | ||
163 | dev_dbg(&(psmouse)->ps2dev.serio->dev, \ | ||
164 | psmouse_fmt(format), ##__VA_ARGS__) | ||
165 | #define psmouse_info(psmouse, format, ...) \ | ||
166 | dev_info(&(psmouse)->ps2dev.serio->dev, \ | ||
167 | psmouse_fmt(format), ##__VA_ARGS__) | ||
168 | #define psmouse_warn(psmouse, format, ...) \ | ||
169 | dev_warn(&(psmouse)->ps2dev.serio->dev, \ | ||
170 | psmouse_fmt(format), ##__VA_ARGS__) | ||
171 | #define psmouse_err(psmouse, format, ...) \ | ||
172 | dev_err(&(psmouse)->ps2dev.serio->dev, \ | ||
173 | psmouse_fmt(format), ##__VA_ARGS__) | ||
174 | #define psmouse_notice(psmouse, format, ...) \ | ||
175 | dev_notice(&(psmouse)->ps2dev.serio->dev, \ | ||
176 | psmouse_fmt(format), ##__VA_ARGS__) | ||
177 | #define psmouse_printk(level, psmouse, format, ...) \ | ||
178 | dev_printk(level, \ | ||
179 | &(psmouse)->ps2dev.serio->dev, \ | ||
180 | psmouse_fmt(format), ##__VA_ARGS__) | ||
181 | |||
182 | |||
183 | #endif /* _PSMOUSE_H */ | 153 | #endif /* _PSMOUSE_H */ |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 0ecb9e7945e..6c5d84fcdea 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | 21 | ||
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <linux/platform_data/mouse-pxa930_trkball.h> | 23 | #include <mach/pxa930_trkball.h> |
24 | 24 | ||
25 | /* Trackball Controller Register Definitions */ | 25 | /* Trackball Controller Register Definitions */ |
26 | #define TBCR (0x000C) | 26 | #define TBCR (0x000C) |
@@ -143,7 +143,7 @@ static void pxa930_trkball_close(struct input_dev *dev) | |||
143 | pxa930_trkball_disable(trkball); | 143 | pxa930_trkball_disable(trkball); |
144 | } | 144 | } |
145 | 145 | ||
146 | static int pxa930_trkball_probe(struct platform_device *pdev) | 146 | static int __devinit pxa930_trkball_probe(struct platform_device *pdev) |
147 | { | 147 | { |
148 | struct pxa930_trkball *trkball; | 148 | struct pxa930_trkball *trkball; |
149 | struct input_dev *input; | 149 | struct input_dev *input; |
@@ -183,7 +183,7 @@ static int pxa930_trkball_probe(struct platform_device *pdev) | |||
183 | /* held the module in reset, will be enabled in open() */ | 183 | /* held the module in reset, will be enabled in open() */ |
184 | pxa930_trkball_disable(trkball); | 184 | pxa930_trkball_disable(trkball); |
185 | 185 | ||
186 | error = request_irq(irq, pxa930_trkball_interrupt, 0, | 186 | error = request_irq(irq, pxa930_trkball_interrupt, IRQF_DISABLED, |
187 | pdev->name, trkball); | 187 | pdev->name, trkball); |
188 | if (error) { | 188 | if (error) { |
189 | dev_err(&pdev->dev, "failed to request irq: %d\n", error); | 189 | dev_err(&pdev->dev, "failed to request irq: %d\n", error); |
@@ -230,7 +230,7 @@ failed: | |||
230 | return error; | 230 | return error; |
231 | } | 231 | } |
232 | 232 | ||
233 | static int pxa930_trkball_remove(struct platform_device *pdev) | 233 | static int __devexit pxa930_trkball_remove(struct platform_device *pdev) |
234 | { | 234 | { |
235 | struct pxa930_trkball *trkball = platform_get_drvdata(pdev); | 235 | struct pxa930_trkball *trkball = platform_get_drvdata(pdev); |
236 | int irq = platform_get_irq(pdev, 0); | 236 | int irq = platform_get_irq(pdev, 0); |
@@ -248,9 +248,21 @@ static struct platform_driver pxa930_trkball_driver = { | |||
248 | .name = "pxa930-trkball", | 248 | .name = "pxa930-trkball", |
249 | }, | 249 | }, |
250 | .probe = pxa930_trkball_probe, | 250 | .probe = pxa930_trkball_probe, |
251 | .remove = pxa930_trkball_remove, | 251 | .remove = __devexit_p(pxa930_trkball_remove), |
252 | }; | 252 | }; |
253 | module_platform_driver(pxa930_trkball_driver); | 253 | |
254 | static int __init pxa930_trkball_init(void) | ||
255 | { | ||
256 | return platform_driver_register(&pxa930_trkball_driver); | ||
257 | } | ||
258 | |||
259 | static void __exit pxa930_trkball_exit(void) | ||
260 | { | ||
261 | platform_driver_unregister(&pxa930_trkball_driver); | ||
262 | } | ||
263 | |||
264 | module_init(pxa930_trkball_init); | ||
265 | module_exit(pxa930_trkball_exit); | ||
254 | 266 | ||
255 | MODULE_AUTHOR("Yong Yao <yaoyong@marvell.com>"); | 267 | MODULE_AUTHOR("Yong Yao <yaoyong@marvell.com>"); |
256 | MODULE_DESCRIPTION("PXA930 Trackball Mouse Driver"); | 268 | MODULE_DESCRIPTION("PXA930 Trackball Mouse Driver"); |
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 21c60fea5d3..272deddc8db 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c | |||
@@ -42,7 +42,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) | |||
42 | 42 | ||
43 | x = (short) iomd_readl(IOMD_MOUSEX); | 43 | x = (short) iomd_readl(IOMD_MOUSEX); |
44 | y = (short) iomd_readl(IOMD_MOUSEY); | 44 | y = (short) iomd_readl(IOMD_MOUSEY); |
45 | b = (short) (__raw_readl(IOMEM(0xe0310000)) ^ 0x70); | 45 | b = (short) (__raw_readl(0xe0310000) ^ 0x70); |
46 | 46 | ||
47 | dx = x - rpcmouse_lastx; | 47 | dx = x - rpcmouse_lastx; |
48 | dy = y - rpcmouse_lasty; | 48 | dy = y - rpcmouse_lasty; |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index cc7e0d4a8f9..2fc887a5106 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Finger Sensing Pad PS/2 mouse driver. | 2 | * Finger Sensing Pad PS/2 mouse driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. |
5 | * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation. | 5 | * Copyright (C) 2005-2010 Tai-hwa Liang, Sentelic Corporation. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/input/mt.h> | ||
25 | #include <linux/ctype.h> | 24 | #include <linux/ctype.h> |
26 | #include <linux/libps2.h> | 25 | #include <linux/libps2.h> |
27 | #include <linux/serio.h> | 26 | #include <linux/serio.h> |
@@ -37,11 +36,8 @@ | |||
37 | #define FSP_CMD_TIMEOUT 200 | 36 | #define FSP_CMD_TIMEOUT 200 |
38 | #define FSP_CMD_TIMEOUT2 30 | 37 | #define FSP_CMD_TIMEOUT2 30 |
39 | 38 | ||
40 | #define GET_ABS_X(packet) ((packet[1] << 2) | ((packet[3] >> 2) & 0x03)) | ||
41 | #define GET_ABS_Y(packet) ((packet[2] << 2) | (packet[3] & 0x03)) | ||
42 | |||
43 | /** Driver version. */ | 39 | /** Driver version. */ |
44 | static const char fsp_drv_ver[] = "1.1.0-K"; | 40 | static const char fsp_drv_ver[] = "1.0.0-K"; |
45 | 41 | ||
46 | /* | 42 | /* |
47 | * Make sure that the value being sent to FSP will not conflict with | 43 | * Make sure that the value being sent to FSP will not conflict with |
@@ -94,7 +90,8 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) | |||
94 | * to do that for writes because sysfs set helper does this for | 90 | * to do that for writes because sysfs set helper does this for |
95 | * us. | 91 | * us. |
96 | */ | 92 | */ |
97 | psmouse_deactivate(psmouse); | 93 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); |
94 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
98 | 95 | ||
99 | ps2_begin_command(ps2dev); | 96 | ps2_begin_command(ps2dev); |
100 | 97 | ||
@@ -131,10 +128,10 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) | |||
131 | 128 | ||
132 | out: | 129 | out: |
133 | ps2_end_command(ps2dev); | 130 | ps2_end_command(ps2dev); |
134 | psmouse_activate(psmouse); | 131 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
135 | psmouse_dbg(psmouse, | 132 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
136 | "READ REG: 0x%02x is 0x%02x (rc = %d)\n", | 133 | dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", |
137 | reg_addr, *reg_val, rc); | 134 | reg_addr, *reg_val, rc); |
138 | return rc; | 135 | return rc; |
139 | } | 136 | } |
140 | 137 | ||
@@ -165,7 +162,7 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) | |||
165 | ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); | 162 | ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); |
166 | 163 | ||
167 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | 164 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) |
168 | goto out; | 165 | return -1; |
169 | 166 | ||
170 | if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { | 167 | if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { |
171 | /* inversion is required */ | 168 | /* inversion is required */ |
@@ -184,9 +181,8 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) | |||
184 | 181 | ||
185 | out: | 182 | out: |
186 | ps2_end_command(ps2dev); | 183 | ps2_end_command(ps2dev); |
187 | psmouse_dbg(psmouse, | 184 | dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", |
188 | "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", | 185 | reg_addr, reg_val, rc); |
189 | reg_addr, reg_val, rc); | ||
190 | return rc; | 186 | return rc; |
191 | } | 187 | } |
192 | 188 | ||
@@ -217,7 +213,8 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) | |||
217 | unsigned char param[3]; | 213 | unsigned char param[3]; |
218 | int rc = -1; | 214 | int rc = -1; |
219 | 215 | ||
220 | psmouse_deactivate(psmouse); | 216 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); |
217 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
221 | 218 | ||
222 | ps2_begin_command(ps2dev); | 219 | ps2_begin_command(ps2dev); |
223 | 220 | ||
@@ -242,10 +239,10 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) | |||
242 | 239 | ||
243 | out: | 240 | out: |
244 | ps2_end_command(ps2dev); | 241 | ps2_end_command(ps2dev); |
245 | psmouse_activate(psmouse); | 242 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
246 | psmouse_dbg(psmouse, | 243 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
247 | "READ PAGE REG: 0x%02x (rc = %d)\n", | 244 | dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", |
248 | *reg_val, rc); | 245 | *reg_val, rc); |
249 | return rc; | 246 | return rc; |
250 | } | 247 | } |
251 | 248 | ||
@@ -264,7 +261,7 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) | |||
264 | ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); | 261 | ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); |
265 | 262 | ||
266 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | 263 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) |
267 | goto out; | 264 | return -1; |
268 | 265 | ||
269 | if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { | 266 | if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { |
270 | ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); | 267 | ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); |
@@ -281,9 +278,8 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) | |||
281 | 278 | ||
282 | out: | 279 | out: |
283 | ps2_end_command(ps2dev); | 280 | ps2_end_command(ps2dev); |
284 | psmouse_dbg(psmouse, | 281 | dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", |
285 | "WRITE PAGE REG: to 0x%02x (rc = %d)\n", | 282 | reg_val, rc); |
286 | reg_val, rc); | ||
287 | return rc; | 283 | return rc; |
288 | } | 284 | } |
289 | 285 | ||
@@ -303,27 +299,6 @@ static int fsp_get_revision(struct psmouse *psmouse, int *rev) | |||
303 | return 0; | 299 | return 0; |
304 | } | 300 | } |
305 | 301 | ||
306 | static int fsp_get_sn(struct psmouse *psmouse, int *sn) | ||
307 | { | ||
308 | int v0, v1, v2; | ||
309 | int rc = -EIO; | ||
310 | |||
311 | /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */ | ||
312 | if (fsp_page_reg_write(psmouse, FSP_PAGE_0B)) | ||
313 | goto out; | ||
314 | if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0)) | ||
315 | goto out; | ||
316 | if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1)) | ||
317 | goto out; | ||
318 | if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2)) | ||
319 | goto out; | ||
320 | *sn = (v0 << 16) | (v1 << 8) | v2; | ||
321 | rc = 0; | ||
322 | out: | ||
323 | fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT); | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | static int fsp_get_buttons(struct psmouse *psmouse, int *btn) | 302 | static int fsp_get_buttons(struct psmouse *psmouse, int *btn) |
328 | { | 303 | { |
329 | static const int buttons[] = { | 304 | static const int buttons[] = { |
@@ -334,7 +309,7 @@ static int fsp_get_buttons(struct psmouse *psmouse, int *btn) | |||
334 | }; | 309 | }; |
335 | int val; | 310 | int val; |
336 | 311 | ||
337 | if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1) | 312 | if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &val) == -1) |
338 | return -EIO; | 313 | return -EIO; |
339 | 314 | ||
340 | *btn = buttons[(val & 0x30) >> 4]; | 315 | *btn = buttons[(val & 0x30) >> 4]; |
@@ -348,7 +323,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable) | |||
348 | int res = 0; | 323 | int res = 0; |
349 | 324 | ||
350 | if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { | 325 | if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { |
351 | psmouse_err(psmouse, "Unable get OPC state.\n"); | 326 | dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n"); |
352 | return -EIO; | 327 | return -EIO; |
353 | } | 328 | } |
354 | 329 | ||
@@ -365,7 +340,8 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable) | |||
365 | } | 340 | } |
366 | 341 | ||
367 | if (res != 0) { | 342 | if (res != 0) { |
368 | psmouse_err(psmouse, "Unable to enable OPC tag.\n"); | 343 | dev_err(&psmouse->ps2dev.serio->dev, |
344 | "Unable to enable OPC tag.\n"); | ||
369 | res = -EIO; | 345 | res = -EIO; |
370 | } | 346 | } |
371 | 347 | ||
@@ -432,7 +408,7 @@ static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable) | |||
432 | static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, | 408 | static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, |
433 | const char *buf, size_t count) | 409 | const char *buf, size_t count) |
434 | { | 410 | { |
435 | int reg, val; | 411 | unsigned long reg, val; |
436 | char *rest; | 412 | char *rest; |
437 | ssize_t retval; | 413 | ssize_t retval; |
438 | 414 | ||
@@ -440,11 +416,7 @@ static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, | |||
440 | if (rest == buf || *rest != ' ' || reg > 0xff) | 416 | if (rest == buf || *rest != ' ' || reg > 0xff) |
441 | return -EINVAL; | 417 | return -EINVAL; |
442 | 418 | ||
443 | retval = kstrtoint(rest + 1, 16, &val); | 419 | if (strict_strtoul(rest + 1, 16, &val) || val > 0xff) |
444 | if (retval) | ||
445 | return retval; | ||
446 | |||
447 | if (val > 0xff) | ||
448 | return -EINVAL; | 420 | return -EINVAL; |
449 | 421 | ||
450 | if (fsp_reg_write_enable(psmouse, true)) | 422 | if (fsp_reg_write_enable(psmouse, true)) |
@@ -476,13 +448,10 @@ static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data, | |||
476 | const char *buf, size_t count) | 448 | const char *buf, size_t count) |
477 | { | 449 | { |
478 | struct fsp_data *pad = psmouse->private; | 450 | struct fsp_data *pad = psmouse->private; |
479 | int reg, val, err; | 451 | unsigned long reg; |
480 | 452 | int val; | |
481 | err = kstrtoint(buf, 16, ®); | ||
482 | if (err) | ||
483 | return err; | ||
484 | 453 | ||
485 | if (reg > 0xff) | 454 | if (strict_strtoul(buf, 16, ®) || reg > 0xff) |
486 | return -EINVAL; | 455 | return -EINVAL; |
487 | 456 | ||
488 | if (fsp_reg_read(psmouse, reg, &val)) | 457 | if (fsp_reg_read(psmouse, reg, &val)) |
@@ -511,13 +480,9 @@ static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse, | |||
511 | static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, | 480 | static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, |
512 | const char *buf, size_t count) | 481 | const char *buf, size_t count) |
513 | { | 482 | { |
514 | int val, err; | 483 | unsigned long val; |
515 | |||
516 | err = kstrtoint(buf, 16, &val); | ||
517 | if (err) | ||
518 | return err; | ||
519 | 484 | ||
520 | if (val > 0xff) | 485 | if (strict_strtoul(buf, 16, &val) || val > 0xff) |
521 | return -EINVAL; | 486 | return -EINVAL; |
522 | 487 | ||
523 | if (fsp_page_reg_write(psmouse, val)) | 488 | if (fsp_page_reg_write(psmouse, val)) |
@@ -540,14 +505,9 @@ static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse, | |||
540 | static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, | 505 | static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, |
541 | const char *buf, size_t count) | 506 | const char *buf, size_t count) |
542 | { | 507 | { |
543 | unsigned int val; | 508 | unsigned long val; |
544 | int err; | ||
545 | 509 | ||
546 | err = kstrtouint(buf, 10, &val); | 510 | if (strict_strtoul(buf, 10, &val) || val > 1) |
547 | if (err) | ||
548 | return err; | ||
549 | |||
550 | if (val > 1) | ||
551 | return -EINVAL; | 511 | return -EINVAL; |
552 | 512 | ||
553 | fsp_onpad_vscr(psmouse, val); | 513 | fsp_onpad_vscr(psmouse, val); |
@@ -569,14 +529,9 @@ static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse, | |||
569 | static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, | 529 | static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, |
570 | const char *buf, size_t count) | 530 | const char *buf, size_t count) |
571 | { | 531 | { |
572 | unsigned int val; | 532 | unsigned long val; |
573 | int err; | ||
574 | |||
575 | err = kstrtouint(buf, 10, &val); | ||
576 | if (err) | ||
577 | return err; | ||
578 | 533 | ||
579 | if (val > 1) | 534 | if (strict_strtoul(buf, 10, &val) || val > 1) |
580 | return -EINVAL; | 535 | return -EINVAL; |
581 | 536 | ||
582 | fsp_onpad_hscr(psmouse, val); | 537 | fsp_onpad_hscr(psmouse, val); |
@@ -643,71 +598,36 @@ static struct attribute_group fsp_attribute_group = { | |||
643 | .attrs = fsp_attributes, | 598 | .attrs = fsp_attributes, |
644 | }; | 599 | }; |
645 | 600 | ||
646 | #ifdef FSP_DEBUG | 601 | #ifdef FSP_DEBUG |
647 | static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[]) | 602 | static void fsp_packet_debug(unsigned char packet[]) |
648 | { | 603 | { |
649 | static unsigned int ps2_packet_cnt; | 604 | static unsigned int ps2_packet_cnt; |
650 | static unsigned int ps2_last_second; | 605 | static unsigned int ps2_last_second; |
651 | unsigned int jiffies_msec; | 606 | unsigned int jiffies_msec; |
652 | const char *packet_type = "UNKNOWN"; | ||
653 | unsigned short abs_x = 0, abs_y = 0; | ||
654 | |||
655 | /* Interpret & dump the packet data. */ | ||
656 | switch (packet[0] >> FSP_PKT_TYPE_SHIFT) { | ||
657 | case FSP_PKT_TYPE_ABS: | ||
658 | packet_type = "Absolute"; | ||
659 | abs_x = GET_ABS_X(packet); | ||
660 | abs_y = GET_ABS_Y(packet); | ||
661 | break; | ||
662 | case FSP_PKT_TYPE_NORMAL: | ||
663 | packet_type = "Normal"; | ||
664 | break; | ||
665 | case FSP_PKT_TYPE_NOTIFY: | ||
666 | packet_type = "Notify"; | ||
667 | break; | ||
668 | case FSP_PKT_TYPE_NORMAL_OPC: | ||
669 | packet_type = "Normal-OPC"; | ||
670 | break; | ||
671 | } | ||
672 | 607 | ||
673 | ps2_packet_cnt++; | 608 | ps2_packet_cnt++; |
674 | jiffies_msec = jiffies_to_msecs(jiffies); | 609 | jiffies_msec = jiffies_to_msecs(jiffies); |
675 | psmouse_dbg(psmouse, | 610 | printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", |
676 | "%08dms %s packets: %02x, %02x, %02x, %02x; " | 611 | jiffies_msec, packet[0], packet[1], packet[2], packet[3]); |
677 | "abs_x: %d, abs_y: %d\n", | ||
678 | jiffies_msec, packet_type, | ||
679 | packet[0], packet[1], packet[2], packet[3], abs_x, abs_y); | ||
680 | 612 | ||
681 | if (jiffies_msec - ps2_last_second > 1000) { | 613 | if (jiffies_msec - ps2_last_second > 1000) { |
682 | psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt); | 614 | printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt); |
683 | ps2_packet_cnt = 0; | 615 | ps2_packet_cnt = 0; |
684 | ps2_last_second = jiffies_msec; | 616 | ps2_last_second = jiffies_msec; |
685 | } | 617 | } |
686 | } | 618 | } |
687 | #else | 619 | #else |
688 | static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[]) | 620 | static void fsp_packet_debug(unsigned char packet[]) |
689 | { | 621 | { |
690 | } | 622 | } |
691 | #endif | 623 | #endif |
692 | 624 | ||
693 | static void fsp_set_slot(struct input_dev *dev, int slot, bool active, | ||
694 | unsigned int x, unsigned int y) | ||
695 | { | ||
696 | input_mt_slot(dev, slot); | ||
697 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | ||
698 | if (active) { | ||
699 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
700 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | 625 | static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) |
705 | { | 626 | { |
706 | struct input_dev *dev = psmouse->dev; | 627 | struct input_dev *dev = psmouse->dev; |
707 | struct fsp_data *ad = psmouse->private; | 628 | struct fsp_data *ad = psmouse->private; |
708 | unsigned char *packet = psmouse->packet; | 629 | unsigned char *packet = psmouse->packet; |
709 | unsigned char button_status = 0, lscroll = 0, rscroll = 0; | 630 | unsigned char button_status = 0, lscroll = 0, rscroll = 0; |
710 | unsigned short abs_x, abs_y, fgrs = 0; | ||
711 | int rel_x, rel_y; | 631 | int rel_x, rel_y; |
712 | 632 | ||
713 | if (psmouse->pktcnt < 4) | 633 | if (psmouse->pktcnt < 4) |
@@ -717,95 +637,16 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
717 | * Full packet accumulated, process it | 637 | * Full packet accumulated, process it |
718 | */ | 638 | */ |
719 | 639 | ||
720 | fsp_packet_debug(psmouse, packet); | ||
721 | |||
722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { | 640 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { |
723 | case FSP_PKT_TYPE_ABS: | 641 | case FSP_PKT_TYPE_ABS: |
724 | 642 | dev_warn(&psmouse->ps2dev.serio->dev, | |
725 | if ((packet[0] == 0x48 || packet[0] == 0x49) && | 643 | "Unexpected absolute mode packet, ignored.\n"); |
726 | packet[1] == 0 && packet[2] == 0) { | ||
727 | /* | ||
728 | * Ignore coordinate noise when finger leaving the | ||
729 | * surface, otherwise cursor may jump to upper-left | ||
730 | * corner. | ||
731 | */ | ||
732 | packet[3] &= 0xf0; | ||
733 | } | ||
734 | |||
735 | abs_x = GET_ABS_X(packet); | ||
736 | abs_y = GET_ABS_Y(packet); | ||
737 | |||
738 | if (packet[0] & FSP_PB0_MFMC) { | ||
739 | /* | ||
740 | * MFMC packet: assume that there are two fingers on | ||
741 | * pad | ||
742 | */ | ||
743 | fgrs = 2; | ||
744 | |||
745 | /* MFMC packet */ | ||
746 | if (packet[0] & FSP_PB0_MFMC_FGR2) { | ||
747 | /* 2nd finger */ | ||
748 | if (ad->last_mt_fgr == 2) { | ||
749 | /* | ||
750 | * workaround for buggy firmware | ||
751 | * which doesn't clear MFMC bit if | ||
752 | * the 1st finger is up | ||
753 | */ | ||
754 | fgrs = 1; | ||
755 | fsp_set_slot(dev, 0, false, 0, 0); | ||
756 | } | ||
757 | ad->last_mt_fgr = 2; | ||
758 | |||
759 | fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y); | ||
760 | } else { | ||
761 | /* 1st finger */ | ||
762 | if (ad->last_mt_fgr == 1) { | ||
763 | /* | ||
764 | * workaround for buggy firmware | ||
765 | * which doesn't clear MFMC bit if | ||
766 | * the 2nd finger is up | ||
767 | */ | ||
768 | fgrs = 1; | ||
769 | fsp_set_slot(dev, 1, false, 0, 0); | ||
770 | } | ||
771 | ad->last_mt_fgr = 1; | ||
772 | fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y); | ||
773 | } | ||
774 | } else { | ||
775 | /* SFAC packet */ | ||
776 | if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) == | ||
777 | FSP_PB0_LBTN) { | ||
778 | /* On-pad click in SFAC mode should be handled | ||
779 | * by userspace. On-pad clicks in MFMC mode | ||
780 | * are real clickpad clicks, and not ignored. | ||
781 | */ | ||
782 | packet[0] &= ~FSP_PB0_LBTN; | ||
783 | } | ||
784 | |||
785 | /* no multi-finger information */ | ||
786 | ad->last_mt_fgr = 0; | ||
787 | |||
788 | if (abs_x != 0 && abs_y != 0) | ||
789 | fgrs = 1; | ||
790 | |||
791 | fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y); | ||
792 | fsp_set_slot(dev, 1, false, 0, 0); | ||
793 | } | ||
794 | if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) { | ||
795 | input_report_abs(dev, ABS_X, abs_x); | ||
796 | input_report_abs(dev, ABS_Y, abs_y); | ||
797 | } | ||
798 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
799 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
800 | input_report_key(dev, BTN_TOUCH, fgrs); | ||
801 | input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1); | ||
802 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2); | ||
803 | break; | 644 | break; |
804 | 645 | ||
805 | case FSP_PKT_TYPE_NORMAL_OPC: | 646 | case FSP_PKT_TYPE_NORMAL_OPC: |
806 | /* on-pad click, filter it if necessary */ | 647 | /* on-pad click, filter it if necessary */ |
807 | if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) | 648 | if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) |
808 | packet[0] &= ~FSP_PB0_LBTN; | 649 | packet[0] &= ~BIT(0); |
809 | /* fall through */ | 650 | /* fall through */ |
810 | 651 | ||
811 | case FSP_PKT_TYPE_NORMAL: | 652 | case FSP_PKT_TYPE_NORMAL: |
@@ -852,6 +693,8 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
852 | 693 | ||
853 | input_sync(dev); | 694 | input_sync(dev); |
854 | 695 | ||
696 | fsp_packet_debug(packet); | ||
697 | |||
855 | return PSMOUSE_FULL_PACKET; | 698 | return PSMOUSE_FULL_PACKET; |
856 | } | 699 | } |
857 | 700 | ||
@@ -875,106 +718,42 @@ static int fsp_activate_protocol(struct psmouse *psmouse) | |||
875 | 718 | ||
876 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); | 719 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); |
877 | if (param[0] != 0x04) { | 720 | if (param[0] != 0x04) { |
878 | psmouse_err(psmouse, | 721 | dev_err(&psmouse->ps2dev.serio->dev, |
879 | "Unable to enable 4 bytes packet format.\n"); | 722 | "Unable to enable 4 bytes packet format.\n"); |
880 | return -EIO; | 723 | return -EIO; |
881 | } | 724 | } |
882 | 725 | ||
883 | if (pad->ver < FSP_VER_STL3888_C0) { | 726 | if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { |
884 | /* Preparing relative coordinates output for older hardware */ | 727 | dev_err(&psmouse->ps2dev.serio->dev, |
885 | if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { | 728 | "Unable to read SYSCTL5 register.\n"); |
886 | psmouse_err(psmouse, | 729 | return -EIO; |
887 | "Unable to read SYSCTL5 register.\n"); | 730 | } |
888 | return -EIO; | ||
889 | } | ||
890 | |||
891 | if (fsp_get_buttons(psmouse, &pad->buttons)) { | ||
892 | psmouse_err(psmouse, | ||
893 | "Unable to retrieve number of buttons.\n"); | ||
894 | return -EIO; | ||
895 | } | ||
896 | |||
897 | val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); | ||
898 | /* Ensure we are not in absolute mode */ | ||
899 | val &= ~FSP_BIT_EN_PKT_G0; | ||
900 | if (pad->buttons == 0x06) { | ||
901 | /* Left/Middle/Right & Scroll Up/Down/Right/Left */ | ||
902 | val |= FSP_BIT_EN_MSID6; | ||
903 | } | ||
904 | |||
905 | if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { | ||
906 | psmouse_err(psmouse, | ||
907 | "Unable to set up required mode bits.\n"); | ||
908 | return -EIO; | ||
909 | } | ||
910 | 731 | ||
911 | /* | 732 | val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); |
912 | * Enable OPC tags such that driver can tell the difference | 733 | /* Ensure we are not in absolute mode */ |
913 | * between on-pad and real button click | 734 | val &= ~FSP_BIT_EN_PKT_G0; |
914 | */ | 735 | if (pad->buttons == 0x06) { |
915 | if (fsp_opc_tag_enable(psmouse, true)) | 736 | /* Left/Middle/Right & Scroll Up/Down/Right/Left */ |
916 | psmouse_warn(psmouse, | 737 | val |= FSP_BIT_EN_MSID6; |
917 | "Failed to enable OPC tag mode.\n"); | ||
918 | /* enable on-pad click by default */ | ||
919 | pad->flags |= FSPDRV_FLAG_EN_OPC; | ||
920 | |||
921 | /* Enable on-pad vertical and horizontal scrolling */ | ||
922 | fsp_onpad_vscr(psmouse, true); | ||
923 | fsp_onpad_hscr(psmouse, true); | ||
924 | } else { | ||
925 | /* Enable absolute coordinates output for Cx/Dx hardware */ | ||
926 | if (fsp_reg_write(psmouse, FSP_REG_SWC1, | ||
927 | FSP_BIT_SWC1_EN_ABS_1F | | ||
928 | FSP_BIT_SWC1_EN_ABS_2F | | ||
929 | FSP_BIT_SWC1_EN_FUP_OUT | | ||
930 | FSP_BIT_SWC1_EN_ABS_CON)) { | ||
931 | psmouse_err(psmouse, | ||
932 | "Unable to enable absolute coordinates output.\n"); | ||
933 | return -EIO; | ||
934 | } | ||
935 | } | 738 | } |
936 | 739 | ||
937 | return 0; | 740 | if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { |
938 | } | 741 | dev_err(&psmouse->ps2dev.serio->dev, |
742 | "Unable to set up required mode bits.\n"); | ||
743 | return -EIO; | ||
744 | } | ||
939 | 745 | ||
940 | static int fsp_set_input_params(struct psmouse *psmouse) | 746 | /* |
941 | { | 747 | * Enable OPC tags such that driver can tell the difference between |
942 | struct input_dev *dev = psmouse->dev; | 748 | * on-pad and real button click |
943 | struct fsp_data *pad = psmouse->private; | 749 | */ |
750 | if (fsp_opc_tag_enable(psmouse, true)) | ||
751 | dev_warn(&psmouse->ps2dev.serio->dev, | ||
752 | "Failed to enable OPC tag mode.\n"); | ||
944 | 753 | ||
945 | if (pad->ver < FSP_VER_STL3888_C0) { | 754 | /* Enable on-pad vertical and horizontal scrolling */ |
946 | __set_bit(BTN_MIDDLE, dev->keybit); | 755 | fsp_onpad_vscr(psmouse, true); |
947 | __set_bit(BTN_BACK, dev->keybit); | 756 | fsp_onpad_hscr(psmouse, true); |
948 | __set_bit(BTN_FORWARD, dev->keybit); | ||
949 | __set_bit(REL_WHEEL, dev->relbit); | ||
950 | __set_bit(REL_HWHEEL, dev->relbit); | ||
951 | } else { | ||
952 | /* | ||
953 | * Hardware prior to Cx performs much better in relative mode; | ||
954 | * hence, only enable absolute coordinates output as well as | ||
955 | * multi-touch output for the newer hardware. | ||
956 | * | ||
957 | * Maximum coordinates can be computed as: | ||
958 | * | ||
959 | * number of scanlines * 64 - 57 | ||
960 | * | ||
961 | * where number of X/Y scanline lines are 16/12. | ||
962 | */ | ||
963 | int abs_x = 967, abs_y = 711; | ||
964 | |||
965 | __set_bit(EV_ABS, dev->evbit); | ||
966 | __clear_bit(EV_REL, dev->evbit); | ||
967 | __set_bit(BTN_TOUCH, dev->keybit); | ||
968 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
969 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); | ||
970 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
971 | |||
972 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); | ||
973 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); | ||
974 | input_mt_init_slots(dev, 2, 0); | ||
975 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); | ||
976 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); | ||
977 | } | ||
978 | 757 | ||
979 | return 0; | 758 | return 0; |
980 | } | 759 | } |
@@ -1032,21 +811,18 @@ static int fsp_reconnect(struct psmouse *psmouse) | |||
1032 | int fsp_init(struct psmouse *psmouse) | 811 | int fsp_init(struct psmouse *psmouse) |
1033 | { | 812 | { |
1034 | struct fsp_data *priv; | 813 | struct fsp_data *priv; |
1035 | int ver, rev, sn = 0; | 814 | int ver, rev, buttons; |
1036 | int error; | 815 | int error; |
1037 | 816 | ||
1038 | if (fsp_get_version(psmouse, &ver) || | 817 | if (fsp_get_version(psmouse, &ver) || |
1039 | fsp_get_revision(psmouse, &rev)) { | 818 | fsp_get_revision(psmouse, &rev) || |
819 | fsp_get_buttons(psmouse, &buttons)) { | ||
1040 | return -ENODEV; | 820 | return -ENODEV; |
1041 | } | 821 | } |
1042 | if (ver >= FSP_VER_STL3888_C0) { | ||
1043 | /* firmware information is only available since C0 */ | ||
1044 | fsp_get_sn(psmouse, &sn); | ||
1045 | } | ||
1046 | 822 | ||
1047 | psmouse_info(psmouse, | 823 | printk(KERN_INFO |
1048 | "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n", | 824 | "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", |
1049 | ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver); | 825 | ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); |
1050 | 826 | ||
1051 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); | 827 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); |
1052 | if (!priv) | 828 | if (!priv) |
@@ -1054,6 +830,17 @@ int fsp_init(struct psmouse *psmouse) | |||
1054 | 830 | ||
1055 | priv->ver = ver; | 831 | priv->ver = ver; |
1056 | priv->rev = rev; | 832 | priv->rev = rev; |
833 | priv->buttons = buttons; | ||
834 | |||
835 | /* enable on-pad click by default */ | ||
836 | priv->flags |= FSPDRV_FLAG_EN_OPC; | ||
837 | |||
838 | /* Set up various supported input event bits */ | ||
839 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
840 | __set_bit(BTN_BACK, psmouse->dev->keybit); | ||
841 | __set_bit(BTN_FORWARD, psmouse->dev->keybit); | ||
842 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | ||
843 | __set_bit(REL_HWHEEL, psmouse->dev->relbit); | ||
1057 | 844 | ||
1058 | psmouse->protocol_handler = fsp_process_byte; | 845 | psmouse->protocol_handler = fsp_process_byte; |
1059 | psmouse->disconnect = fsp_disconnect; | 846 | psmouse->disconnect = fsp_disconnect; |
@@ -1061,20 +848,16 @@ int fsp_init(struct psmouse *psmouse) | |||
1061 | psmouse->cleanup = fsp_reset; | 848 | psmouse->cleanup = fsp_reset; |
1062 | psmouse->pktsize = 4; | 849 | psmouse->pktsize = 4; |
1063 | 850 | ||
851 | /* set default packet output based on number of buttons we found */ | ||
1064 | error = fsp_activate_protocol(psmouse); | 852 | error = fsp_activate_protocol(psmouse); |
1065 | if (error) | 853 | if (error) |
1066 | goto err_out; | 854 | goto err_out; |
1067 | 855 | ||
1068 | /* Set up various supported input event bits */ | ||
1069 | error = fsp_set_input_params(psmouse); | ||
1070 | if (error) | ||
1071 | goto err_out; | ||
1072 | |||
1073 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, | 856 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, |
1074 | &fsp_attribute_group); | 857 | &fsp_attribute_group); |
1075 | if (error) { | 858 | if (error) { |
1076 | psmouse_err(psmouse, | 859 | dev_err(&psmouse->ps2dev.serio->dev, |
1077 | "Failed to create sysfs attributes (%d)", error); | 860 | "Failed to create sysfs attributes (%d)", error); |
1078 | goto err_out; | 861 | goto err_out; |
1079 | } | 862 | } |
1080 | 863 | ||
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h index aa697ece405..ed1395ac7b8 100644 --- a/drivers/input/mouse/sentelic.h +++ b/drivers/input/mouse/sentelic.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * Finger Sensing Pad PS/2 mouse driver. | 2 | * Finger Sensing Pad PS/2 mouse driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. |
5 | * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation. | 5 | * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -33,7 +33,6 @@ | |||
33 | /* Finger-sensing Pad control registers */ | 33 | /* Finger-sensing Pad control registers */ |
34 | #define FSP_REG_SYSCTL1 0x10 | 34 | #define FSP_REG_SYSCTL1 0x10 |
35 | #define FSP_BIT_EN_REG_CLK BIT(5) | 35 | #define FSP_BIT_EN_REG_CLK BIT(5) |
36 | #define FSP_REG_TMOD_STATUS 0x20 | ||
37 | #define FSP_REG_OPC_QDOWN 0x31 | 36 | #define FSP_REG_OPC_QDOWN 0x31 |
38 | #define FSP_BIT_EN_OPC_TAG BIT(7) | 37 | #define FSP_BIT_EN_OPC_TAG BIT(7) |
39 | #define FSP_REG_OPTZ_XLO 0x34 | 38 | #define FSP_REG_OPTZ_XLO 0x34 |
@@ -55,24 +54,6 @@ | |||
55 | #define FSP_BIT_FIX_HSCR BIT(5) | 54 | #define FSP_BIT_FIX_HSCR BIT(5) |
56 | #define FSP_BIT_DRAG_LOCK BIT(6) | 55 | #define FSP_BIT_DRAG_LOCK BIT(6) |
57 | 56 | ||
58 | #define FSP_REG_SWC1 (0x90) | ||
59 | #define FSP_BIT_SWC1_EN_ABS_1F BIT(0) | ||
60 | #define FSP_BIT_SWC1_EN_GID BIT(1) | ||
61 | #define FSP_BIT_SWC1_EN_ABS_2F BIT(2) | ||
62 | #define FSP_BIT_SWC1_EN_FUP_OUT BIT(3) | ||
63 | #define FSP_BIT_SWC1_EN_ABS_CON BIT(4) | ||
64 | #define FSP_BIT_SWC1_GST_GRP0 BIT(5) | ||
65 | #define FSP_BIT_SWC1_GST_GRP1 BIT(6) | ||
66 | #define FSP_BIT_SWC1_BX_COMPAT BIT(7) | ||
67 | |||
68 | #define FSP_PAGE_0B (0x0b) | ||
69 | #define FSP_PAGE_82 (0x82) | ||
70 | #define FSP_PAGE_DEFAULT FSP_PAGE_82 | ||
71 | |||
72 | #define FSP_REG_SN0 (0x40) | ||
73 | #define FSP_REG_SN1 (0x41) | ||
74 | #define FSP_REG_SN2 (0x42) | ||
75 | |||
76 | /* Finger-sensing Pad packet formating related definitions */ | 57 | /* Finger-sensing Pad packet formating related definitions */ |
77 | 58 | ||
78 | /* absolute packet type */ | 59 | /* absolute packet type */ |
@@ -82,32 +63,12 @@ | |||
82 | #define FSP_PKT_TYPE_NORMAL_OPC (0x03) | 63 | #define FSP_PKT_TYPE_NORMAL_OPC (0x03) |
83 | #define FSP_PKT_TYPE_SHIFT (6) | 64 | #define FSP_PKT_TYPE_SHIFT (6) |
84 | 65 | ||
85 | /* bit definitions for the first byte of report packet */ | ||
86 | #define FSP_PB0_LBTN BIT(0) | ||
87 | #define FSP_PB0_RBTN BIT(1) | ||
88 | #define FSP_PB0_MBTN BIT(2) | ||
89 | #define FSP_PB0_MFMC_FGR2 FSP_PB0_MBTN | ||
90 | #define FSP_PB0_MUST_SET BIT(3) | ||
91 | #define FSP_PB0_PHY_BTN BIT(4) | ||
92 | #define FSP_PB0_MFMC BIT(5) | ||
93 | |||
94 | /* hardware revisions */ | ||
95 | #define FSP_VER_STL3888_A4 (0xC1) | ||
96 | #define FSP_VER_STL3888_B0 (0xD0) | ||
97 | #define FSP_VER_STL3888_B1 (0xD1) | ||
98 | #define FSP_VER_STL3888_B2 (0xD2) | ||
99 | #define FSP_VER_STL3888_C0 (0xE0) | ||
100 | #define FSP_VER_STL3888_C1 (0xE1) | ||
101 | #define FSP_VER_STL3888_D0 (0xE2) | ||
102 | #define FSP_VER_STL3888_D1 (0xE3) | ||
103 | #define FSP_VER_STL3888_E0 (0xE4) | ||
104 | |||
105 | #ifdef __KERNEL__ | 66 | #ifdef __KERNEL__ |
106 | 67 | ||
107 | struct fsp_data { | 68 | struct fsp_data { |
108 | unsigned char ver; /* hardware version */ | 69 | unsigned char ver; /* hardware version */ |
109 | unsigned char rev; /* hardware revison */ | 70 | unsigned char rev; /* hardware revison */ |
110 | unsigned int buttons; /* Number of buttons */ | 71 | unsigned char buttons; /* Number of buttons */ |
111 | unsigned int flags; | 72 | unsigned int flags; |
112 | #define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */ | 73 | #define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */ |
113 | 74 | ||
@@ -116,7 +77,6 @@ struct fsp_data { | |||
116 | 77 | ||
117 | unsigned char last_reg; /* Last register we requested read from */ | 78 | unsigned char last_reg; /* Last register we requested read from */ |
118 | unsigned char last_val; | 79 | unsigned char last_val; |
119 | unsigned int last_mt_fgr; /* Last seen finger(multitouch) */ | ||
120 | }; | 80 | }; |
121 | 81 | ||
122 | #ifdef CONFIG_MOUSE_PS2_SENTELIC | 82 | #ifdef CONFIG_MOUSE_PS2_SENTELIC |
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index d5928fd0c91..17ff137b9bd 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -355,4 +355,15 @@ static struct serio_driver sermouse_drv = { | |||
355 | .disconnect = sermouse_disconnect, | 355 | .disconnect = sermouse_disconnect, |
356 | }; | 356 | }; |
357 | 357 | ||
358 | module_serio_driver(sermouse_drv); | 358 | static int __init sermouse_init(void) |
359 | { | ||
360 | return serio_register_driver(&sermouse_drv); | ||
361 | } | ||
362 | |||
363 | static void __exit sermouse_exit(void) | ||
364 | { | ||
365 | serio_unregister_driver(&sermouse_drv); | ||
366 | } | ||
367 | |||
368 | module_init(sermouse_init); | ||
369 | module_exit(sermouse_exit); | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 12d12ca3fee..76753637218 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -40,32 +40,11 @@ | |||
40 | * Note that newer firmware allows querying device for maximum useable | 40 | * Note that newer firmware allows querying device for maximum useable |
41 | * coordinates. | 41 | * coordinates. |
42 | */ | 42 | */ |
43 | #define XMIN 0 | ||
44 | #define XMAX 6143 | ||
45 | #define YMIN 0 | ||
46 | #define YMAX 6143 | ||
47 | #define XMIN_NOMINAL 1472 | 43 | #define XMIN_NOMINAL 1472 |
48 | #define XMAX_NOMINAL 5472 | 44 | #define XMAX_NOMINAL 5472 |
49 | #define YMIN_NOMINAL 1408 | 45 | #define YMIN_NOMINAL 1408 |
50 | #define YMAX_NOMINAL 4448 | 46 | #define YMAX_NOMINAL 4448 |
51 | 47 | ||
52 | /* Size in bits of absolute position values reported by the hardware */ | ||
53 | #define ABS_POS_BITS 13 | ||
54 | |||
55 | /* | ||
56 | * These values should represent the absolute maximum value that will | ||
57 | * be reported for a positive position value. Some Synaptics firmware | ||
58 | * uses this value to indicate a finger near the edge of the touchpad | ||
59 | * whose precise position cannot be determined. | ||
60 | * | ||
61 | * At least one touchpad is known to report positions in excess of this | ||
62 | * value which are actually negative values truncated to the 13-bit | ||
63 | * reporting range. These values have never been observed to be lower | ||
64 | * than 8184 (i.e. -8), so we treat all values greater than 8176 as | ||
65 | * negative and any other value as positive. | ||
66 | */ | ||
67 | #define X_MAX_POSITIVE 8176 | ||
68 | #define Y_MAX_POSITIVE 8176 | ||
69 | 48 | ||
70 | /***************************************************************************** | 49 | /***************************************************************************** |
71 | * Stuff we need even when we do not want native Synaptics support | 50 | * Stuff we need even when we do not want native Synaptics support |
@@ -123,16 +102,6 @@ void synaptics_reset(struct psmouse *psmouse) | |||
123 | ****************************************************************************/ | 102 | ****************************************************************************/ |
124 | 103 | ||
125 | /* | 104 | /* |
126 | * Synaptics touchpads report the y coordinate from bottom to top, which is | ||
127 | * opposite from what userspace expects. | ||
128 | * This function is used to invert y before reporting. | ||
129 | */ | ||
130 | static int synaptics_invert_y(int y) | ||
131 | { | ||
132 | return YMAX_NOMINAL + YMIN_NOMINAL - y; | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Send a command to the synpatics touchpad by special commands | 105 | * Send a command to the synpatics touchpad by special commands |
137 | */ | 106 | */ |
138 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) | 107 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) |
@@ -160,35 +129,6 @@ static int synaptics_model_id(struct psmouse *psmouse) | |||
160 | } | 129 | } |
161 | 130 | ||
162 | /* | 131 | /* |
163 | * Read the board id from the touchpad | ||
164 | * The board id is encoded in the "QUERY MODES" response | ||
165 | */ | ||
166 | static int synaptics_board_id(struct psmouse *psmouse) | ||
167 | { | ||
168 | struct synaptics_data *priv = psmouse->private; | ||
169 | unsigned char bid[3]; | ||
170 | |||
171 | if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) | ||
172 | return -1; | ||
173 | priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Read the firmware id from the touchpad | ||
179 | */ | ||
180 | static int synaptics_firmware_id(struct psmouse *psmouse) | ||
181 | { | ||
182 | struct synaptics_data *priv = psmouse->private; | ||
183 | unsigned char fwid[3]; | ||
184 | |||
185 | if (synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid)) | ||
186 | return -1; | ||
187 | priv->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2]; | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Read the capability-bits from the touchpad | 132 | * Read the capability-bits from the touchpad |
193 | * see also the SYN_CAP_* macros | 133 | * see also the SYN_CAP_* macros |
194 | */ | 134 | */ |
@@ -218,8 +158,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
218 | 158 | ||
219 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { | 159 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { |
220 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { | 160 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { |
221 | psmouse_warn(psmouse, | 161 | printk(KERN_ERR "Synaptics claims to have extended capabilities," |
222 | "device claims to have extended capabilities, but I'm not able to read them.\n"); | 162 | " but I'm not able to read them.\n"); |
223 | } else { | 163 | } else { |
224 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 164 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
225 | 165 | ||
@@ -234,8 +174,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
234 | 174 | ||
235 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { | 175 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { |
236 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { | 176 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { |
237 | psmouse_warn(psmouse, | 177 | printk(KERN_ERR "Synaptics claims to have extended capability 0x0c," |
238 | "device claims to have extended capability 0x0c, but I'm not able to read it.\n"); | 178 | " but I'm not able to read it.\n"); |
239 | } else { | 179 | } else { |
240 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 180 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
241 | } | 181 | } |
@@ -283,8 +223,8 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
283 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && | 223 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
284 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { | 224 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
285 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { | 225 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
286 | psmouse_warn(psmouse, | 226 | printk(KERN_ERR "Synaptics claims to have max coordinates" |
287 | "device claims to have max coordinates query, but I'm not able to read it.\n"); | 227 | " query, but I'm not able to read it.\n"); |
288 | } else { | 228 | } else { |
289 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | 229 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
290 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | 230 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
@@ -294,8 +234,8 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
294 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && | 234 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && |
295 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { | 235 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { |
296 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { | 236 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { |
297 | psmouse_warn(psmouse, | 237 | printk(KERN_ERR "Synaptics claims to have min coordinates" |
298 | "device claims to have min coordinates query, but I'm not able to read it.\n"); | 238 | " query, but I'm not able to read it.\n"); |
299 | } else { | 239 | } else { |
300 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | 240 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
301 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | 241 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
@@ -311,10 +251,6 @@ static int synaptics_query_hardware(struct psmouse *psmouse) | |||
311 | return -1; | 251 | return -1; |
312 | if (synaptics_model_id(psmouse)) | 252 | if (synaptics_model_id(psmouse)) |
313 | return -1; | 253 | return -1; |
314 | if (synaptics_firmware_id(psmouse)) | ||
315 | return -1; | ||
316 | if (synaptics_board_id(psmouse)) | ||
317 | return -1; | ||
318 | if (synaptics_capability(psmouse)) | 254 | if (synaptics_capability(psmouse)) |
319 | return -1; | 255 | return -1; |
320 | if (synaptics_resolution(psmouse)) | 256 | if (synaptics_resolution(psmouse)) |
@@ -323,50 +259,19 @@ static int synaptics_query_hardware(struct psmouse *psmouse) | |||
323 | return 0; | 259 | return 0; |
324 | } | 260 | } |
325 | 261 | ||
326 | static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) | 262 | static int synaptics_set_absolute_mode(struct psmouse *psmouse) |
327 | { | ||
328 | static unsigned char param = 0xc8; | ||
329 | struct synaptics_data *priv = psmouse->private; | ||
330 | |||
331 | if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || | ||
332 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))) | ||
333 | return 0; | ||
334 | |||
335 | if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) | ||
336 | return -1; | ||
337 | |||
338 | if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE)) | ||
339 | return -1; | ||
340 | |||
341 | /* Advanced gesture mode also sends multi finger data */ | ||
342 | priv->capabilities |= BIT(1); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static int synaptics_set_mode(struct psmouse *psmouse) | ||
348 | { | 263 | { |
349 | struct synaptics_data *priv = psmouse->private; | 264 | struct synaptics_data *priv = psmouse->private; |
350 | 265 | ||
351 | priv->mode = 0; | 266 | priv->mode = SYN_BIT_ABSOLUTE_MODE; |
352 | if (priv->absolute_mode) | 267 | if (SYN_ID_MAJOR(priv->identity) >= 4) |
353 | priv->mode |= SYN_BIT_ABSOLUTE_MODE; | ||
354 | if (priv->disable_gesture) | ||
355 | priv->mode |= SYN_BIT_DISABLE_GESTURE; | 268 | priv->mode |= SYN_BIT_DISABLE_GESTURE; |
356 | if (psmouse->rate >= 80) | ||
357 | priv->mode |= SYN_BIT_HIGH_RATE; | ||
358 | if (SYN_CAP_EXTENDED(priv->capabilities)) | 269 | if (SYN_CAP_EXTENDED(priv->capabilities)) |
359 | priv->mode |= SYN_BIT_W_MODE; | 270 | priv->mode |= SYN_BIT_W_MODE; |
360 | 271 | ||
361 | if (synaptics_mode_cmd(psmouse, priv->mode)) | 272 | if (synaptics_mode_cmd(psmouse, priv->mode)) |
362 | return -1; | 273 | return -1; |
363 | 274 | ||
364 | if (priv->absolute_mode && | ||
365 | synaptics_set_advanced_gesture_mode(psmouse)) { | ||
366 | psmouse_err(psmouse, "Advanced gesture mode init failed.\n"); | ||
367 | return -1; | ||
368 | } | ||
369 | |||
370 | return 0; | 275 | return 0; |
371 | } | 276 | } |
372 | 277 | ||
@@ -385,6 +290,25 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate) | |||
385 | synaptics_mode_cmd(psmouse, priv->mode); | 290 | synaptics_mode_cmd(psmouse, priv->mode); |
386 | } | 291 | } |
387 | 292 | ||
293 | static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) | ||
294 | { | ||
295 | static unsigned char param = 0xc8; | ||
296 | struct synaptics_data *priv = psmouse->private; | ||
297 | |||
298 | if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | ||
299 | return 0; | ||
300 | |||
301 | if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) | ||
302 | return -1; | ||
303 | if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE)) | ||
304 | return -1; | ||
305 | |||
306 | /* Advanced gesture mode also sends multi finger data */ | ||
307 | priv->capabilities |= BIT(1); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
388 | /***************************************************************************** | 312 | /***************************************************************************** |
389 | * Synaptics pass-through PS/2 port support | 313 | * Synaptics pass-through PS/2 port support |
390 | ****************************************************************************/ | 314 | ****************************************************************************/ |
@@ -454,8 +378,7 @@ static void synaptics_pt_activate(struct psmouse *psmouse) | |||
454 | priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; | 378 | priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; |
455 | 379 | ||
456 | if (synaptics_mode_cmd(psmouse, priv->mode)) | 380 | if (synaptics_mode_cmd(psmouse, priv->mode)) |
457 | psmouse_warn(psmouse, | 381 | printk(KERN_INFO "synaptics: failed to switch guest protocol\n"); |
458 | "failed to switch guest protocol\n"); | ||
459 | } | 382 | } |
460 | } | 383 | } |
461 | 384 | ||
@@ -465,8 +388,7 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
465 | 388 | ||
466 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | 389 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
467 | if (!serio) { | 390 | if (!serio) { |
468 | psmouse_err(psmouse, | 391 | printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n"); |
469 | "not enough memory for pass-through port\n"); | ||
470 | return; | 392 | return; |
471 | } | 393 | } |
472 | 394 | ||
@@ -480,8 +402,7 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
480 | 402 | ||
481 | psmouse->pt_activate = synaptics_pt_activate; | 403 | psmouse->pt_activate = synaptics_pt_activate; |
482 | 404 | ||
483 | psmouse_info(psmouse, "serio: %s port at %s\n", | 405 | printk(KERN_INFO "serio: %s port at %s\n", serio->name, psmouse->phys); |
484 | serio->name, psmouse->phys); | ||
485 | serio_register_port(serio); | 406 | serio_register_port(serio); |
486 | } | 407 | } |
487 | 408 | ||
@@ -489,44 +410,6 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
489 | * Functions to interpret the absolute mode packets | 410 | * Functions to interpret the absolute mode packets |
490 | ****************************************************************************/ | 411 | ****************************************************************************/ |
491 | 412 | ||
492 | static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count, | ||
493 | int sgm, int agm) | ||
494 | { | ||
495 | state->count = count; | ||
496 | state->sgm = sgm; | ||
497 | state->agm = agm; | ||
498 | } | ||
499 | |||
500 | static void synaptics_parse_agm(const unsigned char buf[], | ||
501 | struct synaptics_data *priv, | ||
502 | struct synaptics_hw_state *hw) | ||
503 | { | ||
504 | struct synaptics_hw_state *agm = &priv->agm; | ||
505 | int agm_packet_type; | ||
506 | |||
507 | agm_packet_type = (buf[5] & 0x30) >> 4; | ||
508 | switch (agm_packet_type) { | ||
509 | case 1: | ||
510 | /* Gesture packet: (x, y, z) half resolution */ | ||
511 | agm->w = hw->w; | ||
512 | agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
513 | agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
514 | agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
515 | break; | ||
516 | |||
517 | case 2: | ||
518 | /* AGM-CONTACT packet: (count, sgm, agm) */ | ||
519 | synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]); | ||
520 | break; | ||
521 | |||
522 | default: | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | /* Record that at least one AGM has been received since last SGM */ | ||
527 | priv->agm_pending = true; | ||
528 | } | ||
529 | |||
530 | static int synaptics_parse_hw_state(const unsigned char buf[], | 413 | static int synaptics_parse_hw_state(const unsigned char buf[], |
531 | struct synaptics_data *priv, | 414 | struct synaptics_data *priv, |
532 | struct synaptics_hw_state *hw) | 415 | struct synaptics_hw_state *hw) |
@@ -560,10 +443,11 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
560 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 443 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
561 | } | 444 | } |
562 | 445 | ||
563 | if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || | 446 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { |
564 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && | 447 | /* Gesture packet: (x, y, z) at half resolution */ |
565 | hw->w == 2) { | 448 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; |
566 | synaptics_parse_agm(buf, priv, hw); | 449 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; |
450 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
567 | return 1; | 451 | return 1; |
568 | } | 452 | } |
569 | 453 | ||
@@ -609,22 +493,6 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
609 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 493 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
610 | } | 494 | } |
611 | 495 | ||
612 | /* | ||
613 | * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE | ||
614 | * is used by some firmware to indicate a finger at the edge of | ||
615 | * the touchpad whose precise position cannot be determined, so | ||
616 | * convert these values to the maximum axis value. | ||
617 | */ | ||
618 | if (hw->x > X_MAX_POSITIVE) | ||
619 | hw->x -= 1 << ABS_POS_BITS; | ||
620 | else if (hw->x == X_MAX_POSITIVE) | ||
621 | hw->x = XMAX; | ||
622 | |||
623 | if (hw->y > Y_MAX_POSITIVE) | ||
624 | hw->y -= 1 << ABS_POS_BITS; | ||
625 | else if (hw->y == Y_MAX_POSITIVE) | ||
626 | hw->y = YMAX; | ||
627 | |||
628 | return 0; | 496 | return 0; |
629 | } | 497 | } |
630 | 498 | ||
@@ -635,7 +503,8 @@ static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot, | |||
635 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | 503 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); |
636 | if (active) { | 504 | if (active) { |
637 | input_report_abs(dev, ABS_MT_POSITION_X, x); | 505 | input_report_abs(dev, ABS_MT_POSITION_X, x); |
638 | input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(y)); | 506 | input_report_abs(dev, ABS_MT_POSITION_Y, |
507 | YMAX_NOMINAL + YMIN_NOMINAL - y); | ||
639 | } | 508 | } |
640 | } | 509 | } |
641 | 510 | ||
@@ -658,388 +527,6 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, | |||
658 | } | 527 | } |
659 | } | 528 | } |
660 | 529 | ||
661 | static void synaptics_report_buttons(struct psmouse *psmouse, | ||
662 | const struct synaptics_hw_state *hw) | ||
663 | { | ||
664 | struct input_dev *dev = psmouse->dev; | ||
665 | struct synaptics_data *priv = psmouse->private; | ||
666 | int i; | ||
667 | |||
668 | input_report_key(dev, BTN_LEFT, hw->left); | ||
669 | input_report_key(dev, BTN_RIGHT, hw->right); | ||
670 | |||
671 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | ||
672 | input_report_key(dev, BTN_MIDDLE, hw->middle); | ||
673 | |||
674 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { | ||
675 | input_report_key(dev, BTN_FORWARD, hw->up); | ||
676 | input_report_key(dev, BTN_BACK, hw->down); | ||
677 | } | ||
678 | |||
679 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | ||
680 | input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i)); | ||
681 | } | ||
682 | |||
683 | static void synaptics_report_slot(struct input_dev *dev, int slot, | ||
684 | const struct synaptics_hw_state *hw) | ||
685 | { | ||
686 | input_mt_slot(dev, slot); | ||
687 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, (hw != NULL)); | ||
688 | if (!hw) | ||
689 | return; | ||
690 | |||
691 | input_report_abs(dev, ABS_MT_POSITION_X, hw->x); | ||
692 | input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(hw->y)); | ||
693 | input_report_abs(dev, ABS_MT_PRESSURE, hw->z); | ||
694 | } | ||
695 | |||
696 | static void synaptics_report_mt_data(struct psmouse *psmouse, | ||
697 | struct synaptics_mt_state *mt_state, | ||
698 | const struct synaptics_hw_state *sgm) | ||
699 | { | ||
700 | struct input_dev *dev = psmouse->dev; | ||
701 | struct synaptics_data *priv = psmouse->private; | ||
702 | struct synaptics_hw_state *agm = &priv->agm; | ||
703 | struct synaptics_mt_state *old = &priv->mt_state; | ||
704 | |||
705 | switch (mt_state->count) { | ||
706 | case 0: | ||
707 | synaptics_report_slot(dev, 0, NULL); | ||
708 | synaptics_report_slot(dev, 1, NULL); | ||
709 | break; | ||
710 | case 1: | ||
711 | if (mt_state->sgm == -1) { | ||
712 | synaptics_report_slot(dev, 0, NULL); | ||
713 | synaptics_report_slot(dev, 1, NULL); | ||
714 | } else if (mt_state->sgm == 0) { | ||
715 | synaptics_report_slot(dev, 0, sgm); | ||
716 | synaptics_report_slot(dev, 1, NULL); | ||
717 | } else { | ||
718 | synaptics_report_slot(dev, 0, NULL); | ||
719 | synaptics_report_slot(dev, 1, sgm); | ||
720 | } | ||
721 | break; | ||
722 | default: | ||
723 | /* | ||
724 | * If the finger slot contained in SGM is valid, and either | ||
725 | * hasn't changed, or is new, then report SGM in MTB slot 0. | ||
726 | * Otherwise, empty MTB slot 0. | ||
727 | */ | ||
728 | if (mt_state->sgm != -1 && | ||
729 | (mt_state->sgm == old->sgm || old->sgm == -1)) | ||
730 | synaptics_report_slot(dev, 0, sgm); | ||
731 | else | ||
732 | synaptics_report_slot(dev, 0, NULL); | ||
733 | |||
734 | /* | ||
735 | * If the finger slot contained in AGM is valid, and either | ||
736 | * hasn't changed, or is new, then report AGM in MTB slot 1. | ||
737 | * Otherwise, empty MTB slot 1. | ||
738 | */ | ||
739 | if (mt_state->agm != -1 && | ||
740 | (mt_state->agm == old->agm || old->agm == -1)) | ||
741 | synaptics_report_slot(dev, 1, agm); | ||
742 | else | ||
743 | synaptics_report_slot(dev, 1, NULL); | ||
744 | break; | ||
745 | } | ||
746 | |||
747 | /* Don't use active slot count to generate BTN_TOOL events. */ | ||
748 | input_mt_report_pointer_emulation(dev, false); | ||
749 | |||
750 | /* Send the number of fingers reported by touchpad itself. */ | ||
751 | input_mt_report_finger_count(dev, mt_state->count); | ||
752 | |||
753 | synaptics_report_buttons(psmouse, sgm); | ||
754 | |||
755 | input_sync(dev); | ||
756 | } | ||
757 | |||
758 | /* Handle case where mt_state->count = 0 */ | ||
759 | static void synaptics_image_sensor_0f(struct synaptics_data *priv, | ||
760 | struct synaptics_mt_state *mt_state) | ||
761 | { | ||
762 | synaptics_mt_state_set(mt_state, 0, -1, -1); | ||
763 | priv->mt_state_lost = false; | ||
764 | } | ||
765 | |||
766 | /* Handle case where mt_state->count = 1 */ | ||
767 | static void synaptics_image_sensor_1f(struct synaptics_data *priv, | ||
768 | struct synaptics_mt_state *mt_state) | ||
769 | { | ||
770 | struct synaptics_hw_state *agm = &priv->agm; | ||
771 | struct synaptics_mt_state *old = &priv->mt_state; | ||
772 | |||
773 | /* | ||
774 | * If the last AGM was (0,0,0), and there is only one finger left, | ||
775 | * then we absolutely know that SGM contains slot 0, and all other | ||
776 | * fingers have been removed. | ||
777 | */ | ||
778 | if (priv->agm_pending && agm->z == 0) { | ||
779 | synaptics_mt_state_set(mt_state, 1, 0, -1); | ||
780 | priv->mt_state_lost = false; | ||
781 | return; | ||
782 | } | ||
783 | |||
784 | switch (old->count) { | ||
785 | case 0: | ||
786 | synaptics_mt_state_set(mt_state, 1, 0, -1); | ||
787 | break; | ||
788 | case 1: | ||
789 | /* | ||
790 | * If mt_state_lost, then the previous transition was 3->1, | ||
791 | * and SGM now contains either slot 0 or 1, but we don't know | ||
792 | * which. So, we just assume that the SGM now contains slot 1. | ||
793 | * | ||
794 | * If pending AGM and either: | ||
795 | * (a) the previous SGM slot contains slot 0, or | ||
796 | * (b) there was no SGM slot | ||
797 | * then, the SGM now contains slot 1 | ||
798 | * | ||
799 | * Case (a) happens with very rapid "drum roll" gestures, where | ||
800 | * slot 0 finger is lifted and a new slot 1 finger touches | ||
801 | * within one reporting interval. | ||
802 | * | ||
803 | * Case (b) happens if initially two or more fingers tap | ||
804 | * briefly, and all but one lift before the end of the first | ||
805 | * reporting interval. | ||
806 | * | ||
807 | * (In both these cases, slot 0 will becomes empty, so SGM | ||
808 | * contains slot 1 with the new finger) | ||
809 | * | ||
810 | * Else, if there was no previous SGM, it now contains slot 0. | ||
811 | * | ||
812 | * Otherwise, SGM still contains the same slot. | ||
813 | */ | ||
814 | if (priv->mt_state_lost || | ||
815 | (priv->agm_pending && old->sgm <= 0)) | ||
816 | synaptics_mt_state_set(mt_state, 1, 1, -1); | ||
817 | else if (old->sgm == -1) | ||
818 | synaptics_mt_state_set(mt_state, 1, 0, -1); | ||
819 | break; | ||
820 | case 2: | ||
821 | /* | ||
822 | * If mt_state_lost, we don't know which finger SGM contains. | ||
823 | * | ||
824 | * So, report 1 finger, but with both slots empty. | ||
825 | * We will use slot 1 on subsequent 1->1 | ||
826 | */ | ||
827 | if (priv->mt_state_lost) { | ||
828 | synaptics_mt_state_set(mt_state, 1, -1, -1); | ||
829 | break; | ||
830 | } | ||
831 | /* | ||
832 | * Since the last AGM was NOT (0,0,0), it was the finger in | ||
833 | * slot 0 that has been removed. | ||
834 | * So, SGM now contains previous AGM's slot, and AGM is now | ||
835 | * empty. | ||
836 | */ | ||
837 | synaptics_mt_state_set(mt_state, 1, old->agm, -1); | ||
838 | break; | ||
839 | case 3: | ||
840 | /* | ||
841 | * Since last AGM was not (0,0,0), we don't know which finger | ||
842 | * is left. | ||
843 | * | ||
844 | * So, report 1 finger, but with both slots empty. | ||
845 | * We will use slot 1 on subsequent 1->1 | ||
846 | */ | ||
847 | synaptics_mt_state_set(mt_state, 1, -1, -1); | ||
848 | priv->mt_state_lost = true; | ||
849 | break; | ||
850 | case 4: | ||
851 | case 5: | ||
852 | /* mt_state was updated by AGM-CONTACT packet */ | ||
853 | break; | ||
854 | } | ||
855 | } | ||
856 | |||
857 | /* Handle case where mt_state->count = 2 */ | ||
858 | static void synaptics_image_sensor_2f(struct synaptics_data *priv, | ||
859 | struct synaptics_mt_state *mt_state) | ||
860 | { | ||
861 | struct synaptics_mt_state *old = &priv->mt_state; | ||
862 | |||
863 | switch (old->count) { | ||
864 | case 0: | ||
865 | synaptics_mt_state_set(mt_state, 2, 0, 1); | ||
866 | break; | ||
867 | case 1: | ||
868 | /* | ||
869 | * If previous SGM contained slot 1 or higher, SGM now contains | ||
870 | * slot 0 (the newly touching finger) and AGM contains SGM's | ||
871 | * previous slot. | ||
872 | * | ||
873 | * Otherwise, SGM still contains slot 0 and AGM now contains | ||
874 | * slot 1. | ||
875 | */ | ||
876 | if (old->sgm >= 1) | ||
877 | synaptics_mt_state_set(mt_state, 2, 0, old->sgm); | ||
878 | else | ||
879 | synaptics_mt_state_set(mt_state, 2, 0, 1); | ||
880 | break; | ||
881 | case 2: | ||
882 | /* | ||
883 | * If mt_state_lost, SGM now contains either finger 1 or 2, but | ||
884 | * we don't know which. | ||
885 | * So, we just assume that the SGM contains slot 0 and AGM 1. | ||
886 | */ | ||
887 | if (priv->mt_state_lost) | ||
888 | synaptics_mt_state_set(mt_state, 2, 0, 1); | ||
889 | /* | ||
890 | * Otherwise, use the same mt_state, since it either hasn't | ||
891 | * changed, or was updated by a recently received AGM-CONTACT | ||
892 | * packet. | ||
893 | */ | ||
894 | break; | ||
895 | case 3: | ||
896 | /* | ||
897 | * 3->2 transitions have two unsolvable problems: | ||
898 | * 1) no indication is given which finger was removed | ||
899 | * 2) no way to tell if agm packet was for finger 3 | ||
900 | * before 3->2, or finger 2 after 3->2. | ||
901 | * | ||
902 | * So, report 2 fingers, but empty all slots. | ||
903 | * We will guess slots [0,1] on subsequent 2->2. | ||
904 | */ | ||
905 | synaptics_mt_state_set(mt_state, 2, -1, -1); | ||
906 | priv->mt_state_lost = true; | ||
907 | break; | ||
908 | case 4: | ||
909 | case 5: | ||
910 | /* mt_state was updated by AGM-CONTACT packet */ | ||
911 | break; | ||
912 | } | ||
913 | } | ||
914 | |||
915 | /* Handle case where mt_state->count = 3 */ | ||
916 | static void synaptics_image_sensor_3f(struct synaptics_data *priv, | ||
917 | struct synaptics_mt_state *mt_state) | ||
918 | { | ||
919 | struct synaptics_mt_state *old = &priv->mt_state; | ||
920 | |||
921 | switch (old->count) { | ||
922 | case 0: | ||
923 | synaptics_mt_state_set(mt_state, 3, 0, 2); | ||
924 | break; | ||
925 | case 1: | ||
926 | /* | ||
927 | * If previous SGM contained slot 2 or higher, SGM now contains | ||
928 | * slot 0 (one of the newly touching fingers) and AGM contains | ||
929 | * SGM's previous slot. | ||
930 | * | ||
931 | * Otherwise, SGM now contains slot 0 and AGM contains slot 2. | ||
932 | */ | ||
933 | if (old->sgm >= 2) | ||
934 | synaptics_mt_state_set(mt_state, 3, 0, old->sgm); | ||
935 | else | ||
936 | synaptics_mt_state_set(mt_state, 3, 0, 2); | ||
937 | break; | ||
938 | case 2: | ||
939 | /* | ||
940 | * If the AGM previously contained slot 3 or higher, then the | ||
941 | * newly touching finger is in the lowest available slot. | ||
942 | * | ||
943 | * If SGM was previously 1 or higher, then the new SGM is | ||
944 | * now slot 0 (with a new finger), otherwise, the new finger | ||
945 | * is now in a hidden slot between 0 and AGM's slot. | ||
946 | * | ||
947 | * In all such cases, the SGM now contains slot 0, and the AGM | ||
948 | * continues to contain the same slot as before. | ||
949 | */ | ||
950 | if (old->agm >= 3) { | ||
951 | synaptics_mt_state_set(mt_state, 3, 0, old->agm); | ||
952 | break; | ||
953 | } | ||
954 | |||
955 | /* | ||
956 | * After some 3->1 and all 3->2 transitions, we lose track | ||
957 | * of which slot is reported by SGM and AGM. | ||
958 | * | ||
959 | * For 2->3 in this state, report 3 fingers, but empty all | ||
960 | * slots, and we will guess (0,2) on a subsequent 0->3. | ||
961 | * | ||
962 | * To userspace, the resulting transition will look like: | ||
963 | * 2:[0,1] -> 3:[-1,-1] -> 3:[0,2] | ||
964 | */ | ||
965 | if (priv->mt_state_lost) { | ||
966 | synaptics_mt_state_set(mt_state, 3, -1, -1); | ||
967 | break; | ||
968 | } | ||
969 | |||
970 | /* | ||
971 | * If the (SGM,AGM) really previously contained slots (0, 1), | ||
972 | * then we cannot know what slot was just reported by the AGM, | ||
973 | * because the 2->3 transition can occur either before or after | ||
974 | * the AGM packet. Thus, this most recent AGM could contain | ||
975 | * either the same old slot 1 or the new slot 2. | ||
976 | * Subsequent AGMs will be reporting slot 2. | ||
977 | * | ||
978 | * To userspace, the resulting transition will look like: | ||
979 | * 2:[0,1] -> 3:[0,-1] -> 3:[0,2] | ||
980 | */ | ||
981 | synaptics_mt_state_set(mt_state, 3, 0, -1); | ||
982 | break; | ||
983 | case 3: | ||
984 | /* | ||
985 | * If, for whatever reason, the previous agm was invalid, | ||
986 | * Assume SGM now contains slot 0, AGM now contains slot 2. | ||
987 | */ | ||
988 | if (old->agm <= 2) | ||
989 | synaptics_mt_state_set(mt_state, 3, 0, 2); | ||
990 | /* | ||
991 | * mt_state either hasn't changed, or was updated by a recently | ||
992 | * received AGM-CONTACT packet. | ||
993 | */ | ||
994 | break; | ||
995 | |||
996 | case 4: | ||
997 | case 5: | ||
998 | /* mt_state was updated by AGM-CONTACT packet */ | ||
999 | break; | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | /* Handle case where mt_state->count = 4, or = 5 */ | ||
1004 | static void synaptics_image_sensor_45f(struct synaptics_data *priv, | ||
1005 | struct synaptics_mt_state *mt_state) | ||
1006 | { | ||
1007 | /* mt_state was updated correctly by AGM-CONTACT packet */ | ||
1008 | priv->mt_state_lost = false; | ||
1009 | } | ||
1010 | |||
1011 | static void synaptics_image_sensor_process(struct psmouse *psmouse, | ||
1012 | struct synaptics_hw_state *sgm) | ||
1013 | { | ||
1014 | struct synaptics_data *priv = psmouse->private; | ||
1015 | struct synaptics_hw_state *agm = &priv->agm; | ||
1016 | struct synaptics_mt_state mt_state; | ||
1017 | |||
1018 | /* Initialize using current mt_state (as updated by last agm) */ | ||
1019 | mt_state = agm->mt_state; | ||
1020 | |||
1021 | /* | ||
1022 | * Update mt_state using the new finger count and current mt_state. | ||
1023 | */ | ||
1024 | if (sgm->z == 0) | ||
1025 | synaptics_image_sensor_0f(priv, &mt_state); | ||
1026 | else if (sgm->w >= 4) | ||
1027 | synaptics_image_sensor_1f(priv, &mt_state); | ||
1028 | else if (sgm->w == 0) | ||
1029 | synaptics_image_sensor_2f(priv, &mt_state); | ||
1030 | else if (sgm->w == 1 && mt_state.count <= 3) | ||
1031 | synaptics_image_sensor_3f(priv, &mt_state); | ||
1032 | else | ||
1033 | synaptics_image_sensor_45f(priv, &mt_state); | ||
1034 | |||
1035 | /* Send resulting input events to user space */ | ||
1036 | synaptics_report_mt_data(psmouse, &mt_state, sgm); | ||
1037 | |||
1038 | /* Store updated mt_state */ | ||
1039 | priv->mt_state = agm->mt_state = mt_state; | ||
1040 | priv->agm_pending = false; | ||
1041 | } | ||
1042 | |||
1043 | /* | 530 | /* |
1044 | * called for each full received packet from the touchpad | 531 | * called for each full received packet from the touchpad |
1045 | */ | 532 | */ |
@@ -1050,15 +537,11 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
1050 | struct synaptics_hw_state hw; | 537 | struct synaptics_hw_state hw; |
1051 | int num_fingers; | 538 | int num_fingers; |
1052 | int finger_width; | 539 | int finger_width; |
540 | int i; | ||
1053 | 541 | ||
1054 | if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) | 542 | if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) |
1055 | return; | 543 | return; |
1056 | 544 | ||
1057 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | ||
1058 | synaptics_image_sensor_process(psmouse, &hw); | ||
1059 | return; | ||
1060 | } | ||
1061 | |||
1062 | if (hw.scroll) { | 545 | if (hw.scroll) { |
1063 | priv->scroll += hw.scroll; | 546 | priv->scroll += hw.scroll; |
1064 | 547 | ||
@@ -1104,8 +587,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
1104 | } | 587 | } |
1105 | 588 | ||
1106 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | 589 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) |
1107 | synaptics_report_semi_mt_data(dev, &hw, &priv->agm, | 590 | synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers); |
1108 | num_fingers); | ||
1109 | 591 | ||
1110 | /* Post events | 592 | /* Post events |
1111 | * BTN_TOUCH has to be first as mousedev relies on it when doing | 593 | * BTN_TOUCH has to be first as mousedev relies on it when doing |
@@ -1116,7 +598,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
1116 | 598 | ||
1117 | if (num_fingers > 0) { | 599 | if (num_fingers > 0) { |
1118 | input_report_abs(dev, ABS_X, hw.x); | 600 | input_report_abs(dev, ABS_X, hw.x); |
1119 | input_report_abs(dev, ABS_Y, synaptics_invert_y(hw.y)); | 601 | input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); |
1120 | } | 602 | } |
1121 | input_report_abs(dev, ABS_PRESSURE, hw.z); | 603 | input_report_abs(dev, ABS_PRESSURE, hw.z); |
1122 | 604 | ||
@@ -1124,25 +606,35 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
1124 | input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); | 606 | input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); |
1125 | 607 | ||
1126 | input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); | 608 | input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); |
609 | input_report_key(dev, BTN_LEFT, hw.left); | ||
610 | input_report_key(dev, BTN_RIGHT, hw.right); | ||
611 | |||
1127 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { | 612 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { |
1128 | input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); | 613 | input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); |
1129 | input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); | 614 | input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); |
1130 | } | 615 | } |
1131 | 616 | ||
1132 | synaptics_report_buttons(psmouse, &hw); | 617 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) |
618 | input_report_key(dev, BTN_MIDDLE, hw.middle); | ||
619 | |||
620 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { | ||
621 | input_report_key(dev, BTN_FORWARD, hw.up); | ||
622 | input_report_key(dev, BTN_BACK, hw.down); | ||
623 | } | ||
624 | |||
625 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | ||
626 | input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i)); | ||
1133 | 627 | ||
1134 | input_sync(dev); | 628 | input_sync(dev); |
1135 | } | 629 | } |
1136 | 630 | ||
1137 | static int synaptics_validate_byte(struct psmouse *psmouse, | 631 | static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type) |
1138 | int idx, unsigned char pkt_type) | ||
1139 | { | 632 | { |
1140 | static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 }; | 633 | static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 }; |
1141 | static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 }; | 634 | static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 }; |
1142 | static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 }; | 635 | static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 }; |
1143 | static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 }; | 636 | static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 }; |
1144 | static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 }; | 637 | static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 }; |
1145 | const char *packet = psmouse->packet; | ||
1146 | 638 | ||
1147 | if (idx < 0 || idx > 4) | 639 | if (idx < 0 || idx > 4) |
1148 | return 0; | 640 | return 0; |
@@ -1160,7 +652,7 @@ static int synaptics_validate_byte(struct psmouse *psmouse, | |||
1160 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; | 652 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; |
1161 | 653 | ||
1162 | default: | 654 | default: |
1163 | psmouse_err(psmouse, "unknown packet type %d\n", pkt_type); | 655 | printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); |
1164 | return 0; | 656 | return 0; |
1165 | } | 657 | } |
1166 | } | 658 | } |
@@ -1170,8 +662,8 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse) | |||
1170 | int i; | 662 | int i; |
1171 | 663 | ||
1172 | for (i = 0; i < 5; i++) | 664 | for (i = 0; i < 5; i++) |
1173 | if (!synaptics_validate_byte(psmouse, i, SYN_NEWABS_STRICT)) { | 665 | if (!synaptics_validate_byte(psmouse->packet, i, SYN_NEWABS_STRICT)) { |
1174 | psmouse_info(psmouse, "using relaxed packet validation\n"); | 666 | printk(KERN_INFO "synaptics: using relaxed packet validation\n"); |
1175 | return SYN_NEWABS_RELAXED; | 667 | return SYN_NEWABS_RELAXED; |
1176 | } | 668 | } |
1177 | 669 | ||
@@ -1196,85 +688,65 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
1196 | return PSMOUSE_FULL_PACKET; | 688 | return PSMOUSE_FULL_PACKET; |
1197 | } | 689 | } |
1198 | 690 | ||
1199 | return synaptics_validate_byte(psmouse, psmouse->pktcnt - 1, priv->pkt_type) ? | 691 | return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ? |
1200 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | 692 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; |
1201 | } | 693 | } |
1202 | 694 | ||
1203 | /***************************************************************************** | 695 | /***************************************************************************** |
1204 | * Driver initialization/cleanup functions | 696 | * Driver initialization/cleanup functions |
1205 | ****************************************************************************/ | 697 | ****************************************************************************/ |
1206 | static void set_abs_position_params(struct input_dev *dev, | ||
1207 | struct synaptics_data *priv, int x_code, | ||
1208 | int y_code) | ||
1209 | { | ||
1210 | int x_min = priv->x_min ?: XMIN_NOMINAL; | ||
1211 | int x_max = priv->x_max ?: XMAX_NOMINAL; | ||
1212 | int y_min = priv->y_min ?: YMIN_NOMINAL; | ||
1213 | int y_max = priv->y_max ?: YMAX_NOMINAL; | ||
1214 | int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? | ||
1215 | SYN_REDUCED_FILTER_FUZZ : 0; | ||
1216 | |||
1217 | input_set_abs_params(dev, x_code, x_min, x_max, fuzz, 0); | ||
1218 | input_set_abs_params(dev, y_code, y_min, y_max, fuzz, 0); | ||
1219 | input_abs_set_res(dev, x_code, priv->x_res); | ||
1220 | input_abs_set_res(dev, y_code, priv->y_res); | ||
1221 | } | ||
1222 | |||
1223 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | 698 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) |
1224 | { | 699 | { |
1225 | int i; | 700 | int i; |
701 | int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? | ||
702 | SYN_REDUCED_FILTER_FUZZ : 0; | ||
1226 | 703 | ||
1227 | /* Things that apply to both modes */ | ||
1228 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | 704 | __set_bit(INPUT_PROP_POINTER, dev->propbit); |
1229 | __set_bit(EV_KEY, dev->evbit); | ||
1230 | __set_bit(BTN_LEFT, dev->keybit); | ||
1231 | __set_bit(BTN_RIGHT, dev->keybit); | ||
1232 | |||
1233 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | ||
1234 | __set_bit(BTN_MIDDLE, dev->keybit); | ||
1235 | 705 | ||
1236 | if (!priv->absolute_mode) { | ||
1237 | /* Relative mode */ | ||
1238 | __set_bit(EV_REL, dev->evbit); | ||
1239 | __set_bit(REL_X, dev->relbit); | ||
1240 | __set_bit(REL_Y, dev->relbit); | ||
1241 | return; | ||
1242 | } | ||
1243 | |||
1244 | /* Absolute mode */ | ||
1245 | __set_bit(EV_ABS, dev->evbit); | 706 | __set_bit(EV_ABS, dev->evbit); |
1246 | set_abs_position_params(dev, priv, ABS_X, ABS_Y); | 707 | input_set_abs_params(dev, ABS_X, |
708 | priv->x_min ?: XMIN_NOMINAL, | ||
709 | priv->x_max ?: XMAX_NOMINAL, | ||
710 | fuzz, 0); | ||
711 | input_set_abs_params(dev, ABS_Y, | ||
712 | priv->y_min ?: YMIN_NOMINAL, | ||
713 | priv->y_max ?: YMAX_NOMINAL, | ||
714 | fuzz, 0); | ||
1247 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 715 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
1248 | 716 | ||
1249 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 717 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
1250 | input_mt_init_slots(dev, 2, 0); | ||
1251 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | ||
1252 | ABS_MT_POSITION_Y); | ||
1253 | /* Image sensors can report per-contact pressure */ | ||
1254 | input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
1255 | |||
1256 | /* Image sensors can signal 4 and 5 finger clicks */ | ||
1257 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
1258 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); | ||
1259 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | ||
1260 | /* Non-image sensors with AGM use semi-mt */ | ||
1261 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 718 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
1262 | input_mt_init_slots(dev, 2, 0); | 719 | input_mt_init_slots(dev, 2); |
1263 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 720 | input_set_abs_params(dev, ABS_MT_POSITION_X, |
1264 | ABS_MT_POSITION_Y); | 721 | priv->x_min ?: XMIN_NOMINAL, |
722 | priv->x_max ?: XMAX_NOMINAL, | ||
723 | fuzz, 0); | ||
724 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
725 | priv->y_min ?: YMIN_NOMINAL, | ||
726 | priv->y_max ?: YMAX_NOMINAL, | ||
727 | fuzz, 0); | ||
728 | |||
729 | input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); | ||
730 | input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); | ||
1265 | } | 731 | } |
1266 | 732 | ||
1267 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 733 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
1268 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); | 734 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); |
1269 | 735 | ||
736 | __set_bit(EV_KEY, dev->evbit); | ||
1270 | __set_bit(BTN_TOUCH, dev->keybit); | 737 | __set_bit(BTN_TOUCH, dev->keybit); |
1271 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | 738 | __set_bit(BTN_TOOL_FINGER, dev->keybit); |
739 | __set_bit(BTN_LEFT, dev->keybit); | ||
740 | __set_bit(BTN_RIGHT, dev->keybit); | ||
1272 | 741 | ||
1273 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { | 742 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { |
1274 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); | 743 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); |
1275 | __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); | 744 | __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); |
1276 | } | 745 | } |
1277 | 746 | ||
747 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | ||
748 | __set_bit(BTN_MIDDLE, dev->keybit); | ||
749 | |||
1278 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities) || | 750 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities) || |
1279 | SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | 751 | SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { |
1280 | __set_bit(BTN_FORWARD, dev->keybit); | 752 | __set_bit(BTN_FORWARD, dev->keybit); |
@@ -1288,6 +760,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1288 | __clear_bit(REL_X, dev->relbit); | 760 | __clear_bit(REL_X, dev->relbit); |
1289 | __clear_bit(REL_Y, dev->relbit); | 761 | __clear_bit(REL_Y, dev->relbit); |
1290 | 762 | ||
763 | input_abs_set_res(dev, ABS_X, priv->x_res); | ||
764 | input_abs_set_res(dev, ABS_Y, priv->y_res); | ||
765 | |||
1291 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 766 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
1292 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | 767 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); |
1293 | /* Clickpads report only left button */ | 768 | /* Clickpads report only left button */ |
@@ -1296,58 +771,10 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1296 | } | 771 | } |
1297 | } | 772 | } |
1298 | 773 | ||
1299 | static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse, | ||
1300 | void *data, char *buf) | ||
1301 | { | ||
1302 | struct synaptics_data *priv = psmouse->private; | ||
1303 | |||
1304 | return sprintf(buf, "%c\n", priv->disable_gesture ? '1' : '0'); | ||
1305 | } | ||
1306 | |||
1307 | static ssize_t synaptics_set_disable_gesture(struct psmouse *psmouse, | ||
1308 | void *data, const char *buf, | ||
1309 | size_t len) | ||
1310 | { | ||
1311 | struct synaptics_data *priv = psmouse->private; | ||
1312 | unsigned int value; | ||
1313 | int err; | ||
1314 | |||
1315 | err = kstrtouint(buf, 10, &value); | ||
1316 | if (err) | ||
1317 | return err; | ||
1318 | |||
1319 | if (value > 1) | ||
1320 | return -EINVAL; | ||
1321 | |||
1322 | if (value == priv->disable_gesture) | ||
1323 | return len; | ||
1324 | |||
1325 | priv->disable_gesture = value; | ||
1326 | if (value) | ||
1327 | priv->mode |= SYN_BIT_DISABLE_GESTURE; | ||
1328 | else | ||
1329 | priv->mode &= ~SYN_BIT_DISABLE_GESTURE; | ||
1330 | |||
1331 | if (synaptics_mode_cmd(psmouse, priv->mode)) | ||
1332 | return -EIO; | ||
1333 | |||
1334 | return len; | ||
1335 | } | ||
1336 | |||
1337 | PSMOUSE_DEFINE_ATTR(disable_gesture, S_IWUSR | S_IRUGO, NULL, | ||
1338 | synaptics_show_disable_gesture, | ||
1339 | synaptics_set_disable_gesture); | ||
1340 | |||
1341 | static void synaptics_disconnect(struct psmouse *psmouse) | 774 | static void synaptics_disconnect(struct psmouse *psmouse) |
1342 | { | 775 | { |
1343 | struct synaptics_data *priv = psmouse->private; | ||
1344 | |||
1345 | if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity)) | ||
1346 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
1347 | &psmouse_attr_disable_gesture.dattr); | ||
1348 | |||
1349 | synaptics_reset(psmouse); | 776 | synaptics_reset(psmouse); |
1350 | kfree(priv); | 777 | kfree(psmouse->private); |
1351 | psmouse->private = NULL; | 778 | psmouse->private = NULL; |
1352 | } | 779 | } |
1353 | 780 | ||
@@ -1377,15 +804,21 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
1377 | return -1; | 804 | return -1; |
1378 | 805 | ||
1379 | if (retry > 1) | 806 | if (retry > 1) |
1380 | psmouse_dbg(psmouse, "reconnected after %d tries\n", retry); | 807 | printk(KERN_DEBUG "Synaptics reconnected after %d tries\n", |
808 | retry); | ||
1381 | 809 | ||
1382 | if (synaptics_query_hardware(psmouse)) { | 810 | if (synaptics_query_hardware(psmouse)) { |
1383 | psmouse_err(psmouse, "Unable to query device.\n"); | 811 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); |
812 | return -1; | ||
813 | } | ||
814 | |||
815 | if (synaptics_set_absolute_mode(psmouse)) { | ||
816 | printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); | ||
1384 | return -1; | 817 | return -1; |
1385 | } | 818 | } |
1386 | 819 | ||
1387 | if (synaptics_set_mode(psmouse)) { | 820 | if (synaptics_set_advanced_gesture_mode(psmouse)) { |
1388 | psmouse_err(psmouse, "Unable to initialize device.\n"); | 821 | printk(KERN_ERR "Advanced gesture mode reconnect failed.\n"); |
1389 | return -1; | 822 | return -1; |
1390 | } | 823 | } |
1391 | 824 | ||
@@ -1393,12 +826,12 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
1393 | old_priv.model_id != priv->model_id || | 826 | old_priv.model_id != priv->model_id || |
1394 | old_priv.capabilities != priv->capabilities || | 827 | old_priv.capabilities != priv->capabilities || |
1395 | old_priv.ext_cap != priv->ext_cap) { | 828 | old_priv.ext_cap != priv->ext_cap) { |
1396 | psmouse_err(psmouse, | 829 | printk(KERN_ERR "Synaptics hardware appears to be different: " |
1397 | "hardware appears to be different: id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n", | 830 | "id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n", |
1398 | old_priv.identity, priv->identity, | 831 | old_priv.identity, priv->identity, |
1399 | old_priv.model_id, priv->model_id, | 832 | old_priv.model_id, priv->model_id, |
1400 | old_priv.capabilities, priv->capabilities, | 833 | old_priv.capabilities, priv->capabilities, |
1401 | old_priv.ext_cap, priv->ext_cap); | 834 | old_priv.ext_cap, priv->ext_cap); |
1402 | return -1; | 835 | return -1; |
1403 | } | 836 | } |
1404 | 837 | ||
@@ -1465,20 +898,21 @@ void __init synaptics_module_init(void) | |||
1465 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | 898 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); |
1466 | } | 899 | } |
1467 | 900 | ||
1468 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | 901 | int synaptics_init(struct psmouse *psmouse) |
1469 | { | 902 | { |
1470 | struct synaptics_data *priv; | 903 | struct synaptics_data *priv; |
1471 | int err = -1; | ||
1472 | 904 | ||
1473 | /* | 905 | /* |
1474 | * The OLPC XO has issues with Synaptics' absolute mode; the constant | 906 | * The OLPC XO has issues with Synaptics' absolute mode; similarly to |
1475 | * packet spew overloads the EC such that key presses on the keyboard | 907 | * the HGPK, it quickly degrades and the hardware becomes jumpy and |
1476 | * are missed. Given that, don't even attempt to use Absolute mode. | 908 | * overly sensitive. Not only that, but the constant packet spew |
1477 | * Relative mode seems to work just fine. | 909 | * (even at a lowered 40pps rate) overloads the EC such that key |
910 | * presses on the keyboard are missed. Given all of that, don't | ||
911 | * even attempt to use Synaptics mode. Relative mode seems to work | ||
912 | * just fine. | ||
1478 | */ | 913 | */ |
1479 | if (absolute_mode && broken_olpc_ec) { | 914 | if (broken_olpc_ec) { |
1480 | psmouse_info(psmouse, | 915 | printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n"); |
1481 | "OLPC XO detected, not enabling Synaptics protocol.\n"); | ||
1482 | return -ENODEV; | 916 | return -ENODEV; |
1483 | } | 917 | } |
1484 | 918 | ||
@@ -1489,28 +923,26 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | |||
1489 | psmouse_reset(psmouse); | 923 | psmouse_reset(psmouse); |
1490 | 924 | ||
1491 | if (synaptics_query_hardware(psmouse)) { | 925 | if (synaptics_query_hardware(psmouse)) { |
1492 | psmouse_err(psmouse, "Unable to query device.\n"); | 926 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); |
1493 | goto init_fail; | 927 | goto init_fail; |
1494 | } | 928 | } |
1495 | 929 | ||
1496 | priv->absolute_mode = absolute_mode; | 930 | if (synaptics_set_absolute_mode(psmouse)) { |
1497 | if (SYN_ID_DISGEST_SUPPORTED(priv->identity)) | 931 | printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); |
1498 | priv->disable_gesture = true; | 932 | goto init_fail; |
933 | } | ||
1499 | 934 | ||
1500 | if (synaptics_set_mode(psmouse)) { | 935 | if (synaptics_set_advanced_gesture_mode(psmouse)) { |
1501 | psmouse_err(psmouse, "Unable to initialize device.\n"); | 936 | printk(KERN_ERR "Advanced gesture mode init failed.\n"); |
1502 | goto init_fail; | 937 | goto init_fail; |
1503 | } | 938 | } |
1504 | 939 | ||
1505 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 940 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
1506 | 941 | ||
1507 | psmouse_info(psmouse, | 942 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
1508 | "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", | 943 | SYN_ID_MODEL(priv->identity), |
1509 | SYN_ID_MODEL(priv->identity), | 944 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
1510 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 945 | priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); |
1511 | priv->model_id, | ||
1512 | priv->capabilities, priv->ext_cap, priv->ext_cap_0c, | ||
1513 | priv->board_id, priv->firmware_id); | ||
1514 | 946 | ||
1515 | set_input_params(psmouse->dev, priv); | 947 | set_input_params(psmouse->dev, priv); |
1516 | 948 | ||
@@ -1524,19 +956,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | |||
1524 | psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | | 956 | psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | |
1525 | (priv->model_id & 0x000000ff); | 957 | (priv->model_id & 0x000000ff); |
1526 | 958 | ||
1527 | if (absolute_mode) { | 959 | psmouse->protocol_handler = synaptics_process_byte; |
1528 | psmouse->protocol_handler = synaptics_process_byte; | ||
1529 | psmouse->pktsize = 6; | ||
1530 | } else { | ||
1531 | /* Relative mode follows standard PS/2 mouse protocol */ | ||
1532 | psmouse->protocol_handler = psmouse_process_byte; | ||
1533 | psmouse->pktsize = 3; | ||
1534 | } | ||
1535 | |||
1536 | psmouse->set_rate = synaptics_set_rate; | 960 | psmouse->set_rate = synaptics_set_rate; |
1537 | psmouse->disconnect = synaptics_disconnect; | 961 | psmouse->disconnect = synaptics_disconnect; |
1538 | psmouse->reconnect = synaptics_reconnect; | 962 | psmouse->reconnect = synaptics_reconnect; |
1539 | psmouse->cleanup = synaptics_reset; | 963 | psmouse->cleanup = synaptics_reset; |
964 | psmouse->pktsize = 6; | ||
1540 | /* Synaptics can usually stay in sync without extra help */ | 965 | /* Synaptics can usually stay in sync without extra help */ |
1541 | psmouse->resync_time = 0; | 966 | psmouse->resync_time = 0; |
1542 | 967 | ||
@@ -1549,38 +974,16 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | |||
1549 | * the same rate as a standard PS/2 mouse). | 974 | * the same rate as a standard PS/2 mouse). |
1550 | */ | 975 | */ |
1551 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { | 976 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { |
1552 | psmouse_info(psmouse, | 977 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", |
1553 | "Toshiba %s detected, limiting rate to 40pps.\n", | 978 | dmi_get_system_info(DMI_PRODUCT_NAME)); |
1554 | dmi_get_system_info(DMI_PRODUCT_NAME)); | ||
1555 | psmouse->rate = 40; | 979 | psmouse->rate = 40; |
1556 | } | 980 | } |
1557 | 981 | ||
1558 | if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity)) { | ||
1559 | err = device_create_file(&psmouse->ps2dev.serio->dev, | ||
1560 | &psmouse_attr_disable_gesture.dattr); | ||
1561 | if (err) { | ||
1562 | psmouse_err(psmouse, | ||
1563 | "Failed to create disable_gesture attribute (%d)", | ||
1564 | err); | ||
1565 | goto init_fail; | ||
1566 | } | ||
1567 | } | ||
1568 | |||
1569 | return 0; | 982 | return 0; |
1570 | 983 | ||
1571 | init_fail: | 984 | init_fail: |
1572 | kfree(priv); | 985 | kfree(priv); |
1573 | return err; | 986 | return -1; |
1574 | } | ||
1575 | |||
1576 | int synaptics_init(struct psmouse *psmouse) | ||
1577 | { | ||
1578 | return __synaptics_init(psmouse, true); | ||
1579 | } | ||
1580 | |||
1581 | int synaptics_init_relative(struct psmouse *psmouse) | ||
1582 | { | ||
1583 | return __synaptics_init(psmouse, false); | ||
1584 | } | 987 | } |
1585 | 988 | ||
1586 | bool synaptics_supported(void) | 989 | bool synaptics_supported(void) |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index e594af0b264..ca040aa80fa 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -18,7 +18,6 @@ | |||
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_FIRMWARE_ID 0x0a | ||
22 | #define SYN_QUE_EXT_CAPAB_0C 0x0c | 21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c |
23 | #define SYN_QUE_EXT_MAX_COORDS 0x0d | 22 | #define SYN_QUE_EXT_MAX_COORDS 0x0d |
24 | #define SYN_QUE_EXT_MIN_COORDS 0x0f | 23 | #define SYN_QUE_EXT_MIN_COORDS 0x0f |
@@ -75,8 +74,6 @@ | |||
75 | * 2 0x04 reduced filtering firmware does less filtering on | 74 | * 2 0x04 reduced filtering firmware does less filtering on |
76 | * position data, driver should watch | 75 | * position data, driver should watch |
77 | * for noise. | 76 | * for noise. |
78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only | ||
79 | * reports 2. | ||
80 | * 2 0x20 report min query 0x0f gives min coord reported | 77 | * 2 0x20 report min query 0x0f gives min coord reported |
81 | */ | 78 | */ |
82 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 79 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
@@ -85,7 +82,6 @@ | |||
85 | #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000) | 82 | #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000) |
86 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | 83 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) |
87 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) | 84 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) |
88 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) | ||
89 | 85 | ||
90 | /* synaptics modes query bits */ | 86 | /* synaptics modes query bits */ |
91 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 87 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -101,7 +97,6 @@ | |||
101 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) | 97 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) |
102 | #define SYN_ID_FULL(i) ((SYN_ID_MAJOR(i) << 8) | SYN_ID_MINOR(i)) | 98 | #define SYN_ID_FULL(i) ((SYN_ID_MAJOR(i) << 8) | SYN_ID_MINOR(i)) |
103 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) | 99 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) |
104 | #define SYN_ID_DISGEST_SUPPORTED(i) (SYN_ID_MAJOR(i) >= 4) | ||
105 | 100 | ||
106 | /* synaptics special commands */ | 101 | /* synaptics special commands */ |
107 | #define SYN_PS_SET_MODE2 0x14 | 102 | #define SYN_PS_SET_MODE2 0x14 |
@@ -117,18 +112,9 @@ | |||
117 | #define SYN_REDUCED_FILTER_FUZZ 8 | 112 | #define SYN_REDUCED_FILTER_FUZZ 8 |
118 | 113 | ||
119 | /* | 114 | /* |
120 | * A structure to describe which internal touchpad finger slots are being | ||
121 | * reported in raw packets. | ||
122 | */ | ||
123 | struct synaptics_mt_state { | ||
124 | int count; /* num fingers being tracked */ | ||
125 | int sgm; /* which slot is reported by sgm pkt */ | ||
126 | int agm; /* which slot is reported by agm pkt*/ | ||
127 | }; | ||
128 | |||
129 | /* | ||
130 | * A structure to describe the state of the touchpad hardware (buttons and pad) | 115 | * A structure to describe the state of the touchpad hardware (buttons and pad) |
131 | */ | 116 | */ |
117 | |||
132 | struct synaptics_hw_state { | 118 | struct synaptics_hw_state { |
133 | int x; | 119 | int x; |
134 | int y; | 120 | int y; |
@@ -141,16 +127,11 @@ struct synaptics_hw_state { | |||
141 | unsigned int down:1; | 127 | unsigned int down:1; |
142 | unsigned char ext_buttons; | 128 | unsigned char ext_buttons; |
143 | signed char scroll; | 129 | signed char scroll; |
144 | |||
145 | /* As reported in last AGM-CONTACT packets */ | ||
146 | struct synaptics_mt_state mt_state; | ||
147 | }; | 130 | }; |
148 | 131 | ||
149 | struct synaptics_data { | 132 | struct synaptics_data { |
150 | /* Data read from the touchpad */ | 133 | /* Data read from the touchpad */ |
151 | unsigned long int model_id; /* Model-ID */ | 134 | unsigned long int model_id; /* Model-ID */ |
152 | unsigned long int firmware_id; /* Firmware-ID */ | ||
153 | unsigned long int board_id; /* Board-ID */ | ||
154 | unsigned long int capabilities; /* Capabilities */ | 135 | unsigned long int capabilities; /* Capabilities */ |
155 | unsigned long int ext_cap; /* Extended Capabilities */ | 136 | unsigned long int ext_cap; /* Extended Capabilities */ |
156 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ | 137 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ |
@@ -163,26 +144,14 @@ struct synaptics_data { | |||
163 | unsigned char mode; /* current mode byte */ | 144 | unsigned char mode; /* current mode byte */ |
164 | int scroll; | 145 | int scroll; |
165 | 146 | ||
166 | bool absolute_mode; /* run in Absolute mode */ | ||
167 | bool disable_gesture; /* disable gestures */ | ||
168 | |||
169 | struct serio *pt_port; /* Pass-through serio port */ | 147 | struct serio *pt_port; /* Pass-through serio port */ |
170 | 148 | ||
171 | struct synaptics_mt_state mt_state; /* Current mt finger state */ | 149 | struct synaptics_hw_state mt; /* current gesture packet */ |
172 | bool mt_state_lost; /* mt_state may be incorrect */ | ||
173 | |||
174 | /* | ||
175 | * Last received Advanced Gesture Mode (AGM) packet. An AGM packet | ||
176 | * contains position data for a second contact, at half resolution. | ||
177 | */ | ||
178 | struct synaptics_hw_state agm; | ||
179 | bool agm_pending; /* new AGM packet received */ | ||
180 | }; | 150 | }; |
181 | 151 | ||
182 | void synaptics_module_init(void); | 152 | void synaptics_module_init(void); |
183 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); | 153 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); |
184 | int synaptics_init(struct psmouse *psmouse); | 154 | int synaptics_init(struct psmouse *psmouse); |
185 | int synaptics_init_relative(struct psmouse *psmouse); | ||
186 | void synaptics_reset(struct psmouse *psmouse); | 155 | void synaptics_reset(struct psmouse *psmouse); |
187 | bool synaptics_supported(void); | 156 | bool synaptics_supported(void); |
188 | 157 | ||
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index ad822608f6e..cba3c84d2f2 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -185,17 +185,17 @@ | |||
185 | #define NO_DATA_SLEEP_MSECS (MSEC_PER_SEC / 4) | 185 | #define NO_DATA_SLEEP_MSECS (MSEC_PER_SEC / 4) |
186 | 186 | ||
187 | /* Control touchpad's No Deceleration option */ | 187 | /* Control touchpad's No Deceleration option */ |
188 | static bool no_decel = 1; | 188 | static int no_decel = 1; |
189 | module_param(no_decel, bool, 0644); | 189 | module_param(no_decel, bool, 0644); |
190 | MODULE_PARM_DESC(no_decel, "No Deceleration. Default = 1 (on)"); | 190 | MODULE_PARM_DESC(no_decel, "No Deceleration. Default = 1 (on)"); |
191 | 191 | ||
192 | /* Control touchpad's Reduced Reporting option */ | 192 | /* Control touchpad's Reduced Reporting option */ |
193 | static bool reduce_report; | 193 | static int reduce_report; |
194 | module_param(reduce_report, bool, 0644); | 194 | module_param(reduce_report, bool, 0644); |
195 | MODULE_PARM_DESC(reduce_report, "Reduced Reporting. Default = 0 (off)"); | 195 | MODULE_PARM_DESC(reduce_report, "Reduced Reporting. Default = 0 (off)"); |
196 | 196 | ||
197 | /* Control touchpad's No Filter option */ | 197 | /* Control touchpad's No Filter option */ |
198 | static bool no_filter; | 198 | static int no_filter; |
199 | module_param(no_filter, bool, 0644); | 199 | module_param(no_filter, bool, 0644); |
200 | MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)"); | 200 | MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)"); |
201 | 201 | ||
@@ -376,7 +376,12 @@ static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch, | |||
376 | 376 | ||
377 | spin_lock_irqsave(&touch->lock, flags); | 377 | spin_lock_irqsave(&touch->lock, flags); |
378 | 378 | ||
379 | mod_delayed_work(system_wq, &touch->dwork, delay); | 379 | /* |
380 | * If work is already scheduled then subsequent schedules will not | ||
381 | * change the scheduled time that's why we have to cancel it first. | ||
382 | */ | ||
383 | __cancel_delayed_work(&touch->dwork); | ||
384 | schedule_delayed_work(&touch->dwork, delay); | ||
380 | 385 | ||
381 | spin_unlock_irqrestore(&touch->lock, flags); | 386 | spin_unlock_irqrestore(&touch->lock, flags); |
382 | } | 387 | } |
@@ -535,7 +540,7 @@ static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *clien | |||
535 | return touch; | 540 | return touch; |
536 | } | 541 | } |
537 | 542 | ||
538 | static int synaptics_i2c_probe(struct i2c_client *client, | 543 | static int __devinit synaptics_i2c_probe(struct i2c_client *client, |
539 | const struct i2c_device_id *dev_id) | 544 | const struct i2c_device_id *dev_id) |
540 | { | 545 | { |
541 | int ret; | 546 | int ret; |
@@ -565,7 +570,7 @@ static int synaptics_i2c_probe(struct i2c_client *client, | |||
565 | "Requesting IRQ: %d\n", touch->client->irq); | 570 | "Requesting IRQ: %d\n", touch->client->irq); |
566 | 571 | ||
567 | ret = request_irq(touch->client->irq, synaptics_i2c_irq, | 572 | ret = request_irq(touch->client->irq, synaptics_i2c_irq, |
568 | IRQ_TYPE_EDGE_FALLING, | 573 | IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING, |
569 | DRIVER_NAME, touch); | 574 | DRIVER_NAME, touch); |
570 | if (ret) { | 575 | if (ret) { |
571 | dev_warn(&touch->client->dev, | 576 | dev_warn(&touch->client->dev, |
@@ -601,7 +606,7 @@ err_mem_free: | |||
601 | return ret; | 606 | return ret; |
602 | } | 607 | } |
603 | 608 | ||
604 | static int synaptics_i2c_remove(struct i2c_client *client) | 609 | static int __devexit synaptics_i2c_remove(struct i2c_client *client) |
605 | { | 610 | { |
606 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | 611 | struct synaptics_i2c *touch = i2c_get_clientdata(client); |
607 | 612 | ||
@@ -614,7 +619,7 @@ static int synaptics_i2c_remove(struct i2c_client *client) | |||
614 | return 0; | 619 | return 0; |
615 | } | 620 | } |
616 | 621 | ||
617 | #ifdef CONFIG_PM_SLEEP | 622 | #ifdef CONFIG_PM |
618 | static int synaptics_i2c_suspend(struct device *dev) | 623 | static int synaptics_i2c_suspend(struct device *dev) |
619 | { | 624 | { |
620 | struct i2c_client *client = to_i2c_client(dev); | 625 | struct i2c_client *client = to_i2c_client(dev); |
@@ -662,12 +667,23 @@ static struct i2c_driver synaptics_i2c_driver = { | |||
662 | }, | 667 | }, |
663 | 668 | ||
664 | .probe = synaptics_i2c_probe, | 669 | .probe = synaptics_i2c_probe, |
665 | .remove = synaptics_i2c_remove, | 670 | .remove = __devexit_p(synaptics_i2c_remove), |
666 | 671 | ||
667 | .id_table = synaptics_i2c_id_table, | 672 | .id_table = synaptics_i2c_id_table, |
668 | }; | 673 | }; |
669 | 674 | ||
670 | module_i2c_driver(synaptics_i2c_driver); | 675 | static int __init synaptics_i2c_init(void) |
676 | { | ||
677 | return i2c_add_driver(&synaptics_i2c_driver); | ||
678 | } | ||
679 | |||
680 | static void __exit synaptics_i2c_exit(void) | ||
681 | { | ||
682 | i2c_del_driver(&synaptics_i2c_driver); | ||
683 | } | ||
684 | |||
685 | module_init(synaptics_i2c_init); | ||
686 | module_exit(synaptics_i2c_exit); | ||
671 | 687 | ||
672 | MODULE_DESCRIPTION("Synaptics I2C touchpad driver"); | 688 | MODULE_DESCRIPTION("Synaptics I2C touchpad driver"); |
673 | MODULE_AUTHOR("Mike Rapoport, Igor Grinberg, Compulab"); | 689 | MODULE_AUTHOR("Mike Rapoport, Igor Grinberg, Compulab"); |
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c deleted file mode 100644 index 64cf34ea760..00000000000 --- a/drivers/input/mouse/synaptics_usb.c +++ /dev/null | |||
@@ -1,557 +0,0 @@ | |||
1 | /* | ||
2 | * USB Synaptics device driver | ||
3 | * | ||
4 | * Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk) | ||
5 | * Copyright (c) 2003 Ron Lee (ron@debian.org) | ||
6 | * cPad driver for kernel 2.4 | ||
7 | * | ||
8 | * Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de) | ||
9 | * Copyright (c) 2004 Ron Lee (ron@debian.org) | ||
10 | * rewritten for kernel 2.6 | ||
11 | * | ||
12 | * cPad display character device part is not included. It can be found at | ||
13 | * http://jan-steinhoff.de/linux/synaptics-usb.html | ||
14 | * | ||
15 | * Bases on: usb_skeleton.c v2.2 by Greg Kroah-Hartman | ||
16 | * drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik | ||
17 | * drivers/input/mouse/synaptics.c by Peter Osterlund | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify it | ||
20 | * under the terms of the GNU General Public License as published by the Free | ||
21 | * Software Foundation; either version 2 of the License, or (at your option) | ||
22 | * any later version. | ||
23 | * | ||
24 | * Trademarks are the property of their respective owners. | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * There are three different types of Synaptics USB devices: Touchpads, | ||
29 | * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported | ||
30 | * by this driver, touchstick support has not been tested much yet, and | ||
31 | * touchscreens have not been tested at all. | ||
32 | * | ||
33 | * Up to three alternate settings are possible: | ||
34 | * setting 0: one int endpoint for relative movement (used by usbhid.ko) | ||
35 | * setting 1: one int endpoint for absolute finger position | ||
36 | * setting 2 (cPad only): one int endpoint for absolute finger position and | ||
37 | * two bulk endpoints for the display (in/out) | ||
38 | * This driver uses setting 1. | ||
39 | */ | ||
40 | |||
41 | #include <linux/kernel.h> | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/slab.h> | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/moduleparam.h> | ||
46 | #include <linux/usb.h> | ||
47 | #include <linux/input.h> | ||
48 | #include <linux/usb/input.h> | ||
49 | |||
50 | #define USB_VENDOR_ID_SYNAPTICS 0x06cb | ||
51 | #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 /* Synaptics USB TouchPad */ | ||
52 | #define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 /* Integrated USB TouchPad */ | ||
53 | #define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 /* Synaptics cPad */ | ||
54 | #define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 /* Synaptics TouchScreen */ | ||
55 | #define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 /* Synaptics USB Styk */ | ||
56 | #define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 /* Synaptics USB WheelPad */ | ||
57 | #define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 /* Composite USB TouchPad */ | ||
58 | #define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 /* Wireless TouchPad */ | ||
59 | #define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 /* DisplayPad */ | ||
60 | |||
61 | #define SYNUSB_TOUCHPAD (1 << 0) | ||
62 | #define SYNUSB_STICK (1 << 1) | ||
63 | #define SYNUSB_TOUCHSCREEN (1 << 2) | ||
64 | #define SYNUSB_AUXDISPLAY (1 << 3) /* For cPad */ | ||
65 | #define SYNUSB_COMBO (1 << 4) /* Composite device (TP + stick) */ | ||
66 | #define SYNUSB_IO_ALWAYS (1 << 5) | ||
67 | |||
68 | #define USB_DEVICE_SYNAPTICS(prod, kind) \ | ||
69 | USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, \ | ||
70 | USB_DEVICE_ID_SYNAPTICS_##prod), \ | ||
71 | .driver_info = (kind), | ||
72 | |||
73 | #define SYNUSB_RECV_SIZE 8 | ||
74 | |||
75 | #define XMIN_NOMINAL 1472 | ||
76 | #define XMAX_NOMINAL 5472 | ||
77 | #define YMIN_NOMINAL 1408 | ||
78 | #define YMAX_NOMINAL 4448 | ||
79 | |||
80 | struct synusb { | ||
81 | struct usb_device *udev; | ||
82 | struct usb_interface *intf; | ||
83 | struct urb *urb; | ||
84 | unsigned char *data; | ||
85 | |||
86 | /* input device related data structures */ | ||
87 | struct input_dev *input; | ||
88 | char name[128]; | ||
89 | char phys[64]; | ||
90 | |||
91 | /* characteristics of the device */ | ||
92 | unsigned long flags; | ||
93 | }; | ||
94 | |||
95 | static void synusb_report_buttons(struct synusb *synusb) | ||
96 | { | ||
97 | struct input_dev *input_dev = synusb->input; | ||
98 | |||
99 | input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04); | ||
100 | input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01); | ||
101 | input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02); | ||
102 | } | ||
103 | |||
104 | static void synusb_report_stick(struct synusb *synusb) | ||
105 | { | ||
106 | struct input_dev *input_dev = synusb->input; | ||
107 | int x, y; | ||
108 | unsigned int pressure; | ||
109 | |||
110 | pressure = synusb->data[6]; | ||
111 | x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7; | ||
112 | y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7; | ||
113 | |||
114 | if (pressure > 0) { | ||
115 | input_report_rel(input_dev, REL_X, x); | ||
116 | input_report_rel(input_dev, REL_Y, -y); | ||
117 | } | ||
118 | |||
119 | input_report_abs(input_dev, ABS_PRESSURE, pressure); | ||
120 | |||
121 | synusb_report_buttons(synusb); | ||
122 | |||
123 | input_sync(input_dev); | ||
124 | } | ||
125 | |||
126 | static void synusb_report_touchpad(struct synusb *synusb) | ||
127 | { | ||
128 | struct input_dev *input_dev = synusb->input; | ||
129 | unsigned int num_fingers, tool_width; | ||
130 | unsigned int x, y; | ||
131 | unsigned int pressure, w; | ||
132 | |||
133 | pressure = synusb->data[6]; | ||
134 | x = be16_to_cpup((__be16 *)&synusb->data[2]); | ||
135 | y = be16_to_cpup((__be16 *)&synusb->data[4]); | ||
136 | w = synusb->data[0] & 0x0f; | ||
137 | |||
138 | if (pressure > 0) { | ||
139 | num_fingers = 1; | ||
140 | tool_width = 5; | ||
141 | switch (w) { | ||
142 | case 0 ... 1: | ||
143 | num_fingers = 2 + w; | ||
144 | break; | ||
145 | |||
146 | case 2: /* pen, pretend its a finger */ | ||
147 | break; | ||
148 | |||
149 | case 4 ... 15: | ||
150 | tool_width = w; | ||
151 | break; | ||
152 | } | ||
153 | } else { | ||
154 | num_fingers = 0; | ||
155 | tool_width = 0; | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Post events | ||
160 | * BTN_TOUCH has to be first as mousedev relies on it when doing | ||
161 | * absolute -> relative conversion | ||
162 | */ | ||
163 | |||
164 | if (pressure > 30) | ||
165 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
166 | if (pressure < 25) | ||
167 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
168 | |||
169 | if (num_fingers > 0) { | ||
170 | input_report_abs(input_dev, ABS_X, x); | ||
171 | input_report_abs(input_dev, ABS_Y, | ||
172 | YMAX_NOMINAL + YMIN_NOMINAL - y); | ||
173 | } | ||
174 | |||
175 | input_report_abs(input_dev, ABS_PRESSURE, pressure); | ||
176 | input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width); | ||
177 | |||
178 | input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1); | ||
179 | input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); | ||
180 | input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); | ||
181 | |||
182 | synusb_report_buttons(synusb); | ||
183 | if (synusb->flags & SYNUSB_AUXDISPLAY) | ||
184 | input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08); | ||
185 | |||
186 | input_sync(input_dev); | ||
187 | } | ||
188 | |||
189 | static void synusb_irq(struct urb *urb) | ||
190 | { | ||
191 | struct synusb *synusb = urb->context; | ||
192 | int error; | ||
193 | |||
194 | /* Check our status in case we need to bail out early. */ | ||
195 | switch (urb->status) { | ||
196 | case 0: | ||
197 | usb_mark_last_busy(synusb->udev); | ||
198 | break; | ||
199 | |||
200 | /* Device went away so don't keep trying to read from it. */ | ||
201 | case -ECONNRESET: | ||
202 | case -ENOENT: | ||
203 | case -ESHUTDOWN: | ||
204 | return; | ||
205 | |||
206 | default: | ||
207 | goto resubmit; | ||
208 | break; | ||
209 | } | ||
210 | |||
211 | if (synusb->flags & SYNUSB_STICK) | ||
212 | synusb_report_stick(synusb); | ||
213 | else | ||
214 | synusb_report_touchpad(synusb); | ||
215 | |||
216 | resubmit: | ||
217 | error = usb_submit_urb(urb, GFP_ATOMIC); | ||
218 | if (error && error != -EPERM) | ||
219 | dev_err(&synusb->intf->dev, | ||
220 | "%s - usb_submit_urb failed with result: %d", | ||
221 | __func__, error); | ||
222 | } | ||
223 | |||
224 | static struct usb_endpoint_descriptor * | ||
225 | synusb_get_in_endpoint(struct usb_host_interface *iface) | ||
226 | { | ||
227 | |||
228 | struct usb_endpoint_descriptor *endpoint; | ||
229 | int i; | ||
230 | |||
231 | for (i = 0; i < iface->desc.bNumEndpoints; ++i) { | ||
232 | endpoint = &iface->endpoint[i].desc; | ||
233 | |||
234 | if (usb_endpoint_is_int_in(endpoint)) { | ||
235 | /* we found our interrupt in endpoint */ | ||
236 | return endpoint; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | return NULL; | ||
241 | } | ||
242 | |||
243 | static int synusb_open(struct input_dev *dev) | ||
244 | { | ||
245 | struct synusb *synusb = input_get_drvdata(dev); | ||
246 | int retval; | ||
247 | |||
248 | retval = usb_autopm_get_interface(synusb->intf); | ||
249 | if (retval) { | ||
250 | dev_err(&synusb->intf->dev, | ||
251 | "%s - usb_autopm_get_interface failed, error: %d\n", | ||
252 | __func__, retval); | ||
253 | return retval; | ||
254 | } | ||
255 | |||
256 | retval = usb_submit_urb(synusb->urb, GFP_KERNEL); | ||
257 | if (retval) { | ||
258 | dev_err(&synusb->intf->dev, | ||
259 | "%s - usb_submit_urb failed, error: %d\n", | ||
260 | __func__, retval); | ||
261 | retval = -EIO; | ||
262 | goto out; | ||
263 | } | ||
264 | |||
265 | synusb->intf->needs_remote_wakeup = 1; | ||
266 | |||
267 | out: | ||
268 | usb_autopm_put_interface(synusb->intf); | ||
269 | return retval; | ||
270 | } | ||
271 | |||
272 | static void synusb_close(struct input_dev *dev) | ||
273 | { | ||
274 | struct synusb *synusb = input_get_drvdata(dev); | ||
275 | int autopm_error; | ||
276 | |||
277 | autopm_error = usb_autopm_get_interface(synusb->intf); | ||
278 | |||
279 | usb_kill_urb(synusb->urb); | ||
280 | synusb->intf->needs_remote_wakeup = 0; | ||
281 | |||
282 | if (!autopm_error) | ||
283 | usb_autopm_put_interface(synusb->intf); | ||
284 | } | ||
285 | |||
286 | static int synusb_probe(struct usb_interface *intf, | ||
287 | const struct usb_device_id *id) | ||
288 | { | ||
289 | struct usb_device *udev = interface_to_usbdev(intf); | ||
290 | struct usb_endpoint_descriptor *ep; | ||
291 | struct synusb *synusb; | ||
292 | struct input_dev *input_dev; | ||
293 | unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber; | ||
294 | unsigned int altsetting = min(intf->num_altsetting, 1U); | ||
295 | int error; | ||
296 | |||
297 | error = usb_set_interface(udev, intf_num, altsetting); | ||
298 | if (error) { | ||
299 | dev_err(&udev->dev, | ||
300 | "Can not set alternate setting to %i, error: %i", | ||
301 | altsetting, error); | ||
302 | return error; | ||
303 | } | ||
304 | |||
305 | ep = synusb_get_in_endpoint(intf->cur_altsetting); | ||
306 | if (!ep) | ||
307 | return -ENODEV; | ||
308 | |||
309 | synusb = kzalloc(sizeof(*synusb), GFP_KERNEL); | ||
310 | input_dev = input_allocate_device(); | ||
311 | if (!synusb || !input_dev) { | ||
312 | error = -ENOMEM; | ||
313 | goto err_free_mem; | ||
314 | } | ||
315 | |||
316 | synusb->udev = udev; | ||
317 | synusb->intf = intf; | ||
318 | synusb->input = input_dev; | ||
319 | |||
320 | synusb->flags = id->driver_info; | ||
321 | if (synusb->flags & SYNUSB_COMBO) { | ||
322 | /* | ||
323 | * This is a combo device, we need to set proper | ||
324 | * capability, depending on the interface. | ||
325 | */ | ||
326 | synusb->flags |= intf_num == 1 ? | ||
327 | SYNUSB_STICK : SYNUSB_TOUCHPAD; | ||
328 | } | ||
329 | |||
330 | synusb->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
331 | if (!synusb->urb) { | ||
332 | error = -ENOMEM; | ||
333 | goto err_free_mem; | ||
334 | } | ||
335 | |||
336 | synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL, | ||
337 | &synusb->urb->transfer_dma); | ||
338 | if (!synusb->data) { | ||
339 | error = -ENOMEM; | ||
340 | goto err_free_urb; | ||
341 | } | ||
342 | |||
343 | usb_fill_int_urb(synusb->urb, udev, | ||
344 | usb_rcvintpipe(udev, ep->bEndpointAddress), | ||
345 | synusb->data, SYNUSB_RECV_SIZE, | ||
346 | synusb_irq, synusb, | ||
347 | ep->bInterval); | ||
348 | synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
349 | |||
350 | if (udev->manufacturer) | ||
351 | strlcpy(synusb->name, udev->manufacturer, | ||
352 | sizeof(synusb->name)); | ||
353 | |||
354 | if (udev->product) { | ||
355 | if (udev->manufacturer) | ||
356 | strlcat(synusb->name, " ", sizeof(synusb->name)); | ||
357 | strlcat(synusb->name, udev->product, sizeof(synusb->name)); | ||
358 | } | ||
359 | |||
360 | if (!strlen(synusb->name)) | ||
361 | snprintf(synusb->name, sizeof(synusb->name), | ||
362 | "USB Synaptics Device %04x:%04x", | ||
363 | le16_to_cpu(udev->descriptor.idVendor), | ||
364 | le16_to_cpu(udev->descriptor.idProduct)); | ||
365 | |||
366 | if (synusb->flags & SYNUSB_STICK) | ||
367 | strlcat(synusb->name, " (Stick)", sizeof(synusb->name)); | ||
368 | |||
369 | usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); | ||
370 | strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); | ||
371 | |||
372 | input_dev->name = synusb->name; | ||
373 | input_dev->phys = synusb->phys; | ||
374 | usb_to_input_id(udev, &input_dev->id); | ||
375 | input_dev->dev.parent = &synusb->intf->dev; | ||
376 | |||
377 | if (!(synusb->flags & SYNUSB_IO_ALWAYS)) { | ||
378 | input_dev->open = synusb_open; | ||
379 | input_dev->close = synusb_close; | ||
380 | } | ||
381 | |||
382 | input_set_drvdata(input_dev, synusb); | ||
383 | |||
384 | __set_bit(EV_ABS, input_dev->evbit); | ||
385 | __set_bit(EV_KEY, input_dev->evbit); | ||
386 | |||
387 | if (synusb->flags & SYNUSB_STICK) { | ||
388 | __set_bit(EV_REL, input_dev->evbit); | ||
389 | __set_bit(REL_X, input_dev->relbit); | ||
390 | __set_bit(REL_Y, input_dev->relbit); | ||
391 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); | ||
392 | } else { | ||
393 | input_set_abs_params(input_dev, ABS_X, | ||
394 | XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); | ||
395 | input_set_abs_params(input_dev, ABS_Y, | ||
396 | YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); | ||
397 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); | ||
398 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); | ||
399 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
400 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
401 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
402 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
403 | } | ||
404 | |||
405 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
406 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
407 | __set_bit(BTN_MIDDLE, input_dev->keybit); | ||
408 | |||
409 | usb_set_intfdata(intf, synusb); | ||
410 | |||
411 | if (synusb->flags & SYNUSB_IO_ALWAYS) { | ||
412 | error = synusb_open(input_dev); | ||
413 | if (error) | ||
414 | goto err_free_dma; | ||
415 | } | ||
416 | |||
417 | error = input_register_device(input_dev); | ||
418 | if (error) { | ||
419 | dev_err(&udev->dev, | ||
420 | "Failed to register input device, error %d\n", | ||
421 | error); | ||
422 | goto err_stop_io; | ||
423 | } | ||
424 | |||
425 | return 0; | ||
426 | |||
427 | err_stop_io: | ||
428 | if (synusb->flags & SYNUSB_IO_ALWAYS) | ||
429 | synusb_close(synusb->input); | ||
430 | err_free_dma: | ||
431 | usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, | ||
432 | synusb->urb->transfer_dma); | ||
433 | err_free_urb: | ||
434 | usb_free_urb(synusb->urb); | ||
435 | err_free_mem: | ||
436 | input_free_device(input_dev); | ||
437 | kfree(synusb); | ||
438 | usb_set_intfdata(intf, NULL); | ||
439 | |||
440 | return error; | ||
441 | } | ||
442 | |||
443 | static void synusb_disconnect(struct usb_interface *intf) | ||
444 | { | ||
445 | struct synusb *synusb = usb_get_intfdata(intf); | ||
446 | struct usb_device *udev = interface_to_usbdev(intf); | ||
447 | |||
448 | if (synusb->flags & SYNUSB_IO_ALWAYS) | ||
449 | synusb_close(synusb->input); | ||
450 | |||
451 | input_unregister_device(synusb->input); | ||
452 | |||
453 | usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, | ||
454 | synusb->urb->transfer_dma); | ||
455 | usb_free_urb(synusb->urb); | ||
456 | kfree(synusb); | ||
457 | |||
458 | usb_set_intfdata(intf, NULL); | ||
459 | } | ||
460 | |||
461 | static int synusb_suspend(struct usb_interface *intf, pm_message_t message) | ||
462 | { | ||
463 | struct synusb *synusb = usb_get_intfdata(intf); | ||
464 | struct input_dev *input_dev = synusb->input; | ||
465 | |||
466 | mutex_lock(&input_dev->mutex); | ||
467 | usb_kill_urb(synusb->urb); | ||
468 | mutex_unlock(&input_dev->mutex); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int synusb_resume(struct usb_interface *intf) | ||
474 | { | ||
475 | struct synusb *synusb = usb_get_intfdata(intf); | ||
476 | struct input_dev *input_dev = synusb->input; | ||
477 | int retval = 0; | ||
478 | |||
479 | mutex_lock(&input_dev->mutex); | ||
480 | |||
481 | if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && | ||
482 | usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { | ||
483 | retval = -EIO; | ||
484 | } | ||
485 | |||
486 | mutex_unlock(&input_dev->mutex); | ||
487 | |||
488 | return retval; | ||
489 | } | ||
490 | |||
491 | static int synusb_pre_reset(struct usb_interface *intf) | ||
492 | { | ||
493 | struct synusb *synusb = usb_get_intfdata(intf); | ||
494 | struct input_dev *input_dev = synusb->input; | ||
495 | |||
496 | mutex_lock(&input_dev->mutex); | ||
497 | usb_kill_urb(synusb->urb); | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int synusb_post_reset(struct usb_interface *intf) | ||
503 | { | ||
504 | struct synusb *synusb = usb_get_intfdata(intf); | ||
505 | struct input_dev *input_dev = synusb->input; | ||
506 | int retval = 0; | ||
507 | |||
508 | if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && | ||
509 | usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { | ||
510 | retval = -EIO; | ||
511 | } | ||
512 | |||
513 | mutex_unlock(&input_dev->mutex); | ||
514 | |||
515 | return retval; | ||
516 | } | ||
517 | |||
518 | static int synusb_reset_resume(struct usb_interface *intf) | ||
519 | { | ||
520 | return synusb_resume(intf); | ||
521 | } | ||
522 | |||
523 | static struct usb_device_id synusb_idtable[] = { | ||
524 | { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) }, | ||
525 | { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) }, | ||
526 | { USB_DEVICE_SYNAPTICS(CPAD, | ||
527 | SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) }, | ||
528 | { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) }, | ||
529 | { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) }, | ||
530 | { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) }, | ||
531 | { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) }, | ||
532 | { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) }, | ||
533 | { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) }, | ||
534 | { } | ||
535 | }; | ||
536 | MODULE_DEVICE_TABLE(usb, synusb_idtable); | ||
537 | |||
538 | static struct usb_driver synusb_driver = { | ||
539 | .name = "synaptics_usb", | ||
540 | .probe = synusb_probe, | ||
541 | .disconnect = synusb_disconnect, | ||
542 | .id_table = synusb_idtable, | ||
543 | .suspend = synusb_suspend, | ||
544 | .resume = synusb_resume, | ||
545 | .pre_reset = synusb_pre_reset, | ||
546 | .post_reset = synusb_post_reset, | ||
547 | .reset_resume = synusb_reset_resume, | ||
548 | .supports_autosuspend = 1, | ||
549 | }; | ||
550 | |||
551 | module_usb_driver(synusb_driver); | ||
552 | |||
553 | MODULE_AUTHOR("Rob Miller <rob@inpharmatica.co.uk>, " | ||
554 | "Ron Lee <ron@debian.org>, " | ||
555 | "Jan Steinhoff <cpad@jan-steinhoff.de>"); | ||
556 | MODULE_DESCRIPTION("Synaptics USB device driver"); | ||
557 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index f3102494237..54b2fa892e1 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -89,12 +89,10 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, | |||
89 | struct trackpoint_data *tp = psmouse->private; | 89 | struct trackpoint_data *tp = psmouse->private; |
90 | struct trackpoint_attr_data *attr = data; | 90 | struct trackpoint_attr_data *attr = data; |
91 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 91 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); |
92 | unsigned char value; | 92 | unsigned long value; |
93 | int err; | ||
94 | 93 | ||
95 | err = kstrtou8(buf, 10, &value); | 94 | if (strict_strtoul(buf, 10, &value) || value > 255) |
96 | if (err) | 95 | return -EINVAL; |
97 | return err; | ||
98 | 96 | ||
99 | *field = value; | 97 | *field = value; |
100 | trackpoint_write(&psmouse->ps2dev, attr->command, value); | 98 | trackpoint_write(&psmouse->ps2dev, attr->command, value); |
@@ -117,14 +115,9 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, | |||
117 | struct trackpoint_data *tp = psmouse->private; | 115 | struct trackpoint_data *tp = psmouse->private; |
118 | struct trackpoint_attr_data *attr = data; | 116 | struct trackpoint_attr_data *attr = data; |
119 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 117 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); |
120 | unsigned int value; | 118 | unsigned long value; |
121 | int err; | ||
122 | |||
123 | err = kstrtouint(buf, 10, &value); | ||
124 | if (err) | ||
125 | return err; | ||
126 | 119 | ||
127 | if (value > 1) | 120 | if (strict_strtoul(buf, 10, &value) || value > 1) |
128 | return -EINVAL; | 121 | return -EINVAL; |
129 | 122 | ||
130 | if (attr->inverted) | 123 | if (attr->inverted) |
@@ -304,7 +297,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
304 | return 0; | 297 | return 0; |
305 | 298 | ||
306 | if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { | 299 | if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { |
307 | psmouse_warn(psmouse, "failed to get extended button data\n"); | 300 | printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); |
308 | button_info = 0; | 301 | button_info = 0; |
309 | } | 302 | } |
310 | 303 | ||
@@ -326,18 +319,16 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
326 | 319 | ||
327 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); | 320 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); |
328 | if (error) { | 321 | if (error) { |
329 | psmouse_err(psmouse, | 322 | printk(KERN_ERR |
330 | "failed to create sysfs attributes, error: %d\n", | 323 | "trackpoint.c: failed to create sysfs attributes, error: %d\n", |
331 | error); | 324 | error); |
332 | kfree(psmouse->private); | 325 | kfree(psmouse->private); |
333 | psmouse->private = NULL; | 326 | psmouse->private = NULL; |
334 | return -1; | 327 | return -1; |
335 | } | 328 | } |
336 | 329 | ||
337 | psmouse_info(psmouse, | 330 | printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", |
338 | "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", | 331 | firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); |
339 | firmware_id, | ||
340 | (button_info & 0xf0) >> 4, button_info & 0x0f); | ||
341 | 332 | ||
342 | return 0; | 333 | return 0; |
343 | } | 334 | } |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index e900d465aaf..eb9a3cfbeef 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -548,4 +548,16 @@ static struct serio_driver vsxxxaa_drv = { | |||
548 | .disconnect = vsxxxaa_disconnect, | 548 | .disconnect = vsxxxaa_disconnect, |
549 | }; | 549 | }; |
550 | 550 | ||
551 | module_serio_driver(vsxxxaa_drv); | 551 | static int __init vsxxxaa_init(void) |
552 | { | ||
553 | return serio_register_driver(&vsxxxaa_drv); | ||
554 | } | ||
555 | |||
556 | static void __exit vsxxxaa_exit(void) | ||
557 | { | ||
558 | serio_unregister_driver(&vsxxxaa_drv); | ||
559 | } | ||
560 | |||
561 | module_init(vsxxxaa_init); | ||
562 | module_exit(vsxxxaa_exit); | ||
563 | |||