elo.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. * Elo serial touchscreen driver
  3. *
  4. * Copyright (c) 2004 Vojtech Pavlik
  5. */
  6. /*
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License version 2 as published by
  9. * the Free Software Foundation.
  10. */
  11. /*
  12. * This driver can handle serial Elo touchscreens using either the Elo standard
  13. * 'E271-2210' 10-byte protocol, Elo legacy 'E281A-4002' 6-byte protocol, Elo
  14. * legacy 'E271-140' 4-byte protocol and Elo legacy 'E261-280' 3-byte protocol.
  15. */
  16. #include <linux/errno.h>
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/slab.h>
  20. #include <linux/input.h>
  21. #include <linux/serio.h>
  22. #include <linux/init.h>
  23. #define DRIVER_DESC "Elo serial touchscreen driver"
  24. MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  25. MODULE_DESCRIPTION(DRIVER_DESC);
  26. MODULE_LICENSE("GPL");
  27. /*
  28. * Definitions & global arrays.
  29. */
  30. #define ELO_MAX_LENGTH 10
  31. /*
  32. * Per-touchscreen data.
  33. */
  34. struct elo {
  35. struct input_dev *dev;
  36. struct serio *serio;
  37. int id;
  38. int idx;
  39. unsigned char csum;
  40. unsigned char data[ELO_MAX_LENGTH];
  41. char phys[32];
  42. };
  43. static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs)
  44. {
  45. struct input_dev *dev = elo->dev;
  46. elo->csum += elo->data[elo->idx] = data;
  47. switch (elo->idx++) {
  48. case 0:
  49. if (data != 'U') {
  50. elo->idx = 0;
  51. elo->csum = 0;
  52. }
  53. break;
  54. case 1:
  55. if (data != 'T') {
  56. elo->idx = 0;
  57. elo->csum = 0;
  58. }
  59. break;
  60. case 9:
  61. if (elo->csum) {
  62. input_regs(dev, regs);
  63. input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
  64. input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
  65. input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
  66. input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
  67. input_sync(dev);
  68. }
  69. elo->idx = 0;
  70. elo->csum = 0;
  71. break;
  72. }
  73. }
  74. static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs)
  75. {
  76. struct input_dev *dev = elo->dev;
  77. elo->data[elo->idx] = data;
  78. switch (elo->idx++) {
  79. case 0: if ((data & 0xc0) != 0xc0) elo->idx = 0; break;
  80. case 1: if ((data & 0xc0) != 0x80) elo->idx = 0; break;
  81. case 2: if ((data & 0xc0) != 0x40) elo->idx = 0; break;
  82. case 3:
  83. if (data & 0xc0) {
  84. elo->idx = 0;
  85. break;
  86. }
  87. input_regs(dev, regs);
  88. input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f));
  89. input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f));
  90. if (elo->id == 2) {
  91. input_report_key(dev, BTN_TOUCH, 1);
  92. input_sync(dev);
  93. elo->idx = 0;
  94. }
  95. break;
  96. case 4:
  97. if (data) {
  98. input_sync(dev);
  99. elo->idx = 0;
  100. }
  101. break;
  102. case 5:
  103. if ((data & 0xf0) == 0) {
  104. input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
  105. input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
  106. }
  107. input_sync(dev);
  108. elo->idx = 0;
  109. break;
  110. }
  111. }
  112. static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs)
  113. {
  114. struct input_dev *dev = elo->dev;
  115. elo->data[elo->idx] = data;
  116. switch (elo->idx++) {
  117. case 0:
  118. if ((data & 0x7f) != 0x01)
  119. elo->idx = 0;
  120. break;
  121. case 2:
  122. input_regs(dev, regs);
  123. input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80));
  124. input_report_abs(dev, ABS_X, elo->data[1]);
  125. input_report_abs(dev, ABS_Y, elo->data[2]);
  126. input_sync(dev);
  127. elo->idx = 0;
  128. break;
  129. }
  130. }
  131. static irqreturn_t elo_interrupt(struct serio *serio,
  132. unsigned char data, unsigned int flags, struct pt_regs *regs)
  133. {
  134. struct elo* elo = serio_get_drvdata(serio);
  135. switch(elo->id) {
  136. case 0:
  137. elo_process_data_10(elo, data, regs);
  138. break;
  139. case 1:
  140. case 2:
  141. elo_process_data_6(elo, data, regs);
  142. break;
  143. case 3:
  144. elo_process_data_3(elo, data, regs);
  145. break;
  146. }
  147. return IRQ_HANDLED;
  148. }
  149. /*
  150. * elo_disconnect() is the opposite of elo_connect()
  151. */
  152. static void elo_disconnect(struct serio *serio)
  153. {
  154. struct elo* elo = serio_get_drvdata(serio);
  155. input_unregister_device(elo->dev);
  156. serio_close(serio);
  157. serio_set_drvdata(serio, NULL);
  158. kfree(elo);
  159. }
  160. /*
  161. * elo_connect() is the routine that is called when someone adds a
  162. * new serio device that supports Gunze protocol and registers it as
  163. * an input device.
  164. */
  165. static int elo_connect(struct serio *serio, struct serio_driver *drv)
  166. {
  167. struct elo *elo;
  168. struct input_dev *input_dev;
  169. int err;
  170. elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
  171. input_dev = input_allocate_device();
  172. if (!elo || !input_dev) {
  173. err = -ENOMEM;
  174. goto fail;
  175. }
  176. elo->serio = serio;
  177. elo->id = serio->id.id;
  178. elo->dev = input_dev;
  179. snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
  180. input_dev->private = elo;
  181. input_dev->name = "Elo Serial TouchScreen";
  182. input_dev->phys = elo->phys;
  183. input_dev->id.bustype = BUS_RS232;
  184. input_dev->id.vendor = SERIO_ELO;
  185. input_dev->id.product = elo->id;
  186. input_dev->id.version = 0x0100;
  187. input_dev->cdev.dev = &serio->dev;
  188. input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
  189. input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
  190. switch (elo->id) {
  191. case 0: /* 10-byte protocol */
  192. input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
  193. input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
  194. input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
  195. break;
  196. case 1: /* 6-byte protocol */
  197. input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
  198. case 2: /* 4-byte protocol */
  199. input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
  200. input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
  201. break;
  202. case 3: /* 3-byte protocol */
  203. input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
  204. input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
  205. break;
  206. }
  207. serio_set_drvdata(serio, elo);
  208. err = serio_open(serio, drv);
  209. if (err)
  210. goto fail;
  211. input_register_device(elo->dev);
  212. return 0;
  213. fail: serio_set_drvdata(serio, NULL);
  214. input_free_device(input_dev);
  215. kfree(elo);
  216. return err;
  217. }
  218. /*
  219. * The serio driver structure.
  220. */
  221. static struct serio_device_id elo_serio_ids[] = {
  222. {
  223. .type = SERIO_RS232,
  224. .proto = SERIO_ELO,
  225. .id = SERIO_ANY,
  226. .extra = SERIO_ANY,
  227. },
  228. { 0 }
  229. };
  230. MODULE_DEVICE_TABLE(serio, elo_serio_ids);
  231. static struct serio_driver elo_drv = {
  232. .driver = {
  233. .name = "elo",
  234. },
  235. .description = DRIVER_DESC,
  236. .id_table = elo_serio_ids,
  237. .interrupt = elo_interrupt,
  238. .connect = elo_connect,
  239. .disconnect = elo_disconnect,
  240. };
  241. /*
  242. * The functions for inserting/removing us as a module.
  243. */
  244. static int __init elo_init(void)
  245. {
  246. serio_register_driver(&elo_drv);
  247. return 0;
  248. }
  249. static void __exit elo_exit(void)
  250. {
  251. serio_unregister_driver(&elo_drv);
  252. }
  253. module_init(elo_init);
  254. module_exit(elo_exit);