tm6000-input.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  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_RDC_IR_LEADER1, 0xaa);
  83. tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, 0x30);
  84. /* IR_PULSE_CNT = 0.7ms */
  85. tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20);
  86. tm6000_set_reg(dev, TM6010_REQ07_RDF_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_RDA_IR_WAKEUP_SEL, 0xff);
  91. /* IR_WKU_ADD code */
  92. tm6000_set_reg(dev, TM6010_REQ07_RDB_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. switch (dev->model) {
  150. case 10:
  151. case 11:
  152. case 14:
  153. case 15:
  154. if (ir->urb_data[1] ==
  155. ((ir->key_addr >> 8) & 0xff)) {
  156. poll_result->rc_data =
  157. ir->urb_data[0]
  158. | ir->urb_data[1] << 8;
  159. }
  160. break;
  161. default:
  162. poll_result->rc_data = ir->urb_data[0]
  163. | ir->urb_data[1] << 8;
  164. }
  165. break;
  166. default:
  167. poll_result->rc_data = ir->urb_data[0]
  168. | ir->urb_data[1] << 8;
  169. break;
  170. }
  171. } else {
  172. tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
  173. msleep(10);
  174. tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
  175. msleep(10);
  176. if (ir->rc_type == RC_TYPE_RC5) {
  177. rc = tm6000_read_write_usb(dev, USB_DIR_IN |
  178. USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  179. REQ_02_GET_IR_CODE, 0, 0, buf, 1);
  180. msleep(10);
  181. dprintk("read data=%02x\n", buf[0]);
  182. if (rc < 0)
  183. return rc;
  184. poll_result->rc_data = buf[0];
  185. } else {
  186. rc = tm6000_read_write_usb(dev, USB_DIR_IN |
  187. USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  188. REQ_02_GET_IR_CODE, 0, 0, buf, 2);
  189. msleep(10);
  190. dprintk("read data=%04x\n", buf[0] | buf[1] << 8);
  191. if (rc < 0)
  192. return rc;
  193. poll_result->rc_data = buf[0] | buf[1] << 8;
  194. }
  195. if ((poll_result->rc_data & 0x00ff) != 0xff)
  196. ir->key = 1;
  197. }
  198. return 0;
  199. }
  200. static void tm6000_ir_handle_key(struct tm6000_IR *ir)
  201. {
  202. struct tm6000_core *dev = ir->dev;
  203. int result;
  204. struct tm6000_ir_poll_result poll_result;
  205. /* read the registers containing the IR status */
  206. result = ir->get_key(ir, &poll_result);
  207. if (result < 0) {
  208. printk(KERN_INFO "ir->get_key() failed %d\n", result);
  209. return;
  210. }
  211. if (ir->pwled) {
  212. if (ir->pwledcnt >= PWLED_OFF) {
  213. ir->pwled = 0;
  214. ir->pwledcnt = 0;
  215. tm6000_flash_led(dev, 1);
  216. } else
  217. ir->pwledcnt += 1;
  218. }
  219. if (ir->key) {
  220. dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
  221. rc_keydown(ir->rc, poll_result.rc_data, 0);
  222. ir->key = 0;
  223. ir->pwled = 1;
  224. ir->pwledcnt = 0;
  225. tm6000_flash_led(dev, 0);
  226. }
  227. return;
  228. }
  229. static void tm6000_ir_work(struct work_struct *work)
  230. {
  231. struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
  232. tm6000_ir_handle_key(ir);
  233. schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
  234. }
  235. static int tm6000_ir_start(struct rc_dev *rc)
  236. {
  237. struct tm6000_IR *ir = rc->priv;
  238. INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
  239. schedule_delayed_work(&ir->work, 0);
  240. return 0;
  241. }
  242. static void tm6000_ir_stop(struct rc_dev *rc)
  243. {
  244. struct tm6000_IR *ir = rc->priv;
  245. cancel_delayed_work_sync(&ir->work);
  246. }
  247. static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
  248. {
  249. struct tm6000_IR *ir = rc->priv;
  250. if (!ir)
  251. return 0;
  252. if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
  253. ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
  254. ir->get_key = default_polling_getkey;
  255. ir->rc_type = rc_type;
  256. tm6000_ir_config(ir);
  257. /* TODO */
  258. return 0;
  259. }
  260. int tm6000_ir_int_start(struct tm6000_core *dev)
  261. {
  262. struct tm6000_IR *ir = dev->ir;
  263. int pipe, size;
  264. int err = -ENOMEM;
  265. if (!ir)
  266. return -ENODEV;
  267. ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
  268. if (!ir->int_urb)
  269. return -ENOMEM;
  270. pipe = usb_rcvintpipe(dev->udev,
  271. dev->int_in.endp->desc.bEndpointAddress
  272. & USB_ENDPOINT_NUMBER_MASK);
  273. size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
  274. dprintk("IR max size: %d\n", size);
  275. ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
  276. if (ir->int_urb->transfer_buffer == NULL) {
  277. usb_free_urb(ir->int_urb);
  278. return err;
  279. }
  280. dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
  281. usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
  282. ir->int_urb->transfer_buffer, size,
  283. tm6000_ir_urb_received, dev,
  284. dev->int_in.endp->desc.bInterval);
  285. err = usb_submit_urb(ir->int_urb, GFP_ATOMIC);
  286. if (err) {
  287. kfree(ir->int_urb->transfer_buffer);
  288. usb_free_urb(ir->int_urb);
  289. return err;
  290. }
  291. ir->urb_data = kzalloc(size, GFP_KERNEL);
  292. return 0;
  293. }
  294. void tm6000_ir_int_stop(struct tm6000_core *dev)
  295. {
  296. struct tm6000_IR *ir = dev->ir;
  297. if (!ir)
  298. return;
  299. usb_kill_urb(ir->int_urb);
  300. kfree(ir->int_urb->transfer_buffer);
  301. usb_free_urb(ir->int_urb);
  302. ir->int_urb = NULL;
  303. kfree(ir->urb_data);
  304. ir->urb_data = NULL;
  305. }
  306. int tm6000_ir_init(struct tm6000_core *dev)
  307. {
  308. struct tm6000_IR *ir;
  309. struct rc_dev *rc;
  310. int err = -ENOMEM;
  311. if (!enable_ir)
  312. return -ENODEV;
  313. if (!dev->caps.has_remote)
  314. return 0;
  315. if (!dev->ir_codes)
  316. return 0;
  317. ir = kzalloc(sizeof(*ir), GFP_KERNEL);
  318. rc = rc_allocate_device();
  319. if (!ir || !rc)
  320. goto out;
  321. /* record handles to ourself */
  322. ir->dev = dev;
  323. dev->ir = ir;
  324. ir->rc = rc;
  325. /* input einrichten */
  326. rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
  327. rc->priv = ir;
  328. rc->change_protocol = tm6000_ir_change_protocol;
  329. rc->open = tm6000_ir_start;
  330. rc->close = tm6000_ir_stop;
  331. rc->driver_type = RC_DRIVER_SCANCODE;
  332. ir->polling = 50;
  333. ir->pwled = 0;
  334. ir->pwledcnt = 0;
  335. snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
  336. dev->name);
  337. usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
  338. strlcat(ir->phys, "/input0", sizeof(ir->phys));
  339. tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
  340. rc->input_name = ir->name;
  341. rc->input_phys = ir->phys;
  342. rc->input_id.bustype = BUS_USB;
  343. rc->input_id.version = 1;
  344. rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
  345. rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
  346. rc->map_name = dev->ir_codes;
  347. rc->driver_name = "tm6000";
  348. rc->dev.parent = &dev->udev->dev;
  349. if (&dev->int_in) {
  350. dprintk("IR over int\n");
  351. err = tm6000_ir_int_start(dev);
  352. if (err)
  353. goto out;
  354. }
  355. /* ir register */
  356. err = rc_register_device(rc);
  357. if (err)
  358. goto out;
  359. return 0;
  360. out:
  361. dev->ir = NULL;
  362. rc_free_device(rc);
  363. kfree(ir);
  364. return err;
  365. }
  366. int tm6000_ir_fini(struct tm6000_core *dev)
  367. {
  368. struct tm6000_IR *ir = dev->ir;
  369. /* skip detach on non attached board */
  370. if (!ir)
  371. return 0;
  372. rc_unregister_device(ir->rc);
  373. if (ir->int_urb)
  374. tm6000_ir_int_stop(dev);
  375. kfree(ir);
  376. dev->ir = NULL;
  377. return 0;
  378. }