diff options
-rw-r--r-- | drivers/media/video/Makefile | 4 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-i2c.c | 13 | ||||
-rw-r--r-- | drivers/media/video/tda9887.c | 461 | ||||
-rw-r--r-- | drivers/media/video/tuner-core.c | 32 | ||||
-rw-r--r-- | drivers/media/video/tuner-types.c | 5 | ||||
-rw-r--r-- | include/media/tuner.h | 10 |
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 | |||
6 | zr36067-objs := zoran_procfs.o zoran_device.o \ | 6 | zr36067-objs := zoran_procfs.o zoran_device.o \ |
7 | zoran_driver.o zoran_card.o | 7 | zoran_driver.o zoran_card.o |
8 | tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ | 8 | tuner-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 | ||
11 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o | 11 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o |
12 | 12 | ||
@@ -60,7 +60,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o | |||
60 | obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o | 60 | obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o |
61 | obj-$(CONFIG_TUNER_3036) += tuner-3036.o | 61 | obj-$(CONFIG_TUNER_3036) += tuner-3036.o |
62 | 62 | ||
63 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o | 63 | obj-$(CONFIG_VIDEO_TUNER) += tuner.o |
64 | obj-$(CONFIG_VIDEO_BUF) += video-buf.o | 64 | obj-$(CONFIG_VIDEO_BUF) += video-buf.o |
65 | obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o | 65 | obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o |
66 | obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o | 66 | obj-$(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 */ | ||
31 | static unsigned short normal_i2c[] = { | ||
32 | 0x84 >>1, | ||
33 | 0x86 >>1, | ||
34 | 0x96 >>1, | ||
35 | I2C_CLIENT_END, | ||
36 | }; | ||
37 | I2C_CLIENT_INSMOD; | ||
38 | |||
39 | /* insmod options */ | ||
40 | static unsigned int debug = 0; | ||
41 | module_param(debug, int, 0644); | ||
42 | MODULE_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 | |||
55 | struct 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 | ||
65 | struct tvnorm { | 37 | struct 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 | ||
73 | static struct i2c_driver driver; | ||
74 | static 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 | ||
284 | static void dump_read_message(struct tda9887 *t, unsigned char *buf) | 253 | static 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 | ||
312 | static void dump_write_message(struct tda9887 *t, unsigned char *buf) | 281 | static 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 | ||
408 | static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) | 377 | static 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); | |||
445 | module_param(qss, int, 0644); | 414 | module_param(qss, int, 0644); |
446 | module_param(adjust, int, 0644); | 415 | module_param(adjust, int, 0644); |
447 | 416 | ||
448 | static int tda9887_set_insmod(struct tda9887 *t, char *buf) | 417 | static 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 | ||
477 | static int tda9887_set_config(struct tda9887 *t, char *buf) | 446 | static 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 | ||
520 | static char pal[] = "--"; | 489 | static int tda9887_status(struct tuner *t) |
521 | static char secam[] = "--"; | ||
522 | static char ntsc[] = "-"; | ||
523 | |||
524 | module_param_string(pal, pal, sizeof(pal), 0644); | ||
525 | module_param_string(secam, secam, sizeof(secam), 0644); | ||
526 | module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); | ||
527 | |||
528 | static 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 | |||
638 | static 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 | ||
650 | static int tda9887_configure(struct tda9887 *t) | 501 | static 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 | ||
697 | static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | 548 | static 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 | ||
719 | static int tda9887_probe(struct i2c_adapter *adap) | 554 | static 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 | ||
726 | static int tda9887_detach(struct i2c_client *client) | 566 | if (1 == i2c_master_recv(&t->i2c,®,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) \ | 572 | static 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 | |||
742 | static int | ||
743 | tda9887_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,®,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 | ||
862 | static int tda9887_suspend(struct device * dev, pm_message_t state) | 577 | static 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 | ||
871 | static int tda9887_resume(struct device * dev) | 582 | int 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); | |
883 | static 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 | }; | ||
894 | static struct i2c_client client_template = | ||
895 | { | ||
896 | .name = "tda9887", | ||
897 | .driver = &driver, | ||
898 | }; | ||
899 | 590 | ||
900 | static 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 | ||
905 | static void __exit tda9887_cleanup_module(void) | 597 | return 0; |
906 | { | ||
907 | i2c_del_driver(&driver); | ||
908 | } | 598 | } |
909 | 599 | ||
910 | module_init(tda9887_init_module); | ||
911 | module_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 | ||
1426 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 1431 | unsigned 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 | ||
28 | extern 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); | |||
219 | extern int tea5767_tuner_init(struct i2c_client *c); | 228 | extern int tea5767_tuner_init(struct i2c_client *c); |
220 | extern int default_tuner_init(struct i2c_client *c); | 229 | extern int default_tuner_init(struct i2c_client *c); |
221 | extern int tea5767_autodetection(struct i2c_client *c); | 230 | extern int tea5767_autodetection(struct i2c_client *c); |
231 | extern 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, \ |