diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-05-10 09:32:46 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-05-10 09:32:46 -0400 |
commit | 0ae28a35bcb7984838acbf28bfba9c030f8b74f0 (patch) | |
tree | 4f449d929b5df9e126e839f388ff0fd2b52028a0 /drivers/input/mouse/elantech.c | |
parent | 6f1f3d0ab5c3eeea9f04486481c25e9afdfa26c5 (diff) | |
parent | b57f95a38233a2e73b679bea4a5453a1cc2a1cc9 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/mtd/mtdcore.c
Pull in the bdi fixes and ARM platform changes that other outstanding
patches depend on.
Diffstat (limited to 'drivers/input/mouse/elantech.c')
-rw-r--r-- | drivers/input/mouse/elantech.c | 85 |
1 files changed, 57 insertions, 28 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b27684f267bf..0520c2e19927 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/input.h> | 16 | #include <linux/input.h> |
16 | #include <linux/serio.h> | 17 | #include <linux/serio.h> |
@@ -24,6 +25,10 @@ | |||
24 | printk(KERN_DEBUG format, ##arg); \ | 25 | printk(KERN_DEBUG format, ##arg); \ |
25 | } while (0) | 26 | } while (0) |
26 | 27 | ||
28 | static bool force_elantech; | ||
29 | module_param_named(force_elantech, force_elantech, bool, 0644); | ||
30 | MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default)."); | ||
31 | |||
27 | /* | 32 | /* |
28 | * Send a Synaptics style sliced query command | 33 | * Send a Synaptics style sliced query command |
29 | */ | 34 | */ |
@@ -181,13 +186,17 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
181 | static int old_fingers; | 186 | static int old_fingers; |
182 | 187 | ||
183 | if (etd->fw_version_maj == 0x01) { | 188 | if (etd->fw_version_maj == 0x01) { |
184 | /* byte 0: D U p1 p2 1 p3 R L | 189 | /* |
185 | byte 1: f 0 th tw x9 x8 y9 y8 */ | 190 | * byte 0: D U p1 p2 1 p3 R L |
191 | * byte 1: f 0 th tw x9 x8 y9 y8 | ||
192 | */ | ||
186 | fingers = ((packet[1] & 0x80) >> 7) + | 193 | fingers = ((packet[1] & 0x80) >> 7) + |
187 | ((packet[1] & 0x30) >> 4); | 194 | ((packet[1] & 0x30) >> 4); |
188 | } else { | 195 | } else { |
189 | /* byte 0: n1 n0 p2 p1 1 p3 R L | 196 | /* |
190 | byte 1: 0 0 0 0 x9 x8 y9 y8 */ | 197 | * byte 0: n1 n0 p2 p1 1 p3 R L |
198 | * byte 1: 0 0 0 0 x9 x8 y9 y8 | ||
199 | */ | ||
191 | fingers = (packet[0] & 0xc0) >> 6; | 200 | fingers = (packet[0] & 0xc0) >> 6; |
192 | } | 201 | } |
193 | 202 | ||
@@ -201,13 +210,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
201 | 210 | ||
202 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 211 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
203 | 212 | ||
204 | /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 | 213 | /* |
205 | byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ | 214 | * byte 2: x7 x6 x5 x4 x3 x2 x1 x0 |
215 | * byte 3: y7 y6 y5 y4 y3 y2 y1 y0 | ||
216 | */ | ||
206 | if (fingers) { | 217 | if (fingers) { |
207 | input_report_abs(dev, ABS_X, | 218 | input_report_abs(dev, ABS_X, |
208 | ((packet[1] & 0x0c) << 6) | packet[2]); | 219 | ((packet[1] & 0x0c) << 6) | packet[2]); |
209 | input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - | 220 | input_report_abs(dev, ABS_Y, |
210 | (((packet[1] & 0x03) << 8) | packet[3])); | 221 | ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); |
211 | } | 222 | } |
212 | 223 | ||
213 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 224 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
@@ -246,34 +257,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
246 | 257 | ||
247 | switch (fingers) { | 258 | switch (fingers) { |
248 | case 1: | 259 | case 1: |
249 | /* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 | 260 | /* |
250 | byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ | 261 | * byte 1: . . . . . x10 x9 x8 |
251 | input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); | 262 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
252 | /* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 | 263 | */ |
253 | byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ | 264 | input_report_abs(dev, ABS_X, |
254 | input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - | 265 | ((packet[1] & 0x07) << 8) | packet[2]); |
255 | ((packet[4] << 8) | packet[5])); | 266 | /* |
267 | * byte 4: . . . . . . y9 y8 | ||
268 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
269 | */ | ||
270 | input_report_abs(dev, ABS_Y, | ||
271 | ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); | ||
256 | break; | 272 | break; |
257 | 273 | ||
258 | case 2: | 274 | case 2: |
259 | /* The coordinate of each finger is reported separately with | 275 | /* |
260 | a lower resolution for two finger touches */ | 276 | * The coordinate of each finger is reported separately |
261 | /* byte 0: . . ay8 ax8 . . . . | 277 | * with a lower resolution for two finger touches: |
262 | byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ | 278 | * byte 0: . . ay8 ax8 . . . . |
279 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | ||
280 | */ | ||
263 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; | 281 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; |
264 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ | 282 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ |
265 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); | 283 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); |
266 | /* byte 3: . . by8 bx8 . . . . | 284 | /* |
267 | byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ | 285 | * byte 3: . . by8 bx8 . . . . |
286 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | ||
287 | */ | ||
268 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; | 288 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; |
269 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ | 289 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ |
270 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); | 290 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); |
271 | /* For compatibility with the X Synaptics driver scale up one | 291 | /* |
272 | coordinate and report as ordinary mouse movent */ | 292 | * For compatibility with the X Synaptics driver scale up |
293 | * one coordinate and report as ordinary mouse movent | ||
294 | */ | ||
273 | input_report_abs(dev, ABS_X, x1 << 2); | 295 | input_report_abs(dev, ABS_X, x1 << 2); |
274 | input_report_abs(dev, ABS_Y, y1 << 2); | 296 | input_report_abs(dev, ABS_Y, y1 << 2); |
275 | /* For compatibility with the proprietary X Elantech driver | 297 | /* |
276 | report both coordinates as hat coordinates */ | 298 | * For compatibility with the proprietary X Elantech driver |
299 | * report both coordinates as hat coordinates | ||
300 | */ | ||
277 | input_report_abs(dev, ABS_HAT0X, x1); | 301 | input_report_abs(dev, ABS_HAT0X, x1); |
278 | input_report_abs(dev, ABS_HAT0Y, y1); | 302 | input_report_abs(dev, ABS_HAT0Y, y1); |
279 | input_report_abs(dev, ABS_HAT1X, x2); | 303 | input_report_abs(dev, ABS_HAT1X, x2); |
@@ -595,8 +619,12 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
595 | param[0], param[1], param[2]); | 619 | param[0], param[1], param[2]); |
596 | 620 | ||
597 | if (param[0] == 0 || param[1] != 0) { | 621 | if (param[0] == 0 || param[1] != 0) { |
598 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); | 622 | if (!force_elantech) { |
599 | return -1; | 623 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); |
624 | return -1; | ||
625 | } | ||
626 | |||
627 | pr_debug("elantech.c: Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); | ||
600 | } | 628 | } |
601 | 629 | ||
602 | if (set_properties) { | 630 | if (set_properties) { |
@@ -665,7 +693,8 @@ int elantech_init(struct psmouse *psmouse) | |||
665 | * Assume every version greater than this is new EeePC style | 693 | * Assume every version greater than this is new EeePC style |
666 | * hardware with 6 byte packets | 694 | * hardware with 6 byte packets |
667 | */ | 695 | */ |
668 | if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) { | 696 | if ((etd->fw_version_maj == 0x02 && etd->fw_version_min >= 0x30) || |
697 | etd->fw_version_maj > 0x02) { | ||
669 | etd->hw_version = 2; | 698 | etd->hw_version = 2; |
670 | /* For now show extra debug information */ | 699 | /* For now show extra debug information */ |
671 | etd->debug = 1; | 700 | etd->debug = 1; |