Re: [PATCH] [media] imon: Fix internal key table for 15c2:0034

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ulrich,

Em Sat, 15 Mar 2014 17:02:30 +0100
Ulrich Eckhardt <uli-lirc@xxxxxxxxxxxxxxx> escreveu:

> The front panel of the Thermaltake DH102 is not working since the 
> internal key table does not contain the correct definitions. Some of the 
> key table entries required for this device are conflicting with existing 
> ones. So I had to extend the code to allow to define a key table for 
> each USB id.


> 
> 
> Signed-off-by: Ulrich Eckhardt <uli@xxxxxxxxxxxxxxx>
> 
> diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
> --- a/drivers/media/rc/imon.c
> +++ b/drivers/media/rc/imon.c
> @@ -47,7 +47,7 @@
>    #define MOD_AUTHOR     "Jarod Wilson <jarod@xxxxxxxxxxxx>"
>    #define MOD_DESC       "Driver for SoundGraph iMON MultiMedia IR/Display"
>    #define MOD_NAME       "imon"

First of all, your emailer mangled the patch. It added extra spaces,
converted tab into spaces, etc. The patch can't be applied like that.

> -#define MOD_VERSION    "0.9.4"
> +#define MOD_VERSION    "0.9.5"
> 
>    #define DISPLAY_MINOR_BASE     144
>    #define DEVICE_NAME    "lcd%d"
> @@ -87,6 +87,18 @@ static ssize_t lcd_write(struct file *fi
> 
>    /*** G L O B A L S ***/
> 
> +struct imon_panel_key_table {
> +       u64 hw_code;
> +       u32 keycode;
> +};
> +
> +struct imon_usb_dev_descr {
> +       __u16 flags;
> +#define IMON_NO_FLAGS 0
> +#define IMON_NEED_20MS_PKT_DELAY 1
> +       struct imon_panel_key_table key_table[];
> +};
> +

It seems that you're merging two different issues at the same patch.
Please split it into one patch per logical change.

>    struct imon_context {
>           struct device *dev;
>           /* Newer devices have two interfaces */
> @@ -150,6 +162,9 @@ struct imon_context {
>           struct timer_list ttimer;       /* touch screen timer */
>           int touch_x;                    /* x coordinate on touchscreen */
>           int touch_y;                    /* y coordinate on touchscreen */
> +
> +       struct imon_usb_dev_descr *dev_descr; /* device description with key
> +                                                table for front panels */
>    };
> 
>    #define TOUCH_TIMEOUT  (HZ/30)
> @@ -186,8 +201,122 @@ enum {
>           IMON_KEY_PANEL  = 2,
>    };
> 
> -enum {
> -       IMON_NEED_20MS_PKT_DELAY = 1
> +/*
> + * Key tables for imon receiver front panel/knob.
> + */
> +
> +static const struct imon_usb_dev_descr imon_default_table = {
> +       .flags = IMON_NO_FLAGS,
> +       .key_table = {
> +               { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
> +               { 0x000000001200ffeell, KEY_UP },
> +               { 0x000000001300ffeell, KEY_DOWN },
> +               { 0x000000001400ffeell, KEY_LEFT },
> +               { 0x000000001500ffeell, KEY_RIGHT },
> +               { 0x000000001600ffeell, KEY_ENTER },
> +               { 0x000000001700ffeell, KEY_ESC },
> +               { 0x000000001f00ffeell, KEY_AUDIO },
> +               { 0x000000002000ffeell, KEY_VIDEO },
> +               { 0x000000002100ffeell, KEY_CAMERA },
> +               { 0x000000002700ffeell, KEY_DVD },
> +               { 0x000000002300ffeell, KEY_TV },
> +               { 0x000000002b00ffeell, KEY_EXIT },
> +               { 0x000000002c00ffeell, KEY_SELECT },
> +               { 0x000000002d00ffeell, KEY_MENU },
> +               { 0x000000000500ffeell, KEY_PREVIOUS },
> +               { 0x000000000700ffeell, KEY_REWIND },
> +               { 0x000000000400ffeell, KEY_STOP },
> +               { 0x000000003c00ffeell, KEY_PLAYPAUSE },
> +               { 0x000000000800ffeell, KEY_FASTFORWARD },
> +               { 0x000000000600ffeell, KEY_NEXT },
> +               { 0x000000010000ffeell, KEY_RIGHT },
> +               { 0x000001000000ffeell, KEY_LEFT },
> +               { 0x000000003d00ffeell, KEY_SELECT },
> +               { 0x000100000000ffeell, KEY_VOLUMEUP },
> +               { 0x010000000000ffeell, KEY_VOLUMEDOWN },
> +               { 0x000000000100ffeell, KEY_MUTE },
> +               /* 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 },
> +               { 0x000008ffffffffeell, KEY_MUTE },
> +               { 0, KEY_RESERVED }
> +       }
> +};
> +
> +static const struct imon_usb_dev_descr imon_OEM_VFD = {
> +       .flags = IMON_NEED_20MS_PKT_DELAY,
> +       .key_table = {
> +               { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
> +               { 0x000000001200ffeell, KEY_UP },
> +               { 0x000000001300ffeell, KEY_DOWN },
> +               { 0x000000001400ffeell, KEY_LEFT },
> +               { 0x000000001500ffeell, KEY_RIGHT },
> +               { 0x000000001600ffeell, KEY_ENTER },
> +               { 0x000000001700ffeell, KEY_ESC },
> +               { 0x000000001f00ffeell, KEY_AUDIO },
> +               { 0x000000002b00ffeell, KEY_EXIT },
> +               { 0x000000002c00ffeell, KEY_SELECT },
> +               { 0x000000002d00ffeell, KEY_MENU },
> +               { 0x000000000500ffeell, KEY_PREVIOUS },
> +               { 0x000000000700ffeell, KEY_REWIND },
> +               { 0x000000000400ffeell, KEY_STOP },
> +               { 0x000000003c00ffeell, KEY_PLAYPAUSE },
> +               { 0x000000000800ffeell, KEY_FASTFORWARD },
> +               { 0x000000000600ffeell, KEY_NEXT },
> +               { 0x000000010000ffeell, KEY_RIGHT },
> +               { 0x000001000000ffeell, KEY_LEFT },
> +               { 0x000000003d00ffeell, KEY_SELECT },
> +               { 0x000100000000ffeell, KEY_VOLUMEUP },
> +               { 0x010000000000ffeell, KEY_VOLUMEDOWN },
> +               { 0x000000000100ffeell, KEY_MUTE },
> +               /* 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 },
> +               { 0x000008ffffffffeell, KEY_MUTE },
> +               { 0, KEY_RESERVED }
> +       }
> +};
> +
> +static const struct imon_usb_dev_descr imon_DH102 = {
> +       .flags = IMON_NO_FLAGS,
> +       .key_table = {
> +               { 0x000100000000ffeell, KEY_VOLUMEUP },
> +               { 0x010000000000ffeell, KEY_VOLUMEDOWN },
> +               { 0x000000010000ffeell, KEY_MUTE },
> +               { 0x0000000f0000ffeell, KEY_MEDIA },
> +               { 0x000000120000ffeell, KEY_UP },
> +               { 0x000000130000ffeell, KEY_DOWN },
> +               { 0x000000140000ffeell, KEY_LEFT },
> +               { 0x000000150000ffeell, KEY_RIGHT },
> +               { 0x000000160000ffeell, KEY_ENTER },
> +               { 0x000000170000ffeell, KEY_ESC },
> +               { 0x0000002b0000ffeell, KEY_EXIT },
> +               { 0x0000002c0000ffeell, KEY_SELECT },
> +               { 0x0000002d0000ffeell, KEY_MENU },
> +               { 0, KEY_RESERVED }
> +       }
>    };
> 
>    /*
> @@ -208,7 +337,10 @@ static struct usb_device_id imon_usb_id_
>            * SoundGraph iMON PAD (IR & LCD)
>            * SoundGraph iMON Knob (IR only)
>            */
> -       { USB_DEVICE(0x15c2, 0xffdc) },
> +       {
> +               USB_DEVICE(0x15c2, 0xffdc),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
> 
>           /*
>            * Newer devices, all driven by the latest iMON Windows 
> driver, full
> @@ -216,43 +348,100 @@ static struct usb_device_id imon_usb_id_
>            * Need user input to fill in details on unknown devices.
>            */
>           /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
> -       { USB_DEVICE(0x15c2, 0x0034) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0034),
> +               .driver_info = (unsigned long)&imon_DH102
> +       },
>           /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
> -       { USB_DEVICE(0x15c2, 0x0035) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0035),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* SoundGraph iMON OEM VFD (IR & VFD) */
> -       { USB_DEVICE(0x15c2, 0x0036), .driver_info = 
> IMON_NEED_20MS_PKT_DELAY },
> +       {
> +               USB_DEVICE(0x15c2, 0x0036),
> +               .driver_info = (unsigned long)&imon_OEM_VFD
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x0037) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0037),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* SoundGraph iMON OEM LCD (IR & LCD) */
> -       { USB_DEVICE(0x15c2, 0x0038) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0038),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* SoundGraph iMON UltraBay (IR & LCD) */
> -       { USB_DEVICE(0x15c2, 0x0039) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0039),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x003a) },
> +       {
> +               USB_DEVICE(0x15c2, 0x003a), .
> +               driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x003b) },
> +       {
> +               USB_DEVICE(0x15c2, 0x003b),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* SoundGraph iMON OEM Inside (IR only) */
> -       { USB_DEVICE(0x15c2, 0x003c) },
> +       {
> +               USB_DEVICE(0x15c2, 0x003c),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x003d) },
> +       {
> +               USB_DEVICE(0x15c2, 0x003d),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x003e) },
> +       {
> +               USB_DEVICE(0x15c2, 0x003e),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x003f) },
> +       {
> +               USB_DEVICE(0x15c2, 0x003f),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x0040) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0040),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* SoundGraph iMON MINI (IR only) */
> -       { USB_DEVICE(0x15c2, 0x0041) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0041),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* Antec Veris Multimedia Station EZ External (IR only) */
> -       { USB_DEVICE(0x15c2, 0x0042) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0042),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* Antec Veris Multimedia Station Basic Internal (IR only) */
> -       { USB_DEVICE(0x15c2, 0x0043) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0043),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* Antec Veris Multimedia Station Elite (IR & VFD) */
> -       { USB_DEVICE(0x15c2, 0x0044) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0044),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* Antec Veris Multimedia Station Premiere (IR & LCD) */
> -       { USB_DEVICE(0x15c2, 0x0045) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0045),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           /* device specifics unknown */
> -       { USB_DEVICE(0x15c2, 0x0046) },
> +       {
> +               USB_DEVICE(0x15c2, 0x0046),
> +               .driver_info = (unsigned long)&imon_default_table
> +       },
>           {}
>    };
> 
> @@ -278,55 +467,6 @@ static struct usb_class_driver imon_lcd_
>           .minor_base     = DISPLAY_MINOR_BASE,
>    };
> 
> -/* imon receiver front panel/knob key table */
> -static const struct {
> -       u64 hw_code;
> -       u32 keycode;
> -} imon_panel_key_table[] = {
> -       { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
> -       { 0x000000001200ffeell, KEY_UP },
> -       { 0x000000001300ffeell, KEY_DOWN },
> -       { 0x000000001400ffeell, KEY_LEFT },
> -       { 0x000000001500ffeell, KEY_RIGHT },
> -       { 0x000000001600ffeell, KEY_ENTER },
> -       { 0x000000001700ffeell, KEY_ESC },
> -       { 0x000000001f00ffeell, KEY_AUDIO },
> -       { 0x000000002000ffeell, KEY_VIDEO },
> -       { 0x000000002100ffeell, KEY_CAMERA },
> -       { 0x000000002700ffeell, KEY_DVD },
> -       { 0x000000002300ffeell, KEY_TV },
> -       { 0x000000002b00ffeell, KEY_EXIT },
> -       { 0x000000002c00ffeell, KEY_SELECT },
> -       { 0x000000002d00ffeell, KEY_MENU },
> -       { 0x000000000500ffeell, KEY_PREVIOUS },
> -       { 0x000000000700ffeell, KEY_REWIND },
> -       { 0x000000000400ffeell, KEY_STOP },
> -       { 0x000000003c00ffeell, KEY_PLAYPAUSE },
> -       { 0x000000000800ffeell, KEY_FASTFORWARD },
> -       { 0x000000000600ffeell, KEY_NEXT },
> -       { 0x000000010000ffeell, KEY_RIGHT },
> -       { 0x000001000000ffeell, KEY_LEFT },
> -       { 0x000000003d00ffeell, KEY_SELECT },
> -       { 0x000100000000ffeell, KEY_VOLUMEUP },
> -       { 0x010000000000ffeell, KEY_VOLUMEDOWN },
> -       { 0x000000000100ffeell, KEY_MUTE },
> -       /* 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 },
> -       { 0x000008ffffffffeell, KEY_MUTE },
> -};
> -
>    /* to prevent races between open() and disconnect(), probing, etc */
>    static DEFINE_MUTEX(driver_lock);
> 
> @@ -1210,18 +1350,20 @@ static u32 imon_mce_key_lookup(struct im
>           return keycode;
>    }
> 
> -static u32 imon_panel_key_lookup(u64 code)
> +static u32 imon_panel_key_lookup(struct imon_context *ictx, u64 code)
>    {
> -       int i;
> +       int i = 0;
> +       struct imon_panel_key_table *key_table = ictx->dev_descr->key_table;
>           u32 keycode = KEY_RESERVED;
> 
> -       for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
> -               if (imon_panel_key_table[i].hw_code == (code | 0xffee)) {
> -                       keycode = imon_panel_key_table[i].keycode;
> +       while (key_table[i].hw_code != 0) {

Why to convert a for into a while? using a for() is more Kernel style
for loops like this one.

> +               if (key_table[i].hw_code == (code | 0xffee)) {
> +                       keycode = key_table[i].keycode;
>                           break;
>                   }
> +               i++;
>           }
> -
> +       ictx->release_code = false;
>           return keycode;
>    }
> 
> @@ -1511,7 +1653,7 @@ static void imon_incoming_packet(struct
>           if (len == 8 && buf[7] == 0xee) {
>                   scancode = be64_to_cpu(*((u64 *)buf));
>                   ktype = IMON_KEY_PANEL;
> -               kc = imon_panel_key_lookup(scancode);
> +               kc = imon_panel_key_lookup(ictx, scancode);
>           } else {
>                   scancode = be32_to_cpu(*((u32 *)buf));
>                   if (ictx->rc_type == RC_BIT_RC6_MCE) {
> @@ -1591,8 +1733,8 @@ static void imon_incoming_packet(struct
>           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) {
> +       /* repeats from panel need to be suppressed */
> +       if (ictx->kc == ictx->last_keycode) {


Why did you remove KEY_MUTE? Again, best to put its removal on a
separate patch, clearly stating why this change is needed.

>                   msec = tv2int(&t, &prev_time);
>                   if (msec < ictx->idev->rep[REP_DELAY]) {
>                           spin_unlock_irqrestore(&ictx->kc_lock, flags);
> @@ -1905,6 +2047,7 @@ out:
> 
>    static struct input_dev *imon_init_idev(struct imon_context *ictx)
>    {
> +       struct imon_panel_key_table *key_table = ictx->dev_descr->key_table;
>           struct input_dev *idev;
>           int ret, i;
> 
> @@ -1932,9 +2075,11 @@ static struct input_dev *imon_init_idev(
>                   BIT_MASK(REL_WHEEL);
> 
>           /* panel and/or knob code support */
> -       for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
> -               u32 kc = imon_panel_key_table[i].keycode;
> +       i = 0;
> +       while (key_table[i].hw_code != 0) {

Again, please keep it as a for.

> +               u32 kc = key_table[i].keycode;
>                   __set_bit(kc, idev->keybit);
> +               i++;
>           }
> 
>           usb_to_input_id(ictx->usbdev_intf0, &idev->id);
> @@ -2136,9 +2281,12 @@ static struct imon_context *imon_init_in
>           ictx->vendor  = 
> le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
>           ictx->product = 
> le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);

Patch was line-wrapped.

> 
> +       /* save drive info for later accessing the panel/knob key table */
> +       ictx->dev_descr = (struct imon_usb_dev_descr *)id->driver_info;
>           /* default send_packet delay is 5ms but some devices need more */
> -       ictx->send_packet_delay = id->driver_info & 
> IMON_NEED_20MS_PKT_DELAY ?
> -                                 20 : 5;
> +       ictx->send_packet_delay =
> +                       ictx->dev_descr->flags & IMON_NEED_20MS_PKT_DELAY ?
> +                       20 : 5;
> 
>           ret = -ENODEV;
>           iface_desc = intf->cur_altsetting;
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux