summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorAndrew de Quincy <devnull@localhost>2004-11-19 19:40:00 +0000
committerAndrew de Quincy <devnull@localhost>2004-11-19 19:40:00 +0000
commite544fb4c869d8f4c62b827890817da0e3e3ac358 (patch)
treea628d7184a2da009b51b30ab492077a79c1ade40 /linux
parent7175dee15a08b254c7847bf4bcba6552677eae7f (diff)
downloadmediapointer-dvb-s2-e544fb4c869d8f4c62b827890817da0e3e3ac358.tar.gz
mediapointer-dvb-s2-e544fb4c869d8f4c62b827890817da0e3e3ac358.tar.bz2
More support for the new Nexus-CA card
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c11
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.h6
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_v4l.c126
3 files changed, 107 insertions, 36 deletions
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 0199f35b9..975c9b124 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -118,7 +118,7 @@ static void init_av7110_av(struct av7110 *av7110)
/* handle different card types */
/* remaining inits according to card and frontend type */
- av7110->has_analog_tuner = 0;
+ av7110->analog_tuner_flags = 0;
av7110->current_input = 0;
if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
@@ -150,9 +150,11 @@ static void init_av7110_av(struct av7110 *av7110)
// switch DVB SCART on
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
- if (rgb_on)
+ if (rgb_on &&
+ (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
- //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
+ }
}
av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
@@ -1653,12 +1655,11 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
int i;
- // this calculation does not match the TDA6405TS datasheet!
div = (params->frequency + 36150000 + 31250) / 62500;
data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff;
- data[2] = 0xce; // this value does not match the TDA6405TS datasheet!
+ data[2] = 0xce;
if (params->frequency < 45000000)
return -EINVAL;
diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h
index 86752bc91..c2623c2a5 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.h
+++ b/linux/drivers/media/dvb/ttpci/av7110.h
@@ -35,6 +35,10 @@
#include <media/saa7146_vv.h>
+#define ANALOG_TUNER_VES1820 1
+#define ANALOG_TUNER_STV0297 2
+#define ANALOG_TUNER_VBI 0x100
+
extern int av7110_debug;
#define dprintk(level,args...) \
@@ -83,7 +87,7 @@ struct av7110 {
char *card_name;
/* support for analog module of dvb-c */
- int has_analog_tuner;
+ int analog_tuner_flags;
int current_input;
u32 current_freq;
diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c
index 8ac2f6558..997cd82a6 100644
--- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -90,10 +90,8 @@ static struct v4l2_input inputs[2] = {
}
};
-/* for Siemens DVB-C analog module: (taken from ves1820.c) */
-static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
+static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
{
- u8 addr = 0x09;
u8 buf[] = { 0x00, reg, data };
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
@@ -104,6 +102,17 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
return 0;
}
+static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
+{
+ u8 buf [] = { reg, data };
+ struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
+
+ if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
+ return -1;
+ return 0;
+}
+
+
static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
{
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
@@ -115,12 +124,7 @@ static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
return 0;
}
-
-/**
- * set up the downconverter frequency divisor for a
- * reference clock comparision frequency of 62.5 kHz.
- */
-static int tuner_set_tv_freq(struct saa7146_dev *dev, u32 freq)
+static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{
u32 div;
u8 config;
@@ -149,6 +153,34 @@ static int tuner_set_tv_freq(struct saa7146_dev *dev, u32 freq)
return tuner_write(dev, 0x61, buf);
}
+static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
+{
+ u32 div;
+ u8 data[4];
+
+ div = (freq + 38900000 + 31250) / 62500;
+
+ data[0] = (div >> 8) & 0x7f;
+ data[1] = div & 0xff;
+ data[2] = 0xce;
+
+ if (freq < 45000000)
+ return -EINVAL;
+ else if (freq < 137000000)
+ data[3] = 0x01;
+ else if (freq < 403000000)
+ data[3] = 0x02;
+ else if (freq < 860000000)
+ data[3] = 0x04;
+ else
+ return -EINVAL;
+
+ stv0297_writereg(dev, 0x1C, 0x87, 0x78);
+ stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
+ return tuner_write(dev, 0x63, data);
+}
+
+
static struct saa7146_standard analog_standard[];
static struct saa7146_standard dvb_standard[];
@@ -166,7 +198,6 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
struct saa7146_vv *vv = dev->vv_data;
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
u16 adswitch;
- u8 band = 0;
int source, sync, err;
dprintk(4, "%p\n", av7110);
@@ -179,10 +210,9 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
vv->ov_suspend = NULL;
}
}
-
+
if (0 != av7110->current_input) {
adswitch = 1;
- band = 0x60; /* analog band */
source = SAA7146_HPS_SOURCE_PORT_B;
sync = SAA7146_HPS_SYNC_PORT_B;
memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
@@ -193,9 +223,16 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
+
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+ if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
+ dprintk(1, "setting band in demodulator failed.\n");
+ } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+ saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
+ }
} else {
adswitch = 0;
- band = 0x20; /* digital band */
source = SAA7146_HPS_SOURCE_PORT_A;
sync = SAA7146_HPS_SYNC_PORT_A;
memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
@@ -206,15 +243,20 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
+
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+ if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
+ dprintk(1, "setting band in demodulator failed.\n");
+ } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+ saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
+ }
}
/* hmm, this does not do anything!? */
if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
dprintk(1, "ADSwitch error\n");
- if (ves1820_writereg(dev, 0x0f, band))
- dprintk(1, "setting band in demodulator failed.\n");
-
saa7146_set_hps_source_and_sync(dev, source, sync);
if (vv->ov_suspend != NULL) {
@@ -240,7 +282,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
- if (!av7110->has_analog_tuner || t->index != 0)
+ if (!av7110->analog_tuner_flags || t->index != 0)
return -EINVAL;
memset(t, 0, sizeof(*t));
@@ -283,7 +325,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
u16 fm_matrix, src;
dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
- if (!av7110->has_analog_tuner || av7110->current_input != 1)
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL;
switch (t->audmode) {
@@ -320,7 +362,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
- if (!av7110->has_analog_tuner || av7110->current_input != 1)
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL;
memset(f, 0, sizeof(*f));
@@ -334,7 +376,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
- if (!av7110->has_analog_tuner || av7110->current_input != 1)
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL;
if (V4L2_TUNER_ANALOG_TV != f->type)
@@ -344,7 +386,11 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
/* tune in desired frequency */
- tuner_set_tv_freq(dev, f->frequency);
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+ ves1820_set_tv_freq(dev, f->frequency);
+ } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+ stv0297_set_tv_freq(dev, f->frequency);
+ }
av7110->current_freq = f->frequency;
msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
@@ -359,7 +405,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
- if (av7110->has_analog_tuner ) {
+ if (av7110->analog_tuner_flags) {
if (i->index < 0 || i->index >= 2)
return -EINVAL;
} else {
@@ -384,7 +430,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
- if (!av7110->has_analog_tuner )
+ if (!av7110->analog_tuner_flags)
return 0;
if (input < 0 || input >= 2)
@@ -526,7 +572,27 @@ int av7110_init_analog_module(struct av7110 *av7110)
INFO(("saa7113 not accessible.\n"));
} else {
u8 *i = saa7113_init_regs;
- av7110->has_analog_tuner = 1;
+
+ if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
+ /* Fujitsu/Siemens DVB-Cable */
+ av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
+ } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
+ /* Hauppauge/TT DVB-C premium */
+ av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
+ } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
+ /* Hauppauge/TT DVB-C premium */
+ av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
+ }
+
+ /* setup for DVB by default */
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+ if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
+ dprintk(1, "setting band in demodulator failed.\n");
+ } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+ saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+ saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
+ }
+
/* init the saa7113 */
while (*i != 0xff) {
if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
@@ -577,7 +643,7 @@ int av7110_init_v4l(struct av7110 *av7110)
/* special case DVB-C: these cards have an analog tuner
plus need some special handling, so we have separate
saa7146_ext_vv data for these... */
- if (av7110->has_analog_tuner)
+ if (av7110->analog_tuner_flags)
ret = saa7146_vv_init(dev, &av7110_vv_data_c);
else
ret = saa7146_vv_init(dev, &av7110_vv_data_st);
@@ -592,12 +658,12 @@ int av7110_init_v4l(struct av7110 *av7110)
saa7146_vv_release(dev);
return -ENODEV;
}
- if (av7110->has_analog_tuner) {
+ if (av7110->analog_tuner_flags) {
if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
ERR(("cannot register vbi v4l2 device. skipping.\n"));
- } else
- /* we use this to remember that this dvb-c card can do vbi */
- av7110->has_analog_tuner = 2;
+ } else {
+ av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
+ }
}
return 0;
}
@@ -605,7 +671,7 @@ int av7110_init_v4l(struct av7110 *av7110)
int av7110_exit_v4l(struct av7110 *av7110)
{
saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
- if (2 == av7110->has_analog_tuner)
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
return 0;
}