diff options
author | Hermann Pitton <hermann-pitton@arcor.de> | 2006-12-07 19:45:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:34:12 -0500 |
commit | 9160723ed620f31bf38332dee02041b1cb4c9967 (patch) | |
tree | 1e2bbbb78b98d9c21a769634f908874f79cbc7ba /drivers/media/video/bt8xx/bttv-input.c | |
parent | c8f71b01a50597e298dc3214a2f2be7b8d31170c (diff) |
V4L/DVB (4961): Add support for the ASUS P7131 remote control
Besides adding the board specific code, this patch moves
the RC5 decoding code from bt8xx to ir-functions.c to make it available
for all drivers.
Signed-off-by: Marc Fargas <telenieko.telenieko.com>
Signed-off-by: Hermann Pitton <hermann-pitton@arcor.de>
Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-input.c')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-input.c | 143 |
1 files changed, 20 insertions, 123 deletions
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; |