tm6000-input.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /*
  2. * tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
  3. *
  4. * Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation version 2
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <linux/module.h>
  20. #include <linux/init.h>
  21. #include <linux/delay.h>
  22. #include <linux/input.h>
  23. #include <linux/usb.h>
  24. #include <media/rc-core.h>
  25. #include "tm6000.h"
  26. #include "tm6000-regs.h"
  27. static unsigned int ir_debug;
  28. module_param(ir_debug, int, 0644);
  29. MODULE_PARM_DESC(ir_debug, "enable debug message [IR]");
  30. static unsigned int enable_ir = 1;
  31. module_param(enable_ir, int, 0644);
  32. MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
  33. /* number of 50ms for ON-OFF-ON power led */
  34. /* show IR activity */
  35. #define PWLED_OFF 2
  36. #undef dprintk
  37. #define dprintk(fmt, arg...) \
  38. if (ir_debug) { \
  39. printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
  40. }
  41. struct tm6000_ir_poll_result {
  42. u16 rc_data;
  43. };
  44. struct tm6000_IR {
  45. struct tm6000_core *dev;
  46. struct rc_dev *rc;
  47. char name[32];
  48. char phys[32];
  49. /* poll expernal decoder */
  50. int polling;
  51. struct delayed_work work;
  52. u8 wait:1;
  53. u8 key:1;
  54. u8 pwled:1;
  55. u8 pwledcnt;
  56. u16 key_addr;
  57. struct urb *int_urb;
  58. u8 *urb_data;
  59. int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
  60. /* IR device properties */
  61. u64 rc_type;
  62. };
  63. void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
  64. {
  65. struct tm6000_IR *ir = dev->ir;
  66. if (!dev->ir)
  67. return;
  68. if (state)
  69. ir->wait = 1;
  70. else
  71. ir->wait = 0;
  72. }
  73. static int tm6000_ir_config(struct tm6000_IR *ir)
  74. {
  75. struct tm6000_core *dev = ir->dev;
  76. u8 buf[10];
  77. int rc;
  78. switch (ir->rc_type) {
  79. case RC_TYPE_NEC:
  80. /* Setup IR decoder for NEC standard 12MHz system clock */
  81. /* IR_LEADER_CNT = 0.9ms */
  82. tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER1, 0xaa);
  83. tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER0, 0x30);
  84. /* IR_PULSE_CNT = 0.7ms */
  85. tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20);
  86. tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0);
  87. /* Remote WAKEUP = enable */
  88. tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);
  89. /* IR_WKUP_SEL = Low byte in decoded IR data */
  90. tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff);
  91. /* IR_WKU_ADD code */
  92. tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0xff);
  93. tm6000_flash_led(dev, 0);
  94. msleep(100);
  95. tm6000_flash_led(dev, 1);
  96. break;
  97. default:
  98. /* hack */
  99. buf[0] = 0xff;
  100. buf[1] = 0xff;
  101. buf[2] = 0xf2;
  102. buf[3] = 0x2b;
  103. buf[4] = 0x20;
  104. buf[5] = 0x35;
  105. buf[6] = 0x60;
  106. buf[7] = 0x04;
  107. buf[8] = 0xc0;
  108. buf[9] = 0x08;
  109. rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
  110. USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a);
  111. msleep(100);
  112. if (rc < 0) {
  113. printk(KERN_INFO "IR configuration failed");
  114. return rc;
  115. }
  116. break;
  117. }
  118. return 0;
  119. }
  120. static void tm6000_ir_urb_received(struct urb *urb)
  121. {
  122. struct tm6000_core *dev = urb->context;
  123. struct tm6000_IR *ir = dev->ir;
  124. int rc;
  125. if (urb->status != 0)
  126. printk(KERN_INFO "not ready\n");
  127. else if (urb->actual_length > 0) {
  128. memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length);
  129. dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
  130. ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
  131. ir->key = 1;
  132. }
  133. rc = usb_submit_urb(urb, GFP_ATOMIC);
  134. }
  135. static int default_polling_getkey(struct tm6000_IR *ir,
  136. struct tm6000_ir_poll_result *poll_result)
  137. {
  138. struct tm6000_core *dev = ir->dev;
  139. int rc;
  140. u8 buf[2];
  141. if (ir->wait && !&dev->int_in)
  142. return 0;
  143. if (&dev->int_in) {
  144. switch (ir->rc_type) {
  145. case RC_TYPE_RC5:
  146. poll_result->rc_data = ir->urb_data[0];
  147. break;
  148. case RC_TYPE_NEC:
  149. if (ir->urb_data[1] == ((ir->key_addr >> 8) & 0xff)) {
  150. poll_result->rc_data = ir->urb_data[0]
  151. | ir->urb_data[1] << 8;
  152. }
  153. break;
  154. default:
  155. poll_result->rc_data = ir->urb_data[0]
  156. | ir->urb_data[1] << 8;
  157. break;
  158. }
  159. } else {
  160. tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
  161. msleep(10);
  162. tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
  163. msleep(10);
  164. if (ir->rc_type == RC_TYPE_RC5) {
  165. rc = tm6000_read_write_usb(dev, USB_DIR_IN |
  166. USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  167. REQ_02_GET_IR_CODE, 0, 0, buf, 1);
  168. msleep(10);
  169. dprintk("read data=%02x\n", buf[0]);
  170. if (rc < 0)
  171. return rc;
  172. poll_result->rc_data = buf[0];
  173. } else {
  174. rc = tm6000_read_write_usb(dev, USB_DIR_IN |
  175. USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  176. REQ_02_GET_IR_CODE, 0, 0, buf, 2);
  177. msleep(10);
  178. dprintk("read data=%04x\n", buf[0] | buf[1] << 8);
  179. if (rc < 0)
  180. return rc;
  181. poll_result->rc_data = buf[0] | buf[1] << 8;
  182. }
  183. if ((poll_result->rc_data & 0x00ff) != 0xff)
  184. ir->key = 1;
  185. }
  186. return 0;
  187. }
  188. static void tm6000_ir_handle_key(struct tm6000_IR *ir)
  189. {
  190. struct tm6000_core *dev = ir->dev;
  191. int result;
  192. struct tm6000_ir_poll_result poll_result;
  193. /* read the registers containing the IR status */
  194. result = ir->get_key(ir, &poll_result);
  195. if (result < 0) {
  196. printk(KERN_INFO "ir->get_key() failed %d\n", result);
  197. return;
  198. }
  199. dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
  200. if (ir->pwled) {
  201. if (ir->pwledcnt >= PWLED_OFF) {
  202. ir->pwled = 0;
  203. ir->pwledcnt = 0;
  204. tm6000_flash_led(dev, 1);
  205. } else
  206. ir->pwledcnt += 1;
  207. }
  208. if (ir->key) {
  209. rc_keydown(ir->rc, poll_result.rc_data, 0);
  210. ir->key = 0;
  211. ir->pwled = 1;
  212. ir->pwledcnt = 0;
  213. tm6000_flash_led(dev, 0);
  214. }
  215. return;
  216. }
  217. static void tm6000_ir_work(struct work_struct *work)
  218. {
  219. struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
  220. tm6000_ir_handle_key(ir);
  221. schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
  222. }
  223. static int tm6000_ir_start(struct rc_dev *rc)
  224. {
  225. struct tm6000_IR *ir = rc->priv;
  226. INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
  227. schedule_delayed_work(&ir->work, 0);
  228. return 0;
  229. }
  230. static void tm6000_ir_stop(struct rc_dev *rc)
  231. {
  232. struct tm6000_IR *ir = rc->priv;
  233. cancel_delayed_work_sync(&ir->work);
  234. }
  235. static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
  236. {
  237. struct tm6000_IR *ir = rc->priv;
  238. if (!ir)
  239. return 0;
  240. if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
  241. ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
  242. ir->get_key = default_polling_getkey;
  243. ir->rc_type = rc_type;
  244. tm6000_ir_config(ir);
  245. /* TODO */
  246. return 0;
  247. }
  248. int tm6000_ir_int_start(struct tm6000_core *dev)
  249. {
  250. struct tm6000_IR *ir = dev->ir;
  251. int pipe, size;
  252. int err = -ENOMEM;
  253. if (!ir)
  254. return -ENODEV;
  255. ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
  256. if (!ir->int_urb)
  257. return -ENOMEM;
  258. pipe = usb_rcvintpipe(dev->udev,
  259. dev->int_in.endp->desc.bEndpointAddress
  260. & USB_ENDPOINT_NUMBER_MASK);
  261. size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
  262. dprintk("IR max size: %d\n", size);
  263. ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
  264. if (ir->int_urb->transfer_buffer == NULL) {
  265. usb_free_urb(ir->int_urb);
  266. return err;
  267. }
  268. dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
  269. usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
  270. ir->int_urb->transfer_buffer, size,
  271. tm6000_ir_urb_received, dev,
  272. dev->int_in.endp->desc.bInterval);
  273. err = usb_submit_urb(ir->int_urb, GFP_KERNEL);
  274. if (err) {
  275. kfree(ir->int_urb->transfer_buffer);
  276. usb_free_urb(ir->int_urb);
  277. return err;
  278. }
  279. ir->urb_data = kzalloc(size, GFP_KERNEL);
  280. return 0;
  281. }
  282. void tm6000_ir_int_stop(struct tm6000_core *dev)
  283. {
  284. struct tm6000_IR *ir = dev->ir;
  285. if (!ir)
  286. return;
  287. usb_kill_urb(ir->int_urb);
  288. kfree(ir->int_urb->transfer_buffer);
  289. usb_free_urb(ir->int_urb);
  290. ir->int_urb = NULL;
  291. kfree(ir->urb_data);
  292. ir->urb_data = NULL;
  293. }
  294. int tm6000_ir_init(struct tm6000_core *dev)
  295. {
  296. struct tm6000_IR *ir;
  297. struct rc_dev *rc;
  298. int err = -ENOMEM;
  299. if (!enable_ir)
  300. return -ENODEV;
  301. if (!dev->caps.has_remote)
  302. return 0;
  303. if (!dev->ir_codes)
  304. return 0;
  305. ir = kzalloc(sizeof(*ir), GFP_KERNEL);
  306. rc = rc_allocate_device();
  307. if (!ir || !rc)
  308. goto out;
  309. /* record handles to ourself */
  310. ir->dev = dev;
  311. dev->ir = ir;
  312. ir->rc = rc;
  313. /* input einrichten */
  314. rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
  315. rc->priv = ir;
  316. rc->change_protocol = tm6000_ir_change_protocol;
  317. rc->open = tm6000_ir_start;
  318. rc->close = tm6000_ir_stop;
  319. rc->driver_type = RC_DRIVER_SCANCODE;
  320. ir->polling = 50;
  321. ir->pwled = 0;
  322. ir->pwledcnt = 0;
  323. snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
  324. dev->name);
  325. usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
  326. strlcat(ir->phys, "/input0", sizeof(ir->phys));
  327. tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
  328. rc->input_name = ir->name;
  329. rc->input_phys = ir->phys;
  330. rc->input_id.bustype = BUS_USB;
  331. rc->input_id.version = 1;
  332. rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
  333. rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
  334. rc->map_name = dev->ir_codes;
  335. rc->driver_name = "tm6000";
  336. rc->dev.parent = &dev->udev->dev;
  337. if (&dev->int_in) {
  338. dprintk("IR over int\n");
  339. err = tm6000_ir_int_start(dev);
  340. if (err)
  341. goto out;
  342. }
  343. /* ir register */
  344. err = rc_register_device(rc);
  345. if (err)
  346. goto out;
  347. return 0;
  348. out:
  349. dev->ir = NULL;
  350. rc_free_device(rc);
  351. kfree(ir);
  352. return err;
  353. }
  354. int tm6000_ir_fini(struct tm6000_core *dev)
  355. {
  356. struct tm6000_IR *ir = dev->ir;
  357. /* skip detach on non attached board */
  358. if (!ir)
  359. return 0;
  360. rc_unregister_device(ir->rc);
  361. if (ir->int_urb)
  362. tm6000_ir_int_stop(dev);
  363. kfree(ir);
  364. dev->ir = NULL;
  365. return 0;
  366. }