Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / media / rc / imon.c
index 8fc0f081b4701ddaf3c7ab0e79b7944f5fede297..6bc35eeb653bf0cbc3ff8a82766481e862d9b198 100644 (file)
@@ -307,6 +307,14 @@ static const struct {
        /* 0xffdc iMON MCE VFD */
        { 0x00010000ffffffeell, KEY_VOLUMEUP },
        { 0x01000000ffffffeell, KEY_VOLUMEDOWN },
+       { 0x00000001ffffffeell, KEY_MUTE },
+       { 0x0000000fffffffeell, KEY_MEDIA },
+       { 0x00000012ffffffeell, KEY_UP },
+       { 0x00000013ffffffeell, KEY_DOWN },
+       { 0x00000014ffffffeell, KEY_LEFT },
+       { 0x00000015ffffffeell, KEY_RIGHT },
+       { 0x00000016ffffffeell, KEY_ENTER },
+       { 0x00000017ffffffeell, KEY_ESC },
        /* iMON Knob values */
        { 0x000100ffffffffeell, KEY_VOLUMEUP },
        { 0x010000ffffffffeell, KEY_VOLUMEDOWN },
@@ -443,16 +451,6 @@ static int display_close(struct inode *inode, struct file *file)
        } else {
                ictx->display_isopen = false;
                dev_dbg(ictx->dev, "display port closed\n");
-               if (!ictx->dev_present_intf0) {
-                       /*
-                        * Device disconnected before close and IR port is not
-                        * open. If IR port is open, context will be deleted by
-                        * ir_close.
-                        */
-                       mutex_unlock(&ictx->lock);
-                       free_imon_context(ictx);
-                       return retval;
-               }
        }
 
        mutex_unlock(&ictx->lock);
@@ -1492,7 +1490,6 @@ static void imon_incoming_packet(struct imon_context *ictx,
        struct device *dev = ictx->dev;
        unsigned long flags;
        u32 kc;
-       bool norelease = false;
        int i;
        u64 scancode;
        int press_type = 0;
@@ -1560,7 +1557,6 @@ static void imon_incoming_packet(struct imon_context *ictx,
             !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
                len = 8;
                imon_pad_to_keys(ictx, buf);
-               norelease = true;
        }
 
        if (debug) {
@@ -1594,16 +1590,16 @@ static void imon_incoming_packet(struct imon_context *ictx,
        /* Only panel type events left to process now */
        spin_lock_irqsave(&ictx->kc_lock, flags);
 
+       do_gettimeofday(&t);
        /* KEY_MUTE repeats from knob need to be suppressed */
        if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
-               do_gettimeofday(&t);
                msec = tv2int(&t, &prev_time);
-               prev_time = t;
                if (msec < ictx->idev->rep[REP_DELAY]) {
                        spin_unlock_irqrestore(&ictx->kc_lock, flags);
                        return;
                }
        }
+       prev_time = t;
        kc = ictx->kc;
 
        spin_unlock_irqrestore(&ictx->kc_lock, flags);
@@ -1615,7 +1611,9 @@ static void imon_incoming_packet(struct imon_context *ictx,
        input_report_key(ictx->idev, kc, 0);
        input_sync(ictx->idev);
 
+       spin_lock_irqsave(&ictx->kc_lock, flags);
        ictx->last_keycode = kc;
+       spin_unlock_irqrestore(&ictx->kc_lock, flags);
 
        return;
 
@@ -1752,6 +1750,8 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
                break;
        /* iMON VFD, MCE IR */
+       case 0x46:
+       case 0x7e:
        case 0x9e:
                dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
@@ -1767,6 +1767,9 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
                dev_info(ictx->dev, "Unknown 0xffdc device, "
                         "defaulting to VFD and iMON IR");
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
+               /* We don't know which one it is, allow user to set the
+                * RC6 one from userspace if OTHER wasn't correct. */
+               allowed_protos |= RC_TYPE_RC6;
                break;
        }
 
@@ -1982,7 +1985,7 @@ static struct input_dev *imon_init_touch(struct imon_context *ictx)
        return touch;
 
 touch_register_failed:
-       input_free_device(ictx->touch);
+       input_free_device(touch);
 
 touch_alloc_failed:
        return NULL;
@@ -2274,14 +2277,12 @@ static int __devinit imon_probe(struct usb_interface *interface,
        struct usb_host_interface *iface_desc = NULL;
        struct usb_interface *first_if;
        struct device *dev = &interface->dev;
-       int ifnum, code_length, sysfs_err;
+       int ifnum, sysfs_err;
        int ret = 0;
        struct imon_context *ictx = NULL;
        struct imon_context *first_if_ctx = NULL;
        u16 vendor, product;
 
-       code_length = BUF_CHUNK_SIZE * 8;
-
        usbdev     = usb_get_dev(interface_to_usbdev(interface));
        iface_desc = interface->cur_altsetting;
        ifnum      = iface_desc->desc.bInterfaceNumber;
@@ -2366,8 +2367,6 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
        dev = ictx->dev;
        ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
 
-       mutex_lock(&ictx->lock);
-
        /*
         * sysfs_remove_group is safe to call even if sysfs_create_group
         * hasn't been called
@@ -2391,24 +2390,20 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
                if (ictx->display_supported) {
                        if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
                                usb_deregister_dev(interface, &imon_lcd_class);
-                       else
+                       else if (ictx->display_type == IMON_DISPLAY_TYPE_VFD)
                                usb_deregister_dev(interface, &imon_vfd_class);
                }
        } else {
                ictx->dev_present_intf1 = false;
                usb_kill_urb(ictx->rx_urb_intf1);
-               if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
+               if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
                        input_unregister_device(ictx->touch);
+                       del_timer_sync(&ictx->ttimer);
+               }
        }
 
-       if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) {
-               if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
-                       del_timer_sync(&ictx->ttimer);
-               mutex_unlock(&ictx->lock);
-               if (!ictx->display_isopen)
-                       free_imon_context(ictx);
-       } else
-               mutex_unlock(&ictx->lock);
+       if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1)
+               free_imon_context(ictx);
 
        mutex_unlock(&driver_lock);