diff options
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-input.c')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-input.c | 105 |
1 files changed, 99 insertions, 6 deletions
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 4b4f6137c6c5..e8f60ab58db6 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -140,7 +140,100 @@ static void bttv_input_timer(unsigned long data) | |||
140 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | 140 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
141 | } | 141 | } |
142 | 142 | ||
143 | /* ---------------------------------------------------------------*/ | 143 | /* |
144 | * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying | ||
145 | * on the rc-core way. As we need to be sure that both IRQ transitions are | ||
146 | * properly triggered, Better to touch it only with this hardware for | ||
147 | * testing. | ||
148 | */ | ||
149 | |||
150 | /* decode raw bit pattern to RC5 code */ | ||
151 | static u32 bttv_rc5_decode(unsigned int code) | ||
152 | { | ||
153 | unsigned int org_code = code; | ||
154 | unsigned int pair; | ||
155 | unsigned int rc5 = 0; | ||
156 | int i; | ||
157 | |||
158 | for (i = 0; i < 14; ++i) { | ||
159 | pair = code & 0x3; | ||
160 | code >>= 2; | ||
161 | |||
162 | rc5 <<= 1; | ||
163 | switch (pair) { | ||
164 | case 0: | ||
165 | case 2: | ||
166 | break; | ||
167 | case 1: | ||
168 | rc5 |= 1; | ||
169 | break; | ||
170 | case 3: | ||
171 | dprintk(KERN_INFO DEVNAME ":rc5_decode(%x) bad code\n", | ||
172 | org_code); | ||
173 | return 0; | ||
174 | } | ||
175 | } | ||
176 | dprintk(KERN_INFO DEVNAME ":" | ||
177 | "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | ||
178 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
179 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
180 | return rc5; | ||
181 | } | ||
182 | |||
183 | void bttv_rc5_timer_end(unsigned long data) | ||
184 | { | ||
185 | struct card_ir *ir = (struct card_ir *)data; | ||
186 | struct timeval tv; | ||
187 | unsigned long current_jiffies; | ||
188 | u32 gap; | ||
189 | u32 rc5 = 0; | ||
190 | |||
191 | /* get time */ | ||
192 | current_jiffies = jiffies; | ||
193 | do_gettimeofday(&tv); | ||
194 | |||
195 | /* avoid overflow with gap >1s */ | ||
196 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
197 | gap = 200000; | ||
198 | } else { | ||
199 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
200 | tv.tv_usec - ir->base_time.tv_usec; | ||
201 | } | ||
202 | |||
203 | /* signal we're ready to start a new code */ | ||
204 | ir->active = 0; | ||
205 | |||
206 | /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ | ||
207 | if (gap < 28000) { | ||
208 | dprintk(KERN_INFO DEVNAME ": spurious timer_end\n"); | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | if (ir->last_bit < 20) { | ||
213 | /* ignore spurious codes (caused by light/other remotes) */ | ||
214 | dprintk(KERN_INFO DEVNAME ": short code: %x\n", ir->code); | ||
215 | } else { | ||
216 | ir->code = (ir->code << ir->shift_by) | 1; | ||
217 | rc5 = bttv_rc5_decode(ir->code); | ||
218 | |||
219 | /* two start bits? */ | ||
220 | if (RC5_START(rc5) != ir->start) { | ||
221 | printk(KERN_INFO DEVNAME ":" | ||
222 | " rc5 start bits invalid: %u\n", RC5_START(rc5)); | ||
223 | |||
224 | /* right address? */ | ||
225 | } else if (RC5_ADDR(rc5) == ir->addr) { | ||
226 | u32 toggle = RC5_TOGGLE(rc5); | ||
227 | u32 instr = RC5_INSTR(rc5); | ||
228 | |||
229 | /* Good code */ | ||
230 | ir_keydown(ir->dev, instr, toggle); | ||
231 | dprintk(KERN_INFO DEVNAME ":" | ||
232 | " instruction %x, toggle %x\n", | ||
233 | instr, toggle); | ||
234 | } | ||
235 | } | ||
236 | } | ||
144 | 237 | ||
145 | static int bttv_rc5_irq(struct bttv *btv) | 238 | static int bttv_rc5_irq(struct bttv *btv) |
146 | { | 239 | { |
@@ -206,7 +299,7 @@ static void bttv_ir_start(struct bttv *btv, struct card_ir *ir) | |||
206 | } else if (ir->rc5_gpio) { | 299 | } else if (ir->rc5_gpio) { |
207 | /* set timer_end for code completion */ | 300 | /* set timer_end for code completion */ |
208 | init_timer(&ir->timer_end); | 301 | init_timer(&ir->timer_end); |
209 | ir->timer_end.function = ir_rc5_timer_end; | 302 | ir->timer_end.function = bttv_rc5_timer_end; |
210 | ir->timer_end.data = (unsigned long)ir; | 303 | ir->timer_end.data = (unsigned long)ir; |
211 | ir->shift_by = 1; | 304 | ir->shift_by = 1; |
212 | ir->start = 3; | 305 | ir->start = 3; |
@@ -283,10 +376,10 @@ void __devinit init_bttv_i2c_ir(struct bttv *btv) | |||
283 | default: | 376 | default: |
284 | /* | 377 | /* |
285 | * The external IR receiver is at i2c address 0x34 (0x35 for | 378 | * The external IR receiver is at i2c address 0x34 (0x35 for |
286 | * reads). Future Hauppauge cards will have an internal | 379 | * reads). Future Hauppauge cards will have an internal |
287 | * receiver at 0x30 (0x31 for reads). In theory, both can be | 380 | * receiver at 0x30 (0x31 for reads). In theory, both can be |
288 | * fitted, and Hauppauge suggest an external overrides an | 381 | * fitted, and Hauppauge suggest an external overrides an |
289 | * internal. | 382 | * internal. |
290 | * That's why we probe 0x1a (~0x34) first. CB | 383 | * That's why we probe 0x1a (~0x34) first. CB |
291 | */ | 384 | */ |
292 | 385 | ||