V4L/DVB (4879): budget-ci IR: integrate with ir-common
authorDavid Hardeman <david@hardeman.nu>
Sat, 2 Dec 2006 23:16:05 +0000 (21:16 -0200)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sun, 10 Dec 2006 11:05:17 +0000 (09:05 -0200)
This converts the budget-ci driver so that it uses ir-common for some of its
IR processing. In particular, the keymap for the Nova-T (sub 13c2:1011) is
switched to the Hauppauge grey/black keymap, of which the keys on the
supplied R808 remote control form a subset.
The old budget-ci keymap is moved to ir-keymaps.c and is used for other
remotes.
The debounce logic for buggy remotes (i.e. Zenith) is made conditional the
new debounce parameter and defaults to off (so that repeat keypresses aren't
ignored for all working remotes).
Some parts are based on Darren Salt's dvb-ir patchset.

Signed-off-by: David Hardeman <david@hardeman.nu>
Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/common/ir-keymaps.c
drivers/media/dvb/ttpci/Kconfig
drivers/media/dvb/ttpci/budget-ci.c
include/media/ir-common.h

index db75344..f51e02f 100644 (file)
@@ -1552,3 +1552,58 @@ IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = {
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_norwood);
+
+/* From reading the following remotes:
+ * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
+ * Hauppauge (from NOVA-CI-s box product)
+ * This is a "middle of the road" approach, differences are noted
+ */
+IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+       [ 0x0a ] = KEY_ENTER,
+       [ 0x0b ] = KEY_RED,
+       [ 0x0c ] = KEY_POWER,             /* RADIO on Hauppauge */
+       [ 0x0d ] = KEY_MUTE,
+       [ 0x0f ] = KEY_A,                 /* TV on Hauppauge */
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x14 ] = KEY_B,
+       [ 0x1c ] = KEY_UP,
+       [ 0x1d ] = KEY_DOWN,
+       [ 0x1e ] = KEY_OPTION,            /* RESERVED on Hauppauge */
+       [ 0x1f ] = KEY_BREAK,
+       [ 0x20 ] = KEY_CHANNELUP,
+       [ 0x21 ] = KEY_CHANNELDOWN,
+       [ 0x22 ] = KEY_PREVIOUS,          /* Prev. Ch on Zenith, SOURCE on Hauppauge */
+       [ 0x24 ] = KEY_RESTART,
+       [ 0x25 ] = KEY_OK,
+       [ 0x26 ] = KEY_CYCLEWINDOWS,      /* MINIMIZE on Hauppauge */
+       [ 0x28 ] = KEY_ENTER,             /* VCR mode on Zenith */
+       [ 0x29 ] = KEY_PAUSE,
+       [ 0x2b ] = KEY_RIGHT,
+       [ 0x2c ] = KEY_LEFT,
+       [ 0x2e ] = KEY_MENU,              /* FULL SCREEN on Hauppauge */
+       [ 0x30 ] = KEY_SLOW,
+       [ 0x31 ] = KEY_PREVIOUS,          /* VCR mode on Zenith */
+       [ 0x32 ] = KEY_REWIND,
+       [ 0x34 ] = KEY_FASTFORWARD,
+       [ 0x35 ] = KEY_PLAY,
+       [ 0x36 ] = KEY_STOP,
+       [ 0x37 ] = KEY_RECORD,
+       [ 0x38 ] = KEY_TUNER,             /* TV/VCR on Zenith */
+       [ 0x3a ] = KEY_C,
+       [ 0x3c ] = KEY_EXIT,
+       [ 0x3d ] = KEY_POWER2,
+       [ 0x3e ] = KEY_TUNER,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old);
index 95531a6..eec7ccf 100644 (file)
@@ -92,6 +92,7 @@ config DVB_BUDGET_CI
        select DVB_STV0299 if !DVB_FE_CUSTOMISE
        select DVB_TDA1004X if !DVB_FE_CUSTOMISE
        select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+       select VIDEO_IR
        help
          Support for simple SAA7146 based DVB cards
          (so called Budget- or Nova-PCI cards) without onboard
index c34b5d3..d1b5402 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/spinlock.h>
+#include <media/ir-common.h>
 
 #include "dvb_ca_en50221.h"
 #include "stv0299.h"
 #define SLOTSTATUS_READY       8
 #define SLOTSTATUS_OCCUPIED    (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
 
+/* Milliseconds during which key presses are regarded as key repeat and during
+ * which the debounce logic is active
+ */
+#define IR_REPEAT_TIMEOUT      350
+
+/* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two),
+ * this setting allows the superflous sequences to be ignored
+ */
+static int debounce = 0;
+module_param(debounce, int, 0644);
+MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)");
+
 struct budget_ci_ir {
        struct input_dev *dev;
        struct tasklet_struct msp430_irq_tasklet;
        char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
        char phys[32];
+       struct ir_input_state state;
 };
 
 struct budget_ci {
@@ -89,59 +103,44 @@ struct budget_ci {
        u8 tuner_pll_address; /* used for philips_tdm1316l configs */
 };
 
-/* from reading the following remotes:
-   Zenith Universal 7 / TV Mode 807 / VCR Mode 837
-   Hauppauge (from NOVA-CI-s box product)
-   i've taken a "middle of the road" approach and note the differences
-*/
-static u16 key_map[64] = {
-       /* 0x0X */
-       KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
-       KEY_9,
-       KEY_ENTER,
-       KEY_RED,
-       KEY_POWER,              /* RADIO on Hauppauge */
-       KEY_MUTE,
-       0,
-       KEY_A,                  /* TV on Hauppauge */
-       /* 0x1X */
-       KEY_VOLUMEUP, KEY_VOLUMEDOWN,
-       0, 0,
-       KEY_B,
-       0, 0, 0, 0, 0, 0, 0,
-       KEY_UP, KEY_DOWN,
-       KEY_OPTION,             /* RESERVED on Hauppauge */
-       KEY_BREAK,
-       /* 0x2X */
-       KEY_CHANNELUP, KEY_CHANNELDOWN,
-       KEY_PREVIOUS,           /* Prev. Ch on Zenith, SOURCE on Hauppauge */
-       0, KEY_RESTART, KEY_OK,
-       KEY_CYCLEWINDOWS,       /* MINIMIZE on Hauppauge */
-       0,
-       KEY_ENTER,              /* VCR mode on Zenith */
-       KEY_PAUSE,
-       0,
-       KEY_RIGHT, KEY_LEFT,
-       0,
-       KEY_MENU,               /* FULL SCREEN on Hauppauge */
-       0,
-       /* 0x3X */
-       KEY_SLOW,
-       KEY_PREVIOUS,           /* VCR mode on Zenith */
-       KEY_REWIND,
-       0,
-       KEY_FASTFORWARD,
-       KEY_PLAY, KEY_STOP,
-       KEY_RECORD,
-       KEY_TUNER,              /* TV/VCR on Zenith */
-       0,
-       KEY_C,
-       0,
-       KEY_EXIT,
-       KEY_POWER2,
-       KEY_TUNER,              /* VCR mode on Zenith */
-       0,
-};
+static void msp430_ir_keyup(unsigned long data)
+{
+       struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
+       ir_input_nokey(ir->dev, &ir->state);
+}
+
+static void msp430_ir_interrupt(unsigned long data)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) data;
+       struct input_dev *dev = budget_ci->ir.dev;
+       static int bounces = 0;
+       u32 ir_key;
+       u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
+
+       if (command & 0x40) {
+               ir_key = command & 0x3f;
+
+               if (ir_key != dev->repeat_key && del_timer(&dev->timer))
+                       /* We were still waiting for a keyup event but this is a new key */
+                       ir_input_nokey(dev, &budget_ci->ir.state);
+
+               if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) {
+                       /* Ignore repeated key sequences if requested */
+                       bounces--;
+                       return;
+               }
+
+               if (!timer_pending(&dev->timer))
+                       /* New keypress */
+                       bounces = debounce;
+
+               /* Prepare a keyup event sometime in the future */
+               mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
+
+               /* Generate a new or repeated keypress */
+               ir_input_keydown(dev, &budget_ci->ir.state, ir_key, command);
+       }
+}
 
 static void msp430_ir_debounce(unsigned long data)
 {
@@ -197,7 +196,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
 {
        struct saa7146_dev *saa = budget_ci->budget.dev;
        struct input_dev *input_dev = budget_ci->ir.dev;
-       int i;
        int error;
 
        budget_ci->ir.dev = input_dev = input_allocate_device();
@@ -230,10 +228,30 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
        input_dev->dev = &saa->pci->dev;
 # endif
 
-       set_bit(EV_KEY, input_dev->evbit);
-       for (i = 0; i < ARRAY_SIZE(key_map); i++)
-               if (key_map[i])
-                       set_bit(key_map[i], input_dev->keybit);
+       /* Select keymap */
+       switch (budget_ci->budget.dev->pci->subsystem_device) {
+       case 0x100c:
+       case 0x100f:
+       case 0x1010:
+       case 0x1011:
+       case 0x1012:
+       case 0x1017:
+               /* The hauppauge keymap is a superset of these remotes */
+               ir_input_init(input_dev, &budget_ci->ir.state,
+                             IR_TYPE_RC5, ir_codes_hauppauge_new);
+               break;
+       default:
+               /* unknown remote */
+               ir_input_init(input_dev, &budget_ci->ir.state,
+                             IR_TYPE_RC5, ir_codes_budget_ci_old);
+               break;
+       }
+
+       /* initialise the key-up timeout handler */
+       input_dev->timer.function = msp430_ir_keyup;
+       input_dev->timer.data = (unsigned long) &budget_ci->ir;
+       input_dev->rep[REP_DELAY] = 1;
+       input_dev->rep[REP_PERIOD] = 1;
 
        error = input_register_device(input_dev);
        if (error) {
@@ -241,8 +259,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
                goto out2;
        }
 
-       input_dev->timer.function = msp430_ir_debounce;
-
        tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
                     (unsigned long) budget_ci);
 
@@ -267,7 +283,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
        tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
 
        if (del_timer(&dev->timer)) {
-               input_event(dev, EV_KEY, key_map[dev->repeat_key], 0);
+               ir_input_nokey(dev, &budget_ci->ir.state);
                input_sync(dev);
        }
 
index 8f58406..2b25f5c 100644 (file)
@@ -92,6 +92,7 @@ extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE];
 
 #endif