diff options
author | David Härdeman <david@hardeman.nu> | 2007-04-27 11:31:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-04-27 14:43:46 -0400 |
commit | 145859cb8fafc1d75e780ea182413b13f5913a7f (patch) | |
tree | bb5eda0a74ed93b1633b0875897210a085ed34ec /drivers/media/dvb/ttpci/budget-ci.c | |
parent | ee820a648fb333034aa455e8e1479b89798a1281 (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.c | 96 |
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 | */ | ||
87 | static int debounce = 0; | ||
88 | module_param(debounce, int, 0644); | ||
89 | MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)"); | ||
90 | |||
91 | static int rc5_device = -1; | 85 | static int rc5_device = -1; |
92 | module_param(rc5_device, int, 0644); | 86 | module_param(rc5_device, int, 0644); |
93 | MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); | 87 | MODULE_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"); | |||
99 | struct budget_ci_ir { | 93 | struct 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 | ||
108 | struct budget_ci { | 106 | struct 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 | ||
204 | static int msp430_ir_init(struct budget_ci *budget_ci) | 179 | static 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 | } |