h3600_ts_input.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
  3. *
  4. * Sponsored by Transvirtual Technology.
  5. *
  6. * Derived from the code in h3600_ts.[ch] by Charles Flynn
  7. */
  8. /*
  9. * Driver for the h3600 Touch Screen and other Atmel controlled devices.
  10. */
  11. /*
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25. *
  26. * Should you need to contact me, the author, you can do so by
  27. * e-mail - mail your message to <jsimmons@transvirtual.com>.
  28. */
  29. #include <linux/errno.h>
  30. #include <linux/kernel.h>
  31. #include <linux/module.h>
  32. #include <linux/slab.h>
  33. #include <linux/input.h>
  34. #include <linux/serio.h>
  35. #include <linux/init.h>
  36. #include <linux/delay.h>
  37. /* SA1100 serial defines */
  38. #include <mach/hardware.h>
  39. #include <mach/irqs.h>
  40. #define DRIVER_DESC "H3600 touchscreen driver"
  41. MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
  42. MODULE_DESCRIPTION(DRIVER_DESC);
  43. MODULE_LICENSE("GPL");
  44. /*
  45. * Definitions & global arrays.
  46. */
  47. /* The start and end of frame characters SOF and EOF */
  48. #define CHAR_SOF 0x02
  49. #define CHAR_EOF 0x03
  50. #define FRAME_OVERHEAD 3 /* CHAR_SOF,CHAR_EOF,LENGTH = 3 */
  51. /*
  52. Atmel events and response IDs contained in frame.
  53. Programmer has no control over these numbers.
  54. TODO there are holes - specifically 1,7,0x0a
  55. */
  56. #define VERSION_ID 0 /* Get Version (request/response) */
  57. #define KEYBD_ID 2 /* Keyboard (event) */
  58. #define TOUCHS_ID 3 /* Touch Screen (event)*/
  59. #define EEPROM_READ_ID 4 /* (request/response) */
  60. #define EEPROM_WRITE_ID 5 /* (request/response) */
  61. #define THERMAL_ID 6 /* (request/response) */
  62. #define NOTIFY_LED_ID 8 /* (request/response) */
  63. #define BATTERY_ID 9 /* (request/response) */
  64. #define SPI_READ_ID 0x0b /* ( request/response) */
  65. #define SPI_WRITE_ID 0x0c /* ( request/response) */
  66. #define FLITE_ID 0x0d /* backlight ( request/response) */
  67. #define STX_ID 0xa1 /* extension pack status (req/resp) */
  68. #define MAX_ID 14
  69. #define H3600_MAX_LENGTH 16
  70. #define H3600_KEY 0xf
  71. #define H3600_SCANCODE_RECORD 1 /* 1 -> record button */
  72. #define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */
  73. #define H3600_SCANCODE_CONTACTS 3 /* 3 -> contact */
  74. #define H3600_SCANCODE_Q 4 /* 4 -> Q button */
  75. #define H3600_SCANCODE_START 5 /* 5 -> start menu */
  76. #define H3600_SCANCODE_UP 6 /* 6 -> up */
  77. #define H3600_SCANCODE_RIGHT 7 /* 7 -> right */
  78. #define H3600_SCANCODE_LEFT 8 /* 8 -> left */
  79. #define H3600_SCANCODE_DOWN 9 /* 9 -> down */
  80. /*
  81. * Per-touchscreen data.
  82. */
  83. struct h3600_dev {
  84. struct input_dev *dev;
  85. struct serio *serio;
  86. unsigned char event; /* event ID from packet */
  87. unsigned char chksum;
  88. unsigned char len;
  89. unsigned char idx;
  90. unsigned char buf[H3600_MAX_LENGTH];
  91. char phys[32];
  92. };
  93. static irqreturn_t action_button_handler(int irq, void *dev_id)
  94. {
  95. int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
  96. struct input_dev *dev = dev_id;
  97. input_report_key(dev, KEY_ENTER, down);
  98. input_sync(dev);
  99. return IRQ_HANDLED;
  100. }
  101. static irqreturn_t npower_button_handler(int irq, void *dev_id)
  102. {
  103. int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
  104. struct input_dev *dev = dev_id;
  105. /*
  106. * This interrupt is only called when we release the key. So we have
  107. * to fake a key press.
  108. */
  109. input_report_key(dev, KEY_SUSPEND, 1);
  110. input_report_key(dev, KEY_SUSPEND, down);
  111. input_sync(dev);
  112. return IRQ_HANDLED;
  113. }
  114. #ifdef CONFIG_PM
  115. static int flite_brightness = 25;
  116. enum flite_pwr {
  117. FLITE_PWR_OFF = 0,
  118. FLITE_PWR_ON = 1
  119. };
  120. /*
  121. * h3600_flite_power: enables or disables power to frontlight, using last bright */
  122. unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
  123. {
  124. unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness;
  125. struct h3600_dev *ts = input_get_drvdata(dev);
  126. /* Must be in this order */
  127. serio_write(ts->serio, 1);
  128. serio_write(ts->serio, pwr);
  129. serio_write(ts->serio, brightness);
  130. return 0;
  131. }
  132. #endif
  133. /*
  134. * This function translates the native event packets to linux input event
  135. * packets. Some packets coming from serial are not touchscreen related. In
  136. * this case we send them off to be processed elsewhere.
  137. */
  138. static void h3600ts_process_packet(struct h3600_dev *ts)
  139. {
  140. struct input_dev *dev = ts->dev;
  141. static int touched = 0;
  142. int key, down = 0;
  143. switch (ts->event) {
  144. /*
  145. Buttons - returned as a single byte
  146. 7 6 5 4 3 2 1 0
  147. S x x x N N N N
  148. S switch state ( 0=pressed 1=released)
  149. x Unused.
  150. NNNN switch number 0-15
  151. Note: This is true for non interrupt generated key events.
  152. */
  153. case KEYBD_ID:
  154. down = (ts->buf[0] & 0x80) ? 0 : 1;
  155. switch (ts->buf[0] & 0x7f) {
  156. case H3600_SCANCODE_RECORD:
  157. key = KEY_RECORD;
  158. break;
  159. case H3600_SCANCODE_CALENDAR:
  160. key = KEY_PROG1;
  161. break;
  162. case H3600_SCANCODE_CONTACTS:
  163. key = KEY_PROG2;
  164. break;
  165. case H3600_SCANCODE_Q:
  166. key = KEY_Q;
  167. break;
  168. case H3600_SCANCODE_START:
  169. key = KEY_PROG3;
  170. break;
  171. case H3600_SCANCODE_UP:
  172. key = KEY_UP;
  173. break;
  174. case H3600_SCANCODE_RIGHT:
  175. key = KEY_RIGHT;
  176. break;
  177. case H3600_SCANCODE_LEFT:
  178. key = KEY_LEFT;
  179. break;
  180. case H3600_SCANCODE_DOWN:
  181. key = KEY_DOWN;
  182. break;
  183. default:
  184. key = 0;
  185. }
  186. if (key)
  187. input_report_key(dev, key, down);
  188. break;
  189. /*
  190. * Native touchscreen event data is formatted as shown below:-
  191. *
  192. * +-------+-------+-------+-------+
  193. * | Xmsb | Xlsb | Ymsb | Ylsb |
  194. * +-------+-------+-------+-------+
  195. * byte 0 1 2 3
  196. */
  197. case TOUCHS_ID:
  198. if (!touched) {
  199. input_report_key(dev, BTN_TOUCH, 1);
  200. touched = 1;
  201. }
  202. if (ts->len) {
  203. unsigned short x, y;
  204. x = ts->buf[0]; x <<= 8; x += ts->buf[1];
  205. y = ts->buf[2]; y <<= 8; y += ts->buf[3];
  206. input_report_abs(dev, ABS_X, x);
  207. input_report_abs(dev, ABS_Y, y);
  208. } else {
  209. input_report_key(dev, BTN_TOUCH, 0);
  210. touched = 0;
  211. }
  212. break;
  213. default:
  214. /* Send a non input event elsewhere */
  215. break;
  216. }
  217. input_sync(dev);
  218. }
  219. /*
  220. * h3600ts_event() handles events from the input module.
  221. */
  222. static int h3600ts_event(struct input_dev *dev, unsigned int type,
  223. unsigned int code, int value)
  224. {
  225. #if 0
  226. struct h3600_dev *ts = input_get_drvdata(dev);
  227. switch (type) {
  228. case EV_LED: {
  229. // serio_write(ts->serio, SOME_CMD);
  230. return 0;
  231. }
  232. }
  233. return -1;
  234. #endif
  235. return 0;
  236. }
  237. /*
  238. Frame format
  239. byte 1 2 3 len + 4
  240. +-------+---------------+---------------+--=------------+
  241. |SOF |id |len | len bytes | Chksum |
  242. +-------+---------------+---------------+--=------------+
  243. bit 0 7 8 11 12 15 16
  244. +-------+---------------+-------+
  245. |SOF |id |0 |Chksum | - Note Chksum does not include SOF
  246. +-------+---------------+-------+
  247. bit 0 7 8 11 12 15 16
  248. */
  249. static int state;
  250. /* decode States */
  251. #define STATE_SOF 0 /* start of FRAME */
  252. #define STATE_ID 1 /* state where we decode the ID & len */
  253. #define STATE_DATA 2 /* state where we decode data */
  254. #define STATE_EOF 3 /* state where we decode checksum or EOF */
  255. static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
  256. unsigned int flags)
  257. {
  258. struct h3600_dev *ts = serio_get_drvdata(serio);
  259. /*
  260. * We have a new frame coming in.
  261. */
  262. switch (state) {
  263. case STATE_SOF:
  264. if (data == CHAR_SOF)
  265. state = STATE_ID;
  266. break;
  267. case STATE_ID:
  268. ts->event = (data & 0xf0) >> 4;
  269. ts->len = (data & 0xf);
  270. ts->idx = 0;
  271. if (ts->event >= MAX_ID) {
  272. state = STATE_SOF;
  273. break;
  274. }
  275. ts->chksum = data;
  276. state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
  277. break;
  278. case STATE_DATA:
  279. ts->chksum += data;
  280. ts->buf[ts->idx]= data;
  281. if (++ts->idx == ts->len)
  282. state = STATE_EOF;
  283. break;
  284. case STATE_EOF:
  285. state = STATE_SOF;
  286. if (data == CHAR_EOF || data == ts->chksum)
  287. h3600ts_process_packet(ts);
  288. break;
  289. default:
  290. printk("Error3\n");
  291. break;
  292. }
  293. return IRQ_HANDLED;
  294. }
  295. /*
  296. * h3600ts_connect() is the routine that is called when someone adds a
  297. * new serio device that supports H3600 protocol and registers it as
  298. * an input device.
  299. */
  300. static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
  301. {
  302. struct h3600_dev *ts;
  303. struct input_dev *input_dev;
  304. int err;
  305. ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL);
  306. input_dev = input_allocate_device();
  307. if (!ts || !input_dev) {
  308. err = -ENOMEM;
  309. goto fail1;
  310. }
  311. ts->serio = serio;
  312. ts->dev = input_dev;
  313. snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys);
  314. input_dev->name = "H3600 TouchScreen";
  315. input_dev->phys = ts->phys;
  316. input_dev->id.bustype = BUS_RS232;
  317. input_dev->id.vendor = SERIO_H3600;
  318. input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */
  319. input_dev->id.version = 0x0100;
  320. input_dev->dev.parent = &serio->dev;
  321. input_set_drvdata(input_dev, ts);
  322. input_dev->event = h3600ts_event;
  323. input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
  324. BIT_MASK(EV_LED) | BIT_MASK(EV_PWR);
  325. input_dev->ledbit[0] = BIT_MASK(LED_SLEEP);
  326. input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
  327. input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
  328. set_bit(KEY_RECORD, input_dev->keybit);
  329. set_bit(KEY_Q, input_dev->keybit);
  330. set_bit(KEY_PROG1, input_dev->keybit);
  331. set_bit(KEY_PROG2, input_dev->keybit);
  332. set_bit(KEY_PROG3, input_dev->keybit);
  333. set_bit(KEY_UP, input_dev->keybit);
  334. set_bit(KEY_RIGHT, input_dev->keybit);
  335. set_bit(KEY_LEFT, input_dev->keybit);
  336. set_bit(KEY_DOWN, input_dev->keybit);
  337. set_bit(KEY_ENTER, input_dev->keybit);
  338. set_bit(KEY_SUSPEND, input_dev->keybit);
  339. set_bit(BTN_TOUCH, input_dev->keybit);
  340. /* Device specific stuff */
  341. set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
  342. set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
  343. if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
  344. IRQF_SHARED, "h3600_action", ts->dev)) {
  345. printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
  346. err = -EBUSY;
  347. goto fail1;
  348. }
  349. if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
  350. IRQF_SHARED, "h3600_suspend", ts->dev)) {
  351. printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
  352. err = -EBUSY;
  353. goto fail2;
  354. }
  355. serio_set_drvdata(serio, ts);
  356. err = serio_open(serio, drv);
  357. if (err)
  358. goto fail3;
  359. //h3600_flite_control(1, 25); /* default brightness */
  360. err = input_register_device(ts->dev);
  361. if (err)
  362. goto fail4;
  363. return 0;
  364. fail4: serio_close(serio);
  365. fail3: serio_set_drvdata(serio, NULL);
  366. free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
  367. fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
  368. fail1: input_free_device(input_dev);
  369. kfree(ts);
  370. return err;
  371. }
  372. /*
  373. * h3600ts_disconnect() is the opposite of h3600ts_connect()
  374. */
  375. static void h3600ts_disconnect(struct serio *serio)
  376. {
  377. struct h3600_dev *ts = serio_get_drvdata(serio);
  378. free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
  379. free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
  380. input_get_device(ts->dev);
  381. input_unregister_device(ts->dev);
  382. serio_close(serio);
  383. serio_set_drvdata(serio, NULL);
  384. input_put_device(ts->dev);
  385. kfree(ts);
  386. }
  387. /*
  388. * The serio driver structure.
  389. */
  390. static struct serio_device_id h3600ts_serio_ids[] = {
  391. {
  392. .type = SERIO_RS232,
  393. .proto = SERIO_H3600,
  394. .id = SERIO_ANY,
  395. .extra = SERIO_ANY,
  396. },
  397. { 0 }
  398. };
  399. MODULE_DEVICE_TABLE(serio, h3600ts_serio_ids);
  400. static struct serio_driver h3600ts_drv = {
  401. .driver = {
  402. .name = "h3600ts",
  403. },
  404. .description = DRIVER_DESC,
  405. .id_table = h3600ts_serio_ids,
  406. .interrupt = h3600ts_interrupt,
  407. .connect = h3600ts_connect,
  408. .disconnect = h3600ts_disconnect,
  409. };
  410. /*
  411. * The functions for inserting/removing us as a module.
  412. */
  413. static int __init h3600ts_init(void)
  414. {
  415. return serio_register_driver(&h3600ts_drv);
  416. }
  417. static void __exit h3600ts_exit(void)
  418. {
  419. serio_unregister_driver(&h3600ts_drv);
  420. }
  421. module_init(h3600ts_init);
  422. module_exit(h3600ts_exit);