h3600_ts_input.c 13 KB

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