diff options
author | Andrew de Quincy <devnull@localhost> | 2004-11-19 19:40:00 +0000 |
---|---|---|
committer | Andrew de Quincy <devnull@localhost> | 2004-11-19 19:40:00 +0000 |
commit | e544fb4c869d8f4c62b827890817da0e3e3ac358 (patch) | |
tree | a628d7184a2da009b51b30ab492077a79c1ade40 /linux | |
parent | 7175dee15a08b254c7847bf4bcba6552677eae7f (diff) | |
download | mediapointer-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.c | 11 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.h | 6 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110_v4l.c | 126 |
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; } |