diff options
-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 | } |