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
static 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);