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 20#include <linux/module.h> 21#include <linux/init.h> 22#include <linux/delay.h> 23 24#include <linux/input.h> 25#include <linux/usb.h> 26 27#include <media/ir-core.h> 28#include <media/ir-common.h> 29 30#include "tm6000.h" 31#include "tm6000-regs.h" 32 33static unsigned int ir_debug; 34module_param(ir_debug, int, 0644); 35MODULE_PARM_DESC(ir_debug, "enable debug message [IR]"); 36 37static unsigned int enable_ir = 1; 38module_param(enable_ir, int, 0644); 39MODULE_PARM_DESC(enable_ir, "enable ir (default is enable"); 40 41#undef dprintk 42 43#define dprintk(fmt, arg...) \ 44 if (ir_debug) { \ 45 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ 46 } 47 48struct tm6000_ir_poll_result { 49 u16 rc_data; 50}; 51 52struct tm6000_IR { 53 struct tm6000_core *dev; 54 struct ir_input_dev *input; 55 struct ir_input_state ir; 56 char name[32]; 57 char phys[32]; 58 59 /* poll expernal decoder */ 60 int polling; 61 struct delayed_work work; 62 u8 wait:1; 63 u8 key:1; 64 struct urb *int_urb; 65 u8 *urb_data; 66 67 int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); 68 69 /* IR device properties */ 70 struct ir_dev_props props; 71}; 72 73 74void tm6000_ir_wait(struct tm6000_core *dev, u8 state) 75{ 76 struct tm6000_IR *ir = dev->ir; 77 78 if (!dev->ir) 79 return; 80 81 if (state) 82 ir->wait = 1; 83 else 84 ir->wait = 0; 85} 86 87 88static int tm6000_ir_config(struct tm6000_IR *ir) 89{ 90 struct tm6000_core *dev = ir->dev; 91 u8 buf[10]; 92 int rc; 93 94 /* hack */ 95 buf[0] = 0xff; 96 buf[1] = 0xff; 97 buf[2] = 0xf2; 98 buf[3] = 0x2b; 99 buf[4] = 0x20; 100 buf[5] = 0x35; 101 buf[6] = 0x60; 102 buf[7] = 0x04; 103 buf[8] = 0xc0; 104 buf[9] = 0x08; 105 106 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | 107 USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a); 108 msleep(100); 109 110 if (rc < 0) { 111 printk(KERN_INFO "IR configuration failed"); 112 return rc; 113 } 114 return 0; 115} 116 117static void tm6000_ir_urb_received(struct urb *urb) 118{ 119 struct tm6000_core *dev = urb->context; 120 struct tm6000_IR *ir = dev->ir; 121 int rc; 122 123 if (urb->status != 0) 124 printk(KERN_INFO "not ready\n"); 125 else if (urb->actual_length > 0) { 126 memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); 127 128 dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], 129 ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); 130 131 ir->key = 1; 132 } 133 134 rc = usb_submit_urb(urb, GFP_ATOMIC); 135} 136 137static int default_polling_getkey(struct tm6000_IR *ir, 138 struct tm6000_ir_poll_result *poll_result) 139{ 140 struct tm6000_core *dev = ir->dev; 141 int rc; 142 u8 buf[2]; 143 144 if (ir->wait && !&dev->int_in) 145 return 0; 146 147 if (&dev->int_in) { 148 if (ir->ir.ir_type == IR_TYPE_RC5) 149 poll_result->rc_data = ir->urb_data[0]; 150 else 151 poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8; 152 } else { 153 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); 154 msleep(10); 155 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); 156 msleep(10); 157 158 if (ir->ir.ir_type == IR_TYPE_RC5) { 159 rc = tm6000_read_write_usb(dev, USB_DIR_IN | 160 USB_TYPE_VENDOR | USB_RECIP_DEVICE, 161 REQ_02_GET_IR_CODE, 0, 0, buf, 1); 162 163 msleep(10); 164 165 dprintk("read data=%02x\n", buf[0]); 166 if (rc < 0) 167 return rc; 168 169 poll_result->rc_data = buf[0]; 170 } else { 171 rc = tm6000_read_write_usb(dev, USB_DIR_IN | 172 USB_TYPE_VENDOR | USB_RECIP_DEVICE, 173 REQ_02_GET_IR_CODE, 0, 0, buf, 2); 174 175 msleep(10); 176 177 dprintk("read data=%04x\n", buf[0] | buf[1] << 8); 178 if (rc < 0) 179 return rc; 180 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 189static void tm6000_ir_handle_key(struct tm6000_IR *ir) 190{ 191 int result; 192 struct tm6000_ir_poll_result poll_result; 193 194 /* read the registers containing the IR status */ 195 result = ir->get_key(ir, &poll_result); 196 if (result < 0) { 197 printk(KERN_INFO "ir->get_key() failed %d\n", result); 198 return; 199 } 200 201 dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); 202 203 if (ir->key) { 204 ir_input_keydown(ir->input->input_dev, &ir->ir, 205 (u32)poll_result.rc_data); 206 207 ir_input_nokey(ir->input->input_dev, &ir->ir); 208 ir->key = 0; 209 } 210 return; 211} 212 213static void tm6000_ir_work(struct work_struct *work) 214{ 215 struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); 216 217 tm6000_ir_handle_key(ir); 218 schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); 219} 220 221static int tm6000_ir_start(void *priv) 222{ 223 struct tm6000_IR *ir = priv; 224 225 INIT_DELAYED_WORK(&ir->work, tm6000_ir_work); 226 schedule_delayed_work(&ir->work, 0); 227 228 return 0; 229} 230 231static void tm6000_ir_stop(void *priv) 232{ 233 struct tm6000_IR *ir = priv; 234 235 cancel_delayed_work_sync(&ir->work); 236} 237 238int tm6000_ir_change_protocol(void *priv, u64 ir_type) 239{ 240 struct tm6000_IR *ir = priv; 241 242 ir->get_key = default_polling_getkey; 243 244 tm6000_ir_config(ir); 245 /* TODO */ 246 return 0; 247} 248 249int tm6000_ir_init(struct tm6000_core *dev) 250{ 251 struct tm6000_IR *ir; 252 struct ir_input_dev *ir_input_dev; 253 int err = -ENOMEM; 254 int pipe, size, rc; 255 256 if (!enable_ir) 257 return -ENODEV; 258 259 if (!dev->caps.has_remote) 260 return 0; 261 262 if (!dev->ir_codes) 263 return 0; 264 265 ir = kzalloc(sizeof(*ir), GFP_KERNEL); 266 ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL); 267 ir_input_dev->input_dev = input_allocate_device(); 268 if (!ir || !ir_input_dev || !ir_input_dev->input_dev) 269 goto err_out_free; 270 271 /* record handles to ourself */ 272 ir->dev = dev; 273 dev->ir = ir; 274 275 ir->input = ir_input_dev; 276 277 /* input einrichten */ 278 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; 279 ir->props.priv = ir; 280 ir->props.change_protocol = tm6000_ir_change_protocol; 281 ir->props.open = tm6000_ir_start; 282 ir->props.close = tm6000_ir_stop; 283 ir->props.driver_type = RC_DRIVER_SCANCODE; 284 285 ir->polling = 50; 286 287 snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)", 288 dev->name); 289 290 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 291 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 292 293 tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN); 294 err = ir_input_init(ir_input_dev->input_dev, &ir->ir, IR_TYPE_OTHER); 295 if (err < 0) 296 goto err_out_free; 297 298 ir_input_dev->input_dev->name = ir->name; 299 ir_input_dev->input_dev->phys = ir->phys; 300 ir_input_dev->input_dev->id.bustype = BUS_USB; 301 ir_input_dev->input_dev->id.version = 1; 302 ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); 303 ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); 304 305 ir_input_dev->input_dev->dev.parent = &dev->udev->dev; 306 307 if (&dev->int_in) { 308 dprintk("IR over int\n"); 309 310 ir->int_urb = usb_alloc_urb(0, GFP_KERNEL); 311 312 pipe = usb_rcvintpipe(dev->udev, 313 dev->int_in.endp->desc.bEndpointAddress 314 & USB_ENDPOINT_NUMBER_MASK); 315 316 size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); 317 dprintk("IR max size: %d\n", size); 318 319 ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); 320 if (ir->int_urb->transfer_buffer == NULL) { 321 usb_free_urb(ir->int_urb); 322 goto err_out_stop; 323 } 324 dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval); 325 usb_fill_int_urb(ir->int_urb, dev->udev, pipe, 326 ir->int_urb->transfer_buffer, size, 327 tm6000_ir_urb_received, dev, 328 dev->int_in.endp->desc.bInterval); 329 rc = usb_submit_urb(ir->int_urb, GFP_KERNEL); 330 if (rc) { 331 kfree(ir->int_urb->transfer_buffer); 332 usb_free_urb(ir->int_urb); 333 err = rc; 334 goto err_out_stop; 335 } 336 ir->urb_data = kzalloc(size, GFP_KERNEL); 337 } 338 339 /* ir register */ 340 err = ir_input_register(ir->input->input_dev, dev->ir_codes, 341 &ir->props, "tm6000"); 342 if (err) 343 goto err_out_stop; 344 345 return 0; 346 347err_out_stop: 348 dev->ir = NULL; 349err_out_free: 350 kfree(ir_input_dev); 351 kfree(ir); 352 return err; 353} 354 355int tm6000_ir_fini(struct tm6000_core *dev) 356{ 357 struct tm6000_IR *ir = dev->ir; 358 359 /* skip detach on non attached board */ 360 361 if (!ir) 362 return 0; 363 364 ir_input_unregister(ir->input->input_dev); 365 366 if (ir->int_urb) { 367 usb_kill_urb(ir->int_urb); 368 kfree(ir->int_urb->transfer_buffer); 369 usb_free_urb(ir->int_urb); 370 ir->int_urb = NULL; 371 kfree(ir->urb_data); 372 ir->urb_data = NULL; 373 } 374 375 kfree(ir->input); 376 ir->input = NULL; 377 kfree(ir); 378 dev->ir = NULL; 379 380 return 0; 381} 382