linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [media] imon: Fix internal key table for 15c2:0034
@ 2014-03-15 16:02 Ulrich Eckhardt
  2014-07-23 20:55 ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 7+ messages in thread
From: Ulrich Eckhardt @ 2014-03-15 16:02 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, jarod; +Cc: linux-media

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@uli-eckhardt.de>

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@wilsonet.com>"
   #define MOD_DESC       "Driver for SoundGraph iMON MultiMedia IR/Display"
   #define MOD_NAME       "imon"
-#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[];
+};
+
   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) {
+               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) {
                  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) {
+               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);

+       /* 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;


-- 
Ulrich Eckhardt                  http://www.uli-eckhardt.de

Ein Blitzableiter auf dem Kirchturm ist das denkbar stärkste
Misstrauensvotum gegen den lieben Gott. (Karl Krauss)

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-07-26 18:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-15 16:02 [PATCH] [media] imon: Fix internal key table for 15c2:0034 Ulrich Eckhardt
2014-07-23 20:55 ` Mauro Carvalho Chehab
2014-07-26  9:40   ` Ulrich Eckhardt
2014-07-26 17:46   ` [PATCH 0/3] " Ulrich Eckhardt
2014-07-26 17:56     ` [PATCH 1/3] [media] imon: Define keytables per USB Device Id Ulrich Eckhardt
2014-07-26 17:59     ` [PATCH 2/3] [media] imon: Add internal key table for 15c2:0034 Ulrich Eckhardt
2014-07-26 18:01     ` [PATCH 3/3] [media] imon: Fix not working front panel Ulrich Eckhardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).