elantech.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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. __clear_bit(EV_REL, dev->evbit);
  365. __set_bit(BTN_LEFT, dev->keybit);
  366. __set_bit(BTN_RIGHT, dev->keybit);
  367. __set_bit(BTN_TOUCH, dev->keybit);
  368. __set_bit(BTN_TOOL_FINGER, dev->keybit);
  369. __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
  370. __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
  371. switch (etd->hw_version) {
  372. case 1:
  373. /* Rocker button */
  374. if ((etd->fw_version_maj == 0x01) &&
  375. (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
  376. __set_bit(BTN_FORWARD, dev->keybit);
  377. __set_bit(BTN_BACK, dev->keybit);
  378. }
  379. input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0);
  380. input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0);
  381. break;
  382. case 2:
  383. input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
  384. input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
  385. input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
  386. input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
  387. input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
  388. input_set_abs_params(dev, ABS_HAT1Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
  389. break;
  390. }
  391. }
  392. struct elantech_attr_data {
  393. size_t field_offset;
  394. unsigned char reg;
  395. };
  396. /*
  397. * Display a register value by reading a sysfs entry
  398. */
  399. static ssize_t elantech_show_int_attr(struct psmouse *psmouse, void *data,
  400. char *buf)
  401. {
  402. struct elantech_data *etd = psmouse->private;
  403. struct elantech_attr_data *attr = data;
  404. unsigned char *reg = (unsigned char *) etd + attr->field_offset;
  405. int rc = 0;
  406. if (attr->reg)
  407. rc = elantech_read_reg(psmouse, attr->reg, reg);
  408. return sprintf(buf, "0x%02x\n", (attr->reg && rc) ? -1 : *reg);
  409. }
  410. /*
  411. * Write a register value by writing a sysfs entry
  412. */
  413. static ssize_t elantech_set_int_attr(struct psmouse *psmouse,
  414. void *data, const char *buf, size_t count)
  415. {
  416. struct elantech_data *etd = psmouse->private;
  417. struct elantech_attr_data *attr = data;
  418. unsigned char *reg = (unsigned char *) etd + attr->field_offset;
  419. unsigned long value;
  420. int err;
  421. err = strict_strtoul(buf, 16, &value);
  422. if (err)
  423. return err;
  424. if (value > 0xff)
  425. return -EINVAL;
  426. /* Do we need to preserve some bits for version 2 hardware too? */
  427. if (etd->hw_version == 1) {
  428. if (attr->reg == 0x10)
  429. /* Force absolute mode always on */
  430. value |= ETP_R10_ABSOLUTE_MODE;
  431. else if (attr->reg == 0x11)
  432. /* Force 4 byte mode always on */
  433. value |= ETP_R11_4_BYTE_MODE;
  434. }
  435. if (!attr->reg || elantech_write_reg(psmouse, attr->reg, value) == 0)
  436. *reg = value;
  437. return count;
  438. }
  439. #define ELANTECH_INT_ATTR(_name, _register) \
  440. static struct elantech_attr_data elantech_attr_##_name = { \
  441. .field_offset = offsetof(struct elantech_data, _name), \
  442. .reg = _register, \
  443. }; \
  444. PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \
  445. &elantech_attr_##_name, \
  446. elantech_show_int_attr, \
  447. elantech_set_int_attr)
  448. ELANTECH_INT_ATTR(reg_10, 0x10);
  449. ELANTECH_INT_ATTR(reg_11, 0x11);
  450. ELANTECH_INT_ATTR(reg_20, 0x20);
  451. ELANTECH_INT_ATTR(reg_21, 0x21);
  452. ELANTECH_INT_ATTR(reg_22, 0x22);
  453. ELANTECH_INT_ATTR(reg_23, 0x23);
  454. ELANTECH_INT_ATTR(reg_24, 0x24);
  455. ELANTECH_INT_ATTR(reg_25, 0x25);
  456. ELANTECH_INT_ATTR(reg_26, 0x26);
  457. ELANTECH_INT_ATTR(debug, 0);
  458. ELANTECH_INT_ATTR(paritycheck, 0);
  459. static struct attribute *elantech_attrs[] = {
  460. &psmouse_attr_reg_10.dattr.attr,
  461. &psmouse_attr_reg_11.dattr.attr,
  462. &psmouse_attr_reg_20.dattr.attr,
  463. &psmouse_attr_reg_21.dattr.attr,
  464. &psmouse_attr_reg_22.dattr.attr,
  465. &psmouse_attr_reg_23.dattr.attr,
  466. &psmouse_attr_reg_24.dattr.attr,
  467. &psmouse_attr_reg_25.dattr.attr,
  468. &psmouse_attr_reg_26.dattr.attr,
  469. &psmouse_attr_debug.dattr.attr,
  470. &psmouse_attr_paritycheck.dattr.attr,
  471. NULL
  472. };
  473. static struct attribute_group elantech_attr_group = {
  474. .attrs = elantech_attrs,
  475. };
  476. /*
  477. * Use magic knock to detect Elantech touchpad
  478. */
  479. int elantech_detect(struct psmouse *psmouse, bool set_properties)
  480. {
  481. struct ps2dev *ps2dev = &psmouse->ps2dev;
  482. unsigned char param[3];
  483. ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
  484. if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
  485. ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
  486. ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
  487. ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
  488. ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
  489. pr_debug("elantech.c: sending Elantech magic knock failed.\n");
  490. return -1;
  491. }
  492. /*
  493. * Report this in case there are Elantech models that use a different
  494. * set of magic numbers
  495. */
  496. if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
  497. pr_debug("elantech.c: "
  498. "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
  499. param[0], param[1], param[2]);
  500. return -1;
  501. }
  502. /*
  503. * Query touchpad's firmware version and see if it reports known
  504. * value to avoid mis-detection. Logitech mice are known to respond
  505. * to Elantech magic knock and there might be more.
  506. */
  507. if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
  508. pr_debug("elantech.c: failed to query firmware version.\n");
  509. return -1;
  510. }
  511. pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n",
  512. param[0], param[1], param[2]);
  513. if (param[0] == 0 || param[1] != 0) {
  514. pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
  515. return -1;
  516. }
  517. if (set_properties) {
  518. psmouse->vendor = "Elantech";
  519. psmouse->name = "Touchpad";
  520. }
  521. return 0;
  522. }
  523. /*
  524. * Clean up sysfs entries when disconnecting
  525. */
  526. static void elantech_disconnect(struct psmouse *psmouse)
  527. {
  528. sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
  529. &elantech_attr_group);
  530. kfree(psmouse->private);
  531. psmouse->private = NULL;
  532. }
  533. /*
  534. * Put the touchpad back into absolute mode when reconnecting
  535. */
  536. static int elantech_reconnect(struct psmouse *psmouse)
  537. {
  538. if (elantech_detect(psmouse, 0))
  539. return -1;
  540. if (elantech_set_absolute_mode(psmouse)) {
  541. pr_err("elantech.c: failed to put touchpad back into absolute mode.\n");
  542. return -1;
  543. }
  544. return 0;
  545. }
  546. /*
  547. * Initialize the touchpad and create sysfs entries
  548. */
  549. int elantech_init(struct psmouse *psmouse)
  550. {
  551. struct elantech_data *etd;
  552. int i, error;
  553. unsigned char param[3];
  554. psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
  555. if (!etd)
  556. return -1;
  557. etd->parity[0] = 1;
  558. for (i = 1; i < 256; i++)
  559. etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
  560. /*
  561. * Do the version query again so we can store the result
  562. */
  563. if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
  564. pr_err("elantech.c: failed to query firmware version.\n");
  565. goto init_fail;
  566. }
  567. etd->fw_version_maj = param[0];
  568. etd->fw_version_min = param[2];
  569. /*
  570. * Assume every version greater than this is new EeePC style
  571. * hardware with 6 byte packets
  572. */
  573. if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) {
  574. etd->hw_version = 2;
  575. /* For now show extra debug information */
  576. etd->debug = 1;
  577. /* Don't know how to do parity checking for version 2 */
  578. etd->paritycheck = 0;
  579. } else {
  580. etd->hw_version = 1;
  581. etd->paritycheck = 1;
  582. }
  583. pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n",
  584. etd->hw_version, etd->fw_version_maj, etd->fw_version_min);
  585. if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) {
  586. pr_err("elantech.c: failed to query capabilities.\n");
  587. goto init_fail;
  588. }
  589. pr_info("elantech.c: Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n",
  590. param[0], param[1], param[2]);
  591. etd->capabilities = param[0];
  592. /*
  593. * This firmware seems to suffer from misreporting coordinates when
  594. * a touch action starts causing the mouse cursor or scrolled page
  595. * to jump. Enable a workaround.
  596. */
  597. if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) {
  598. pr_info("elantech.c: firmware version 2.34 detected, "
  599. "enabling jumpy cursor workaround\n");
  600. etd->jumpy_cursor = 1;
  601. }
  602. if (elantech_set_absolute_mode(psmouse)) {
  603. pr_err("elantech.c: failed to put touchpad into absolute mode.\n");
  604. goto init_fail;
  605. }
  606. elantech_set_input_params(psmouse);
  607. error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
  608. &elantech_attr_group);
  609. if (error) {
  610. pr_err("elantech.c: failed to create sysfs attributes, error: %d.\n",
  611. error);
  612. goto init_fail;
  613. }
  614. psmouse->protocol_handler = elantech_process_byte;
  615. psmouse->disconnect = elantech_disconnect;
  616. psmouse->reconnect = elantech_reconnect;
  617. psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
  618. return 0;
  619. init_fail:
  620. kfree(etd);
  621. return -1;
  622. }