V4L/DVB: ir-core: Add support for badly-implemented hardware decoders
[pandora-kernel.git] / drivers / media / video / cx88 / cx88-input.c
1 /*
2  *
3  * Device driver for GPIO attached remote control interfaces
4  * on Conexant 2388x based TV/DVB cards.
5  *
6  * Copyright (c) 2003 Pavel Machek
7  * Copyright (c) 2004 Gerd Knorr
8  * Copyright (c) 2004, 2005 Chris Pascoe
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24
25 #include <linux/init.h>
26 #include <linux/hrtimer.h>
27 #include <linux/input.h>
28 #include <linux/pci.h>
29 #include <linux/slab.h>
30 #include <linux/module.h>
31
32 #include "cx88.h"
33 #include <media/ir-common.h>
34
35 #define MODULE_NAME "cx88xx"
36
37 /* ---------------------------------------------------------------------- */
38
39 struct cx88_IR {
40         struct cx88_core *core;
41         struct input_dev *input;
42         struct ir_input_state ir;
43         struct ir_dev_props props;
44
45         int users;
46
47         char name[32];
48         char phys[32];
49
50         /* sample from gpio pin 16 */
51         u32 sampling;
52         u32 samples[16];
53         int scount;
54         unsigned long release;
55
56         /* poll external decoder */
57         int polling;
58         struct hrtimer timer;
59         u32 gpio_addr;
60         u32 last_gpio;
61         u32 mask_keycode;
62         u32 mask_keydown;
63         u32 mask_keyup;
64 };
65
66 static int ir_debug;
67 module_param(ir_debug, int, 0644);      /* debug level [IR] */
68 MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
69
70 #define ir_dprintk(fmt, arg...) if (ir_debug) \
71         printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
72
73 /* ---------------------------------------------------------------------- */
74
75 static void cx88_ir_handle_key(struct cx88_IR *ir)
76 {
77         struct cx88_core *core = ir->core;
78         u32 gpio, data, auxgpio;
79
80         /* read gpio value */
81         gpio = cx_read(ir->gpio_addr);
82         switch (core->boardnr) {
83         case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
84                 /* This board apparently uses a combination of 2 GPIO
85                    to represent the keys. Additionally, the second GPIO
86                    can be used for parity.
87
88                    Example:
89
90                    for key "5"
91                         gpio = 0x758, auxgpio = 0xe5 or 0xf5
92                    for key "Power"
93                         gpio = 0x758, auxgpio = 0xed or 0xfd
94                  */
95
96                 auxgpio = cx_read(MO_GP1_IO);
97                 /* Take out the parity part */
98                 gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
99                 break;
100         case CX88_BOARD_WINFAST_DTV1000:
101         case CX88_BOARD_WINFAST_DTV1800H:
102         case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
103                 gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
104                 auxgpio = gpio;
105                 break;
106         default:
107                 auxgpio = gpio;
108         }
109         if (ir->polling) {
110                 if (ir->last_gpio == auxgpio)
111                         return;
112                 ir->last_gpio = auxgpio;
113         }
114
115         /* extract data */
116         data = ir_extract_bits(gpio, ir->mask_keycode);
117         ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
118                    gpio, data,
119                    ir->polling ? "poll" : "irq",
120                    (gpio & ir->mask_keydown) ? " down" : "",
121                    (gpio & ir->mask_keyup) ? " up" : "");
122
123         if (ir->core->boardnr == CX88_BOARD_NORWOOD_MICRO) {
124                 u32 gpio_key = cx_read(MO_GP0_IO);
125
126                 data = (data << 4) | ((gpio_key & 0xf0) >> 4);
127
128                 ir_input_keydown(ir->input, &ir->ir, data);
129                 ir_input_nokey(ir->input, &ir->ir);
130
131         } else if (ir->mask_keydown) {
132                 /* bit set on keydown */
133                 if (gpio & ir->mask_keydown) {
134                         ir_input_keydown(ir->input, &ir->ir, data);
135                 } else {
136                         ir_input_nokey(ir->input, &ir->ir);
137                 }
138
139         } else if (ir->mask_keyup) {
140                 /* bit cleared on keydown */
141                 if (0 == (gpio & ir->mask_keyup)) {
142                         ir_input_keydown(ir->input, &ir->ir, data);
143                 } else {
144                         ir_input_nokey(ir->input, &ir->ir);
145                 }
146
147         } else {
148                 /* can't distinguish keydown/up :-/ */
149                 ir_input_keydown(ir->input, &ir->ir, data);
150                 ir_input_nokey(ir->input, &ir->ir);
151         }
152 }
153
154 static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer)
155 {
156         unsigned long missed;
157         struct cx88_IR *ir = container_of(timer, struct cx88_IR, timer);
158
159         cx88_ir_handle_key(ir);
160         missed = hrtimer_forward_now(&ir->timer,
161                                      ktime_set(0, ir->polling * 1000000));
162         if (missed > 1)
163                 ir_dprintk("Missed ticks %ld\n", missed - 1);
164
165         return HRTIMER_RESTART;
166 }
167
168 static int __cx88_ir_start(void *priv)
169 {
170         struct cx88_core *core = priv;
171         struct cx88_IR *ir;
172
173         if (!core || !core->ir)
174                 return -EINVAL;
175
176         ir = core->ir;
177
178         if (ir->polling) {
179                 hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
180                 ir->timer.function = cx88_ir_work;
181                 hrtimer_start(&ir->timer,
182                               ktime_set(0, ir->polling * 1000000),
183                               HRTIMER_MODE_REL);
184         }
185         if (ir->sampling) {
186                 core->pci_irqmask |= PCI_INT_IR_SMPINT;
187                 cx_write(MO_DDS_IO, 0xa80a80);  /* 4 kHz sample rate */
188                 cx_write(MO_DDSCFG_IO, 0x5);    /* enable */
189         }
190         return 0;
191 }
192
193 static void __cx88_ir_stop(void *priv)
194 {
195         struct cx88_core *core = priv;
196         struct cx88_IR *ir;
197
198         if (!core || !core->ir)
199                 return;
200
201         ir = core->ir;
202         if (ir->sampling) {
203                 cx_write(MO_DDSCFG_IO, 0x0);
204                 core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
205         }
206
207         if (ir->polling)
208                 hrtimer_cancel(&ir->timer);
209 }
210
211 int cx88_ir_start(struct cx88_core *core)
212 {
213         if (core->ir->users)
214                 return __cx88_ir_start(core);
215
216         return 0;
217 }
218
219 void cx88_ir_stop(struct cx88_core *core)
220 {
221         if (core->ir->users)
222                 __cx88_ir_stop(core);
223 }
224
225 static int cx88_ir_open(void *priv)
226 {
227         struct cx88_core *core = priv;
228
229         core->ir->users++;
230         return __cx88_ir_start(core);
231 }
232
233 static void cx88_ir_close(void *priv)
234 {
235         struct cx88_core *core = priv;
236
237         core->ir->users--;
238         if (!core->ir->users)
239                 __cx88_ir_stop(core);
240 }
241
242 /* ---------------------------------------------------------------------- */
243
244 int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
245 {
246         struct cx88_IR *ir;
247         struct input_dev *input_dev;
248         char *ir_codes = NULL;
249         u64 ir_type = IR_TYPE_OTHER;
250         int err = -ENOMEM;
251         u32 hardware_mask = 0;  /* For devices with a hardware mask, when
252                                  * used with a full-code IR table
253                                  */
254
255         ir = kzalloc(sizeof(*ir), GFP_KERNEL);
256         input_dev = input_allocate_device();
257         if (!ir || !input_dev)
258                 goto err_out_free;
259
260         ir->input = input_dev;
261
262         /* detect & configure */
263         switch (core->boardnr) {
264         case CX88_BOARD_DNTV_LIVE_DVB_T:
265         case CX88_BOARD_KWORLD_DVB_T:
266         case CX88_BOARD_KWORLD_DVB_T_CX22702:
267                 ir_codes = RC_MAP_DNTV_LIVE_DVB_T;
268                 ir->gpio_addr = MO_GP1_IO;
269                 ir->mask_keycode = 0x1f;
270                 ir->mask_keyup = 0x60;
271                 ir->polling = 50; /* ms */
272                 break;
273         case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
274                 ir_codes = RC_MAP_CINERGY_1400;
275                 ir_type = IR_TYPE_PD;
276                 ir->sampling = 0xeb04; /* address */
277                 break;
278         case CX88_BOARD_HAUPPAUGE:
279         case CX88_BOARD_HAUPPAUGE_DVB_T1:
280         case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
281         case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
282         case CX88_BOARD_HAUPPAUGE_HVR1100:
283         case CX88_BOARD_HAUPPAUGE_HVR3000:
284         case CX88_BOARD_HAUPPAUGE_HVR4000:
285         case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
286         case CX88_BOARD_PCHDTV_HD3000:
287         case CX88_BOARD_PCHDTV_HD5500:
288         case CX88_BOARD_HAUPPAUGE_IRONLY:
289                 ir_codes = RC_MAP_HAUPPAUGE_NEW;
290                 ir_type = IR_TYPE_RC5;
291                 ir->sampling = 1;
292                 break;
293         case CX88_BOARD_WINFAST_DTV2000H:
294         case CX88_BOARD_WINFAST_DTV2000H_J:
295         case CX88_BOARD_WINFAST_DTV1800H:
296                 ir_codes = RC_MAP_WINFAST;
297                 ir->gpio_addr = MO_GP0_IO;
298                 ir->mask_keycode = 0x8f8;
299                 ir->mask_keyup = 0x100;
300                 ir->polling = 50; /* ms */
301                 break;
302         case CX88_BOARD_WINFAST2000XP_EXPERT:
303         case CX88_BOARD_WINFAST_DTV1000:
304         case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
305                 ir_codes = RC_MAP_WINFAST;
306                 ir->gpio_addr = MO_GP0_IO;
307                 ir->mask_keycode = 0x8f8;
308                 ir->mask_keyup = 0x100;
309                 ir->polling = 1; /* ms */
310                 break;
311         case CX88_BOARD_IODATA_GVBCTV7E:
312                 ir_codes = RC_MAP_IODATA_BCTV7E;
313                 ir->gpio_addr = MO_GP0_IO;
314                 ir->mask_keycode = 0xfd;
315                 ir->mask_keydown = 0x02;
316                 ir->polling = 5; /* ms */
317                 break;
318         case CX88_BOARD_PROLINK_PLAYTVPVR:
319         case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
320                 /*
321                  * It seems that this hardware is paired with NEC extended
322                  * address 0x866b. So, unfortunately, its usage with other
323                  * IR's with different address won't work. Still, there are
324                  * other IR's from the same manufacturer that works, like the
325                  * 002-T mini RC, provided with newer PV hardware
326                  */
327                 ir_codes = RC_MAP_PIXELVIEW_MK12;
328                 ir->gpio_addr = MO_GP1_IO;
329                 ir->mask_keyup = 0x80;
330                 ir->polling = 10; /* ms */
331                 hardware_mask = 0x3f;   /* Hardware returns only 6 bits from command part */
332                 break;
333         case CX88_BOARD_PROLINK_PV_8000GT:
334         case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
335                 ir_codes = RC_MAP_PIXELVIEW_NEW;
336                 ir->gpio_addr = MO_GP1_IO;
337                 ir->mask_keycode = 0x3f;
338                 ir->mask_keyup = 0x80;
339                 ir->polling = 1; /* ms */
340                 break;
341         case CX88_BOARD_KWORLD_LTV883:
342                 ir_codes = RC_MAP_PIXELVIEW;
343                 ir->gpio_addr = MO_GP1_IO;
344                 ir->mask_keycode = 0x1f;
345                 ir->mask_keyup = 0x60;
346                 ir->polling = 1; /* ms */
347                 break;
348         case CX88_BOARD_ADSTECH_DVB_T_PCI:
349                 ir_codes = RC_MAP_ADSTECH_DVB_T_PCI;
350                 ir->gpio_addr = MO_GP1_IO;
351                 ir->mask_keycode = 0xbf;
352                 ir->mask_keyup = 0x40;
353                 ir->polling = 50; /* ms */
354                 break;
355         case CX88_BOARD_MSI_TVANYWHERE_MASTER:
356                 ir_codes = RC_MAP_MSI_TVANYWHERE;
357                 ir->gpio_addr = MO_GP1_IO;
358                 ir->mask_keycode = 0x1f;
359                 ir->mask_keyup = 0x40;
360                 ir->polling = 1; /* ms */
361                 break;
362         case CX88_BOARD_AVERTV_303:
363         case CX88_BOARD_AVERTV_STUDIO_303:
364                 ir_codes         = RC_MAP_AVERTV_303;
365                 ir->gpio_addr    = MO_GP2_IO;
366                 ir->mask_keycode = 0xfb;
367                 ir->mask_keydown = 0x02;
368                 ir->polling      = 50; /* ms */
369                 break;
370         case CX88_BOARD_OMICOM_SS4_PCI:
371         case CX88_BOARD_SATTRADE_ST4200:
372         case CX88_BOARD_TBS_8920:
373         case CX88_BOARD_TBS_8910:
374         case CX88_BOARD_PROF_7300:
375         case CX88_BOARD_PROF_7301:
376         case CX88_BOARD_PROF_6200:
377                 ir_codes = RC_MAP_TBS_NEC;
378                 ir_type = IR_TYPE_PD;
379                 ir->sampling = 0xff00; /* address */
380                 break;
381         case CX88_BOARD_TEVII_S460:
382         case CX88_BOARD_TEVII_S420:
383                 ir_codes = RC_MAP_TEVII_NEC;
384                 ir_type = IR_TYPE_PD;
385                 ir->sampling = 0xff00; /* address */
386                 break;
387         case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
388                 ir_codes         = RC_MAP_DNTV_LIVE_DVBT_PRO;
389                 ir_type          = IR_TYPE_PD;
390                 ir->sampling     = 0xff00; /* address */
391                 break;
392         case CX88_BOARD_NORWOOD_MICRO:
393                 ir_codes         = RC_MAP_NORWOOD;
394                 ir->gpio_addr    = MO_GP1_IO;
395                 ir->mask_keycode = 0x0e;
396                 ir->mask_keyup   = 0x80;
397                 ir->polling      = 50; /* ms */
398                 break;
399         case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
400                 ir_codes         = RC_MAP_NPGTECH;
401                 ir->gpio_addr    = MO_GP0_IO;
402                 ir->mask_keycode = 0xfa;
403                 ir->polling      = 50; /* ms */
404                 break;
405         case CX88_BOARD_PINNACLE_PCTV_HD_800i:
406                 ir_codes         = RC_MAP_PINNACLE_PCTV_HD;
407                 ir_type          = IR_TYPE_RC5;
408                 ir->sampling     = 1;
409                 break;
410         case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
411                 ir_codes         = RC_MAP_POWERCOLOR_REAL_ANGEL;
412                 ir->gpio_addr    = MO_GP2_IO;
413                 ir->mask_keycode = 0x7e;
414                 ir->polling      = 100; /* ms */
415                 break;
416         }
417
418         if (NULL == ir_codes) {
419                 err = -ENODEV;
420                 goto err_out_free;
421         }
422
423         /*
424          * The usage of mask_keycode were very convenient, due to several
425          * reasons. Among others, the scancode tables were using the scancode
426          * as the index elements. So, the less bits it was used, the smaller
427          * the table were stored. After the input changes, the better is to use
428          * the full scancodes, since it allows replacing the IR remote by
429          * another one. Unfortunately, there are still some hardware, like
430          * Pixelview Ultra Pro, where only part of the scancode is sent via
431          * GPIO. So, there's no way to get the full scancode. Due to that,
432          * hardware_mask were introduced here: it represents those hardware
433          * that has such limits.
434          */
435         if (hardware_mask && !ir->mask_keycode)
436                 ir->mask_keycode = hardware_mask;
437
438         /* init input device */
439         snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
440         snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
441
442         err = ir_input_init(input_dev, &ir->ir, ir_type);
443         if (err < 0)
444                 goto err_out_free;
445
446         input_dev->name = ir->name;
447         input_dev->phys = ir->phys;
448         input_dev->id.bustype = BUS_PCI;
449         input_dev->id.version = 1;
450         if (pci->subsystem_vendor) {
451                 input_dev->id.vendor = pci->subsystem_vendor;
452                 input_dev->id.product = pci->subsystem_device;
453         } else {
454                 input_dev->id.vendor = pci->vendor;
455                 input_dev->id.product = pci->device;
456         }
457         input_dev->dev.parent = &pci->dev;
458         /* record handles to ourself */
459         ir->core = core;
460         core->ir = ir;
461
462         ir->props.priv = core;
463         ir->props.open = cx88_ir_open;
464         ir->props.close = cx88_ir_close;
465         ir->props.scanmask = hardware_mask;
466
467         /* all done */
468         err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
469         if (err)
470                 goto err_out_free;
471
472         return 0;
473
474  err_out_free:
475         core->ir = NULL;
476         kfree(ir);
477         return err;
478 }
479
480 int cx88_ir_fini(struct cx88_core *core)
481 {
482         struct cx88_IR *ir = core->ir;
483
484         /* skip detach on non attached boards */
485         if (NULL == ir)
486                 return 0;
487
488         cx88_ir_stop(core);
489         ir_input_unregister(ir->input);
490         kfree(ir);
491
492         /* done */
493         core->ir = NULL;
494         return 0;
495 }
496
497 /* ---------------------------------------------------------------------- */
498
499 void cx88_ir_irq(struct cx88_core *core)
500 {
501         struct cx88_IR *ir = core->ir;
502         u32 samples, ircode;
503         int i, start, range, toggle, dev, code;
504
505         if (NULL == ir)
506                 return;
507         if (!ir->sampling)
508                 return;
509
510         samples = cx_read(MO_SAMPLE_IO);
511         if (0 != samples && 0xffffffff != samples) {
512                 /* record sample data */
513                 if (ir->scount < ARRAY_SIZE(ir->samples))
514                         ir->samples[ir->scount++] = samples;
515                 return;
516         }
517         if (!ir->scount) {
518                 /* nothing to sample */
519                 if (ir->ir.keypressed && time_after(jiffies, ir->release))
520                         ir_input_nokey(ir->input, &ir->ir);
521                 return;
522         }
523
524         /* have a complete sample */
525         if (ir->scount < ARRAY_SIZE(ir->samples))
526                 ir->samples[ir->scount++] = samples;
527         for (i = 0; i < ir->scount; i++)
528                 ir->samples[i] = ~ir->samples[i];
529         if (ir_debug)
530                 ir_dump_samples(ir->samples, ir->scount);
531
532         /* decode it */
533         switch (core->boardnr) {
534         case CX88_BOARD_TEVII_S460:
535         case CX88_BOARD_TEVII_S420:
536         case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
537         case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
538         case CX88_BOARD_OMICOM_SS4_PCI:
539         case CX88_BOARD_SATTRADE_ST4200:
540         case CX88_BOARD_TBS_8920:
541         case CX88_BOARD_TBS_8910:
542         case CX88_BOARD_PROF_7300:
543         case CX88_BOARD_PROF_7301:
544         case CX88_BOARD_PROF_6200:
545                 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
546
547                 if (ircode == 0xffffffff) { /* decoding error */
548                         ir_dprintk("pulse distance decoding error\n");
549                         break;
550                 }
551
552                 ir_dprintk("pulse distance decoded: %x\n", ircode);
553
554                 if (ircode == 0) { /* key still pressed */
555                         ir_dprintk("pulse distance decoded repeat code\n");
556                         ir->release = jiffies + msecs_to_jiffies(120);
557                         break;
558                 }
559
560                 if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
561                         ir_dprintk("pulse distance decoded wrong address\n");
562                         break;
563                 }
564
565                 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
566                         ir_dprintk("pulse distance decoded wrong check sum\n");
567                         break;
568                 }
569
570                 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
571
572                 ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
573                 ir->release = jiffies + msecs_to_jiffies(120);
574                 break;
575         case CX88_BOARD_HAUPPAUGE:
576         case CX88_BOARD_HAUPPAUGE_DVB_T1:
577         case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
578         case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
579         case CX88_BOARD_HAUPPAUGE_HVR1100:
580         case CX88_BOARD_HAUPPAUGE_HVR3000:
581         case CX88_BOARD_HAUPPAUGE_HVR4000:
582         case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
583         case CX88_BOARD_PCHDTV_HD3000:
584         case CX88_BOARD_PCHDTV_HD5500:
585         case CX88_BOARD_HAUPPAUGE_IRONLY:
586                 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
587                 ir_dprintk("biphase decoded: %x\n", ircode);
588                 /*
589                  * RC5 has an extension bit which adds a new range
590                  * of available codes, this is detected here. Also
591                  * hauppauge remotes (black/silver) always use
592                  * specific device ids. If we do not filter the
593                  * device ids then messages destined for devices
594                  * such as TVs (id=0) will get through to the
595                  * device causing mis-fired events.
596                  */
597                 /* split rc5 data block ... */
598                 start = (ircode & 0x2000) >> 13;
599                 range = (ircode & 0x1000) >> 12;
600                 toggle= (ircode & 0x0800) >> 11;
601                 dev   = (ircode & 0x07c0) >> 6;
602                 code  = (ircode & 0x003f) | ((range << 6) ^ 0x0040);
603                 if( start != 1)
604                         /* no key pressed */
605                         break;
606                 if ( dev != 0x1e && dev != 0x1f )
607                         /* not a hauppauge remote */
608                         break;
609                 ir_input_keydown(ir->input, &ir->ir, code);
610                 ir->release = jiffies + msecs_to_jiffies(120);
611                 break;
612         case CX88_BOARD_PINNACLE_PCTV_HD_800i:
613                 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
614                 ir_dprintk("biphase decoded: %x\n", ircode);
615                 if ((ircode & 0xfffff000) != 0x3000)
616                         break;
617                 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
618                 ir->release = jiffies + msecs_to_jiffies(120);
619                 break;
620         }
621
622         ir->scount = 0;
623         return;
624 }
625
626 /* ---------------------------------------------------------------------- */
627
628 MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe");
629 MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls");
630 MODULE_LICENSE("GPL");
631 /*
632  * Local variables:
633  * c-basic-offset: 8
634  * End:
635  */