summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci
diff options
context:
space:
mode:
authorDavid Hardeman <david@hardeman.nu>2006-12-02 21:16:05 -0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 09:05:17 -0200
commit2520fffd8b7a312e77009414d3201c9751d6448c (patch)
tree72a997320430ce7ec75212af8e63fe4cff396812 /drivers/media/dvb/ttpci
parentee579bc9332ef8a67e20f512e7bc91e3efb92225 (diff)
V4L/DVB (4879): budget-ci IR: integrate with ir-common
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>
Diffstat (limited to 'drivers/media/dvb/ttpci')
-rw-r--r--drivers/media/dvb/ttpci/Kconfig1
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c138
2 files changed, 78 insertions, 61 deletions
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 95531a62499..eec7ccf41f8 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -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
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index c34b5d3bdde..d1b5402cd6f 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -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"
@@ -72,11 +73,24 @@
#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);
}