diff options
Diffstat (limited to 'drivers/staging/tm6000/tm6000-input.c')
| -rw-r--r-- | drivers/staging/tm6000/tm6000-input.c | 381 |
1 files changed, 0 insertions, 381 deletions
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c deleted file mode 100644 index 6022caaa739..00000000000 --- a/drivers/staging/tm6000/tm6000-input.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> - -#include <linux/input.h> -#include <linux/usb.h> - -#include <media/ir-core.h> -#include <media/ir-common.h> - -#include "tm6000.h" -#include "tm6000-regs.h" - -static unsigned int ir_debug; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debug message [IR]"); - -static unsigned int enable_ir = 1; -module_param(enable_ir, int, 0644); -MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)"); - -#undef dprintk - -#define dprintk(fmt, arg...) \ - if (ir_debug) { \ - printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ - } - -struct tm6000_ir_poll_result { - u16 rc_data; -}; - -struct tm6000_IR { - struct tm6000_core *dev; - struct ir_input_dev *input; - struct ir_input_state ir; - char name[32]; - char phys[32]; - - /* poll expernal decoder */ - int polling; - struct delayed_work work; - u8 wait:1; - u8 key:1; - struct urb *int_urb; - u8 *urb_data; - - int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); - - /* IR device properties */ - struct ir_dev_props props; -}; - - -void tm6000_ir_wait(struct tm6000_core *dev, u8 state) -{ - struct tm6000_IR *ir = dev->ir; - - if (!dev->ir) - return; - - if (state) - ir->wait = 1; - else - ir->wait = 0; -} - - -static int tm6000_ir_config(struct tm6000_IR *ir) -{ - struct tm6000_core *dev = ir->dev; - u8 buf[10]; - int rc; - - /* hack */ - buf[0] = 0xff; - buf[1] = 0xff; - buf[2] = 0xf2; - buf[3] = 0x2b; - buf[4] = 0x20; - buf[5] = 0x35; - buf[6] = 0x60; - buf[7] = 0x04; - buf[8] = 0xc0; - buf[9] = 0x08; - - rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a); - msleep(100); - - if (rc < 0) { - printk(KERN_INFO "IR configuration failed"); - return rc; - } - return 0; -} - -static void tm6000_ir_urb_received(struct urb *urb) -{ - struct tm6000_core *dev = urb->context; - struct tm6000_IR *ir = dev->ir; - int rc; - - if (urb->status != 0) - printk(KERN_INFO "not ready\n"); - else if (urb->actual_length > 0) { - memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); - - dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], - ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); - - ir->key = 1; - } - - rc = usb_submit_urb(urb, GFP_ATOMIC); -} - -static int default_polling_getkey(struct tm6000_IR *ir, - struct tm6000_ir_poll_result *poll_result) -{ - struct tm6000_core *dev = ir->dev; - int rc; - u8 buf[2]; - - if (ir->wait && !&dev->int_in) - return 0; - - if (&dev->int_in) { - if (ir->ir.ir_type == IR_TYPE_RC5) - poll_result->rc_data = ir->urb_data[0]; - else - poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8; - } else { - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); - msleep(10); - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); - msleep(10); - - if (ir->ir.ir_type == IR_TYPE_RC5) { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_02_GET_IR_CODE, 0, 0, buf, 1); - - msleep(10); - - dprintk("read data=%02x\n", buf[0]); - if (rc < 0) - return rc; - - poll_result->rc_data = buf[0]; - } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_02_GET_IR_CODE, 0, 0, buf, 2); - - msleep(10); - - dprintk("read data=%04x\n", buf[0] | buf[1] << 8); - if (rc < 0) - return rc; - - poll_result->rc_data = buf[0] | buf[1] << 8; - } - if ((poll_result->rc_data & 0x00ff) != 0xff) - ir->key = 1; - } - return 0; -} - -static void tm6000_ir_handle_key(struct tm6000_IR *ir) -{ - int result; - struct tm6000_ir_poll_result poll_result; - - /* read the registers containing the IR status */ - result = ir->get_key(ir, &poll_result); - if (result < 0) { - printk(KERN_INFO "ir->get_key() failed %d\n", result); - return; - } - - dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); - - if (ir->key) { - ir_input_keydown(ir->input->input_dev, &ir->ir, - (u32)poll_result.rc_data); - - ir_input_nokey(ir->input->input_dev, &ir->ir); - ir->key = 0; - } - return; -} - -static void tm6000_ir_work(struct work_struct *work) -{ - struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); - - tm6000_ir_handle_key(ir); - schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); -} - -static int tm6000_ir_start(void *priv) -{ - struct tm6000_IR *ir = priv; - - INIT_DELAYED_WORK(&ir->work, tm6000_ir_work); - schedule_delayed_work(&ir->work, 0); - - return 0; -} - -static void tm6000_ir_stop(void *priv) -{ - struct tm6000_IR *ir = priv; - - cancel_delayed_work_sync(&ir->work); -} - -int tm6000_ir_change_protocol(void *priv, u64 ir_type) -{ - struct tm6000_IR *ir = priv; - - ir->get_key = default_polling_getkey; - - tm6000_ir_config(ir); - /* TODO */ - return 0; -} - -int tm6000_ir_init(struct tm6000_core *dev) -{ - struct tm6000_IR *ir; - struct ir_input_dev *ir_input_dev; - int err = -ENOMEM; - int pipe, size, rc; - - if (!enable_ir) - return -ENODEV; - - if (!dev->caps.has_remote) - return 0; - - if (!dev->ir_codes) - return 0; - - ir = kzalloc(sizeof(*ir), GFP_KERNEL); - ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL); - ir_input_dev->input_dev = input_allocate_device(); - if (!ir || !ir_input_dev || !ir_input_dev->input_dev) - goto err_out_free; - - /* record handles to ourself */ - ir->dev = dev; - dev->ir = ir; - - ir->input = ir_input_dev; - - /* input einrichten */ - ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; - ir->props.priv = ir; - ir->props.change_protocol = tm6000_ir_change_protocol; - ir->props.open = tm6000_ir_start; - ir->props.close = tm6000_ir_stop; - ir->props.driver_type = RC_DRIVER_SCANCODE; - - ir->polling = 50; - - snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)", - dev->name); - - usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); - strlcat(ir->phys, "/input0", sizeof(ir->phys)); - - tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN); - err = ir_input_init(ir_input_dev->input_dev, &ir->ir, IR_TYPE_OTHER); - if (err < 0) - goto err_out_free; - - ir_input_dev->input_dev->name = ir->name; - ir_input_dev->input_dev->phys = ir->phys; - ir_input_dev->input_dev->id.bustype = BUS_USB; - ir_input_dev->input_dev->id.version = 1; - ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); - ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); - - ir_input_dev->input_dev->dev.parent = &dev->udev->dev; - - if (&dev->int_in) { - dprintk("IR over int\n"); - - ir->int_urb = usb_alloc_urb(0, GFP_KERNEL); - - pipe = usb_rcvintpipe(dev->udev, - dev->int_in.endp->desc.bEndpointAddress - & USB_ENDPOINT_NUMBER_MASK); - - size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); - dprintk("IR max size: %d\n", size); - - ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); - if (ir->int_urb->transfer_buffer == NULL) { - usb_free_urb(ir->int_urb); - goto err_out_stop; - } - dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval); - usb_fill_int_urb(ir->int_urb, dev->udev, pipe, - ir->int_urb->transfer_buffer, size, - tm6000_ir_urb_received, dev, - dev->int_in.endp->desc.bInterval); - rc = usb_submit_urb(ir->int_urb, GFP_KERNEL); - if (rc) { - kfree(ir->int_urb->transfer_buffer); - usb_free_urb(ir->int_urb); - err = rc; - goto err_out_stop; - } - ir->urb_data = kzalloc(size, GFP_KERNEL); - } - - /* ir register */ - err = ir_input_register(ir->input->input_dev, dev->ir_codes, - &ir->props, "tm6000"); - if (err) - goto err_out_stop; - - return 0; - -err_out_stop: - dev->ir = NULL; -err_out_free: - kfree(ir_input_dev); - kfree(ir); - return err; -} - -int tm6000_ir_fini(struct tm6000_core *dev) -{ - struct tm6000_IR *ir = dev->ir; - - /* skip detach on non attached board */ - - if (!ir) - return 0; - - ir_input_unregister(ir->input->input_dev); - - if (ir->int_urb) { - usb_kill_urb(ir->int_urb); - kfree(ir->int_urb->transfer_buffer); - usb_free_urb(ir->int_urb); - ir->int_urb = NULL; - kfree(ir->urb_data); - ir->urb_data = NULL; - } - - kfree(ir->input); - ir->input = NULL; - kfree(ir); - dev->ir = NULL; - - return 0; -} |
