h3600_ts_input.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons 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, struct pt_regs *regs)
  96. {
  97. int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
  98. struct input_dev *dev = (struct input_dev *) dev_id;
  99. input_regs(dev, regs);
  100. input_report_key(dev, KEY_ENTER, down);
  101. input_sync(dev);
  102. return IRQ_HANDLED;
  103. }
  104. static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
  105. {
  106. int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
  107. struct input_dev *dev = (struct input_dev *) dev_id;
  108. /*
  109. * This interrupt is only called when we release the key. So we have
  110. * to fake a key press.
  111. */
  112. input_regs(dev, regs);
  113. input_report_key(dev, KEY_SUSPEND, 1);
  114. input_report_key(dev, KEY_SUSPEND, down);
  115. input_sync(dev);
  116. return IRQ_HANDLED;
  117. }
  118. #ifdef CONFIG_PM
  119. static int flite_brightness = 25;
  120. enum flite_pwr {
  121. FLITE_PWR_OFF = 0,
  122. FLITE_PWR_ON = 1
  123. };
  124. /*
  125. * h3600_flite_power: enables or disables power to frontlight, using last bright */
  126. unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
  127. {
  128. unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness;
  129. struct h3600_dev *ts = dev->private;
  130. /* Must be in this order */
  131. ts->serio->write(ts->serio, 1);
  132. ts->serio->write(ts->serio, pwr);
  133. ts->serio->write(ts->serio, brightness);
  134. return 0;
  135. }
  136. #endif
  137. /*
  138. * This function translates the native event packets to linux input event
  139. * packets. Some packets coming from serial are not touchscreen related. In
  140. * this case we send them off to be processed elsewhere.
  141. */
  142. static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
  143. {
  144. struct input_dev *dev = ts->dev;
  145. static int touched = 0;
  146. int key, down = 0;
  147. input_regs(dev, regs);
  148. switch (ts->event) {
  149. /*
  150. Buttons - returned as a single byte
  151. 7 6 5 4 3 2 1 0
  152. S x x x N N N N
  153. S switch state ( 0=pressed 1=released)
  154. x Unused.
  155. NNNN switch number 0-15
  156. Note: This is true for non interrupt generated key events.
  157. */
  158. case KEYBD_ID:
  159. down = (ts->buf[0] & 0x80) ? 0 : 1;
  160. switch (ts->buf[0] & 0x7f) {
  161. case H3600_SCANCODE_RECORD:
  162. key = KEY_RECORD;
  163. break;
  164. case H3600_SCANCODE_CALENDAR:
  165. key = KEY_PROG1;
  166. break;
  167. case H3600_SCANCODE_CONTACTS:
  168. key = KEY_PROG2;
  169. break;
  170. case H3600_SCANCODE_Q:
  171. key = KEY_Q;
  172. break;
  173. case H3600_SCANCODE_START:
  174. key = KEY_PROG3;
  175. break;
  176. case H3600_SCANCODE_UP:
  177. key = KEY_UP;
  178. break;
  179. case H3600_SCANCODE_RIGHT:
  180. key = KEY_RIGHT;
  181. break;
  182. case H3600_SCANCODE_LEFT:
  183. key = KEY_LEFT;
  184. break;
  185. case H3600_SCANCODE_DOWN:
  186. key = KEY_DOWN;
  187. break;
  188. default:
  189. key = 0;
  190. }
  191. if (key)
  192. input_report_key(dev, key, down);
  193. break;
  194. /*
  195. * Native touchscreen event data is formatted as shown below:-
  196. *
  197. * +-------+-------+-------+-------+
  198. * | Xmsb | Xlsb | Ymsb | Ylsb |
  199. * +-------+-------+-------+-------+
  200. * byte 0 1 2 3
  201. */
  202. case TOUCHS_ID:
  203. if (!touched) {
  204. input_report_key(dev, BTN_TOUCH, 1);
  205. touched = 1;
  206. }
  207. if (ts->len) {
  208. unsigned short x, y;
  209. x = ts->buf[0]; x <<= 8; x += ts->buf[1];
  210. y = ts->buf[2]; y <<= 8; y += ts->buf[3];
  211. input_report_abs(dev, ABS_X, x);
  212. input_report_abs(dev, ABS_Y, y);
  213. } else {
  214. input_report_key(dev, BTN_TOUCH, 0);
  215. touched = 0;
  216. }
  217. break;
  218. default:
  219. /* Send a non input event elsewhere */
  220. break;
  221. }
  222. input_sync(dev);
  223. }
  224. /*
  225. * h3600ts_event() handles events from the input module.
  226. */
  227. static int h3600ts_event(struct input_dev *dev, unsigned int type,
  228. unsigned int code, int value)
  229. {
  230. #if 0
  231. struct h3600_dev *ts = dev->private;
  232. switch (type) {
  233. case EV_LED: {
  234. // ts->serio->write(ts->serio, SOME_CMD);
  235. return 0;
  236. }
  237. }
  238. return -1;
  239. #endif
  240. return 0;
  241. }
  242. /*
  243. Frame format
  244. byte 1 2 3 len + 4
  245. +-------+---------------+---------------+--=------------+
  246. |SOF |id |len | len bytes | Chksum |
  247. +-------+---------------+---------------+--=------------+
  248. bit 0 7 8 11 12 15 16
  249. +-------+---------------+-------+
  250. |SOF |id |0 |Chksum | - Note Chksum does not include SOF
  251. +-------+---------------+-------+
  252. bit 0 7 8 11 12 15 16
  253. */
  254. static int state;
  255. /* decode States */
  256. #define STATE_SOF 0 /* start of FRAME */
  257. #define STATE_ID 1 /* state where we decode the ID & len */
  258. #define STATE_DATA 2 /* state where we decode data */
  259. #define STATE_EOF 3 /* state where we decode checksum or EOF */
  260. static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
  261. unsigned int flags, struct pt_regs *regs)
  262. {
  263. struct h3600_dev *ts = serio_get_drvdata(serio);
  264. /*
  265. * We have a new frame coming in.
  266. */
  267. switch (state) {
  268. case STATE_SOF:
  269. if (data == CHAR_SOF)
  270. state = STATE_ID;
  271. break;
  272. case STATE_ID:
  273. ts->event = (data & 0xf0) >> 4;
  274. ts->len = (data & 0xf);
  275. ts->idx = 0;
  276. if (ts->event >= MAX_ID) {
  277. state = STATE_SOF;
  278. break;
  279. }
  280. ts->chksum = data;
  281. state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
  282. break;
  283. case STATE_DATA:
  284. ts->chksum += data;
  285. ts->buf[ts->idx]= data;
  286. if (++ts->idx == ts->len)
  287. state = STATE_EOF;
  288. break;
  289. case STATE_EOF:
  290. state = STATE_SOF;
  291. if (data == CHAR_EOF || data == ts->chksum)
  292. h3600ts_process_packet(ts, regs);
  293. break;
  294. default:
  295. printk("Error3\n");
  296. break;
  297. }
  298. return IRQ_HANDLED;
  299. }
  300. /*
  301. * h3600ts_connect() is the routine that is called when someone adds a
  302. * new serio device that supports H3600 protocol and registers it as
  303. * an input device.
  304. */
  305. static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
  306. {
  307. struct h3600_dev *ts;
  308. struct input_dev *input_dev;
  309. int err;
  310. ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL);
  311. input_dev = input_allocate_device();
  312. if (!ts || !input_dev) {
  313. err = -ENOMEM;
  314. goto fail1;
  315. }
  316. ts->serio = serio;
  317. ts->dev = input_dev;
  318. sprintf(ts->phys, "%s/input0", serio->phys);
  319. input_dev->name = "H3600 TouchScreen";
  320. input_dev->phys = ts->phys;
  321. input_dev->id.bustype = BUS_RS232;
  322. input_dev->id.vendor = SERIO_H3600;
  323. input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */
  324. input_dev->id.version = 0x0100;
  325. input_dev->cdev.dev = &serio->dev;
  326. input_dev->private = ts;
  327. input_dev->event = h3600ts_event;
  328. input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
  329. input_dev->ledbit[0] = BIT(LED_SLEEP);
  330. input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
  331. input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
  332. set_bit(KEY_RECORD, input_dev->keybit);
  333. set_bit(KEY_Q, input_dev->keybit);
  334. set_bit(KEY_PROG1, input_dev->keybit);
  335. set_bit(KEY_PROG2, input_dev->keybit);
  336. set_bit(KEY_PROG3, input_dev->keybit);
  337. set_bit(KEY_UP, input_dev->keybit);
  338. set_bit(KEY_RIGHT, input_dev->keybit);
  339. set_bit(KEY_LEFT, input_dev->keybit);
  340. set_bit(KEY_DOWN, input_dev->keybit);
  341. set_bit(KEY_ENTER, input_dev->keybit);
  342. set_bit(KEY_SUSPEND, input_dev->keybit);
  343. set_bit(BTN_TOUCH, input_dev->keybit);
  344. /* Device specific stuff */
  345. set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
  346. set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
  347. if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
  348. SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
  349. "h3600_action", &ts->dev)) {
  350. printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
  351. err = -EBUSY;
  352. goto fail2;
  353. }
  354. if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
  355. SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
  356. "h3600_suspend", &ts->dev)) {
  357. printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
  358. err = -EBUSY;
  359. goto fail3;
  360. }
  361. serio_set_drvdata(serio, ts);
  362. err = serio_open(serio, drv);
  363. if (err)
  364. return err;
  365. //h3600_flite_control(1, 25); /* default brightness */
  366. input_register_device(ts->dev);
  367. return 0;
  368. fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
  369. fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
  370. fail1: serio_set_drvdata(serio, NULL);
  371. input_free_device(input_dev);
  372. kfree(ts);
  373. return err;
  374. }
  375. /*
  376. * h3600ts_disconnect() is the opposite of h3600ts_connect()
  377. */
  378. static void h3600ts_disconnect(struct serio *serio)
  379. {
  380. struct h3600_dev *ts = serio_get_drvdata(serio);
  381. free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
  382. free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
  383. input_get_device(ts->dev);
  384. input_unregister_device(ts->dev);
  385. serio_close(serio);
  386. serio_set_drvdata(serio, NULL);
  387. input_put_device(ts->dev);
  388. kfree(ts);
  389. }
  390. /*
  391. * The serio driver structure.
  392. */
  393. static struct serio_device_id h3600ts_serio_ids[] = {
  394. {
  395. .type = SERIO_RS232,
  396. .proto = SERIO_H3600,
  397. .id = SERIO_ANY,
  398. .extra = SERIO_ANY,
  399. },
  400. { 0 }
  401. };
  402. MODULE_DEVICE_TABLE(serio, h3600ts_serio_ids);
  403. static struct serio_driver h3600ts_drv = {
  404. .driver = {
  405. .name = "h3600ts",
  406. },
  407. .description = DRIVER_DESC,
  408. .id_table = h3600ts_serio_ids,
  409. .interrupt = h3600ts_interrupt,
  410. .connect = h3600ts_connect,
  411. .disconnect = h3600ts_disconnect,
  412. };
  413. /*
  414. * The functions for inserting/removing us as a module.
  415. */
  416. static int __init h3600ts_init(void)
  417. {
  418. serio_register_driver(&h3600ts_drv);
  419. return 0;
  420. }
  421. static void __exit h3600ts_exit(void)
  422. {
  423. serio_unregister_driver(&h3600ts_drv);
  424. }
  425. module_init(h3600ts_init);
  426. module_exit(h3600ts_exit);