aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2010-10-29 15:08:02 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:35 -0500
commit2997137be8eba5bf9c07a24d5fda1f4225f9ca7d (patch)
tree98e386a7cc5303567183e4effacf8212e638e7af /drivers/media/video/cx88
parent00df055ae315c9c8792dc4d012e6ad9c4d527e87 (diff)
[media] ir-core: convert drivers/media/video/cx88 to ir-core
This patch converts the cx88 driver (for sampling hw) to use the decoders provided by ir-core instead of the separate ones provided by ir-functions (and gets rid of those). The value for MO_DDS_IO had a comment saying it corresponded to a 4kHz samplerate. That comment was unfortunately misleading. The actual samplerate was something like 3250Hz. The current value has been derived by analyzing the elapsed time between interrupts for different values (knowing that each interrupt corresponds to 32 samples). Thanks to Mariusz Bialonczyk <manio@skyboo.net> for testing my patches (about one a day for two weeks!) on actual hardware. Signed-off-by: David Härdeman <david@hardeman.nu> Acked-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-input.c163
2 files changed, 37 insertions, 128 deletions
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 0fa85cbefbb1..bcfd1ac48cc6 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -1,6 +1,6 @@
1config VIDEO_CX88 1config VIDEO_CX88
2 tristate "Conexant 2388x (bt878 successor) support" 2 tristate "Conexant 2388x (bt878 successor) support"
3 depends on VIDEO_DEV && PCI && I2C && INPUT 3 depends on VIDEO_DEV && PCI && I2C && INPUT && IR_CORE
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select VIDEO_BTCX 5 select VIDEO_BTCX
6 select VIDEOBUF_DMA_SG 6 select VIDEOBUF_DMA_SG
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index fc777bc6e716..436ace8196a5 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -41,7 +41,6 @@ struct cx88_IR {
41 struct cx88_core *core; 41 struct cx88_core *core;
42 struct input_dev *input; 42 struct input_dev *input;
43 struct ir_dev_props props; 43 struct ir_dev_props props;
44 u64 ir_type;
45 44
46 int users; 45 int users;
47 46
@@ -50,8 +49,6 @@ struct cx88_IR {
50 49
51 /* sample from gpio pin 16 */ 50 /* sample from gpio pin 16 */
52 u32 sampling; 51 u32 sampling;
53 u32 samples[16];
54 int scount;
55 52
56 /* poll external decoder */ 53 /* poll external decoder */
57 int polling; 54 int polling;
@@ -63,6 +60,10 @@ struct cx88_IR {
63 u32 mask_keyup; 60 u32 mask_keyup;
64}; 61};
65 62
63static unsigned ir_samplerate = 4;
64module_param(ir_samplerate, uint, 0444);
65MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4");
66
66static int ir_debug; 67static int ir_debug;
67module_param(ir_debug, int, 0644); /* debug level [IR] */ 68module_param(ir_debug, int, 0644); /* debug level [IR] */
68MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); 69MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
@@ -176,8 +177,8 @@ static int __cx88_ir_start(void *priv)
176 } 177 }
177 if (ir->sampling) { 178 if (ir->sampling) {
178 core->pci_irqmask |= PCI_INT_IR_SMPINT; 179 core->pci_irqmask |= PCI_INT_IR_SMPINT;
179 cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ 180 cx_write(MO_DDS_IO, 0x33F286 * ir_samplerate); /* samplerate */
180 cx_write(MO_DDSCFG_IO, 0x5); /* enable */ 181 cx_write(MO_DDSCFG_IO, 0x5); /* enable */
181 } 182 }
182 return 0; 183 return 0;
183} 184}
@@ -264,7 +265,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
264 break; 265 break;
265 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 266 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
266 ir_codes = RC_MAP_CINERGY_1400; 267 ir_codes = RC_MAP_CINERGY_1400;
267 ir_type = IR_TYPE_NEC;
268 ir->sampling = 0xeb04; /* address */ 268 ir->sampling = 0xeb04; /* address */
269 break; 269 break;
270 case CX88_BOARD_HAUPPAUGE: 270 case CX88_BOARD_HAUPPAUGE:
@@ -279,7 +279,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
279 case CX88_BOARD_PCHDTV_HD5500: 279 case CX88_BOARD_PCHDTV_HD5500:
280 case CX88_BOARD_HAUPPAUGE_IRONLY: 280 case CX88_BOARD_HAUPPAUGE_IRONLY:
281 ir_codes = RC_MAP_HAUPPAUGE_NEW; 281 ir_codes = RC_MAP_HAUPPAUGE_NEW;
282 ir_type = IR_TYPE_RC5;
283 ir->sampling = 1; 282 ir->sampling = 1;
284 break; 283 break;
285 case CX88_BOARD_WINFAST_DTV2000H: 284 case CX88_BOARD_WINFAST_DTV2000H:
@@ -367,18 +366,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
367 case CX88_BOARD_PROF_7301: 366 case CX88_BOARD_PROF_7301:
368 case CX88_BOARD_PROF_6200: 367 case CX88_BOARD_PROF_6200:
369 ir_codes = RC_MAP_TBS_NEC; 368 ir_codes = RC_MAP_TBS_NEC;
370 ir_type = IR_TYPE_NEC;
371 ir->sampling = 0xff00; /* address */ 369 ir->sampling = 0xff00; /* address */
372 break; 370 break;
373 case CX88_BOARD_TEVII_S460: 371 case CX88_BOARD_TEVII_S460:
374 case CX88_BOARD_TEVII_S420: 372 case CX88_BOARD_TEVII_S420:
375 ir_codes = RC_MAP_TEVII_NEC; 373 ir_codes = RC_MAP_TEVII_NEC;
376 ir_type = IR_TYPE_NEC;
377 ir->sampling = 0xff00; /* address */ 374 ir->sampling = 0xff00; /* address */
378 break; 375 break;
379 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 376 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
380 ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO; 377 ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO;
381 ir_type = IR_TYPE_NEC;
382 ir->sampling = 0xff00; /* address */ 378 ir->sampling = 0xff00; /* address */
383 break; 379 break;
384 case CX88_BOARD_NORWOOD_MICRO: 380 case CX88_BOARD_NORWOOD_MICRO:
@@ -396,7 +392,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
396 break; 392 break;
397 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 393 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
398 ir_codes = RC_MAP_PINNACLE_PCTV_HD; 394 ir_codes = RC_MAP_PINNACLE_PCTV_HD;
399 ir_type = IR_TYPE_RC5;
400 ir->sampling = 1; 395 ir->sampling = 1;
401 break; 396 break;
402 case CX88_BOARD_POWERCOLOR_REAL_ANGEL: 397 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
@@ -412,7 +407,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
412 break; 407 break;
413 } 408 }
414 409
415 if (NULL == ir_codes) { 410 if (!ir_codes) {
416 err = -ENODEV; 411 err = -ENODEV;
417 goto err_out_free; 412 goto err_out_free;
418 } 413 }
@@ -436,8 +431,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
436 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); 431 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
437 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); 432 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
438 433
439 ir->ir_type = ir_type;
440
441 input_dev->name = ir->name; 434 input_dev->name = ir->name;
442 input_dev->phys = ir->phys; 435 input_dev->phys = ir->phys;
443 input_dev->id.bustype = BUS_PCI; 436 input_dev->id.bustype = BUS_PCI;
@@ -454,10 +447,18 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
454 ir->core = core; 447 ir->core = core;
455 core->ir = ir; 448 core->ir = ir;
456 449
450 if (ir->sampling) {
451 ir_type = IR_TYPE_ALL;
452 ir->props.driver_type = RC_DRIVER_IR_RAW;
453 ir->props.timeout = 10 * 1000 * 1000; /* 10 ms */
454 } else
455 ir->props.driver_type = RC_DRIVER_SCANCODE;
456
457 ir->props.priv = core; 457 ir->props.priv = core;
458 ir->props.open = cx88_ir_open; 458 ir->props.open = cx88_ir_open;
459 ir->props.close = cx88_ir_close; 459 ir->props.close = cx88_ir_close;
460 ir->props.scanmask = hardware_mask; 460 ir->props.scanmask = hardware_mask;
461 ir->props.allowed_protos = ir_type;
461 462
462 /* all done */ 463 /* all done */
463 err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME); 464 err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
@@ -494,128 +495,36 @@ int cx88_ir_fini(struct cx88_core *core)
494void cx88_ir_irq(struct cx88_core *core) 495void cx88_ir_irq(struct cx88_core *core)
495{ 496{
496 struct cx88_IR *ir = core->ir; 497 struct cx88_IR *ir = core->ir;
497 u32 samples, ircode; 498 u32 samples;
498 int i, start, range, toggle, dev, code; 499 unsigned todo, bits;
500 struct ir_raw_event ev;
501 struct ir_input_dev *irdev;
499 502
500 if (NULL == ir) 503 if (!ir || !ir->sampling)
501 return;
502 if (!ir->sampling)
503 return; 504 return;
504 505
506 /*
507 * Samples are stored in a 32 bit register, oldest sample in
508 * the msb. A set bit represents space and an unset bit
509 * represents a pulse.
510 */
505 samples = cx_read(MO_SAMPLE_IO); 511 samples = cx_read(MO_SAMPLE_IO);
506 if (0 != samples && 0xffffffff != samples) { 512 irdev = input_get_drvdata(ir->input);
507 /* record sample data */
508 if (ir->scount < ARRAY_SIZE(ir->samples))
509 ir->samples[ir->scount++] = samples;
510 return;
511 }
512 if (!ir->scount) {
513 /* nothing to sample */
514 return;
515 }
516
517 /* have a complete sample */
518 if (ir->scount < ARRAY_SIZE(ir->samples))
519 ir->samples[ir->scount++] = samples;
520 for (i = 0; i < ir->scount; i++)
521 ir->samples[i] = ~ir->samples[i];
522 if (ir_debug)
523 ir_dump_samples(ir->samples, ir->scount);
524
525 /* decode it */
526 switch (core->boardnr) {
527 case CX88_BOARD_TEVII_S460:
528 case CX88_BOARD_TEVII_S420:
529 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
530 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
531 case CX88_BOARD_OMICOM_SS4_PCI:
532 case CX88_BOARD_SATTRADE_ST4200:
533 case CX88_BOARD_TBS_8920:
534 case CX88_BOARD_TBS_8910:
535 case CX88_BOARD_PROF_7300:
536 case CX88_BOARD_PROF_7301:
537 case CX88_BOARD_PROF_6200:
538 case CX88_BOARD_TWINHAN_VP1027_DVBS:
539 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
540
541 if (ircode == 0xffffffff) { /* decoding error */
542 ir_dprintk("pulse distance decoding error\n");
543 break;
544 }
545
546 ir_dprintk("pulse distance decoded: %x\n", ircode);
547 513
548 if (ircode == 0) { /* key still pressed */ 514 if (samples == 0xff && irdev->idle)
549 ir_dprintk("pulse distance decoded repeat code\n"); 515 return;
550 ir_repeat(ir->input);
551 break;
552 }
553
554 if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
555 ir_dprintk("pulse distance decoded wrong address\n");
556 break;
557 }
558
559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
560 ir_dprintk("pulse distance decoded wrong check sum\n");
561 break;
562 }
563 516
564 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0xff); 517 init_ir_raw_event(&ev);
565 ir_keydown(ir->input, (ircode >> 16) & 0xff, 0); 518 for (todo = 32; todo > 0; todo -= bits) {
566 break; 519 ev.pulse = samples & 0x80000000 ? false : true;
567 case CX88_BOARD_HAUPPAUGE: 520 bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
568 case CX88_BOARD_HAUPPAUGE_DVB_T1: 521 ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate);
569 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 522 ir_raw_event_store_with_filter(ir->input, &ev);
570 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 523 samples <<= bits;
571 case CX88_BOARD_HAUPPAUGE_HVR1100:
572 case CX88_BOARD_HAUPPAUGE_HVR3000:
573 case CX88_BOARD_HAUPPAUGE_HVR4000:
574 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
575 case CX88_BOARD_PCHDTV_HD3000:
576 case CX88_BOARD_PCHDTV_HD5500:
577 case CX88_BOARD_HAUPPAUGE_IRONLY:
578 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
579 ir_dprintk("biphase decoded: %x\n", ircode);
580 /*
581 * RC5 has an extension bit which adds a new range
582 * of available codes, this is detected here. Also
583 * hauppauge remotes (black/silver) always use
584 * specific device ids. If we do not filter the
585 * device ids then messages destined for devices
586 * such as TVs (id=0) will get through to the
587 * device causing mis-fired events.
588 */
589 /* split rc5 data block ... */
590 start = (ircode & 0x2000) >> 13;
591 range = (ircode & 0x1000) >> 12;
592 toggle= (ircode & 0x0800) >> 11;
593 dev = (ircode & 0x07c0) >> 6;
594 code = (ircode & 0x003f) | ((range << 6) ^ 0x0040);
595 if( start != 1)
596 /* no key pressed */
597 break;
598 if ( dev != 0x1e && dev != 0x1f )
599 /* not a hauppauge remote */
600 break;
601 ir_keydown(ir->input, code, toggle);
602 break;
603 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
604 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
605 ir_dprintk("biphase decoded: %x\n", ircode);
606 if ((ircode & 0xfffff000) != 0x3000)
607 break;
608 /* Note: bit 0x800 being the toggle is assumed, not checked
609 with real hardware */
610 ir_keydown(ir->input, ircode & 0x3f, ircode & 0x0800 ? 1 : 0);
611 break;
612 } 524 }
613 525 ir_raw_event_handle(ir->input);
614 ir->scount = 0;
615 return;
616} 526}
617 527
618
619void cx88_i2c_init_ir(struct cx88_core *core) 528void cx88_i2c_init_ir(struct cx88_core *core)
620{ 529{
621 struct i2c_board_info info; 530 struct i2c_board_info info;