diff options
-rw-r--r-- | drivers/media/common/ir-functions.c | 110 | ||||
-rw-r--r-- | drivers/media/common/ir-keymaps.c | 54 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-input.c | 143 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv.h | 27 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttvp.h | 2 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-cards.c | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 86 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 17 | ||||
-rw-r--r-- | include/media/ir-common.h | 47 |
9 files changed, 315 insertions, 172 deletions
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 9a8dd8764c99..cbf7c0564889 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c | |||
@@ -256,6 +256,112 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high) | |||
256 | return value; | 256 | return value; |
257 | } | 257 | } |
258 | 258 | ||
259 | /* RC5 decoding stuff, moved from bttv-input.c to share it with | ||
260 | * saa7134 */ | ||
261 | |||
262 | /* decode raw bit pattern to RC5 code */ | ||
263 | u32 ir_rc5_decode(unsigned int code) | ||
264 | { | ||
265 | unsigned int org_code = code; | ||
266 | unsigned int pair; | ||
267 | unsigned int rc5 = 0; | ||
268 | int i; | ||
269 | |||
270 | for (i = 0; i < 14; ++i) { | ||
271 | pair = code & 0x3; | ||
272 | code >>= 2; | ||
273 | |||
274 | rc5 <<= 1; | ||
275 | switch (pair) { | ||
276 | case 0: | ||
277 | case 2: | ||
278 | break; | ||
279 | case 1: | ||
280 | rc5 |= 1; | ||
281 | break; | ||
282 | case 3: | ||
283 | dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); | ||
284 | return 0; | ||
285 | } | ||
286 | } | ||
287 | dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | ||
288 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
289 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
290 | return rc5; | ||
291 | } | ||
292 | |||
293 | void ir_rc5_timer_end(unsigned long data) | ||
294 | { | ||
295 | struct card_ir *ir = (struct card_ir *)data; | ||
296 | struct timeval tv; | ||
297 | unsigned long current_jiffies, timeout; | ||
298 | u32 gap; | ||
299 | u32 rc5 = 0; | ||
300 | |||
301 | /* get time */ | ||
302 | current_jiffies = jiffies; | ||
303 | do_gettimeofday(&tv); | ||
304 | |||
305 | /* avoid overflow with gap >1s */ | ||
306 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
307 | gap = 200000; | ||
308 | } else { | ||
309 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
310 | tv.tv_usec - ir->base_time.tv_usec; | ||
311 | } | ||
312 | |||
313 | /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ | ||
314 | if (gap < 28000) { | ||
315 | dprintk(1, "ir-common: spurious timer_end\n"); | ||
316 | return; | ||
317 | } | ||
318 | |||
319 | ir->active = 0; | ||
320 | if (ir->last_bit < 20) { | ||
321 | /* ignore spurious codes (caused by light/other remotes) */ | ||
322 | dprintk(1, "ir-common: short code: %x\n", ir->code); | ||
323 | } else { | ||
324 | ir->code = (ir->code << ir->shift_by) | 1; | ||
325 | rc5 = ir_rc5_decode(ir->code); | ||
326 | |||
327 | /* two start bits? */ | ||
328 | if (RC5_START(rc5) != ir->start) { | ||
329 | dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); | ||
330 | |||
331 | /* right address? */ | ||
332 | } else if (RC5_ADDR(rc5) == ir->addr) { | ||
333 | u32 toggle = RC5_TOGGLE(rc5); | ||
334 | u32 instr = RC5_INSTR(rc5); | ||
335 | |||
336 | /* Good code, decide if repeat/repress */ | ||
337 | if (toggle != RC5_TOGGLE(ir->last_rc5) || | ||
338 | instr != RC5_INSTR(ir->last_rc5)) { | ||
339 | dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, | ||
340 | toggle); | ||
341 | ir_input_nokey(ir->dev, &ir->ir); | ||
342 | ir_input_keydown(ir->dev, &ir->ir, instr, | ||
343 | instr); | ||
344 | } | ||
345 | |||
346 | /* Set/reset key-up timer */ | ||
347 | timeout = current_jiffies + (500 + ir->rc5_key_timeout | ||
348 | * HZ) / 1000; | ||
349 | mod_timer(&ir->timer_keyup, timeout); | ||
350 | |||
351 | /* Save code for repeat test */ | ||
352 | ir->last_rc5 = rc5; | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | void ir_rc5_timer_keyup(unsigned long data) | ||
358 | { | ||
359 | struct card_ir *ir = (struct card_ir *)data; | ||
360 | |||
361 | dprintk(1, "ir-common: key released\n"); | ||
362 | ir_input_nokey(ir->dev, &ir->ir); | ||
363 | } | ||
364 | |||
259 | EXPORT_SYMBOL_GPL(ir_input_init); | 365 | EXPORT_SYMBOL_GPL(ir_input_init); |
260 | EXPORT_SYMBOL_GPL(ir_input_nokey); | 366 | EXPORT_SYMBOL_GPL(ir_input_nokey); |
261 | EXPORT_SYMBOL_GPL(ir_input_keydown); | 367 | EXPORT_SYMBOL_GPL(ir_input_keydown); |
@@ -265,6 +371,10 @@ EXPORT_SYMBOL_GPL(ir_dump_samples); | |||
265 | EXPORT_SYMBOL_GPL(ir_decode_biphase); | 371 | EXPORT_SYMBOL_GPL(ir_decode_biphase); |
266 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); | 372 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); |
267 | 373 | ||
374 | EXPORT_SYMBOL_GPL(ir_rc5_decode); | ||
375 | EXPORT_SYMBOL_GPL(ir_rc5_timer_end); | ||
376 | EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); | ||
377 | |||
268 | /* | 378 | /* |
269 | * Local variables: | 379 | * Local variables: |
270 | * c-basic-offset: 8 | 380 | * c-basic-offset: 8 |
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index 0e948a5c5a03..4a54a559d81c 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c | |||
@@ -1606,3 +1606,57 @@ IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = { | |||
1606 | }; | 1606 | }; |
1607 | 1607 | ||
1608 | EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old); | 1608 | EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old); |
1609 | |||
1610 | /* | ||
1611 | * Marc Fargas <telenieko@telenieko.com> | ||
1612 | * this is the remote control that comes with the asus p7131 | ||
1613 | * which has a label saying is "Model PC-39" | ||
1614 | */ | ||
1615 | IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE] = { | ||
1616 | /* Keys 0 to 9 */ | ||
1617 | [ 0x15 ] = KEY_0, | ||
1618 | [ 0x29 ] = KEY_1, | ||
1619 | [ 0x2d ] = KEY_2, | ||
1620 | [ 0x2b ] = KEY_3, | ||
1621 | [ 0x09 ] = KEY_4, | ||
1622 | [ 0x0d ] = KEY_5, | ||
1623 | [ 0x0b ] = KEY_6, | ||
1624 | [ 0x31 ] = KEY_7, | ||
1625 | [ 0x35 ] = KEY_8, | ||
1626 | [ 0x33 ] = KEY_9, | ||
1627 | |||
1628 | [ 0x3e ] = KEY_RADIO, /* radio */ | ||
1629 | [ 0x03 ] = KEY_MENU, /* dvd/menu */ | ||
1630 | [ 0x2a ] = KEY_VOLUMEUP, | ||
1631 | [ 0x19 ] = KEY_VOLUMEDOWN, | ||
1632 | [ 0x37 ] = KEY_UP, | ||
1633 | [ 0x3b ] = KEY_DOWN, | ||
1634 | [ 0x27 ] = KEY_LEFT, | ||
1635 | [ 0x2f ] = KEY_RIGHT, | ||
1636 | [ 0x25 ] = KEY_VIDEO, /* video */ | ||
1637 | [ 0x39 ] = KEY_AUDIO, /* music */ | ||
1638 | |||
1639 | [ 0x21 ] = KEY_TV, /* tv */ | ||
1640 | [ 0x1d ] = KEY_EXIT, /* back */ | ||
1641 | [ 0x0a ] = KEY_CHANNELUP, /* channel / program + */ | ||
1642 | [ 0x1b ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
1643 | [ 0x1a ] = KEY_ENTER, /* enter */ | ||
1644 | |||
1645 | [ 0x06 ] = KEY_PAUSE, /* play/pause */ | ||
1646 | [ 0x1e ] = KEY_PREVIOUS, /* rew */ | ||
1647 | [ 0x26 ] = KEY_NEXT, /* forward */ | ||
1648 | [ 0x0e ] = KEY_REWIND, /* backward << */ | ||
1649 | [ 0x3a ] = KEY_FASTFORWARD, /* forward >> */ | ||
1650 | [ 0x36 ] = KEY_STOP, | ||
1651 | [ 0x2e ] = KEY_RECORD, /* recording */ | ||
1652 | [ 0x16 ] = KEY_POWER, /* the button that reads "close" */ | ||
1653 | |||
1654 | [ 0x11 ] = KEY_ZOOM, /* full screen */ | ||
1655 | [ 0x13 ] = KEY_MACRO, /* recall */ | ||
1656 | [ 0x23 ] = KEY_HOME, /* home */ | ||
1657 | [ 0x05 ] = KEY_PVR, /* picture */ | ||
1658 | [ 0x3d ] = KEY_MUTE, /* mute */ | ||
1659 | [ 0x01 ] = KEY_DVD, /* dvd */ | ||
1660 | }; | ||
1661 | |||
1662 | EXPORT_SYMBOL_GPL(ir_codes_asus_pc39); | ||
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index cbc012f71f52..14c07c606632 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -36,13 +36,18 @@ module_param(repeat_delay, int, 0644); | |||
36 | static int repeat_period = 33; | 36 | static int repeat_period = 33; |
37 | module_param(repeat_period, int, 0644); | 37 | module_param(repeat_period, int, 0644); |
38 | 38 | ||
39 | int ir_rc5_remote_gap = 885; | ||
40 | module_param(ir_rc5_remote_gap, int, 0644); | ||
41 | int ir_rc5_key_timeout = 200; | ||
42 | module_param(ir_rc5_key_timeout, int, 0644); | ||
43 | |||
39 | #define DEVNAME "bttv-input" | 44 | #define DEVNAME "bttv-input" |
40 | 45 | ||
41 | /* ---------------------------------------------------------------------- */ | 46 | /* ---------------------------------------------------------------------- */ |
42 | 47 | ||
43 | static void ir_handle_key(struct bttv *btv) | 48 | static void ir_handle_key(struct bttv *btv) |
44 | { | 49 | { |
45 | struct bttv_ir *ir = btv->remote; | 50 | struct card_ir *ir = btv->remote; |
46 | u32 gpio,data; | 51 | u32 gpio,data; |
47 | 52 | ||
48 | /* read gpio value */ | 53 | /* read gpio value */ |
@@ -72,7 +77,7 @@ static void ir_handle_key(struct bttv *btv) | |||
72 | 77 | ||
73 | void bttv_input_irq(struct bttv *btv) | 78 | void bttv_input_irq(struct bttv *btv) |
74 | { | 79 | { |
75 | struct bttv_ir *ir = btv->remote; | 80 | struct card_ir *ir = btv->remote; |
76 | 81 | ||
77 | if (!ir->polling) | 82 | if (!ir->polling) |
78 | ir_handle_key(btv); | 83 | ir_handle_key(btv); |
@@ -81,7 +86,7 @@ void bttv_input_irq(struct bttv *btv) | |||
81 | static void bttv_input_timer(unsigned long data) | 86 | static void bttv_input_timer(unsigned long data) |
82 | { | 87 | { |
83 | struct bttv *btv = (struct bttv*)data; | 88 | struct bttv *btv = (struct bttv*)data; |
84 | struct bttv_ir *ir = btv->remote; | 89 | struct card_ir *ir = btv->remote; |
85 | unsigned long timeout; | 90 | unsigned long timeout; |
86 | 91 | ||
87 | ir_handle_key(btv); | 92 | ir_handle_key(btv); |
@@ -91,51 +96,9 @@ static void bttv_input_timer(unsigned long data) | |||
91 | 96 | ||
92 | /* ---------------------------------------------------------------*/ | 97 | /* ---------------------------------------------------------------*/ |
93 | 98 | ||
94 | static int rc5_remote_gap = 885; | ||
95 | module_param(rc5_remote_gap, int, 0644); | ||
96 | static int rc5_key_timeout = 200; | ||
97 | module_param(rc5_key_timeout, int, 0644); | ||
98 | |||
99 | #define RC5_START(x) (((x)>>12)&3) | ||
100 | #define RC5_TOGGLE(x) (((x)>>11)&1) | ||
101 | #define RC5_ADDR(x) (((x)>>6)&31) | ||
102 | #define RC5_INSTR(x) ((x)&63) | ||
103 | |||
104 | /* decode raw bit pattern to RC5 code */ | ||
105 | static u32 rc5_decode(unsigned int code) | ||
106 | { | ||
107 | unsigned int org_code = code; | ||
108 | unsigned int pair; | ||
109 | unsigned int rc5 = 0; | ||
110 | int i; | ||
111 | |||
112 | code = (code << 1) | 1; | ||
113 | for (i = 0; i < 14; ++i) { | ||
114 | pair = code & 0x3; | ||
115 | code >>= 2; | ||
116 | |||
117 | rc5 <<= 1; | ||
118 | switch (pair) { | ||
119 | case 0: | ||
120 | case 2: | ||
121 | break; | ||
122 | case 1: | ||
123 | rc5 |= 1; | ||
124 | break; | ||
125 | case 3: | ||
126 | dprintk(KERN_WARNING "bad code: %x\n", org_code); | ||
127 | return 0; | ||
128 | } | ||
129 | } | ||
130 | dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | ||
131 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
132 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
133 | return rc5; | ||
134 | } | ||
135 | |||
136 | static int bttv_rc5_irq(struct bttv *btv) | 99 | static int bttv_rc5_irq(struct bttv *btv) |
137 | { | 100 | { |
138 | struct bttv_ir *ir = btv->remote; | 101 | struct card_ir *ir = btv->remote; |
139 | struct timeval tv; | 102 | struct timeval tv; |
140 | u32 gpio; | 103 | u32 gpio; |
141 | u32 gap; | 104 | u32 gap; |
@@ -165,8 +128,8 @@ static int bttv_rc5_irq(struct bttv *btv) | |||
165 | /* only if in the code (otherwise spurious IRQ or timer | 128 | /* only if in the code (otherwise spurious IRQ or timer |
166 | late) */ | 129 | late) */ |
167 | if (ir->last_bit < 28) { | 130 | if (ir->last_bit < 28) { |
168 | ir->last_bit = (gap - rc5_remote_gap / 2) / | 131 | ir->last_bit = (gap - ir_rc5_remote_gap / 2) / |
169 | rc5_remote_gap; | 132 | ir_rc5_remote_gap; |
170 | ir->code |= 1 << ir->last_bit; | 133 | ir->code |= 1 << ir->last_bit; |
171 | } | 134 | } |
172 | /* starting new code */ | 135 | /* starting new code */ |
@@ -186,80 +149,9 @@ static int bttv_rc5_irq(struct bttv *btv) | |||
186 | return 1; | 149 | return 1; |
187 | } | 150 | } |
188 | 151 | ||
189 | |||
190 | static void bttv_rc5_timer_end(unsigned long data) | ||
191 | { | ||
192 | struct bttv_ir *ir = (struct bttv_ir *)data; | ||
193 | struct timeval tv; | ||
194 | unsigned long current_jiffies, timeout; | ||
195 | u32 gap; | ||
196 | |||
197 | /* get time */ | ||
198 | current_jiffies = jiffies; | ||
199 | do_gettimeofday(&tv); | ||
200 | |||
201 | /* avoid overflow with gap >1s */ | ||
202 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
203 | gap = 200000; | ||
204 | } else { | ||
205 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
206 | tv.tv_usec - ir->base_time.tv_usec; | ||
207 | } | ||
208 | |||
209 | /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ | ||
210 | if (gap < 28000) { | ||
211 | dprintk(KERN_WARNING "spurious timer_end\n"); | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | ir->active = 0; | ||
216 | if (ir->last_bit < 20) { | ||
217 | /* ignore spurious codes (caused by light/other remotes) */ | ||
218 | dprintk(KERN_WARNING "short code: %x\n", ir->code); | ||
219 | } else { | ||
220 | u32 rc5 = rc5_decode(ir->code); | ||
221 | |||
222 | /* two start bits? */ | ||
223 | if (RC5_START(rc5) != 3) { | ||
224 | dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5)); | ||
225 | |||
226 | /* right address? */ | ||
227 | } else if (RC5_ADDR(rc5) == 0x0) { | ||
228 | u32 toggle = RC5_TOGGLE(rc5); | ||
229 | u32 instr = RC5_INSTR(rc5); | ||
230 | |||
231 | /* Good code, decide if repeat/repress */ | ||
232 | if (toggle != RC5_TOGGLE(ir->last_rc5) || | ||
233 | instr != RC5_INSTR(ir->last_rc5)) { | ||
234 | dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr, | ||
235 | toggle); | ||
236 | ir_input_nokey(ir->dev, &ir->ir); | ||
237 | ir_input_keydown(ir->dev, &ir->ir, instr, | ||
238 | instr); | ||
239 | } | ||
240 | |||
241 | /* Set/reset key-up timer */ | ||
242 | timeout = current_jiffies + (500 + rc5_key_timeout | ||
243 | * HZ) / 1000; | ||
244 | mod_timer(&ir->timer_keyup, timeout); | ||
245 | |||
246 | /* Save code for repeat test */ | ||
247 | ir->last_rc5 = rc5; | ||
248 | } | ||
249 | } | ||
250 | } | ||
251 | |||
252 | static void bttv_rc5_timer_keyup(unsigned long data) | ||
253 | { | ||
254 | struct bttv_ir *ir = (struct bttv_ir *)data; | ||
255 | |||
256 | dprintk(KERN_DEBUG "key released\n"); | ||
257 | ir_input_nokey(ir->dev, &ir->ir); | ||
258 | } | ||
259 | |||
260 | /* ---------------------------------------------------------------------- */ | 152 | /* ---------------------------------------------------------------------- */ |
261 | 153 | ||
262 | static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) | 154 | static void bttv_ir_start(struct bttv *btv, struct card_ir *ir) |
263 | { | 155 | { |
264 | if (ir->polling) { | 156 | if (ir->polling) { |
265 | init_timer(&ir->timer); | 157 | init_timer(&ir->timer); |
@@ -270,12 +162,17 @@ static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) | |||
270 | } else if (ir->rc5_gpio) { | 162 | } else if (ir->rc5_gpio) { |
271 | /* set timer_end for code completion */ | 163 | /* set timer_end for code completion */ |
272 | init_timer(&ir->timer_end); | 164 | init_timer(&ir->timer_end); |
273 | ir->timer_end.function = bttv_rc5_timer_end; | 165 | ir->timer_end.function = ir_rc5_timer_end; |
274 | ir->timer_end.data = (unsigned long)ir; | 166 | ir->timer_end.data = (unsigned long)ir; |
275 | 167 | ||
276 | init_timer(&ir->timer_keyup); | 168 | init_timer(&ir->timer_keyup); |
277 | ir->timer_keyup.function = bttv_rc5_timer_keyup; | 169 | ir->timer_keyup.function = ir_rc5_timer_keyup; |
278 | ir->timer_keyup.data = (unsigned long)ir; | 170 | ir->timer_keyup.data = (unsigned long)ir; |
171 | ir->shift_by = 1; | ||
172 | ir->start = 3; | ||
173 | ir->addr = 0x0; | ||
174 | ir->rc5_key_timeout = ir_rc5_key_timeout; | ||
175 | ir->rc5_remote_gap = ir_rc5_remote_gap; | ||
279 | } | 176 | } |
280 | } | 177 | } |
281 | 178 | ||
@@ -299,7 +196,7 @@ static void bttv_ir_stop(struct bttv *btv) | |||
299 | 196 | ||
300 | int bttv_input_init(struct bttv *btv) | 197 | int bttv_input_init(struct bttv *btv) |
301 | { | 198 | { |
302 | struct bttv_ir *ir; | 199 | struct card_ir *ir; |
303 | IR_KEYTAB_TYPE *ir_codes = NULL; | 200 | IR_KEYTAB_TYPE *ir_codes = NULL; |
304 | struct input_dev *input_dev; | 201 | struct input_dev *input_dev; |
305 | int ir_type = IR_TYPE_OTHER; | 202 | int ir_type = IR_TYPE_OTHER; |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index f9c9e3c4d111..5491acbdaf63 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -197,33 +197,6 @@ struct bttv_core { | |||
197 | struct bttv; | 197 | struct bttv; |
198 | 198 | ||
199 | 199 | ||
200 | struct bttv_ir { | ||
201 | struct input_dev *dev; | ||
202 | struct ir_input_state ir; | ||
203 | char name[32]; | ||
204 | char phys[32]; | ||
205 | |||
206 | /* Usual gpio signalling */ | ||
207 | |||
208 | u32 mask_keycode; | ||
209 | u32 mask_keydown; | ||
210 | u32 mask_keyup; | ||
211 | u32 polling; | ||
212 | u32 last_gpio; | ||
213 | struct work_struct work; | ||
214 | struct timer_list timer; | ||
215 | |||
216 | /* RC5 gpio */ | ||
217 | u32 rc5_gpio; | ||
218 | struct timer_list timer_end; /* timer_end for code completion */ | ||
219 | struct timer_list timer_keyup; /* timer_end for key release */ | ||
220 | u32 last_rc5; /* last good rc5 code */ | ||
221 | u32 last_bit; /* last raw bit seen */ | ||
222 | u32 code; /* raw code under construction */ | ||
223 | struct timeval base_time; /* time of last seen code */ | ||
224 | int active; /* building raw code */ | ||
225 | }; | ||
226 | |||
227 | struct tvcard | 200 | struct tvcard |
228 | { | 201 | { |
229 | char *name; | 202 | char *name; |
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 311c4c541e01..3802cafc9e41 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -308,7 +308,7 @@ struct bttv { | |||
308 | 308 | ||
309 | /* infrared remote */ | 309 | /* infrared remote */ |
310 | int has_remote; | 310 | int has_remote; |
311 | struct bttv_ir *remote; | 311 | struct card_ir *remote; |
312 | 312 | ||
313 | /* locking */ | 313 | /* locking */ |
314 | spinlock_t s_lock; | 314 | spinlock_t s_lock; |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index ae984bbe36b6..dc45b2374f58 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -3926,6 +3926,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3926 | case SAA7134_BOARD_KWORLD_TERMINATOR: | 3926 | case SAA7134_BOARD_KWORLD_TERMINATOR: |
3927 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: | 3927 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: |
3928 | case SAA7134_BOARD_FLYDVBT_LR301: | 3928 | case SAA7134_BOARD_FLYDVBT_LR301: |
3929 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | ||
3929 | case SAA7134_BOARD_FLYDVBTDUO: | 3930 | case SAA7134_BOARD_FLYDVBTDUO: |
3930 | case SAA7134_BOARD_PROTEUS_2309: | 3931 | case SAA7134_BOARD_PROTEUS_2309: |
3931 | case SAA7134_BOARD_AVERMEDIA_A16AR: | 3932 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index e4252683a597..08848ebc682f 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -40,16 +40,24 @@ static int pinnacle_remote = 0; | |||
40 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ | 40 | module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ |
41 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); | 41 | MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); |
42 | 42 | ||
43 | int ir_rc5_remote_gap = 885; | ||
44 | module_param(ir_rc5_remote_gap, int, 0644); | ||
45 | int ir_rc5_key_timeout = 115; | ||
46 | module_param(ir_rc5_key_timeout, int, 0644); | ||
47 | |||
43 | #define dprintk(fmt, arg...) if (ir_debug) \ | 48 | #define dprintk(fmt, arg...) if (ir_debug) \ |
44 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 49 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
45 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 50 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
46 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 51 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) |
47 | 52 | ||
53 | /** rc5 functions */ | ||
54 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | ||
55 | |||
48 | /* -------------------- GPIO generic keycode builder -------------------- */ | 56 | /* -------------------- GPIO generic keycode builder -------------------- */ |
49 | 57 | ||
50 | static int build_key(struct saa7134_dev *dev) | 58 | static int build_key(struct saa7134_dev *dev) |
51 | { | 59 | { |
52 | struct saa7134_ir *ir = dev->remote; | 60 | struct card_ir *ir = dev->remote; |
53 | u32 gpio, data; | 61 | u32 gpio, data; |
54 | 62 | ||
55 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | 63 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ |
@@ -134,16 +142,19 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
134 | 142 | ||
135 | void saa7134_input_irq(struct saa7134_dev *dev) | 143 | void saa7134_input_irq(struct saa7134_dev *dev) |
136 | { | 144 | { |
137 | struct saa7134_ir *ir = dev->remote; | 145 | struct card_ir *ir = dev->remote; |
138 | 146 | ||
139 | if (!ir->polling) | 147 | if (!ir->polling && !ir->rc5_gpio) { |
140 | build_key(dev); | 148 | build_key(dev); |
149 | } else if (ir->rc5_gpio) { | ||
150 | saa7134_rc5_irq(dev); | ||
151 | } | ||
141 | } | 152 | } |
142 | 153 | ||
143 | static void saa7134_input_timer(unsigned long data) | 154 | static void saa7134_input_timer(unsigned long data) |
144 | { | 155 | { |
145 | struct saa7134_dev *dev = (struct saa7134_dev*)data; | 156 | struct saa7134_dev *dev = (struct saa7134_dev*)data; |
146 | struct saa7134_ir *ir = dev->remote; | 157 | struct card_ir *ir = dev->remote; |
147 | unsigned long timeout; | 158 | unsigned long timeout; |
148 | 159 | ||
149 | build_key(dev); | 160 | build_key(dev); |
@@ -151,7 +162,7 @@ static void saa7134_input_timer(unsigned long data) | |||
151 | mod_timer(&ir->timer, timeout); | 162 | mod_timer(&ir->timer, timeout); |
152 | } | 163 | } |
153 | 164 | ||
154 | static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir) | 165 | static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) |
155 | { | 166 | { |
156 | if (ir->polling) { | 167 | if (ir->polling) { |
157 | init_timer(&ir->timer); | 168 | init_timer(&ir->timer); |
@@ -159,6 +170,19 @@ static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir) | |||
159 | ir->timer.data = (unsigned long)dev; | 170 | ir->timer.data = (unsigned long)dev; |
160 | ir->timer.expires = jiffies + HZ; | 171 | ir->timer.expires = jiffies + HZ; |
161 | add_timer(&ir->timer); | 172 | add_timer(&ir->timer); |
173 | } else if (ir->rc5_gpio) { | ||
174 | /* set timer_end for code completion */ | ||
175 | init_timer(&ir->timer_end); | ||
176 | ir->timer_end.function = ir_rc5_timer_end; | ||
177 | ir->timer_end.data = (unsigned long)ir; | ||
178 | init_timer(&ir->timer_keyup); | ||
179 | ir->timer_keyup.function = ir_rc5_timer_keyup; | ||
180 | ir->timer_keyup.data = (unsigned long)ir; | ||
181 | ir->shift_by = 2; | ||
182 | ir->start = 0x2; | ||
183 | ir->addr = 0x17; | ||
184 | ir->rc5_key_timeout = ir_rc5_key_timeout; | ||
185 | ir->rc5_remote_gap = ir_rc5_remote_gap; | ||
162 | } | 186 | } |
163 | } | 187 | } |
164 | 188 | ||
@@ -170,13 +194,14 @@ static void saa7134_ir_stop(struct saa7134_dev *dev) | |||
170 | 194 | ||
171 | int saa7134_input_init1(struct saa7134_dev *dev) | 195 | int saa7134_input_init1(struct saa7134_dev *dev) |
172 | { | 196 | { |
173 | struct saa7134_ir *ir; | 197 | struct card_ir *ir; |
174 | struct input_dev *input_dev; | 198 | struct input_dev *input_dev; |
175 | IR_KEYTAB_TYPE *ir_codes = NULL; | 199 | IR_KEYTAB_TYPE *ir_codes = NULL; |
176 | u32 mask_keycode = 0; | 200 | u32 mask_keycode = 0; |
177 | u32 mask_keydown = 0; | 201 | u32 mask_keydown = 0; |
178 | u32 mask_keyup = 0; | 202 | u32 mask_keyup = 0; |
179 | int polling = 0; | 203 | int polling = 0; |
204 | int rc5_gpio = 0; | ||
180 | int ir_type = IR_TYPE_OTHER; | 205 | int ir_type = IR_TYPE_OTHER; |
181 | int err; | 206 | int err; |
182 | 207 | ||
@@ -295,6 +320,11 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
295 | mask_keycode = 0x0001F00; | 320 | mask_keycode = 0x0001F00; |
296 | mask_keydown = 0x0040000; | 321 | mask_keydown = 0x0040000; |
297 | break; | 322 | break; |
323 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | ||
324 | ir_codes = ir_codes_asus_pc39; | ||
325 | mask_keydown = 0x0040000; | ||
326 | rc5_gpio = 1; | ||
327 | break; | ||
298 | } | 328 | } |
299 | if (NULL == ir_codes) { | 329 | if (NULL == ir_codes) { |
300 | printk("%s: Oops: IR config error [card=%d]\n", | 330 | printk("%s: Oops: IR config error [card=%d]\n", |
@@ -316,6 +346,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
316 | ir->mask_keydown = mask_keydown; | 346 | ir->mask_keydown = mask_keydown; |
317 | ir->mask_keyup = mask_keyup; | 347 | ir->mask_keyup = mask_keyup; |
318 | ir->polling = polling; | 348 | ir->polling = polling; |
349 | ir->rc5_gpio = rc5_gpio; | ||
319 | 350 | ||
320 | /* init input device */ | 351 | /* init input device */ |
321 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", | 352 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", |
@@ -402,6 +433,49 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | |||
402 | } | 433 | } |
403 | 434 | ||
404 | } | 435 | } |
436 | |||
437 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | ||
438 | { | ||
439 | struct card_ir *ir = dev->remote; | ||
440 | struct timeval tv; | ||
441 | u32 gap; | ||
442 | unsigned long current_jiffies, timeout; | ||
443 | |||
444 | /* get time of bit */ | ||
445 | current_jiffies = jiffies; | ||
446 | do_gettimeofday(&tv); | ||
447 | |||
448 | /* avoid overflow with gap >1s */ | ||
449 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
450 | gap = 200000; | ||
451 | } else { | ||
452 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
453 | tv.tv_usec - ir->base_time.tv_usec; | ||
454 | } | ||
455 | |||
456 | /* active code => add bit */ | ||
457 | if (ir->active) { | ||
458 | /* only if in the code (otherwise spurious IRQ or timer | ||
459 | late) */ | ||
460 | if (ir->last_bit < 28) { | ||
461 | ir->last_bit = (gap - ir_rc5_remote_gap / 2) / | ||
462 | ir_rc5_remote_gap; | ||
463 | ir->code |= 1 << ir->last_bit; | ||
464 | } | ||
465 | /* starting new code */ | ||
466 | } else { | ||
467 | ir->active = 1; | ||
468 | ir->code = 0; | ||
469 | ir->base_time = tv; | ||
470 | ir->last_bit = 0; | ||
471 | |||
472 | timeout = current_jiffies + (500 + 30 * HZ) / 1000; | ||
473 | mod_timer(&ir->timer_end, timeout); | ||
474 | } | ||
475 | |||
476 | return 1; | ||
477 | } | ||
478 | |||
405 | /* ---------------------------------------------------------------------- | 479 | /* ---------------------------------------------------------------------- |
406 | * Local variables: | 480 | * Local variables: |
407 | * c-basic-offset: 8 | 481 | * c-basic-offset: 8 |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 88cd1297df13..73b16b2044f6 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -411,20 +411,6 @@ struct saa7134_dmasound { | |||
411 | struct snd_pcm_substream *substream; | 411 | struct snd_pcm_substream *substream; |
412 | }; | 412 | }; |
413 | 413 | ||
414 | /* IR input */ | ||
415 | struct saa7134_ir { | ||
416 | struct input_dev *dev; | ||
417 | struct ir_input_state ir; | ||
418 | char name[32]; | ||
419 | char phys[32]; | ||
420 | u32 mask_keycode; | ||
421 | u32 mask_keydown; | ||
422 | u32 mask_keyup; | ||
423 | int polling; | ||
424 | u32 last_gpio; | ||
425 | struct timer_list timer; | ||
426 | }; | ||
427 | |||
428 | /* ts/mpeg status */ | 414 | /* ts/mpeg status */ |
429 | struct saa7134_ts { | 415 | struct saa7134_ts { |
430 | /* TS capture */ | 416 | /* TS capture */ |
@@ -463,7 +449,7 @@ struct saa7134_dev { | |||
463 | 449 | ||
464 | /* infrared remote */ | 450 | /* infrared remote */ |
465 | int has_remote; | 451 | int has_remote; |
466 | struct saa7134_ir *remote; | 452 | struct card_ir *remote; |
467 | 453 | ||
468 | /* pci i/o */ | 454 | /* pci i/o */ |
469 | char name[32]; | 455 | char name[32]; |
@@ -698,6 +684,7 @@ void saa7134_input_fini(struct saa7134_dev *dev); | |||
698 | void saa7134_input_irq(struct saa7134_dev *dev); | 684 | void saa7134_input_irq(struct saa7134_dev *dev); |
699 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); | 685 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); |
700 | 686 | ||
687 | |||
701 | /* | 688 | /* |
702 | * Local variables: | 689 | * Local variables: |
703 | * c-basic-offset: 8 | 690 | * c-basic-offset: 8 |
diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 4bb0ad810179..c60a30997973 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h | |||
@@ -36,6 +36,14 @@ | |||
36 | #define IR_KEYCODE(tab,code) (((unsigned)code < IR_KEYTAB_SIZE) \ | 36 | #define IR_KEYCODE(tab,code) (((unsigned)code < IR_KEYTAB_SIZE) \ |
37 | ? tab[code] : KEY_RESERVED) | 37 | ? tab[code] : KEY_RESERVED) |
38 | 38 | ||
39 | extern int ir_rc5_remote_gap; | ||
40 | extern int ir_rc5_key_timeout; | ||
41 | |||
42 | #define RC5_START(x) (((x)>>12)&3) | ||
43 | #define RC5_TOGGLE(x) (((x)>>11)&1) | ||
44 | #define RC5_ADDR(x) (((x)>>6)&31) | ||
45 | #define RC5_INSTR(x) ((x)&63) | ||
46 | |||
39 | struct ir_input_state { | 47 | struct ir_input_state { |
40 | /* configuration */ | 48 | /* configuration */ |
41 | int ir_type; | 49 | int ir_type; |
@@ -48,6 +56,40 @@ struct ir_input_state { | |||
48 | int keypressed; /* current state */ | 56 | int keypressed; /* current state */ |
49 | }; | 57 | }; |
50 | 58 | ||
59 | /* this was saa7134_ir and bttv_ir, moved here for | ||
60 | * rc5 decoding. */ | ||
61 | struct card_ir { | ||
62 | struct input_dev *dev; | ||
63 | struct ir_input_state ir; | ||
64 | char name[32]; | ||
65 | char phys[32]; | ||
66 | |||
67 | /* Usual gpio signalling */ | ||
68 | |||
69 | u32 mask_keycode; | ||
70 | u32 mask_keydown; | ||
71 | u32 mask_keyup; | ||
72 | u32 polling; | ||
73 | u32 last_gpio; | ||
74 | int shift_by; | ||
75 | int start; // What should RC5_START() be | ||
76 | int addr; // What RC5_ADDR() should be. | ||
77 | int rc5_key_timeout; | ||
78 | int rc5_remote_gap; | ||
79 | struct work_struct work; | ||
80 | struct timer_list timer; | ||
81 | |||
82 | /* RC5 gpio */ | ||
83 | u32 rc5_gpio; | ||
84 | struct timer_list timer_end; /* timer_end for code completion */ | ||
85 | struct timer_list timer_keyup; /* timer_end for key release */ | ||
86 | u32 last_rc5; /* last good rc5 code */ | ||
87 | u32 last_bit; /* last raw bit seen */ | ||
88 | u32 code; /* raw code under construction */ | ||
89 | struct timeval base_time; /* time of last seen code */ | ||
90 | int active; /* building raw code */ | ||
91 | }; | ||
92 | |||
51 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | 93 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, |
52 | int ir_type, IR_KEYTAB_TYPE *ir_codes); | 94 | int ir_type, IR_KEYTAB_TYPE *ir_codes); |
53 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); | 95 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); |
@@ -58,6 +100,10 @@ int ir_dump_samples(u32 *samples, int count); | |||
58 | int ir_decode_biphase(u32 *samples, int count, int low, int high); | 100 | int ir_decode_biphase(u32 *samples, int count, int low, int high); |
59 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); | 101 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); |
60 | 102 | ||
103 | u32 ir_rc5_decode(unsigned int code); | ||
104 | void ir_rc5_timer_end(unsigned long data); | ||
105 | void ir_rc5_timer_keyup(unsigned long data); | ||
106 | |||
61 | /* Keymaps to be used by other modules */ | 107 | /* Keymaps to be used by other modules */ |
62 | 108 | ||
63 | extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; | 109 | extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; |
@@ -94,6 +140,7 @@ extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE]; | |||
94 | extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE]; | 140 | extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE]; |
95 | extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE]; | 141 | extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE]; |
96 | extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE]; | 142 | extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE]; |
143 | extern IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE]; | ||
97 | 144 | ||
98 | #endif | 145 | #endif |
99 | 146 | ||