aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/budget-ci.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2007-04-27 11:31:22 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-04-27 14:43:46 -0400
commit145859cb8fafc1d75e780ea182413b13f5913a7f (patch)
treebb5eda0a74ed93b1633b0875897210a085ed34ec /drivers/media/dvb/ttpci/budget-ci.c
parentee820a648fb333034aa455e8e1479b89798a1281 (diff)
V4L/DVB (5335): Budget-ci: Use the repeat handling of the input subsystem
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>
Diffstat (limited to 'drivers/media/dvb/ttpci/budget-ci.c')
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c96
1 files changed, 37 insertions, 59 deletions
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 464feaf1a9ad..4ed4599ce816 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -73,21 +73,15 @@
73#define SLOTSTATUS_READY 8 73#define SLOTSTATUS_READY 8
74#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) 74#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
75 75
76/* Milliseconds during which key presses are regarded as key repeat and during 76/*
77 * which the debounce logic is active 77 * Milliseconds during which a key is regarded as pressed.
78 * If an identical command arrives within this time, the timer will start over.
78 */ 79 */
79#define IR_REPEAT_TIMEOUT 350 80#define IR_KEYPRESS_TIMEOUT 250
80 81
81/* RC5 device wildcard */ 82/* RC5 device wildcard */
82#define IR_DEVICE_ANY 255 83#define IR_DEVICE_ANY 255
83 84
84/* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two),
85 * this setting allows the superflous sequences to be ignored
86 */
87static int debounce = 0;
88module_param(debounce, int, 0644);
89MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)");
90
91static int rc5_device = -1; 85static int rc5_device = -1;
92module_param(rc5_device, int, 0644); 86module_param(rc5_device, int, 0644);
93MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); 87MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
@@ -99,10 +93,14 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
99struct budget_ci_ir { 93struct budget_ci_ir {
100 struct input_dev *dev; 94 struct input_dev *dev;
101 struct tasklet_struct msp430_irq_tasklet; 95 struct tasklet_struct msp430_irq_tasklet;
96 struct timer_list timer_keyup;
102 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ 97 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
103 char phys[32]; 98 char phys[32];
104 struct ir_input_state state; 99 struct ir_input_state state;
105 int rc5_device; 100 int rc5_device;
101 u32 last_raw;
102 u32 ir_key;
103 bool have_command;
106}; 104};
107 105
108struct budget_ci { 106struct budget_ci {
@@ -125,13 +123,8 @@ static void msp430_ir_interrupt(unsigned long data)
125{ 123{
126 struct budget_ci *budget_ci = (struct budget_ci *) data; 124 struct budget_ci *budget_ci = (struct budget_ci *) data;
127 struct input_dev *dev = budget_ci->ir.dev; 125 struct input_dev *dev = budget_ci->ir.dev;
128 static int bounces = 0;
129 int device;
130 int toggle;
131 static int prev_toggle = -1;
132 static u32 ir_key;
133 static int state = 0;
134 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; 126 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
127 u32 raw;
135 128
136 /* 129 /*
137 * The msp430 chip can generate two different bytes, command and device 130 * The msp430 chip can generate two different bytes, command and device
@@ -143,7 +136,7 @@ static void msp430_ir_interrupt(unsigned long data)
143 * bytes and one or more device bytes. For the repeated bytes, the 136 * bytes and one or more device bytes. For the repeated bytes, the
144 * highest bit (X) is set. The first command byte is always generated 137 * highest bit (X) is set. The first command byte is always generated
145 * before the first device byte. Other than that, no specific order 138 * before the first device byte. Other than that, no specific order
146 * seems to apply. 139 * seems to apply. To make life interesting, bytes can also be lost.
147 * 140 *
148 * Only when we have a command and device byte, a keypress is 141 * Only when we have a command and device byte, a keypress is
149 * generated. 142 * generated.
@@ -152,53 +145,35 @@ static void msp430_ir_interrupt(unsigned long data)
152 if (ir_debug) 145 if (ir_debug)
153 printk("budget_ci: received byte 0x%02x\n", command); 146 printk("budget_ci: received byte 0x%02x\n", command);
154 147
155 /* Is this a repeated byte? */ 148 /* Remove repeat bit, we use every command */
156 if (command & 0x80) 149 command = command & 0x7f;
157 return;
158 150
159 /* Is this a RC5 command byte? */ 151 /* Is this a RC5 command byte? */
160 if (command & 0x40) { 152 if (command & 0x40) {
161 state = 1; 153 budget_ci->ir.have_command = true;
162 ir_key = command & 0x3f; 154 budget_ci->ir.ir_key = command & 0x3f;
163 return; 155 return;
164 } 156 }
165 157
166 /* It's a RC5 device byte */ 158 /* It's a RC5 device byte */
167 if (!state) 159 if (!budget_ci->ir.have_command)
168 return; 160 return;
169 state = 0; 161 budget_ci->ir.have_command = false;
170 device = command & 0x1f;
171 toggle = command & 0x20;
172 162
173 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device) 163 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
164 budget_ci->ir.rc5_device != (command & 0x1f))
174 return; 165 return;
175 166
176 /* Ignore repeated key sequences if requested */ 167 /* Is this a repeated key sequence? (same device, command, toggle) */
177 if (toggle == prev_toggle && ir_key == dev->repeat_key && 168 raw = budget_ci->ir.ir_key | (command << 8);
178 bounces > 0 && timer_pending(&dev->timer)) { 169 if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
179 if (ir_debug)
180 printk("budget_ci: debounce logic ignored IR command\n");
181 bounces--;
182 return;
183 }
184 prev_toggle = toggle;
185
186 /* Are we still waiting for a keyup event? */
187 if (del_timer(&dev->timer))
188 ir_input_nokey(dev, &budget_ci->ir.state);
189
190 /* Generate keypress */
191 if (ir_debug)
192 printk("budget_ci: generating keypress 0x%02x\n", ir_key);
193 ir_input_keydown(dev, &budget_ci->ir.state, ir_key, (ir_key & (command << 8)));
194
195 /* Do we want to delay the keyup event? */
196 if (debounce) {
197 bounces = debounce;
198 mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
199 } else {
200 ir_input_nokey(dev, &budget_ci->ir.state); 170 ir_input_nokey(dev, &budget_ci->ir.state);
171 ir_input_keydown(dev, &budget_ci->ir.state,
172 budget_ci->ir.ir_key, raw);
173 budget_ci->ir.last_raw = raw;
201 } 174 }
175
176 mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
202} 177}
203 178
204static int msp430_ir_init(struct budget_ci *budget_ci) 179static int msp430_ir_init(struct budget_ci *budget_ci)
@@ -271,16 +246,21 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
271 break; 246 break;
272 } 247 }
273 248
274 /* initialise the key-up debounce timeout handler */ 249 /* initialise the key-up timeout handler */
275 input_dev->timer.function = msp430_ir_keyup; 250 init_timer(&budget_ci->ir.timer_keyup);
276 input_dev->timer.data = (unsigned long) &budget_ci->ir; 251 budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
277 252 budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
253 budget_ci->ir.last_raw = 0xffff; /* An impossible value */
278 error = input_register_device(input_dev); 254 error = input_register_device(input_dev);
279 if (error) { 255 if (error) {
280 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); 256 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
281 goto out2; 257 goto out2;
282 } 258 }
283 259
260 /* note: these must be after input_register_device */
261 input_dev->rep[REP_DELAY] = 400;
262 input_dev->rep[REP_PERIOD] = 250;
263
284 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, 264 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
285 (unsigned long) budget_ci); 265 (unsigned long) budget_ci);
286 266
@@ -304,10 +284,8 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
304 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 284 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
305 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); 285 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
306 286
307 if (del_timer(&dev->timer)) { 287 del_timer_sync(&dev->timer);
308 ir_input_nokey(dev, &budget_ci->ir.state); 288 ir_input_nokey(dev, &budget_ci->ir.state);
309 input_sync(dev);
310 }
311 289
312 input_unregister_device(dev); 290 input_unregister_device(dev);
313} 291}