touchit213.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Sahara TouchIT-213 serial touchscreen driver
  3. *
  4. * Copyright (c) 2007-2008 Claudio Nieder <private@claudio.ch>
  5. *
  6. * Based on Touchright driver (drivers/input/touchscreen/touchright.c)
  7. * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
  8. * Copyright (c) 2004 Vojtech Pavlik
  9. * and Dan Streetman <ddstreet@ieee.org>
  10. */
  11. /*
  12. * This program is free software; you can redistribute it and/or modify it
  13. * under the terms of the GNU General Public License version 2 as published
  14. * by the Free Software Foundation.
  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 "Sahara TouchIT-213 serial touchscreen driver"
  24. MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
  25. MODULE_DESCRIPTION(DRIVER_DESC);
  26. MODULE_LICENSE("GPL");
  27. /*
  28. * Definitions & global arrays.
  29. */
  30. /*
  31. * Data is received through COM1 at 9600bit/s,8bit,no parity in packets
  32. * of 5 byte each.
  33. *
  34. * +--------+ +--------+ +--------+ +--------+ +--------+
  35. * |1000000p| |0xxxxxxx| |0xxxxxxx| |0yyyyyyy| |0yyyyyyy|
  36. * +--------+ +--------+ +--------+ +--------+ +--------+
  37. * MSB LSB MSB LSB
  38. *
  39. * The value of p is 1 as long as the screen is touched and 0 when
  40. * reporting the location where touching stopped, e.g. where the pen was
  41. * lifted from the screen.
  42. *
  43. * When holding the screen in landscape mode as the BIOS text output is
  44. * presented, x is the horizontal axis with values growing from left to
  45. * right and y is the vertical axis with values growing from top to
  46. * bottom.
  47. *
  48. * When holding the screen in portrait mode with the Sahara logo in its
  49. * correct position, x ist the vertical axis with values growing from
  50. * top to bottom and y is the horizontal axis with values growing from
  51. * right to left.
  52. */
  53. #define T213_FORMAT_TOUCH_BIT 0x01
  54. #define T213_FORMAT_STATUS_BYTE 0x80
  55. #define T213_FORMAT_STATUS_MASK ~T213_FORMAT_TOUCH_BIT
  56. /*
  57. * On my Sahara Touch-IT 213 I have observed x values from 0 to 0x7f0
  58. * and y values from 0x1d to 0x7e9, so the actual measurement is
  59. * probably done with an 11 bit precision.
  60. */
  61. #define T213_MIN_XC 0
  62. #define T213_MAX_XC 0x07ff
  63. #define T213_MIN_YC 0
  64. #define T213_MAX_YC 0x07ff
  65. /*
  66. * Per-touchscreen data.
  67. */
  68. struct touchit213 {
  69. struct input_dev *dev;
  70. struct serio *serio;
  71. int idx;
  72. unsigned char csum;
  73. unsigned char data[5];
  74. char phys[32];
  75. };
  76. static irqreturn_t touchit213_interrupt(struct serio *serio,
  77. unsigned char data, unsigned int flags)
  78. {
  79. struct touchit213 *touchit213 = serio_get_drvdata(serio);
  80. struct input_dev *dev = touchit213->dev;
  81. touchit213->data[touchit213->idx] = data;
  82. switch (touchit213->idx++) {
  83. case 0:
  84. if ((touchit213->data[0] & T213_FORMAT_STATUS_MASK) !=
  85. T213_FORMAT_STATUS_BYTE) {
  86. pr_debug("unsynchronized data: 0x%02x\n", data);
  87. touchit213->idx = 0;
  88. }
  89. break;
  90. case 4:
  91. touchit213->idx = 0;
  92. input_report_abs(dev, ABS_X,
  93. (touchit213->data[1] << 7) | touchit213->data[2]);
  94. input_report_abs(dev, ABS_Y,
  95. (touchit213->data[3] << 7) | touchit213->data[4]);
  96. input_report_key(dev, BTN_TOUCH,
  97. touchit213->data[0] & T213_FORMAT_TOUCH_BIT);
  98. input_sync(dev);
  99. break;
  100. }
  101. return IRQ_HANDLED;
  102. }
  103. /*
  104. * touchit213_disconnect() is the opposite of touchit213_connect()
  105. */
  106. static void touchit213_disconnect(struct serio *serio)
  107. {
  108. struct touchit213 *touchit213 = serio_get_drvdata(serio);
  109. input_get_device(touchit213->dev);
  110. input_unregister_device(touchit213->dev);
  111. serio_close(serio);
  112. serio_set_drvdata(serio, NULL);
  113. input_put_device(touchit213->dev);
  114. kfree(touchit213);
  115. }
  116. /*
  117. * touchit213_connect() is the routine that is called when someone adds a
  118. * new serio device that supports the Touchright protocol and registers it as
  119. * an input device.
  120. */
  121. static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
  122. {
  123. struct touchit213 *touchit213;
  124. struct input_dev *input_dev;
  125. int err;
  126. touchit213 = kzalloc(sizeof(struct touchit213), GFP_KERNEL);
  127. input_dev = input_allocate_device();
  128. if (!touchit213 || !input_dev) {
  129. err = -ENOMEM;
  130. goto fail1;
  131. }
  132. touchit213->serio = serio;
  133. touchit213->dev = input_dev;
  134. snprintf(touchit213->phys, sizeof(touchit213->phys),
  135. "%s/input0", serio->phys);
  136. input_dev->name = "Sahara Touch-iT213 Serial TouchScreen";
  137. input_dev->phys = touchit213->phys;
  138. input_dev->id.bustype = BUS_RS232;
  139. input_dev->id.vendor = SERIO_TOUCHIT213;
  140. input_dev->id.product = 0;
  141. input_dev->id.version = 0x0100;
  142. input_dev->dev.parent = &serio->dev;
  143. input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  144. input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
  145. input_set_abs_params(touchit213->dev, ABS_X,
  146. T213_MIN_XC, T213_MAX_XC, 0, 0);
  147. input_set_abs_params(touchit213->dev, ABS_Y,
  148. T213_MIN_YC, T213_MAX_YC, 0, 0);
  149. serio_set_drvdata(serio, touchit213);
  150. err = serio_open(serio, drv);
  151. if (err)
  152. goto fail2;
  153. err = input_register_device(touchit213->dev);
  154. if (err)
  155. goto fail3;
  156. return 0;
  157. fail3: serio_close(serio);
  158. fail2: serio_set_drvdata(serio, NULL);
  159. fail1: input_free_device(input_dev);
  160. kfree(touchit213);
  161. return err;
  162. }
  163. /*
  164. * The serio driver structure.
  165. */
  166. static struct serio_device_id touchit213_serio_ids[] = {
  167. {
  168. .type = SERIO_RS232,
  169. .proto = SERIO_TOUCHIT213,
  170. .id = SERIO_ANY,
  171. .extra = SERIO_ANY,
  172. },
  173. { 0 }
  174. };
  175. MODULE_DEVICE_TABLE(serio, touchit213_serio_ids);
  176. static struct serio_driver touchit213_drv = {
  177. .driver = {
  178. .name = "touchit213",
  179. },
  180. .description = DRIVER_DESC,
  181. .id_table = touchit213_serio_ids,
  182. .interrupt = touchit213_interrupt,
  183. .connect = touchit213_connect,
  184. .disconnect = touchit213_disconnect,
  185. };
  186. /*
  187. * The functions for inserting/removing us as a module.
  188. */
  189. static int __init touchit213_init(void)
  190. {
  191. return serio_register_driver(&touchit213_drv);
  192. }
  193. static void __exit touchit213_exit(void)
  194. {
  195. serio_unregister_driver(&touchit213_drv);
  196. }
  197. module_init(touchit213_init);
  198. module_exit(touchit213_exit);