aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/Makefile4
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c13
-rw-r--r--drivers/media/video/tda9887.c461
-rw-r--r--drivers/media/video/tuner-core.c32
-rw-r--r--drivers/media/video/tuner-types.c5
-rw-r--r--include/media/tuner.h10
6 files changed, 130 insertions, 395 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 5341eef00bdc..6c401b46398a 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -6,7 +6,7 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
6zr36067-objs := zoran_procfs.o zoran_device.o \ 6zr36067-objs := zoran_procfs.o zoran_device.o \
7 zoran_driver.o zoran_card.o 7 zoran_driver.o zoran_card.o
8tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ 8tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \
9 mt20xx.o tda8290.o tea5767.o 9 mt20xx.o tda8290.o tea5767.o tda9887.o
10 10
11msp3400-objs := msp3400-driver.o msp3400-kthreads.o 11msp3400-objs := msp3400-driver.o msp3400-kthreads.o
12 12
@@ -60,7 +60,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
60obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o 60obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
61obj-$(CONFIG_TUNER_3036) += tuner-3036.o 61obj-$(CONFIG_TUNER_3036) += tuner-3036.o
62 62
63obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o 63obj-$(CONFIG_VIDEO_TUNER) += tuner.o
64obj-$(CONFIG_VIDEO_BUF) += video-buf.o 64obj-$(CONFIG_VIDEO_BUF) += video-buf.o
65obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o 65obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
66obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o 66obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index fce30d341887..d829d8f8c1f6 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -425,9 +425,19 @@ static int attach_inform(struct i2c_client *client)
425 struct em28xx *dev = client->adapter->algo_data; 425 struct em28xx *dev = client->adapter->algo_data;
426 426
427 switch (client->addr << 1) { 427 switch (client->addr << 1) {
428 case 0x86: 428 case 0x43:
429 case 0x4b:
430 {
431 struct tuner_setup tun_setup;
432
433 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
434 tun_setup.type = TUNER_TDA9887;
435 tun_setup.addr = client->addr;
436
437 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
429 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); 438 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
430 break; 439 break;
440 }
431 case 0x42: 441 case 0x42:
432 dprintk1(1,"attach_inform: saa7114 detected.\n"); 442 dprintk1(1,"attach_inform: saa7114 detected.\n");
433 break; 443 break;
@@ -453,6 +463,7 @@ static int attach_inform(struct i2c_client *client)
453 case 0xba: 463 case 0xba:
454 dprintk1(1,"attach_inform: tvp5150 detected.\n"); 464 dprintk1(1,"attach_inform: tvp5150 detected.\n");
455 break; 465 break;
466
456 default: 467 default:
457 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); 468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
458 dev->tuner_addr = client->addr; 469 dev->tuner_addr = client->addr;
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 0d54f6c1982b..b6ae969563b2 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -18,49 +18,21 @@
18 TDA9886 (PAL, SECAM, NTSC) 18 TDA9886 (PAL, SECAM, NTSC)
19 TDA9887 (PAL, SECAM, NTSC, FM Radio) 19 TDA9887 (PAL, SECAM, NTSC, FM Radio)
20 20
21 found on: 21 Used as part of several tuners
22 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
23 TDA9887 (world), TDA9885 (USA)
24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
25 - KNC One TV-Station RDS (saa7134)
26 - Hauppauge PVR-150/500 (possibly more)
27*/ 22*/
28 23
24#define tda9887_info(fmt, arg...) do {\
25 printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \
26 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
27#define tda9887_dbg(fmt, arg...) do {\
28 if (tuner_debug) \
29 printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \
30 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
29 31
30/* Addresses to scan */
31static unsigned short normal_i2c[] = {
32 0x84 >>1,
33 0x86 >>1,
34 0x96 >>1,
35 I2C_CLIENT_END,
36};
37I2C_CLIENT_INSMOD;
38
39/* insmod options */
40static unsigned int debug = 0;
41module_param(debug, int, 0644);
42MODULE_LICENSE("GPL");
43 32
44/* ---------------------------------------------------------------------- */ 33/* ---------------------------------------------------------------------- */
45 34
46#define UNSET (-1U) 35#define UNSET (-1U)
47#define tda9887_info(fmt, arg...) do {\
48 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
49 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
50#define tda9887_dbg(fmt, arg...) do {\
51 if (debug) \
52 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
53 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
54
55struct tda9887 {
56 struct i2c_client client;
57 v4l2_std_id std;
58 enum tuner_mode mode;
59 unsigned int config;
60 unsigned int using_v4l2;
61 unsigned int radio_mode;
62 unsigned char data[4];
63};
64 36
65struct tvnorm { 37struct tvnorm {
66 v4l2_std_id std; 38 v4l2_std_id std;
@@ -70,9 +42,6 @@ struct tvnorm {
70 unsigned char e; 42 unsigned char e;
71}; 43};
72 44
73static struct i2c_driver driver;
74static struct i2c_client client_template;
75
76/* ---------------------------------------------------------------------- */ 45/* ---------------------------------------------------------------------- */
77 46
78// 47//
@@ -281,7 +250,7 @@ static struct tvnorm radio_mono = {
281 250
282/* ---------------------------------------------------------------------- */ 251/* ---------------------------------------------------------------------- */
283 252
284static void dump_read_message(struct tda9887 *t, unsigned char *buf) 253static void dump_read_message(struct tuner *t, unsigned char *buf)
285{ 254{
286 static char *afc[16] = { 255 static char *afc[16] = {
287 "- 12.5 kHz", 256 "- 12.5 kHz",
@@ -309,7 +278,7 @@ static void dump_read_message(struct tda9887 *t, unsigned char *buf)
309 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 278 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
310} 279}
311 280
312static void dump_write_message(struct tda9887 *t, unsigned char *buf) 281static void dump_write_message(struct tuner *t, unsigned char *buf)
313{ 282{
314 static char *sound[4] = { 283 static char *sound[4] = {
315 "AM/TV", 284 "AM/TV",
@@ -405,13 +374,13 @@ static void dump_write_message(struct tda9887 *t, unsigned char *buf)
405 374
406/* ---------------------------------------------------------------------- */ 375/* ---------------------------------------------------------------------- */
407 376
408static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) 377static int tda9887_set_tvnorm(struct tuner *t, char *buf)
409{ 378{
410 struct tvnorm *norm = NULL; 379 struct tvnorm *norm = NULL;
411 int i; 380 int i;
412 381
413 if (t->mode == T_RADIO) { 382 if (t->mode == V4L2_TUNER_RADIO) {
414 if (t->radio_mode == V4L2_TUNER_MODE_MONO) 383 if (t->audmode == V4L2_TUNER_MODE_MONO)
415 norm = &radio_mono; 384 norm = &radio_mono;
416 else 385 else
417 norm = &radio_stereo; 386 norm = &radio_stereo;
@@ -445,7 +414,7 @@ module_param(port2, int, 0644);
445module_param(qss, int, 0644); 414module_param(qss, int, 0644);
446module_param(adjust, int, 0644); 415module_param(adjust, int, 0644);
447 416
448static int tda9887_set_insmod(struct tda9887 *t, char *buf) 417static int tda9887_set_insmod(struct tuner *t, char *buf)
449{ 418{
450 if (UNSET != port1) { 419 if (UNSET != port1) {
451 if (port1) 420 if (port1)
@@ -474,27 +443,27 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf)
474 return 0; 443 return 0;
475} 444}
476 445
477static int tda9887_set_config(struct tda9887 *t, char *buf) 446static int tda9887_set_config(struct tuner *t, char *buf)
478{ 447{
479 if (t->config & TDA9887_PORT1_ACTIVE) 448 if (t->tda9887_config & TDA9887_PORT1_ACTIVE)
480 buf[1] &= ~cOutputPort1Inactive; 449 buf[1] &= ~cOutputPort1Inactive;
481 if (t->config & TDA9887_PORT1_INACTIVE) 450 if (t->tda9887_config & TDA9887_PORT1_INACTIVE)
482 buf[1] |= cOutputPort1Inactive; 451 buf[1] |= cOutputPort1Inactive;
483 if (t->config & TDA9887_PORT2_ACTIVE) 452 if (t->tda9887_config & TDA9887_PORT2_ACTIVE)
484 buf[1] &= ~cOutputPort2Inactive; 453 buf[1] &= ~cOutputPort2Inactive;
485 if (t->config & TDA9887_PORT2_INACTIVE) 454 if (t->tda9887_config & TDA9887_PORT2_INACTIVE)
486 buf[1] |= cOutputPort2Inactive; 455 buf[1] |= cOutputPort2Inactive;
487 456
488 if (t->config & TDA9887_QSS) 457 if (t->tda9887_config & TDA9887_QSS)
489 buf[1] |= cQSS; 458 buf[1] |= cQSS;
490 if (t->config & TDA9887_INTERCARRIER) 459 if (t->tda9887_config & TDA9887_INTERCARRIER)
491 buf[1] &= ~cQSS; 460 buf[1] &= ~cQSS;
492 461
493 if (t->config & TDA9887_AUTOMUTE) 462 if (t->tda9887_config & TDA9887_AUTOMUTE)
494 buf[1] |= cAutoMuteFmActive; 463 buf[1] |= cAutoMuteFmActive;
495 if (t->config & TDA9887_DEEMPHASIS_MASK) { 464 if (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
496 buf[2] &= ~0x60; 465 buf[2] &= ~0x60;
497 switch (t->config & TDA9887_DEEMPHASIS_MASK) { 466 switch (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
498 case TDA9887_DEEMPHASIS_NONE: 467 case TDA9887_DEEMPHASIS_NONE:
499 buf[2] |= cDeemphasisOFF; 468 buf[2] |= cDeemphasisOFF;
500 break; 469 break;
@@ -506,153 +475,36 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
506 break; 475 break;
507 } 476 }
508 } 477 }
509 if (t->config & TDA9887_TOP_SET) { 478 if (t->tda9887_config & TDA9887_TOP_SET) {
510 buf[2] &= ~cTopMask; 479 buf[2] &= ~cTopMask;
511 buf[2] |= (t->config >> 8) & cTopMask; 480 buf[2] |= (t->tda9887_config >> 8) & cTopMask;
512 } 481 }
513 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) 482 if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
514 buf[1] &= ~cQSS; 483 buf[1] &= ~cQSS;
515 return 0; 484 return 0;
516} 485}
517 486
518/* ---------------------------------------------------------------------- */ 487/* ---------------------------------------------------------------------- */
519 488
520static char pal[] = "--"; 489static int tda9887_status(struct tuner *t)
521static char secam[] = "--";
522static char ntsc[] = "-";
523
524module_param_string(pal, pal, sizeof(pal), 0644);
525module_param_string(secam, secam, sizeof(secam), 0644);
526module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
527
528static int tda9887_fixup_std(struct tda9887 *t)
529{
530 /* get more precise norm info from insmod option */
531 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
532 switch (pal[0]) {
533 case 'b':
534 case 'B':
535 case 'g':
536 case 'G':
537 case 'h':
538 case 'H':
539 case 'n':
540 case 'N':
541 if (pal[1] == 'c' || pal[1] == 'C') {
542 tda9887_dbg("insmod fixup: PAL => PAL-Nc\n");
543 t->std = V4L2_STD_PAL_Nc;
544 } else {
545 tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n");
546 t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N;
547 }
548 break;
549 case 'i':
550 case 'I':
551 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
552 t->std = V4L2_STD_PAL_I;
553 break;
554 case 'd':
555 case 'D':
556 case 'k':
557 case 'K':
558 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
559 t->std = V4L2_STD_PAL_DK;
560 break;
561 case 'm':
562 case 'M':
563 tda9887_dbg("insmod fixup: PAL => PAL-M\n");
564 t->std = V4L2_STD_PAL_M;
565 break;
566 case '-':
567 /* default parameter, do nothing */
568 break;
569 default:
570 tda9887_info("pal= argument not recognised\n");
571 break;
572 }
573 }
574 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
575 switch (secam[0]) {
576 case 'b':
577 case 'B':
578 case 'g':
579 case 'G':
580 case 'h':
581 case 'H':
582 tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n");
583 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
584 break;
585 case 'd':
586 case 'D':
587 case 'k':
588 case 'K':
589 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
590 t->std = V4L2_STD_SECAM_DK;
591 break;
592 case 'l':
593 case 'L':
594 if (secam[1] == 'c' || secam[1] == 'C') {
595 tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n");
596 t->std = V4L2_STD_SECAM_LC;
597 } else {
598 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
599 t->std = V4L2_STD_SECAM_L;
600 }
601 break;
602 case '-':
603 /* default parameter, do nothing */
604 break;
605 default:
606 tda9887_info("secam= argument not recognised\n");
607 break;
608 }
609 }
610 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
611 switch (ntsc[0]) {
612 case 'm':
613 case 'M':
614 tda9887_dbg("insmod fixup: NTSC => NTSC-M\n");
615 t->std = V4L2_STD_NTSC_M;
616 break;
617 case 'j':
618 case 'J':
619 tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
620 t->std = V4L2_STD_NTSC_M_JP;
621 break;
622 case 'k':
623 case 'K':
624 tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
625 t->std = V4L2_STD_NTSC_M_KR;
626 break;
627 case '-':
628 /* default parameter, do nothing */
629 break;
630 default:
631 tda9887_info("ntsc= argument not recognised\n");
632 break;
633 }
634 }
635 return 0;
636}
637
638static int tda9887_status(struct tda9887 *t)
639{ 490{
640 unsigned char buf[1]; 491 unsigned char buf[1];
641 int rc; 492 int rc;
642 493
643 memset(buf,0,sizeof(buf)); 494 memset(buf,0,sizeof(buf));
644 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 495 if (1 != (rc = i2c_master_recv(&t->i2c,buf,1)))
645 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); 496 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
646 dump_read_message(t, buf); 497 dump_read_message(t, buf);
647 return 0; 498 return 0;
648} 499}
649 500
650static int tda9887_configure(struct tda9887 *t) 501static void tda9887_configure(struct i2c_client *client)
651{ 502{
503 struct tuner *t = i2c_get_clientdata(client);
652 int rc; 504 int rc;
653 505
654 memset(t->data,0,sizeof(t->data)); 506 memset(t->tda9887_data,0,sizeof(t->tda9887_data));
655 tda9887_set_tvnorm(t,t->data); 507 tda9887_set_tvnorm(t,t->tda9887_data);
656 508
657 /* A note on the port settings: 509 /* A note on the port settings:
658 These settings tend to depend on the specifics of the board. 510 These settings tend to depend on the specifics of the board.
@@ -667,249 +519,84 @@ static int tda9887_configure(struct tda9887 *t)
667 the ports should be set to active (0), but, again, that may 519 the ports should be set to active (0), but, again, that may
668 differ depending on the precise hardware configuration. 520 differ depending on the precise hardware configuration.
669 */ 521 */
670 t->data[1] |= cOutputPort1Inactive; 522 t->tda9887_data[1] |= cOutputPort1Inactive;
671 t->data[1] |= cOutputPort2Inactive; 523 t->tda9887_data[1] |= cOutputPort2Inactive;
672 524
673 tda9887_set_config(t,t->data); 525 tda9887_set_config(t,t->tda9887_data);
674 tda9887_set_insmod(t,t->data); 526 tda9887_set_insmod(t,t->tda9887_data);
675 527
676 if (t->mode == T_STANDBY) { 528 if (t->mode == T_STANDBY) {
677 t->data[1] |= cForcedMuteAudioON; 529 t->tda9887_data[1] |= cForcedMuteAudioON;
678 } 530 }
679 531
680 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", 532 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
681 t->data[1],t->data[2],t->data[3]); 533 t->tda9887_data[1],t->tda9887_data[2],t->tda9887_data[3]);
682 if (debug > 1) 534 if (tuner_debug > 1)
683 dump_write_message(t, t->data); 535 dump_write_message(t, t->tda9887_data);
684 536
685 if (4 != (rc = i2c_master_send(&t->client,t->data,4))) 537 if (4 != (rc = i2c_master_send(&t->i2c,t->tda9887_data,4)))
686 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); 538 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
687 539
688 if (debug > 2) { 540 if (tuner_debug > 2) {
689 msleep_interruptible(1000); 541 msleep_interruptible(1000);
690 tda9887_status(t); 542 tda9887_status(t);
691 } 543 }
692 return 0;
693} 544}
694 545
695/* ---------------------------------------------------------------------- */ 546/* ---------------------------------------------------------------------- */
696 547
697static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) 548static void tda9887_tuner_status(struct i2c_client *client)
698{ 549{
699 struct tda9887 *t; 550 struct tuner *t = i2c_get_clientdata(client);
700 551 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->tda9887_data[1], t->tda9887_data[2], t->tda9887_data[3]);
701 client_template.adapter = adap;
702 client_template.addr = addr;
703
704 if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL)))
705 return -ENOMEM;
706
707 t->client = client_template;
708 t->std = 0;
709 t->radio_mode = V4L2_TUNER_MODE_STEREO;
710
711 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
712
713 i2c_set_clientdata(&t->client, t);
714 i2c_attach_client(&t->client);
715
716 return 0;
717} 552}
718 553
719static int tda9887_probe(struct i2c_adapter *adap) 554static int tda9887_get_afc(struct i2c_client *client)
720{ 555{
721 if (adap->class & I2C_CLASS_TV_ANALOG) 556 struct tuner *t = i2c_get_clientdata(client);
722 return i2c_probe(adap, &addr_data, tda9887_attach); 557 static int AFC_BITS_2_kHz[] = {
723 return 0; 558 -12500, -37500, -62500, -97500,
724} 559 -112500, -137500, -162500, -187500,
560 187500, 162500, 137500, 112500,
561 97500 , 62500, 37500 , 12500
562 };
563 int afc=0;
564 __u8 reg = 0;
725 565
726static int tda9887_detach(struct i2c_client *client) 566 if (1 == i2c_master_recv(&t->i2c,&reg,1))
727{ 567 afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
728 struct tda9887 *t = i2c_get_clientdata(client);
729 568
730 i2c_detach_client(client); 569 return afc;
731 kfree(t);
732 return 0;
733} 570}
734 571
735#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 572static void tda9887_standby(struct i2c_client *client)
736 tda9887_info("switching to v4l2\n"); \
737 t->using_v4l2 = 1;
738#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
739 tda9887_info("ignore v4l1 call\n"); \
740 return 0; }
741
742static int
743tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
744{ 573{
745 struct tda9887 *t = i2c_get_clientdata(client); 574 tda9887_configure(client);
746
747 switch (cmd) {
748
749 /* --- configuration --- */
750 case AUDC_SET_RADIO:
751 {
752 t->mode = T_RADIO;
753 tda9887_configure(t);
754 break;
755 }
756 case TUNER_SET_STANDBY:
757 {
758 t->mode = T_STANDBY;
759 tda9887_configure(t);
760 break;
761 }
762 case TDA9887_SET_CONFIG:
763 {
764 int *i = arg;
765
766 t->config = *i;
767 tda9887_configure(t);
768 break;
769 }
770 /* --- v4l ioctls --- */
771 /* take care: bttv does userspace copying, we'll get a
772 kernel pointer here... */
773 case VIDIOCSCHAN:
774 {
775 static const v4l2_std_id map[] = {
776 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
777 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
778 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
779 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
780 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
781 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
782 };
783 struct video_channel *vc = arg;
784
785 CHECK_V4L2;
786 t->mode = T_ANALOG_TV;
787 if (vc->norm < ARRAY_SIZE(map))
788 t->std = map[vc->norm];
789 tda9887_fixup_std(t);
790 tda9887_configure(t);
791 break;
792 }
793 case VIDIOC_S_STD:
794 {
795 v4l2_std_id *id = arg;
796
797 SWITCH_V4L2;
798 t->mode = T_ANALOG_TV;
799 t->std = *id;
800 tda9887_fixup_std(t);
801 tda9887_configure(t);
802 break;
803 }
804 case VIDIOC_S_FREQUENCY:
805 {
806 struct v4l2_frequency *f = arg;
807
808 SWITCH_V4L2;
809 if (V4L2_TUNER_ANALOG_TV == f->type) {
810 if (t->mode == T_ANALOG_TV)
811 return 0;
812 t->mode = T_ANALOG_TV;
813 }
814 if (V4L2_TUNER_RADIO == f->type) {
815 if (t->mode == T_RADIO)
816 return 0;
817 t->mode = T_RADIO;
818 }
819 tda9887_configure(t);
820 break;
821 }
822 case VIDIOC_G_TUNER:
823 {
824 static int AFC_BITS_2_kHz[] = {
825 -12500, -37500, -62500, -97500,
826 -112500, -137500, -162500, -187500,
827 187500, 162500, 137500, 112500,
828 97500 , 62500, 37500 , 12500
829 };
830 struct v4l2_tuner* tuner = arg;
831
832 if (t->mode == T_RADIO) {
833 __u8 reg = 0;
834 tuner->afc=0;
835 if (1 == i2c_master_recv(&t->client,&reg,1))
836 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
837 }
838 break;
839 }
840 case VIDIOC_S_TUNER:
841 {
842 struct v4l2_tuner* tuner = arg;
843
844 if (t->mode == T_RADIO) {
845 t->radio_mode = tuner->audmode;
846 tda9887_configure (t);
847 }
848 break;
849 }
850 case VIDIOC_LOG_STATUS:
851 {
852 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
853 break;
854 }
855 default:
856 /* nothing */
857 break;
858 }
859 return 0;
860} 575}
861 576
862static int tda9887_suspend(struct device * dev, pm_message_t state) 577static void tda9887_set_freq(struct i2c_client *client, unsigned int freq)
863{ 578{
864 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 579 tda9887_configure(client);
865 struct tda9887 *t = i2c_get_clientdata(c);
866
867 tda9887_dbg("suspend\n");
868 return 0;
869} 580}
870 581
871static int tda9887_resume(struct device * dev) 582int tda9887_tuner_init(struct i2c_client *c)
872{ 583{
873 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 584 struct tuner *t = i2c_get_clientdata(c);
874 struct tda9887 *t = i2c_get_clientdata(c);
875 585
876 tda9887_dbg("resume\n"); 586 strlcpy(c->name, "tda9887", sizeof(c->name));
877 tda9887_configure(t);
878 return 0;
879}
880 587
881/* ----------------------------------------------------------------------- */ 588 tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr,
882 589 t->i2c.driver->driver.name);
883static struct i2c_driver driver = {
884 .id = I2C_DRIVERID_TDA9887,
885 .attach_adapter = tda9887_probe,
886 .detach_client = tda9887_detach,
887 .command = tda9887_command,
888 .driver = {
889 .name = "tda9887",
890 .suspend = tda9887_suspend,
891 .resume = tda9887_resume,
892 },
893};
894static struct i2c_client client_template =
895{
896 .name = "tda9887",
897 .driver = &driver,
898};
899 590
900static int __init tda9887_init_module(void) 591 t->set_tv_freq = tda9887_set_freq;
901{ 592 t->set_radio_freq = tda9887_set_freq;
902 return i2c_add_driver(&driver); 593 t->standby = tda9887_standby;
903} 594 t->tuner_status=tda9887_tuner_status;
595 t->get_afc=tda9887_get_afc;
904 596
905static void __exit tda9887_cleanup_module(void) 597 return 0;
906{
907 i2c_del_driver(&driver);
908} 598}
909 599
910module_init(tda9887_init_module);
911module_exit(tda9887_cleanup_module);
912
913/* 600/*
914 * Overrides for Emacs so that we follow Linus's tabbing style. 601 * Overrides for Emacs so that we follow Linus's tabbing style.
915 * --------------------------------------------------------------------------- 602 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index cc4a38b34585..e95792fd70f8 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -215,6 +215,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
215 i2c_master_send(c,buffer,4); 215 i2c_master_send(c,buffer,4);
216 default_tuner_init(c); 216 default_tuner_init(c);
217 break; 217 break;
218 case TUNER_TDA9887:
219 tda9887_tuner_init(c);
220 break;
218 default: 221 default:
219 default_tuner_init(c); 222 default_tuner_init(c);
220 break; 223 break;
@@ -241,6 +244,8 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
241{ 244{
242 struct tuner *t = i2c_get_clientdata(c); 245 struct tuner *t = i2c_get_clientdata(c);
243 246
247 tuner_dbg("set addr for type %i\n", t->type);
248
244 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && 249 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
245 (t->mode_mask & tun_setup->mode_mask)) || 250 (t->mode_mask & tun_setup->mode_mask)) ||
246 tun_setup->addr == c->addr)) { 251 tun_setup->addr == c->addr)) {
@@ -436,6 +441,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
436 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ 441 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
437 t->audmode = V4L2_TUNER_MODE_STEREO; 442 t->audmode = V4L2_TUNER_MODE_STEREO;
438 t->mode_mask = T_UNINITIALIZED; 443 t->mode_mask = T_UNINITIALIZED;
444 t->tuner_status = tuner_status;
439 if (tuner_debug_old) { 445 if (tuner_debug_old) {
440 tuner_debug = tuner_debug_old; 446 tuner_debug = tuner_debug_old;
441 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); 447 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n");
@@ -462,10 +468,14 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
462 case 0x4b: 468 case 0x4b:
463 /* If chip is not tda8290, don't register. 469 /* If chip is not tda8290, don't register.
464 since it can be tda9887*/ 470 since it can be tda9887*/
465 if (tda8290_probe(&t->i2c) != 0) { 471 if (tda8290_probe(&t->i2c) == 0) {
466 tuner_dbg("chip at addr %x is not a tda8290\n", addr); 472 tuner_dbg("chip at addr %x is a tda8290\n", addr);
467 kfree(t); 473 } else {
468 return 0; 474 /* Default is being tda9887 */
475 t->type = TUNER_TDA9887;
476 t->mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
477 t->mode = T_STANDBY;
478 goto register_client;
469 } 479 }
470 break; 480 break;
471 case 0x60: 481 case 0x60:
@@ -592,6 +602,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
592 case TUNER_SET_STANDBY: 602 case TUNER_SET_STANDBY:
593 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) 603 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
594 return 0; 604 return 0;
605 t->mode = T_STANDBY;
595 if (t->standby) 606 if (t->standby)
596 t->standby (client); 607 t->standby (client);
597 break; 608 break;
@@ -604,6 +615,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
604 /* Should be implemented, since bttv calls it */ 615 /* Should be implemented, since bttv calls it */
605 tuner_dbg("VIDIOCSAUDIO not implemented.\n"); 616 tuner_dbg("VIDIOCSAUDIO not implemented.\n");
606 break; 617 break;
618 case TDA9887_SET_CONFIG:
619 {
620 int *i = arg;
621
622 t->tda9887_config = *i;
623 set_freq(client, t->tv_freq);
624 break;
625 }
607 /* --- v4l ioctls --- */ 626 /* --- v4l ioctls --- */
608 /* take care: bttv does userspace copying, we'll get a 627 /* take care: bttv does userspace copying, we'll get a
609 kernel pointer here... */ 628 kernel pointer here... */
@@ -744,6 +763,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
744 switch_v4l2(); 763 switch_v4l2();
745 764
746 tuner->type = t->mode; 765 tuner->type = t->mode;
766 if (t->get_afc)
767 tuner->afc=t->get_afc(client);
747 if (t->mode == V4L2_TUNER_ANALOG_TV) 768 if (t->mode == V4L2_TUNER_ANALOG_TV)
748 tuner->capability |= V4L2_TUNER_CAP_NORM; 769 tuner->capability |= V4L2_TUNER_CAP_NORM;
749 if (t->mode != V4L2_TUNER_RADIO) { 770 if (t->mode != V4L2_TUNER_RADIO) {
@@ -787,7 +808,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
787 break; 808 break;
788 } 809 }
789 case VIDIOC_LOG_STATUS: 810 case VIDIOC_LOG_STATUS:
790 tuner_status(client); 811 if (t->tuner_status)
812 t->tuner_status(client);
791 break; 813 break;
792 } 814 }
793 815
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
index 58cae6642977..9d9226cb6393 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/video/tuner-types.c
@@ -1421,6 +1421,11 @@ struct tunertype tuners[] = {
1421 .params = tuner_samsung_tcpg_6121p30a_params, 1421 .params = tuner_samsung_tcpg_6121p30a_params,
1422 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params), 1422 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params),
1423 }, 1423 },
1424 [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator.
1425 This chip is part of some modern tuners */
1426 .name = "Philips TDA988[5,6,7] IF PLL Demodulator",
1427 /* see tda9887.c for details */
1428 },
1424}; 1429};
1425 1430
1426unsigned const int tuner_count = ARRAY_SIZE(tuners); 1431unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 1601014c3f1e..2f7b00b08e88 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -25,6 +25,8 @@
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <media/tuner-types.h> 26#include <media/tuner-types.h>
27 27
28extern int tuner_debug;
29
28#define ADDR_UNSET (255) 30#define ADDR_UNSET (255)
29 31
30#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ 32#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
@@ -120,6 +122,7 @@
120 122
121#define TUNER_THOMSON_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ 123#define TUNER_THOMSON_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */
122#define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */ 124#define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */
125#define TUNER_TDA9887 74 /* This tuner should be used only internally */
123 126
124/* tv card specific */ 127/* tv card specific */
125#define TDA9887_PRESENT (1<<0) 128#define TDA9887_PRESENT (1<<0)
@@ -191,6 +194,10 @@ struct tuner {
191 194
192 int using_v4l2; 195 int using_v4l2;
193 196
197 /* used by tda9887 */
198 unsigned int tda9887_config;
199 unsigned char tda9887_data[4];
200
194 /* used by MT2032 */ 201 /* used by MT2032 */
195 unsigned int xogc; 202 unsigned int xogc;
196 unsigned int radio_if2; 203 unsigned int radio_if2;
@@ -207,6 +214,8 @@ struct tuner {
207 void (*set_radio_freq)(struct i2c_client *c, unsigned int freq); 214 void (*set_radio_freq)(struct i2c_client *c, unsigned int freq);
208 int (*has_signal)(struct i2c_client *c); 215 int (*has_signal)(struct i2c_client *c);
209 int (*is_stereo)(struct i2c_client *c); 216 int (*is_stereo)(struct i2c_client *c);
217 int (*get_afc)(struct i2c_client *c);
218 void (*tuner_status)(struct i2c_client *c);
210 void (*standby)(struct i2c_client *c); 219 void (*standby)(struct i2c_client *c);
211}; 220};
212 221
@@ -219,6 +228,7 @@ extern int tda8290_probe(struct i2c_client *c);
219extern int tea5767_tuner_init(struct i2c_client *c); 228extern int tea5767_tuner_init(struct i2c_client *c);
220extern int default_tuner_init(struct i2c_client *c); 229extern int default_tuner_init(struct i2c_client *c);
221extern int tea5767_autodetection(struct i2c_client *c); 230extern int tea5767_autodetection(struct i2c_client *c);
231extern int tda9887_tuner_init(struct i2c_client *c);
222 232
223#define tuner_warn(fmt, arg...) do {\ 233#define tuner_warn(fmt, arg...) do {\
224 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ 234 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \