Commit 2520fffd authored by David Hardeman's avatar David Hardeman Committed by Mauro Carvalho Chehab

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: default avatarDavid Hardeman <david@hardeman.nu>
Signed-off-by: default avatarAndrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent ee579bc9
......@@ -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);
......@@ -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
......
......@@ -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);
}
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment