aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/pci/bt8xx/Kconfig3
-rw-r--r--drivers/media/pci/bt8xx/bttv-cards.c317
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c6
-rw-r--r--drivers/media/pci/bt8xx/bttvp.h14
4 files changed, 125 insertions, 215 deletions
diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig
index 496cf6b2dc43..4a93f6ded100 100644
--- a/drivers/media/pci/bt8xx/Kconfig
+++ b/drivers/media/pci/bt8xx/Kconfig
@@ -4,12 +4,15 @@ config VIDEO_BT848
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select VIDEOBUF_DMA_SG 5 select VIDEOBUF_DMA_SG
6 depends on RC_CORE 6 depends on RC_CORE
7 depends on MEDIA_RADIO_SUPPORT
7 select VIDEO_TUNER 8 select VIDEO_TUNER
8 select VIDEO_TVEEPROM 9 select VIDEO_TVEEPROM
9 select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT 10 select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT
10 select VIDEO_TVAUDIO if MEDIA_SUBDRV_AUTOSELECT 11 select VIDEO_TVAUDIO if MEDIA_SUBDRV_AUTOSELECT
11 select VIDEO_TDA7432 if MEDIA_SUBDRV_AUTOSELECT 12 select VIDEO_TDA7432 if MEDIA_SUBDRV_AUTOSELECT
12 select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT 13 select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT
14 select RADIO_ADAPTERS
15 select RADIO_TEA575X
13 ---help--- 16 ---help---
14 Support for BT848 based frame grabber/overlay boards. This includes 17 Support for BT848 based frame grabber/overlay boards. This includes
15 the Miro, Hauppauge and STB boards. Please read the material in 18 the Miro, Hauppauge and STB boards. Please read the material in
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index c5186778fc8c..4654fb65ca21 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -84,8 +84,7 @@ static void gv800s_init(struct bttv *btv);
84static void td3116_muxsel(struct bttv *btv, unsigned int input); 84static void td3116_muxsel(struct bttv *btv, unsigned int input);
85 85
86static int terratec_active_radio_upgrade(struct bttv *btv); 86static int terratec_active_radio_upgrade(struct bttv *btv);
87static int tea5757_read(struct bttv *btv); 87static int tea575x_init(struct bttv *btv);
88static int tea5757_write(struct bttv *btv, int value);
89static void identify_by_eeprom(struct bttv *btv, 88static void identify_by_eeprom(struct bttv *btv,
90 unsigned char eeprom_data[256]); 89 unsigned char eeprom_data[256]);
91static int pvr_boot(struct bttv *btv); 90static int pvr_boot(struct bttv *btv);
@@ -3085,12 +3084,12 @@ static void miro_pinnacle_gpio(struct bttv *btv)
3085 if (0 == (gpio & 0x20)) { 3084 if (0 == (gpio & 0x20)) {
3086 btv->has_radio = 1; 3085 btv->has_radio = 1;
3087 if (!miro_fmtuner[id]) { 3086 if (!miro_fmtuner[id]) {
3088 btv->has_matchbox = 1; 3087 btv->has_tea575x = 1;
3089 btv->mbox_we = (1<<6); 3088 btv->tea_gpio.wren = 6;
3090 btv->mbox_most = (1<<7); 3089 btv->tea_gpio.most = 7;
3091 btv->mbox_clk = (1<<8); 3090 btv->tea_gpio.clk = 8;
3092 btv->mbox_data = (1<<9); 3091 btv->tea_gpio.data = 9;
3093 btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9); 3092 tea575x_init(btv);
3094 } 3093 }
3095 } else { 3094 } else {
3096 btv->has_radio = 0; 3095 btv->has_radio = 0;
@@ -3104,7 +3103,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
3104 pr_info("%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", 3103 pr_info("%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
3105 btv->c.nr, id+1, btv->tuner_type, 3104 btv->c.nr, id+1, btv->tuner_type,
3106 !btv->has_radio ? "no" : 3105 !btv->has_radio ? "no" :
3107 (btv->has_matchbox ? "matchbox" : "fmtuner"), 3106 (btv->has_tea575x ? "tea575x" : "fmtuner"),
3108 (-1 == msp) ? "no" : "yes"); 3107 (-1 == msp) ? "no" : "yes");
3109 } else { 3108 } else {
3110 /* new cards with microtune tuner */ 3109 /* new cards with microtune tuner */
@@ -3382,12 +3381,12 @@ void bttv_init_card2(struct bttv *btv)
3382 break; 3381 break;
3383 case BTTV_BOARD_VHX: 3382 case BTTV_BOARD_VHX:
3384 btv->has_radio = 1; 3383 btv->has_radio = 1;
3385 btv->has_matchbox = 1; 3384 btv->has_tea575x = 1;
3386 btv->mbox_we = 0x20; 3385 btv->tea_gpio.wren = 5;
3387 btv->mbox_most = 0; 3386 btv->tea_gpio.most = 6;
3388 btv->mbox_clk = 0x08; 3387 btv->tea_gpio.clk = 3;
3389 btv->mbox_data = 0x10; 3388 btv->tea_gpio.data = 4;
3390 btv->mbox_mask = 0x38; 3389 tea575x_init(btv);
3391 break; 3390 break;
3392 case BTTV_BOARD_VOBIS_BOOSTAR: 3391 case BTTV_BOARD_VOBIS_BOOSTAR:
3393 case BTTV_BOARD_TERRATV: 3392 case BTTV_BOARD_TERRATV:
@@ -3745,33 +3744,112 @@ static void hauppauge_eeprom(struct bttv *btv)
3745 btv->radio_uses_msp_demodulator = 1; 3744 btv->radio_uses_msp_demodulator = 1;
3746} 3745}
3747 3746
3748static int terratec_active_radio_upgrade(struct bttv *btv) 3747/* ----------------------------------------------------------------------- */
3748
3749static void bttv_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
3750{
3751 struct bttv *btv = tea->private_data;
3752 struct bttv_tea575x_gpio gpio = btv->tea_gpio;
3753 u16 val = 0;
3754
3755 val |= (pins & TEA575X_DATA) ? (1 << gpio.data) : 0;
3756 val |= (pins & TEA575X_CLK) ? (1 << gpio.clk) : 0;
3757 val |= (pins & TEA575X_WREN) ? (1 << gpio.wren) : 0;
3758
3759 gpio_bits((1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren), val);
3760 if (btv->mbox_ior) {
3761 /* IOW and CSEL active */
3762 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3763 udelay(5);
3764 /* all inactive */
3765 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3766 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3767 }
3768}
3769
3770static u8 bttv_tea575x_get_pins(struct snd_tea575x *tea)
3749{ 3771{
3750 int freq; 3772 struct bttv *btv = tea->private_data;
3773 struct bttv_tea575x_gpio gpio = btv->tea_gpio;
3774 u8 ret = 0;
3775 u16 val;
3776
3777 if (btv->mbox_ior) {
3778 /* IOR and CSEL active */
3779 gpio_bits(btv->mbox_ior | btv->mbox_csel, 0);
3780 udelay(5);
3781 }
3782 val = gpio_read();
3783 if (btv->mbox_ior) {
3784 /* all inactive */
3785 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3786 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3787 }
3788
3789 if (val & (1 << gpio.data))
3790 ret |= TEA575X_DATA;
3791 if (val & (1 << gpio.most))
3792 ret |= TEA575X_MOST;
3793
3794 return ret;
3795}
3796
3797static void bttv_tea575x_set_direction(struct snd_tea575x *tea, bool output)
3798{
3799 struct bttv *btv = tea->private_data;
3800 struct bttv_tea575x_gpio gpio = btv->tea_gpio;
3801 u32 mask = (1 << gpio.clk) | (1 << gpio.wren) | (1 << gpio.data) |
3802 (1 << gpio.most);
3803
3804 if (output)
3805 gpio_inout(mask, (1 << gpio.data) | (1 << gpio.clk) |
3806 (1 << gpio.wren));
3807 else
3808 gpio_inout(mask, (1 << gpio.clk) | (1 << gpio.wren));
3809}
3810
3811static struct snd_tea575x_ops bttv_tea_ops = {
3812 .set_pins = bttv_tea575x_set_pins,
3813 .get_pins = bttv_tea575x_get_pins,
3814 .set_direction = bttv_tea575x_set_direction,
3815};
3816
3817static int tea575x_init(struct bttv *btv)
3818{
3819 btv->tea.private_data = btv;
3820 btv->tea.ops = &bttv_tea_ops;
3821 if (!snd_tea575x_hw_init(&btv->tea)) {
3822 pr_info("%d: detected TEA575x radio\n", btv->c.nr);
3823 btv->tea.mute = false;
3824 return 0;
3825 }
3751 3826
3827 btv->has_tea575x = 0;
3828 btv->has_radio = 0;
3829
3830 return -ENODEV;
3831}
3832
3833/* ----------------------------------------------------------------------- */
3834
3835static int terratec_active_radio_upgrade(struct bttv *btv)
3836{
3752 btv->has_radio = 1; 3837 btv->has_radio = 1;
3753 btv->has_matchbox = 1; 3838 btv->has_tea575x = 1;
3754 btv->mbox_we = 0x10; 3839 btv->tea_gpio.wren = 4;
3755 btv->mbox_most = 0x20; 3840 btv->tea_gpio.most = 5;
3756 btv->mbox_clk = 0x08; 3841 btv->tea_gpio.clk = 3;
3757 btv->mbox_data = 0x04; 3842 btv->tea_gpio.data = 2;
3758 btv->mbox_mask = 0x3c;
3759 3843
3760 btv->mbox_iow = 1 << 8; 3844 btv->mbox_iow = 1 << 8;
3761 btv->mbox_ior = 1 << 9; 3845 btv->mbox_ior = 1 << 9;
3762 btv->mbox_csel = 1 << 10; 3846 btv->mbox_csel = 1 << 10;
3763 3847
3764 freq=88000/62.5; 3848 if (!tea575x_init(btv)) {
3765 tea5757_write(btv, 5 * freq + 0x358); /* write 0x1ed8 */
3766 if (0x1ed8 == tea5757_read(btv)) {
3767 pr_info("%d: Terratec Active Radio Upgrade found\n", btv->c.nr); 3849 pr_info("%d: Terratec Active Radio Upgrade found\n", btv->c.nr);
3768 btv->has_radio = 1; 3850 btv->has_saa6588 = 1;
3769 btv->has_saa6588 = 1;
3770 btv->has_matchbox = 1;
3771 } else {
3772 btv->has_radio = 0;
3773 btv->has_matchbox = 0;
3774 } 3851 }
3852
3775 return 0; 3853 return 0;
3776} 3854}
3777 3855
@@ -4292,181 +4370,6 @@ init_PCI8604PW(struct bttv *btv)
4292 } 4370 }
4293} 4371}
4294 4372
4295
4296
4297/* ----------------------------------------------------------------------- */
4298/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
4299/*
4300 * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
4301 * This code is placed under the terms of the GNU General Public License
4302 *
4303 * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
4304 */
4305
4306static void bus_low(struct bttv *btv, int bit)
4307{
4308 if (btv->mbox_ior) {
4309 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4310 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4311 udelay(5);
4312 }
4313
4314 gpio_bits(bit,0);
4315 udelay(5);
4316
4317 if (btv->mbox_ior) {
4318 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
4319 udelay(5);
4320 }
4321}
4322
4323static void bus_high(struct bttv *btv, int bit)
4324{
4325 if (btv->mbox_ior) {
4326 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4327 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4328 udelay(5);
4329 }
4330
4331 gpio_bits(bit,bit);
4332 udelay(5);
4333
4334 if (btv->mbox_ior) {
4335 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
4336 udelay(5);
4337 }
4338}
4339
4340static int bus_in(struct bttv *btv, int bit)
4341{
4342 if (btv->mbox_ior) {
4343 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4344 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4345 udelay(5);
4346
4347 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
4348 udelay(5);
4349 }
4350 return gpio_read() & (bit);
4351}
4352
4353/* TEA5757 register bits */
4354#define TEA_FREQ 0:14
4355#define TEA_BUFFER 15:15
4356
4357#define TEA_SIGNAL_STRENGTH 16:17
4358
4359#define TEA_PORT1 18:18
4360#define TEA_PORT0 19:19
4361
4362#define TEA_BAND 20:21
4363#define TEA_BAND_FM 0
4364#define TEA_BAND_MW 1
4365#define TEA_BAND_LW 2
4366#define TEA_BAND_SW 3
4367
4368#define TEA_MONO 22:22
4369#define TEA_ALLOW_STEREO 0
4370#define TEA_FORCE_MONO 1
4371
4372#define TEA_SEARCH_DIRECTION 23:23
4373#define TEA_SEARCH_DOWN 0
4374#define TEA_SEARCH_UP 1
4375
4376#define TEA_STATUS 24:24
4377#define TEA_STATUS_TUNED 0
4378#define TEA_STATUS_SEARCHING 1
4379
4380/* Low-level stuff */
4381static int tea5757_read(struct bttv *btv)
4382{
4383 unsigned long timeout;
4384 int value = 0;
4385 int i;
4386
4387 /* better safe than sorry */
4388 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we);
4389
4390 if (btv->mbox_ior) {
4391 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4392 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4393 udelay(5);
4394 }
4395
4396 if (bttv_gpio)
4397 bttv_gpio_tracking(btv,"tea5757 read");
4398
4399 bus_low(btv,btv->mbox_we);
4400 bus_low(btv,btv->mbox_clk);
4401
4402 udelay(10);
4403 timeout= jiffies + msecs_to_jiffies(1000);
4404
4405 /* wait for DATA line to go low; error if it doesn't */
4406 while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
4407 schedule();
4408 if (bus_in(btv,btv->mbox_data)) {
4409 pr_warn("%d: tea5757: read timeout\n", btv->c.nr);
4410 return -1;
4411 }
4412
4413 dprintk("%d: tea5757:", btv->c.nr);
4414 for (i = 0; i < 24; i++) {
4415 udelay(5);
4416 bus_high(btv,btv->mbox_clk);
4417 udelay(5);
4418 dprintk_cont("%c",
4419 bus_in(btv, btv->mbox_most) == 0 ? 'T' : '-');
4420 bus_low(btv,btv->mbox_clk);
4421 value <<= 1;
4422 value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */
4423 dprintk_cont("%c",
4424 bus_in(btv, btv->mbox_most) == 0 ? 'S' : 'M');
4425 }
4426 dprintk_cont("\n");
4427 dprintk("%d: tea5757: read 0x%X\n", btv->c.nr, value);
4428 return value;
4429}
4430
4431static int tea5757_write(struct bttv *btv, int value)
4432{
4433 int i;
4434 int reg = value;
4435
4436 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data);
4437
4438 if (btv->mbox_ior) {
4439 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4440 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4441 udelay(5);
4442 }
4443 if (bttv_gpio)
4444 bttv_gpio_tracking(btv,"tea5757 write");
4445
4446 dprintk("%d: tea5757: write 0x%X\n", btv->c.nr, value);
4447 bus_low(btv,btv->mbox_clk);
4448 bus_high(btv,btv->mbox_we);
4449 for (i = 0; i < 25; i++) {
4450 if (reg & 0x1000000)
4451 bus_high(btv,btv->mbox_data);
4452 else
4453 bus_low(btv,btv->mbox_data);
4454 reg <<= 1;
4455 bus_high(btv,btv->mbox_clk);
4456 udelay(10);
4457 bus_low(btv,btv->mbox_clk);
4458 udelay(10);
4459 }
4460 bus_low(btv,btv->mbox_we); /* unmute !!! */
4461 return 0;
4462}
4463
4464void tea5757_set_freq(struct bttv *btv, unsigned short freq)
4465{
4466 dprintk("tea5757_set_freq %d\n",freq);
4467 tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
4468}
4469
4470/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas] 4373/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
4471 * 4374 *
4472 * This is needed because rv605 don't use a normal multiplex, but a crosspoint 4375 * This is needed because rv605 don't use a normal multiplex, but a crosspoint
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 6eed8f75c13c..e7f8aded35f8 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -1874,8 +1874,10 @@ static void bttv_set_frequency(struct bttv *btv, const struct v4l2_frequency *f)
1874 if (new_freq.type == V4L2_TUNER_RADIO) { 1874 if (new_freq.type == V4L2_TUNER_RADIO) {
1875 radio_enable(btv); 1875 radio_enable(btv);
1876 btv->radio_freq = new_freq.frequency; 1876 btv->radio_freq = new_freq.frequency;
1877 if (btv->has_matchbox) 1877 if (btv->has_tea575x) {
1878 tea5757_set_freq(btv, btv->radio_freq); 1878 btv->tea.freq = btv->radio_freq;
1879 snd_tea575x_set_freq(&btv->tea);
1880 }
1879 } else { 1881 } else {
1880 btv->tv_freq = new_freq.frequency; 1882 btv->tv_freq = new_freq.frequency;
1881 } 1883 }
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index e6e2c60f9e3e..bc048c586b1f 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -42,6 +42,7 @@
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43#include <media/rc-core.h> 43#include <media/rc-core.h>
44#include <media/ir-kbd-i2c.h> 44#include <media/ir-kbd-i2c.h>
45#include <media/tea575x.h>
45 46
46#include "bt848.h" 47#include "bt848.h"
47#include "bttv.h" 48#include "bttv.h"
@@ -359,6 +360,10 @@ struct bttv_suspend_state {
359 struct bttv_buffer *vbi; 360 struct bttv_buffer *vbi;
360}; 361};
361 362
363struct bttv_tea575x_gpio {
364 u8 data, clk, wren, most;
365};
366
362struct bttv { 367struct bttv {
363 struct bttv_core c; 368 struct bttv_core c;
364 369
@@ -445,12 +450,9 @@ struct bttv {
445 450
446 /* miro/pinnacle + Aimslab VHX 451 /* miro/pinnacle + Aimslab VHX
447 philips matchbox (tea5757 radio tuner) support */ 452 philips matchbox (tea5757 radio tuner) support */
448 int has_matchbox; 453 int has_tea575x;
449 int mbox_we; 454 struct bttv_tea575x_gpio tea_gpio;
450 int mbox_data; 455 struct snd_tea575x tea;
451 int mbox_clk;
452 int mbox_most;
453 int mbox_mask;
454 456
455 /* ISA stuff (Terratec Active Radio Upgrade) */ 457 /* ISA stuff (Terratec Active Radio Upgrade) */
456 int mbox_ior; 458 int mbox_ior;