2 * tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
4 * Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
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
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.
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.
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
24 #include <linux/input.h>
25 #include <linux/usb.h>
27 #include <media/rc-core.h>
30 #include "tm6000-regs.h"
32 static unsigned int ir_debug
;
33 module_param(ir_debug
, int, 0644);
34 MODULE_PARM_DESC(ir_debug
, "enable debug message [IR]");
36 static unsigned int enable_ir
= 1;
37 module_param(enable_ir
, int, 0644);
38 MODULE_PARM_DESC(enable_ir
, "enable ir (default is enable)");
40 /* number of 50ms for ON-OFF-ON power led */
41 /* show IR activity */
46 #define dprintk(fmt, arg...) \
48 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
51 struct tm6000_ir_poll_result
{
56 struct tm6000_core
*dev
;
61 /* poll expernal decoder */
63 struct delayed_work work
;
72 int (*get_key
) (struct tm6000_IR
*, struct tm6000_ir_poll_result
*);
74 /* IR device properties */
79 void tm6000_ir_wait(struct tm6000_core
*dev
, u8 state
)
81 struct tm6000_IR
*ir
= dev
->ir
;
93 static int tm6000_ir_config(struct tm6000_IR
*ir
)
95 struct tm6000_core
*dev
= ir
->dev
;
99 switch (ir
->rc_type
) {
101 /* Setup IR decoder for NEC standard 12MHz system clock */
102 /* IR_LEADER_CNT = 0.9ms */
103 tm6000_set_reg(dev
, TM6010_REQ07_RD8_IR_LEADER1
, 0xaa);
104 tm6000_set_reg(dev
, TM6010_REQ07_RD8_IR_LEADER0
, 0x30);
105 /* IR_PULSE_CNT = 0.7ms */
106 tm6000_set_reg(dev
, TM6010_REQ07_RD8_IR_PULSE_CNT1
, 0x20);
107 tm6000_set_reg(dev
, TM6010_REQ07_RD8_IR_PULSE_CNT0
, 0xd0);
108 /* Remote WAKEUP = enable */
109 tm6000_set_reg(dev
, TM6010_REQ07_RE5_REMOTE_WAKEUP
, 0xfe);
110 /* IR_WKUP_SEL = Low byte in decoded IR data */
111 tm6000_set_reg(dev
, TM6010_REQ07_RD8_IR_WAKEUP_SEL
, 0xff);
112 /* IR_WKU_ADD code */
113 tm6000_set_reg(dev
, TM6010_REQ07_RD8_IR_WAKEUP_ADD
, 0xff);
114 tm6000_flash_led(dev
, 0);
116 tm6000_flash_led(dev
, 1);
131 rc
= tm6000_read_write_usb(dev
, USB_DIR_OUT
| USB_TYPE_VENDOR
|
132 USB_RECIP_DEVICE
, REQ_00_SET_IR_VALUE
, 0, 0, buf
, 0x0a);
136 printk(KERN_INFO
"IR configuration failed");
145 static void tm6000_ir_urb_received(struct urb
*urb
)
147 struct tm6000_core
*dev
= urb
->context
;
148 struct tm6000_IR
*ir
= dev
->ir
;
151 if (urb
->status
!= 0)
152 printk(KERN_INFO
"not ready\n");
153 else if (urb
->actual_length
> 0) {
154 memcpy(ir
->urb_data
, urb
->transfer_buffer
, urb
->actual_length
);
156 dprintk("data %02x %02x %02x %02x\n", ir
->urb_data
[0],
157 ir
->urb_data
[1], ir
->urb_data
[2], ir
->urb_data
[3]);
162 rc
= usb_submit_urb(urb
, GFP_ATOMIC
);
165 static int default_polling_getkey(struct tm6000_IR
*ir
,
166 struct tm6000_ir_poll_result
*poll_result
)
168 struct tm6000_core
*dev
= ir
->dev
;
172 if (ir
->wait
&& !&dev
->int_in
)
176 switch (ir
->rc_type
) {
178 poll_result
->rc_data
= ir
->urb_data
[0];
181 if (ir
->urb_data
[1] == ((ir
->key_addr
>> 8) & 0xff)) {
182 poll_result
->rc_data
= ir
->urb_data
[0]
183 | ir
->urb_data
[1] << 8;
187 poll_result
->rc_data
= ir
->urb_data
[0]
188 | ir
->urb_data
[1] << 8;
192 tm6000_set_reg(dev
, REQ_04_EN_DISABLE_MCU_INT
, 2, 0);
194 tm6000_set_reg(dev
, REQ_04_EN_DISABLE_MCU_INT
, 2, 1);
197 if (ir
->rc_type
== RC_TYPE_RC5
) {
198 rc
= tm6000_read_write_usb(dev
, USB_DIR_IN
|
199 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
200 REQ_02_GET_IR_CODE
, 0, 0, buf
, 1);
204 dprintk("read data=%02x\n", buf
[0]);
208 poll_result
->rc_data
= buf
[0];
210 rc
= tm6000_read_write_usb(dev
, USB_DIR_IN
|
211 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
212 REQ_02_GET_IR_CODE
, 0, 0, buf
, 2);
216 dprintk("read data=%04x\n", buf
[0] | buf
[1] << 8);
220 poll_result
->rc_data
= buf
[0] | buf
[1] << 8;
222 if ((poll_result
->rc_data
& 0x00ff) != 0xff)
228 static void tm6000_ir_handle_key(struct tm6000_IR
*ir
)
230 struct tm6000_core
*dev
= ir
->dev
;
232 struct tm6000_ir_poll_result poll_result
;
234 /* read the registers containing the IR status */
235 result
= ir
->get_key(ir
, &poll_result
);
237 printk(KERN_INFO
"ir->get_key() failed %d\n", result
);
241 dprintk("ir->get_key result data=%04x\n", poll_result
.rc_data
);
244 if (ir
->pwledcnt
>= PWLED_OFF
) {
247 tm6000_flash_led(dev
, 1);
253 rc_keydown(ir
->rc
, poll_result
.rc_data
, 0);
257 tm6000_flash_led(dev
, 0);
262 static void tm6000_ir_work(struct work_struct
*work
)
264 struct tm6000_IR
*ir
= container_of(work
, struct tm6000_IR
, work
.work
);
266 tm6000_ir_handle_key(ir
);
267 schedule_delayed_work(&ir
->work
, msecs_to_jiffies(ir
->polling
));
270 static int tm6000_ir_start(struct rc_dev
*rc
)
272 struct tm6000_IR
*ir
= rc
->priv
;
274 INIT_DELAYED_WORK(&ir
->work
, tm6000_ir_work
);
275 schedule_delayed_work(&ir
->work
, 0);
280 static void tm6000_ir_stop(struct rc_dev
*rc
)
282 struct tm6000_IR
*ir
= rc
->priv
;
284 cancel_delayed_work_sync(&ir
->work
);
287 int tm6000_ir_change_protocol(struct rc_dev
*rc
, u64 rc_type
)
289 struct tm6000_IR
*ir
= rc
->priv
;
294 if ((rc
->rc_map
.scan
) && (rc_type
== RC_TYPE_NEC
))
295 ir
->key_addr
= ((rc
->rc_map
.scan
[0].scancode
>> 8) & 0xffff);
297 ir
->get_key
= default_polling_getkey
;
298 ir
->rc_type
= rc_type
;
300 tm6000_ir_config(ir
);
305 int tm6000_ir_int_start(struct tm6000_core
*dev
)
307 struct tm6000_IR
*ir
= dev
->ir
;
315 ir
->int_urb
= usb_alloc_urb(0, GFP_KERNEL
);
319 pipe
= usb_rcvintpipe(dev
->udev
,
320 dev
->int_in
.endp
->desc
.bEndpointAddress
321 & USB_ENDPOINT_NUMBER_MASK
);
323 size
= usb_maxpacket(dev
->udev
, pipe
, usb_pipeout(pipe
));
324 dprintk("IR max size: %d\n", size
);
326 ir
->int_urb
->transfer_buffer
= kzalloc(size
, GFP_KERNEL
);
327 if (ir
->int_urb
->transfer_buffer
== NULL
) {
328 usb_free_urb(ir
->int_urb
);
331 dprintk("int interval: %d\n", dev
->int_in
.endp
->desc
.bInterval
);
332 usb_fill_int_urb(ir
->int_urb
, dev
->udev
, pipe
,
333 ir
->int_urb
->transfer_buffer
, size
,
334 tm6000_ir_urb_received
, dev
,
335 dev
->int_in
.endp
->desc
.bInterval
);
336 err
= usb_submit_urb(ir
->int_urb
, GFP_KERNEL
);
338 kfree(ir
->int_urb
->transfer_buffer
);
339 usb_free_urb(ir
->int_urb
);
342 ir
->urb_data
= kzalloc(size
, GFP_KERNEL
);
347 void tm6000_ir_int_stop(struct tm6000_core
*dev
)
349 struct tm6000_IR
*ir
= dev
->ir
;
354 usb_kill_urb(ir
->int_urb
);
355 kfree(ir
->int_urb
->transfer_buffer
);
356 usb_free_urb(ir
->int_urb
);
362 int tm6000_ir_init(struct tm6000_core
*dev
)
364 struct tm6000_IR
*ir
;
371 if (!dev
->caps
.has_remote
)
377 ir
= kzalloc(sizeof(*ir
), GFP_KERNEL
);
378 rc
= rc_allocate_device();
382 /* record handles to ourself */
387 /* input einrichten */
388 rc
->allowed_protos
= RC_TYPE_RC5
| RC_TYPE_NEC
;
390 rc
->change_protocol
= tm6000_ir_change_protocol
;
391 rc
->open
= tm6000_ir_start
;
392 rc
->close
= tm6000_ir_stop
;
393 rc
->driver_type
= RC_DRIVER_SCANCODE
;
400 snprintf(ir
->name
, sizeof(ir
->name
), "tm5600/60x0 IR (%s)",
403 usb_make_path(dev
->udev
, ir
->phys
, sizeof(ir
->phys
));
404 strlcat(ir
->phys
, "/input0", sizeof(ir
->phys
));
406 tm6000_ir_change_protocol(rc
, RC_TYPE_UNKNOWN
);
408 rc
->input_name
= ir
->name
;
409 rc
->input_phys
= ir
->phys
;
410 rc
->input_id
.bustype
= BUS_USB
;
411 rc
->input_id
.version
= 1;
412 rc
->input_id
.vendor
= le16_to_cpu(dev
->udev
->descriptor
.idVendor
);
413 rc
->input_id
.product
= le16_to_cpu(dev
->udev
->descriptor
.idProduct
);
414 rc
->map_name
= dev
->ir_codes
;
415 rc
->driver_name
= "tm6000";
416 rc
->dev
.parent
= &dev
->udev
->dev
;
419 dprintk("IR over int\n");
421 err
= tm6000_ir_int_start(dev
);
428 err
= rc_register_device(rc
);
441 int tm6000_ir_fini(struct tm6000_core
*dev
)
443 struct tm6000_IR
*ir
= dev
->ir
;
445 /* skip detach on non attached board */
450 rc_unregister_device(ir
->rc
);
453 tm6000_ir_int_stop(dev
);