Input: wistron_btns - switch to using kmemdup()
[deliverable/linux.git] / drivers / input / mouse / elantech.c
CommitLineData
2a0bd75e 1/*
3f8c0df4 2 * Elantech Touchpad driver (v6)
2a0bd75e 3 *
3f8c0df4 4 * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net>
2a0bd75e
AO
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 *
10 * Trademarks are the property of their respective owners.
11 */
12
13#include <linux/delay.h>
5a0e3ad6 14#include <linux/slab.h>
2a0bd75e
AO
15#include <linux/module.h>
16#include <linux/input.h>
17#include <linux/serio.h>
18#include <linux/libps2.h>
19#include "psmouse.h"
20#include "elantech.h"
21
22#define elantech_debug(format, arg...) \
23 do { \
24 if (etd->debug) \
25 printk(KERN_DEBUG format, ##arg); \
26 } while (0)
27
f81bc788
FR
28static bool force_elantech;
29module_param_named(force_elantech, force_elantech, bool, 0644);
30MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default).");
31
2a0bd75e
AO
32/*
33 * Send a Synaptics style sliced query command
34 */
35static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c,
36 unsigned char *param)
37{
38 if (psmouse_sliced_command(psmouse, c) ||
39 ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) {
40 pr_err("elantech.c: synaptics_send_cmd query 0x%02x failed.\n", c);
41 return -1;
42 }
43
44 return 0;
45}
46
47/*
48 * A retrying version of ps2_command
49 */
50static int elantech_ps2_command(struct psmouse *psmouse,
51 unsigned char *param, int command)
52{
53 struct ps2dev *ps2dev = &psmouse->ps2dev;
54 struct elantech_data *etd = psmouse->private;
55 int rc;
56 int tries = ETP_PS2_COMMAND_TRIES;
57
58 do {
59 rc = ps2_command(ps2dev, param, command);
60 if (rc == 0)
61 break;
62 tries--;
63 elantech_debug("elantech.c: retrying ps2 command 0x%02x (%d).\n",
64 command, tries);
65 msleep(ETP_PS2_COMMAND_DELAY);
66 } while (tries > 0);
67
68 if (rc)
69 pr_err("elantech.c: ps2 command 0x%02x failed.\n", command);
70
71 return rc;
72}
73
74/*
75 * Send an Elantech style special command to read a value from a register
76 */
77static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg,
78 unsigned char *val)
79{
80 struct elantech_data *etd = psmouse->private;
81 unsigned char param[3];
82 int rc = 0;
83
84 if (reg < 0x10 || reg > 0x26)
85 return -1;
86
87 if (reg > 0x11 && reg < 0x20)
88 return -1;
89
90 switch (etd->hw_version) {
91 case 1:
92 if (psmouse_sliced_command(psmouse, ETP_REGISTER_READ) ||
93 psmouse_sliced_command(psmouse, reg) ||
94 ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) {
95 rc = -1;
96 }
97 break;
98
99 case 2:
100 if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
101 elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READ) ||
102 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
103 elantech_ps2_command(psmouse, NULL, reg) ||
104 elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
105 rc = -1;
106 }
107 break;
108 }
109
110 if (rc)
111 pr_err("elantech.c: failed to read register 0x%02x.\n", reg);
112 else
113 *val = param[0];
114
115 return rc;
116}
117
118/*
119 * Send an Elantech style special command to write a register with a value
120 */
121static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg,
122 unsigned char val)
123{
124 struct elantech_data *etd = psmouse->private;
125 int rc = 0;
126
127 if (reg < 0x10 || reg > 0x26)
128 return -1;
129
130 if (reg > 0x11 && reg < 0x20)
131 return -1;
132
133 switch (etd->hw_version) {
134 case 1:
135 if (psmouse_sliced_command(psmouse, ETP_REGISTER_WRITE) ||
136 psmouse_sliced_command(psmouse, reg) ||
137 psmouse_sliced_command(psmouse, val) ||
138 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) {
139 rc = -1;
140 }
141 break;
142
143 case 2:
144 if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
145 elantech_ps2_command(psmouse, NULL, ETP_REGISTER_WRITE) ||
146 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
147 elantech_ps2_command(psmouse, NULL, reg) ||
148 elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
149 elantech_ps2_command(psmouse, NULL, val) ||
150 elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) {
151 rc = -1;
152 }
153 break;
154 }
155
156 if (rc)
157 pr_err("elantech.c: failed to write register 0x%02x with value 0x%02x.\n",
158 reg, val);
159
160 return rc;
161}
162
163/*
164 * Dump a complete mouse movement packet to the syslog
165 */
166static void elantech_packet_dump(unsigned char *packet, int size)
167{
168 int i;
169
170 printk(KERN_DEBUG "elantech.c: PS/2 packet [");
171 for (i = 0; i < size; i++)
172 printk("%s0x%02x ", (i) ? ", " : " ", packet[i]);
173 printk("]\n");
174}
175
176/*
177 * Interpret complete data packets and report absolute mode input events for
178 * hardware version 1. (4 byte packets)
179 */
180static void elantech_report_absolute_v1(struct psmouse *psmouse)
181{
182 struct input_dev *dev = psmouse->dev;
183 struct elantech_data *etd = psmouse->private;
184 unsigned char *packet = psmouse->packet;
185 int fingers;
3f8c0df4 186 static int old_fingers;
2a0bd75e 187
504e8bee 188 if (etd->fw_version < 0x020000) {
e938fbfd
FR
189 /*
190 * byte 0: D U p1 p2 1 p3 R L
191 * byte 1: f 0 th tw x9 x8 y9 y8
192 */
2a0bd75e
AO
193 fingers = ((packet[1] & 0x80) >> 7) +
194 ((packet[1] & 0x30) >> 4);
195 } else {
e938fbfd
FR
196 /*
197 * byte 0: n1 n0 p2 p1 1 p3 R L
198 * byte 1: 0 0 0 0 x9 x8 y9 y8
199 */
2a0bd75e
AO
200 fingers = (packet[0] & 0xc0) >> 6;
201 }
202
3f8c0df4
AO
203 if (etd->jumpy_cursor) {
204 /* Discard packets that are likely to have bogus coordinates */
205 if (fingers > old_fingers) {
206 elantech_debug("elantech.c: discarding packet\n");
207 goto discard_packet_v1;
208 }
209 }
210
2a0bd75e
AO
211 input_report_key(dev, BTN_TOUCH, fingers != 0);
212
e938fbfd
FR
213 /*
214 * byte 2: x7 x6 x5 x4 x3 x2 x1 x0
215 * byte 3: y7 y6 y5 y4 y3 y2 y1 y0
216 */
2a0bd75e
AO
217 if (fingers) {
218 input_report_abs(dev, ABS_X,
219 ((packet[1] & 0x0c) << 6) | packet[2]);
e938fbfd
FR
220 input_report_abs(dev, ABS_Y,
221 ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
2a0bd75e
AO
222 }
223
224 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
225 input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
226 input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
227 input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
228 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
229
504e8bee 230 if (etd->fw_version < 0x020000 &&
2a0bd75e
AO
231 (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
232 /* rocker up */
233 input_report_key(dev, BTN_FORWARD, packet[0] & 0x40);
234 /* rocker down */
235 input_report_key(dev, BTN_BACK, packet[0] & 0x80);
236 }
237
238 input_sync(dev);
3f8c0df4
AO
239
240 discard_packet_v1:
241 old_fingers = fingers;
2a0bd75e
AO
242}
243
244/*
245 * Interpret complete data packets and report absolute mode input events for
246 * hardware version 2. (6 byte packets)
247 */
248static void elantech_report_absolute_v2(struct psmouse *psmouse)
249{
250 struct input_dev *dev = psmouse->dev;
251 unsigned char *packet = psmouse->packet;
252 int fingers, x1, y1, x2, y2;
253
254 /* byte 0: n1 n0 . . . . R L */
255 fingers = (packet[0] & 0xc0) >> 6;
256 input_report_key(dev, BTN_TOUCH, fingers != 0);
257
258 switch (fingers) {
259 case 1:
e938fbfd
FR
260 /*
261 * byte 1: . . . . . x10 x9 x8
262 * byte 2: x7 x6 x5 x4 x4 x2 x1 x0
263 */
264 input_report_abs(dev, ABS_X,
265 ((packet[1] & 0x07) << 8) | packet[2]);
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]));
2a0bd75e
AO
272 break;
273
274 case 2:
e938fbfd
FR
275 /*
276 * The coordinate of each finger is reported separately
277 * with a lower resolution for two finger touches:
278 * byte 0: . . ay8 ax8 . . . .
279 * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
280 */
2a0bd75e
AO
281 x1 = ((packet[0] & 0x10) << 4) | packet[1];
282 /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
283 y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
e938fbfd
FR
284 /*
285 * byte 3: . . by8 bx8 . . . .
286 * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
287 */
2a0bd75e
AO
288 x2 = ((packet[3] & 0x10) << 4) | packet[4];
289 /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
290 y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
e938fbfd
FR
291 /*
292 * For compatibility with the X Synaptics driver scale up
293 * one coordinate and report as ordinary mouse movent
294 */
2a0bd75e
AO
295 input_report_abs(dev, ABS_X, x1 << 2);
296 input_report_abs(dev, ABS_Y, y1 << 2);
e938fbfd
FR
297 /*
298 * For compatibility with the proprietary X Elantech driver
299 * report both coordinates as hat coordinates
300 */
2a0bd75e
AO
301 input_report_abs(dev, ABS_HAT0X, x1);
302 input_report_abs(dev, ABS_HAT0Y, y1);
303 input_report_abs(dev, ABS_HAT1X, x2);
304 input_report_abs(dev, ABS_HAT1Y, y2);
305 break;
306 }
307
308 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
309 input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
310 input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
311 input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
312 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
313
314 input_sync(dev);
315}
316
317static int elantech_check_parity_v1(struct psmouse *psmouse)
318{
319 struct elantech_data *etd = psmouse->private;
320 unsigned char *packet = psmouse->packet;
321 unsigned char p1, p2, p3;
322
323 /* Parity bits are placed differently */
504e8bee 324 if (etd->fw_version < 0x020000) {
2a0bd75e
AO
325 /* byte 0: D U p1 p2 1 p3 R L */
326 p1 = (packet[0] & 0x20) >> 5;
327 p2 = (packet[0] & 0x10) >> 4;
328 } else {
329 /* byte 0: n1 n0 p2 p1 1 p3 R L */
330 p1 = (packet[0] & 0x10) >> 4;
331 p2 = (packet[0] & 0x20) >> 5;
332 }
333
334 p3 = (packet[0] & 0x04) >> 2;
335
336 return etd->parity[packet[1]] == p1 &&
337 etd->parity[packet[2]] == p2 &&
338 etd->parity[packet[3]] == p3;
339}
340
341/*
342 * Process byte stream from mouse and handle complete packets
343 */
344static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
345{
346 struct elantech_data *etd = psmouse->private;
347
348 if (psmouse->pktcnt < psmouse->pktsize)
349 return PSMOUSE_GOOD_DATA;
350
351 if (etd->debug > 1)
352 elantech_packet_dump(psmouse->packet, psmouse->pktsize);
353
354 switch (etd->hw_version) {
355 case 1:
356 if (etd->paritycheck && !elantech_check_parity_v1(psmouse))
357 return PSMOUSE_BAD_DATA;
358
359 elantech_report_absolute_v1(psmouse);
360 break;
361
362 case 2:
363 /* We don't know how to check parity in protocol v2 */
364 elantech_report_absolute_v2(psmouse);
365 break;
366 }
367
368 return PSMOUSE_FULL_PACKET;
369}
370
371/*
372 * Put the touchpad into absolute mode
373 */
374static int elantech_set_absolute_mode(struct psmouse *psmouse)
375{
376 struct elantech_data *etd = psmouse->private;
377 unsigned char val;
378 int tries = ETP_READ_BACK_TRIES;
379 int rc = 0;
380
381 switch (etd->hw_version) {
382 case 1:
383 etd->reg_10 = 0x16;
384 etd->reg_11 = 0x8f;
385 if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
386 elantech_write_reg(psmouse, 0x11, etd->reg_11)) {
387 rc = -1;
388 }
389 break;
390
391 case 2:
392 /* Windows driver values */
393 etd->reg_10 = 0x54;
394 etd->reg_11 = 0x88; /* 0x8a */
395 etd->reg_21 = 0x60; /* 0x00 */
396 if (elantech_write_reg(psmouse, 0x10, etd->reg_10) ||
397 elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
398 elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
399 rc = -1;
400 break;
401 }
b2546df6
AO
402 }
403
404 if (rc == 0) {
2a0bd75e 405 /*
b2546df6
AO
406 * Read back reg 0x10. For hardware version 1 we must make
407 * sure the absolute mode bit is set. For hardware version 2
408 * the touchpad is probably initalising and not ready until
409 * we read back the value we just wrote.
2a0bd75e
AO
410 */
411 do {
412 rc = elantech_read_reg(psmouse, 0x10, &val);
413 if (rc == 0)
414 break;
415 tries--;
416 elantech_debug("elantech.c: retrying read (%d).\n",
b2546df6 417 tries);
2a0bd75e
AO
418 msleep(ETP_READ_BACK_DELAY);
419 } while (tries > 0);
b2546df6
AO
420
421 if (rc) {
2a0bd75e 422 pr_err("elantech.c: failed to read back register 0x10.\n");
b2546df6
AO
423 } else if (etd->hw_version == 1 &&
424 !(val & ETP_R10_ABSOLUTE_MODE)) {
425 pr_err("elantech.c: touchpad refuses "
426 "to switch to absolute mode.\n");
427 rc = -1;
428 }
2a0bd75e
AO
429 }
430
431 if (rc)
432 pr_err("elantech.c: failed to initialise registers.\n");
433
434 return rc;
435}
436
437/*
438 * Set the appropriate event bits for the input subsystem
439 */
440static void elantech_set_input_params(struct psmouse *psmouse)
441{
442 struct input_dev *dev = psmouse->dev;
443 struct elantech_data *etd = psmouse->private;
444
445 __set_bit(EV_KEY, dev->evbit);
446 __set_bit(EV_ABS, dev->evbit);
c7a1f3cc 447 __clear_bit(EV_REL, dev->evbit);
2a0bd75e
AO
448
449 __set_bit(BTN_LEFT, dev->keybit);
450 __set_bit(BTN_RIGHT, dev->keybit);
451
452 __set_bit(BTN_TOUCH, dev->keybit);
453 __set_bit(BTN_TOOL_FINGER, dev->keybit);
454 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
455 __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
456
457 switch (etd->hw_version) {
458 case 1:
459 /* Rocker button */
504e8bee 460 if (etd->fw_version < 0x020000 &&
2a0bd75e
AO
461 (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
462 __set_bit(BTN_FORWARD, dev->keybit);
463 __set_bit(BTN_BACK, dev->keybit);
464 }
465 input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0);
466 input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0);
467 break;
468
469 case 2:
470 input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
471 input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
472 input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
473 input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
474 input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
475 input_set_abs_params(dev, ABS_HAT1Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
476 break;
477 }
478}
479
480struct elantech_attr_data {
481 size_t field_offset;
482 unsigned char reg;
483};
484
485/*
486 * Display a register value by reading a sysfs entry
487 */
488static ssize_t elantech_show_int_attr(struct psmouse *psmouse, void *data,
489 char *buf)
490{
491 struct elantech_data *etd = psmouse->private;
492 struct elantech_attr_data *attr = data;
493 unsigned char *reg = (unsigned char *) etd + attr->field_offset;
494 int rc = 0;
495
496 if (attr->reg)
497 rc = elantech_read_reg(psmouse, attr->reg, reg);
498
499 return sprintf(buf, "0x%02x\n", (attr->reg && rc) ? -1 : *reg);
500}
501
502/*
503 * Write a register value by writing a sysfs entry
504 */
505static ssize_t elantech_set_int_attr(struct psmouse *psmouse,
506 void *data, const char *buf, size_t count)
507{
508 struct elantech_data *etd = psmouse->private;
509 struct elantech_attr_data *attr = data;
510 unsigned char *reg = (unsigned char *) etd + attr->field_offset;
511 unsigned long value;
512 int err;
513
514 err = strict_strtoul(buf, 16, &value);
515 if (err)
516 return err;
517
518 if (value > 0xff)
519 return -EINVAL;
520
521 /* Do we need to preserve some bits for version 2 hardware too? */
522 if (etd->hw_version == 1) {
523 if (attr->reg == 0x10)
524 /* Force absolute mode always on */
525 value |= ETP_R10_ABSOLUTE_MODE;
526 else if (attr->reg == 0x11)
527 /* Force 4 byte mode always on */
528 value |= ETP_R11_4_BYTE_MODE;
529 }
530
531 if (!attr->reg || elantech_write_reg(psmouse, attr->reg, value) == 0)
532 *reg = value;
533
534 return count;
535}
536
537#define ELANTECH_INT_ATTR(_name, _register) \
538 static struct elantech_attr_data elantech_attr_##_name = { \
539 .field_offset = offsetof(struct elantech_data, _name), \
540 .reg = _register, \
541 }; \
542 PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \
543 &elantech_attr_##_name, \
544 elantech_show_int_attr, \
545 elantech_set_int_attr)
546
547ELANTECH_INT_ATTR(reg_10, 0x10);
548ELANTECH_INT_ATTR(reg_11, 0x11);
549ELANTECH_INT_ATTR(reg_20, 0x20);
550ELANTECH_INT_ATTR(reg_21, 0x21);
551ELANTECH_INT_ATTR(reg_22, 0x22);
552ELANTECH_INT_ATTR(reg_23, 0x23);
553ELANTECH_INT_ATTR(reg_24, 0x24);
554ELANTECH_INT_ATTR(reg_25, 0x25);
555ELANTECH_INT_ATTR(reg_26, 0x26);
556ELANTECH_INT_ATTR(debug, 0);
557ELANTECH_INT_ATTR(paritycheck, 0);
558
559static struct attribute *elantech_attrs[] = {
560 &psmouse_attr_reg_10.dattr.attr,
561 &psmouse_attr_reg_11.dattr.attr,
562 &psmouse_attr_reg_20.dattr.attr,
563 &psmouse_attr_reg_21.dattr.attr,
564 &psmouse_attr_reg_22.dattr.attr,
565 &psmouse_attr_reg_23.dattr.attr,
566 &psmouse_attr_reg_24.dattr.attr,
567 &psmouse_attr_reg_25.dattr.attr,
568 &psmouse_attr_reg_26.dattr.attr,
569 &psmouse_attr_debug.dattr.attr,
570 &psmouse_attr_paritycheck.dattr.attr,
571 NULL
572};
573
574static struct attribute_group elantech_attr_group = {
575 .attrs = elantech_attrs,
576};
577
578/*
579 * Use magic knock to detect Elantech touchpad
580 */
b7802c5c 581int elantech_detect(struct psmouse *psmouse, bool set_properties)
2a0bd75e
AO
582{
583 struct ps2dev *ps2dev = &psmouse->ps2dev;
584 unsigned char param[3];
585
586 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
587
588 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
589 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
590 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
591 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
592 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
9ab7b25e 593 pr_debug("elantech.c: sending Elantech magic knock failed.\n");
2a0bd75e
AO
594 return -1;
595 }
596
597 /*
598 * Report this in case there are Elantech models that use a different
599 * set of magic numbers
600 */
601 if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
9ab7b25e
AO
602 pr_debug("elantech.c: "
603 "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
604 param[0], param[1], param[2]);
605 return -1;
606 }
607
608 /*
609 * Query touchpad's firmware version and see if it reports known
610 * value to avoid mis-detection. Logitech mice are known to respond
611 * to Elantech magic knock and there might be more.
612 */
613 if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
614 pr_debug("elantech.c: failed to query firmware version.\n");
615 return -1;
616 }
617
618 pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n",
619 param[0], param[1], param[2]);
620
621 if (param[0] == 0 || param[1] != 0) {
f81bc788
FR
622 if (!force_elantech) {
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");
2a0bd75e
AO
628 }
629
630 if (set_properties) {
631 psmouse->vendor = "Elantech";
632 psmouse->name = "Touchpad";
633 }
634
635 return 0;
636}
637
638/*
639 * Clean up sysfs entries when disconnecting
640 */
641static void elantech_disconnect(struct psmouse *psmouse)
642{
643 sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
644 &elantech_attr_group);
645 kfree(psmouse->private);
646 psmouse->private = NULL;
647}
648
649/*
650 * Put the touchpad back into absolute mode when reconnecting
651 */
652static int elantech_reconnect(struct psmouse *psmouse)
653{
654 if (elantech_detect(psmouse, 0))
655 return -1;
656
657 if (elantech_set_absolute_mode(psmouse)) {
658 pr_err("elantech.c: failed to put touchpad back into absolute mode.\n");
659 return -1;
660 }
661
662 return 0;
663}
664
665/*
666 * Initialize the touchpad and create sysfs entries
667 */
668int elantech_init(struct psmouse *psmouse)
669{
670 struct elantech_data *etd;
671 int i, error;
672 unsigned char param[3];
673
9ab7b25e 674 psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
2a0bd75e
AO
675 if (!etd)
676 return -1;
677
678 etd->parity[0] = 1;
679 for (i = 1; i < 256; i++)
680 etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
681
682 /*
9ab7b25e 683 * Do the version query again so we can store the result
2a0bd75e
AO
684 */
685 if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
686 pr_err("elantech.c: failed to query firmware version.\n");
687 goto init_fail;
688 }
504e8bee
DT
689
690 etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
2a0bd75e
AO
691
692 /*
693 * Assume every version greater than this is new EeePC style
694 * hardware with 6 byte packets
695 */
504e8bee 696 if (etd->fw_version >= 0x020030) {
2a0bd75e
AO
697 etd->hw_version = 2;
698 /* For now show extra debug information */
699 etd->debug = 1;
700 /* Don't know how to do parity checking for version 2 */
701 etd->paritycheck = 0;
702 } else {
703 etd->hw_version = 1;
704 etd->paritycheck = 1;
705 }
504e8bee
DT
706
707 pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n",
708 etd->hw_version, param[0], param[1], param[2]);
2a0bd75e
AO
709
710 if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) {
711 pr_err("elantech.c: failed to query capabilities.\n");
712 goto init_fail;
713 }
714 pr_info("elantech.c: Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n",
715 param[0], param[1], param[2]);
716 etd->capabilities = param[0];
717
3f8c0df4
AO
718 /*
719 * This firmware seems to suffer from misreporting coordinates when
720 * a touch action starts causing the mouse cursor or scrolled page
721 * to jump. Enable a workaround.
722 */
504e8bee
DT
723 if (etd->fw_version == 0x020022) {
724 pr_info("elantech.c: firmware version 2.0.34 detected, "
3f8c0df4
AO
725 "enabling jumpy cursor workaround\n");
726 etd->jumpy_cursor = 1;
727 }
728
2a0bd75e
AO
729 if (elantech_set_absolute_mode(psmouse)) {
730 pr_err("elantech.c: failed to put touchpad into absolute mode.\n");
731 goto init_fail;
732 }
733
734 elantech_set_input_params(psmouse);
735
736 error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
737 &elantech_attr_group);
738 if (error) {
739 pr_err("elantech.c: failed to create sysfs attributes, error: %d.\n",
740 error);
741 goto init_fail;
742 }
743
744 psmouse->protocol_handler = elantech_process_byte;
745 psmouse->disconnect = elantech_disconnect;
746 psmouse->reconnect = elantech_reconnect;
747 psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
748
749 return 0;
750
751 init_fail:
752 kfree(etd);
753 return -1;
754}
This page took 0.129506 seconds and 5 git commands to generate.