elantech.c 19 KB

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