Skip to content

Commit

Permalink
V4L/DVB (5335): Budget-ci: Use the repeat handling of the input subsy…
Browse files Browse the repository at this point in the history
…stem

The attached patch contains the last set of changes to the budget-ci IR
handling which makes it use the repeat handling of the input subsystem.
This allows some code simplification, makes sure that repeat key presses
are reported as such and also allows the "debounce" hack to be removed
altogether.
In addition a couple of static variables were removed which would have
confused the IR code if more than one card is used.

Signed-off-by: David Hardeman <david@hardeman.nu>
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
David H�rdeman authored and Mauro Carvalho Chehab committed Apr 27, 2007
1 parent ee820a6 commit 145859c
Showing 1 changed file with 37 additions and 59 deletions.
96 changes: 37 additions & 59 deletions drivers/media/dvb/ttpci/budget-ci.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,15 @@
#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
/*
* Milliseconds during which a key is regarded as pressed.
* If an identical command arrives within this time, the timer will start over.
*/
#define IR_REPEAT_TIMEOUT 350
#define IR_KEYPRESS_TIMEOUT 250

/* RC5 device wildcard */
#define IR_DEVICE_ANY 255

/* 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)");

static int rc5_device = -1;
module_param(rc5_device, int, 0644);
MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
Expand All @@ -99,10 +93,14 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
struct budget_ci_ir {
struct input_dev *dev;
struct tasklet_struct msp430_irq_tasklet;
struct timer_list timer_keyup;
char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
char phys[32];
struct ir_input_state state;
int rc5_device;
u32 last_raw;
u32 ir_key;
bool have_command;
};

struct budget_ci {
Expand All @@ -125,13 +123,8 @@ 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;
int device;
int toggle;
static int prev_toggle = -1;
static u32 ir_key;
static int state = 0;
u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
u32 raw;

/*
* The msp430 chip can generate two different bytes, command and device
Expand All @@ -143,7 +136,7 @@ static void msp430_ir_interrupt(unsigned long data)
* bytes and one or more device bytes. For the repeated bytes, the
* highest bit (X) is set. The first command byte is always generated
* before the first device byte. Other than that, no specific order
* seems to apply.
* seems to apply. To make life interesting, bytes can also be lost.
*
* Only when we have a command and device byte, a keypress is
* generated.
Expand All @@ -152,53 +145,35 @@ static void msp430_ir_interrupt(unsigned long data)
if (ir_debug)
printk("budget_ci: received byte 0x%02x\n", command);

/* Is this a repeated byte? */
if (command & 0x80)
return;
/* Remove repeat bit, we use every command */
command = command & 0x7f;

/* Is this a RC5 command byte? */
if (command & 0x40) {
state = 1;
ir_key = command & 0x3f;
budget_ci->ir.have_command = true;
budget_ci->ir.ir_key = command & 0x3f;
return;
}

/* It's a RC5 device byte */
if (!state)
if (!budget_ci->ir.have_command)
return;
state = 0;
device = command & 0x1f;
toggle = command & 0x20;
budget_ci->ir.have_command = false;

if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device)
if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
budget_ci->ir.rc5_device != (command & 0x1f))
return;

/* Ignore repeated key sequences if requested */
if (toggle == prev_toggle && ir_key == dev->repeat_key &&
bounces > 0 && timer_pending(&dev->timer)) {
if (ir_debug)
printk("budget_ci: debounce logic ignored IR command\n");
bounces--;
return;
}
prev_toggle = toggle;

/* Are we still waiting for a keyup event? */
if (del_timer(&dev->timer))
ir_input_nokey(dev, &budget_ci->ir.state);

/* Generate keypress */
if (ir_debug)
printk("budget_ci: generating keypress 0x%02x\n", ir_key);
ir_input_keydown(dev, &budget_ci->ir.state, ir_key, (ir_key & (command << 8)));

/* Do we want to delay the keyup event? */
if (debounce) {
bounces = debounce;
mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
} else {
/* Is this a repeated key sequence? (same device, command, toggle) */
raw = budget_ci->ir.ir_key | (command << 8);
if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
ir_input_nokey(dev, &budget_ci->ir.state);
ir_input_keydown(dev, &budget_ci->ir.state,
budget_ci->ir.ir_key, raw);
budget_ci->ir.last_raw = raw;
}

mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
}

static int msp430_ir_init(struct budget_ci *budget_ci)
Expand Down Expand Up @@ -271,16 +246,21 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
break;
}

/* initialise the key-up debounce timeout handler */
input_dev->timer.function = msp430_ir_keyup;
input_dev->timer.data = (unsigned long) &budget_ci->ir;

/* initialise the key-up timeout handler */
init_timer(&budget_ci->ir.timer_keyup);
budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
budget_ci->ir.last_raw = 0xffff; /* An impossible value */
error = input_register_device(input_dev);
if (error) {
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
goto out2;
}

/* note: these must be after input_register_device */
input_dev->rep[REP_DELAY] = 400;
input_dev->rep[REP_PERIOD] = 250;

tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
(unsigned long) budget_ci);

Expand All @@ -304,10 +284,8 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);

if (del_timer(&dev->timer)) {
ir_input_nokey(dev, &budget_ci->ir.state);
input_sync(dev);
}
del_timer_sync(&dev->timer);
ir_input_nokey(dev, &budget_ci->ir.state);

input_unregister_device(dev);
}
Expand Down

0 comments on commit 145859c

Please sign in to comment.