diff --git a/packages/linux/patches/default/linux-063-imon_ultrabay-id_0x98.patch b/packages/linux/patches/default/linux-063-imon_ultrabay-id_0x98.patch new file mode 100644 index 0000000000..2612d876fd --- /dev/null +++ b/packages/linux/patches/default/linux-063-imon_ultrabay-id_0x98.patch @@ -0,0 +1,153 @@ +From cf330691668a3bee37b8ac8212709b3ccdd87997 Mon Sep 17 00:00:00 2001 +From: Flavius Georgescu +Date: Fri, 20 Sep 2019 13:11:39 -0300 +Subject: media: rc: Add support for another iMON 0xffdc device + +The device it's an iMON UltraBay (0x98 in config byte) with LCD, +IR and dual-knobs front panel. + +To work properly the device also require its own key table, +and repeat suppression for all buttons. + +Signed-off-by: Flavius Georgescu +Co-developed-by: Chris Vandomelen +Signed-off-by: Chris Vandomelen +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/media/rc/imon.c | 61 +++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 51 insertions(+), 10 deletions(-) + +(limited to 'drivers/media/rc/imon.c') + +diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c +index 37a850421fbb..b8d96c50a804 100644 +--- a/drivers/media/rc/imon.c ++++ b/drivers/media/rc/imon.c +@@ -83,6 +83,7 @@ struct imon_usb_dev_descr { + __u16 flags; + #define IMON_NO_FLAGS 0 + #define IMON_NEED_20MS_PKT_DELAY 1 ++#define IMON_SUPPRESS_REPEATED_KEYS 2 + struct imon_panel_key_table key_table[]; + }; + +@@ -149,8 +150,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 */ ++ const struct imon_usb_dev_descr *dev_descr; ++ /* device description with key */ ++ /* table for front panels */ + }; + + #define TOUCH_TIMEOUT (HZ/30) +@@ -315,6 +317,32 @@ static const struct imon_usb_dev_descr imon_DH102 = { + } + }; + ++/* imon ultrabay front panel key table */ ++static const struct imon_usb_dev_descr ultrabay_table = { ++ .flags = IMON_SUPPRESS_REPEATED_KEYS, ++ .key_table = { ++ { 0x0000000f0000ffeell, KEY_MEDIA }, /* Go */ ++ { 0x000000000100ffeell, KEY_UP }, ++ { 0x000000000001ffeell, KEY_DOWN }, ++ { 0x000000160000ffeell, KEY_ENTER }, ++ { 0x0000001f0000ffeell, KEY_AUDIO }, /* Music */ ++ { 0x000000200000ffeell, KEY_VIDEO }, /* Movie */ ++ { 0x000000210000ffeell, KEY_CAMERA }, /* Photo */ ++ { 0x000000270000ffeell, KEY_DVD }, /* DVD */ ++ { 0x000000230000ffeell, KEY_TV }, /* TV */ ++ { 0x000000050000ffeell, KEY_PREVIOUS }, /* Previous */ ++ { 0x000000070000ffeell, KEY_REWIND }, ++ { 0x000000040000ffeell, KEY_STOP }, ++ { 0x000000020000ffeell, KEY_PLAYPAUSE }, ++ { 0x000000080000ffeell, KEY_FASTFORWARD }, ++ { 0x000000060000ffeell, KEY_NEXT }, /* Next */ ++ { 0x000100000000ffeell, KEY_VOLUMEUP }, ++ { 0x010000000000ffeell, KEY_VOLUMEDOWN }, ++ { 0x000000010000ffeell, KEY_MUTE }, ++ { 0, KEY_RESERVED }, ++ } ++}; ++ + /* + * USB Device ID for iMON USB Control Boards + * +@@ -1264,9 +1292,11 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode) + + static u32 imon_panel_key_lookup(struct imon_context *ictx, u64 code) + { +- int i; ++ const struct imon_panel_key_table *key_table; + u32 keycode = KEY_RESERVED; +- struct imon_panel_key_table *key_table = ictx->dev_descr->key_table; ++ int i; ++ ++ key_table = ictx->dev_descr->key_table; + + for (i = 0; key_table[i].hw_code != 0; i++) { + if (key_table[i].hw_code == (code | 0xffee)) { +@@ -1550,7 +1580,6 @@ static void imon_incoming_packet(struct imon_context *ictx, + u32 kc; + u64 scancode; + int press_type = 0; +- long msec; + ktime_t t; + static ktime_t prev_time; + u8 ktype; +@@ -1653,14 +1682,16 @@ static void imon_incoming_packet(struct imon_context *ictx, + spin_lock_irqsave(&ictx->kc_lock, flags); + + t = ktime_get(); +- /* KEY_MUTE repeats from knob need to be suppressed */ +- if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { +- msec = ktime_ms_delta(t, prev_time); +- if (msec < ictx->idev->rep[REP_DELAY]) { ++ /* KEY repeats from knob and panel that need to be suppressed */ ++ if (ictx->kc == KEY_MUTE || ++ ictx->dev_descr->flags & IMON_SUPPRESS_REPEATED_KEYS) { ++ if (ictx->kc == ictx->last_keycode && ++ ktime_ms_delta(t, prev_time) < ictx->idev->rep[REP_DELAY]) { + spin_unlock_irqrestore(&ictx->kc_lock, flags); + return; + } + } ++ + prev_time = t; + kc = ictx->kc; + +@@ -1848,6 +1879,14 @@ static void imon_get_ffdc_type(struct imon_context *ictx) + dev_info(ictx->dev, "0xffdc iMON Inside, iMON IR"); + ictx->display_supported = false; + break; ++ /* Soundgraph iMON UltraBay */ ++ case 0x98: ++ dev_info(ictx->dev, "0xffdc iMON UltraBay, LCD + IR"); ++ detected_display_type = IMON_DISPLAY_TYPE_LCD; ++ allowed_protos = RC_PROTO_BIT_IMON | RC_PROTO_BIT_RC6_MCE; ++ ictx->dev_descr = &ultrabay_table; ++ break; ++ + default: + dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; +@@ -1979,10 +2018,12 @@ out: + + static struct input_dev *imon_init_idev(struct imon_context *ictx) + { +- struct imon_panel_key_table *key_table = ictx->dev_descr->key_table; ++ const struct imon_panel_key_table *key_table; + struct input_dev *idev; + int ret, i; + ++ key_table = ictx->dev_descr->key_table; ++ + idev = input_allocate_device(); + if (!idev) + goto out; +-- +cgit 1.2-0.3.lf.el7