aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt8xx/bttv-input.c
diff options
context:
space:
mode:
authorHermann Pitton <hermann-pitton@arcor.de>2006-12-07 19:45:28 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-02-21 10:34:12 -0500
commit9160723ed620f31bf38332dee02041b1cb4c9967 (patch)
tree1e2bbbb78b98d9c21a769634f908874f79cbc7ba /drivers/media/video/bt8xx/bttv-input.c
parentc8f71b01a50597e298dc3214a2f2be7b8d31170c (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.c143
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);
36static int repeat_period = 33; 36static int repeat_period = 33;
37module_param(repeat_period, int, 0644); 37module_param(repeat_period, int, 0644);
38 38
39int ir_rc5_remote_gap = 885;
40module_param(ir_rc5_remote_gap, int, 0644);
41int ir_rc5_key_timeout = 200;
42module_param(ir_rc5_key_timeout, int, 0644);
43
39#define DEVNAME "bttv-input" 44#define DEVNAME "bttv-input"
40 45
41/* ---------------------------------------------------------------------- */ 46/* ---------------------------------------------------------------------- */
42 47
43static void ir_handle_key(struct bttv *btv) 48static 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
73void bttv_input_irq(struct bttv *btv) 78void 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)
81static void bttv_input_timer(unsigned long data) 86static 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
94static int rc5_remote_gap = 885;
95module_param(rc5_remote_gap, int, 0644);
96static int rc5_key_timeout = 200;
97module_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 */
105static 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
136static int bttv_rc5_irq(struct bttv *btv) 99static 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
190static 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
252static 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
262static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) 154static 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
300int bttv_input_init(struct bttv *btv) 197int 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;