touchit213.c 5.6 KB

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