X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Fttpci%2Fav7110.c;h=11e9ba7681d66d7ec1d8866986250182d9824fba;hb=44c40f29869a02dd430beb7fed0b6ca7d8ef5e54;hp=41ade3783a034342e970c9c45d1ceba62dd0550c;hpb=8d40237c730b8be87c1b80a5d96b9c603fefa829;p=linux-2.6.git diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 41ade3783..11e9ba768 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include @@ -51,14 +50,18 @@ #include #include #include -#include #include #include #include +#include "dvb_i2c.h" #include "dvb_frontend.h" +#include "dvb_functions.h" + + + #define DEBUG_VARIABLE av7110_debug #include "ttpci-eeprom.h" #include "av7110.h" @@ -67,112 +70,33 @@ #include "av7110_ca.h" #include "av7110_ipack.h" -int av7110_debug; - -static int vidmode=CVBS_RGB_OUT; -static int pids_off; -static int adac=DVB_ADAC_TI; -static int hw_sections; -static int rgb_on; -static int volume = 255; - -module_param_named(debug, av7110_debug, int, 0644); -MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); -module_param(vidmode, int, 0444); -MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC"); -module_param(pids_off, int, 0444); -MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed"); -module_param(adac, int, 0444); -MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)"); -module_param(hw_sections, int, 0444); -MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware"); -module_param(rgb_on, int, 0444); -MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" - " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); -module_param(volume, int, 0444); -MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); static void restart_feeds(struct av7110 *av7110); -static int av7110_num = 0; - -#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \ -{\ - if (fe_func != NULL) { \ - av7110_copy = fe_func; \ - fe_func = av7110_func; \ - } \ -} - - -static void init_av7110_av(struct av7110 *av7110) -{ - struct saa7146_dev *dev=av7110->dev; - - /* set internal volume control to maximum */ - av7110->adac_type = DVB_ADAC_TI; - av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); - - av7710_set_video_mode(av7110, vidmode); - - /* handle different card types */ - /* remaining inits according to card and frontend type */ - 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", - av7110->dvb_adapter->num); - av7110->adac_type = DVB_ADAC_CRYSTAL; - i2c_writereg(av7110, 0x20, 0x01, 0xd2); - i2c_writereg(av7110, 0x20, 0x02, 0x49); - i2c_writereg(av7110, 0x20, 0x03, 0x00); - i2c_writereg(av7110, 0x20, 0x04, 0x00); +int av7110_debug = 0; - /** - * some special handling for the Siemens DVB-C cards... - */ - } else if (0 == av7110_init_analog_module(av7110)) { - /* done. */ - } - else if (dev->pci->subsystem_vendor == 0x110a) { - printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n", - av7110->dvb_adapter->num); - av7110->adac_type = DVB_ADAC_NONE; - } - else { - av7110->adac_type = adac; - printk("dvb-ttpci: adac type set to %d @ card %d\n", - av7110->dvb_adapter->num, av7110->adac_type); - } +static int vidmode=CVBS_RGB_OUT; +static int pids_off; +static int adac=DVB_ADAC_TI; +static int hw_sections = 0; +static int rgb_on = 0; - if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { - // 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 && - (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 - } - } +int av7110_num = 0; - av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); - av7110_setup_irc_config(av7110, 0); -} static void recover_arm(struct av7110 *av7110) { - dprintk(4, "%p\n",av7110); + DEB_EE(("av7110: %p\n",av7110)); av7110_bootarm(av7110); - msleep(100); + dvb_delay(100); restart_feeds(av7110); av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); } static void arm_error(struct av7110 *av7110) { - dprintk(4, "%p\n",av7110); + DEB_EE(("av7110: %p\n",av7110)); av7110->arm_errors++; av7110->arm_ready=0; @@ -182,22 +106,17 @@ static void arm_error(struct av7110 *av7110) static int arm_thread(void *data) { struct av7110 *av7110 = data; + unsigned long timeout; u16 newloops = 0; - int timeout; - dprintk(4, "%p\n",av7110); + DEB_EE(("av7110: %p\n",av7110)); - lock_kernel (); - daemonize ("arm_mon"); - sigfillset (¤t->blocked); - unlock_kernel (); - + dvb_kernel_thread_setup ("arm_mon"); av7110->arm_thread = current; - for (;;) { - timeout = wait_event_interruptible_timeout(av7110->arm_wait, - av7110->arm_rmmod, 5 * HZ); - if (-ERESTARTSYS == timeout || av7110->arm_rmmod) { + while (1) { + timeout = wait_event_interruptible_timeout(av7110->arm_wait,0 != av7110->arm_rmmod, 5*HZ); + if (-ERESTARTSYS == timeout || 0 != av7110->arm_rmmod) { /* got signal or told to quit*/ break; } @@ -212,13 +131,10 @@ static int arm_thread(void *data) up(&av7110->dcomlock); if (newloops==av7110->arm_loops) { - printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", + printk(KERN_ERR "av7110%d: ARM crashed!\n", av7110->dvb_adapter->num); arm_error(av7110); - av7710_set_video_mode(av7110, vidmode); - - init_av7110_av(av7110); if (down_interruptible(&av7110->dcomlock)) break; @@ -244,7 +160,7 @@ void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config) { static struct av7110 *last; - dprintk(4, "%p\n",av7110); + DEB_EE(("av7110: %p\n",av7110)); if (!av7110) av7110 = last; @@ -261,27 +177,27 @@ static void (*irc_handler)(u32); void av7110_register_irc_handler(void (*func)(u32)) { - dprintk(4, "registering %p\n", func); + DEB_EE(("registering %p\n", func)); irc_handler = func; } void av7110_unregister_irc_handler(void (*func)(u32)) { - dprintk(4, "unregistering %p\n", func); + DEB_EE(("unregistering %p\n", func)); irc_handler = NULL; } -static void run_handlers(unsigned long ircom) +void run_handlers(unsigned long ircom) { if (irc_handler != NULL) (*irc_handler)((u32) ircom); } -static DECLARE_TASKLET(irtask, run_handlers, 0); +DECLARE_TASKLET(irtask,run_handlers,0); -static void IR_handle(struct av7110 *av7110, u32 ircom) +void IR_handle(struct av7110 *av7110, u32 ircom) { - dprintk(4, "ircommand = %08x\n", ircom); + DEB_S(("av7110: ircommand = %08x\n", ircom)); irtask.data = (unsigned long) ircom; tasklet_schedule(&irtask); } @@ -290,12 +206,14 @@ static void IR_handle(struct av7110 *av7110, u32 ircom) * IRQ handling ****************************************************************************/ -static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len, +static inline int DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len, u8 * buffer2, size_t buffer2_len, struct dvb_demux_filter *dvbdmxfilter, enum dmx_success success, struct av7110 *av7110) { + DEB_INT(("av7110: %p\n",av7110)); + if (!dvbdmxfilter->feed->demux->dmx.frontend) return 0; if (dvbdmxfilter->feed->demux->dmx.frontend->source==DMX_MEMORY_FE) @@ -355,11 +273,12 @@ static void debiirq (unsigned long data) int type=av7110->debitype; int handle=(type>>8)&0x1f; -// dprintk(4, "%p\n",av7110); +// DEB_EE(("av7110: %p\n",av7110)); print_time("debi"); - SAA7146_IER_DISABLE(av7110->dev, MASK_19); - SAA7146_ISR_CLEAR(av7110->dev, MASK_19); + saa7146_write(av7110->dev, IER, + saa7146_read(av7110->dev, IER) & ~MASK_19 ); + saa7146_write(av7110->dev, ISR, MASK_19 ); if (type==-1) { printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", @@ -486,8 +405,10 @@ static void gpioirq (unsigned long data) u32 rxbuf, txbuf; int len; + //printk("GPIO0 irq\n"); + if (av7110->debitype !=-1) - printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", + printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", jiffies, saa7146_read(av7110->dev, PSR), saa7146_read(av7110->dev, SSR)); @@ -495,8 +416,9 @@ static void gpioirq (unsigned long data) ARM_ClearIrq(av7110); - SAA7146_IER_DISABLE(av7110->dev, MASK_19); - SAA7146_ISR_CLEAR(av7110->dev, MASK_19); + saa7146_write(av7110->dev, IER, + saa7146_read(av7110->dev, IER) & ~MASK_19 ); + saa7146_write(av7110->dev, ISR, MASK_19 ); av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); @@ -504,10 +426,10 @@ static void gpioirq (unsigned long data) txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); len = (av7110->debilen + 3) & ~3; -// dprintk(8, "GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen); +// DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen)); print_time("gpio"); -// dprintk(8, "GPIO0 irq %02x\n", av7110->debitype&0xff); +// DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff)); switch (av7110->debitype&0xff) { case DATA_TS_PLAY: @@ -526,10 +448,10 @@ static void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); av7110->video_size.h = h_ar & 0xfff; - dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", + DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", av7110->video_size.w, av7110->video_size.h, - av7110->video_size.aspect_ratio); + av7110->video_size.aspect_ratio)); event.type = VIDEO_EVENT_SIZE_CHANGED; event.u.size.w = av7110->video_size.w; @@ -582,7 +504,7 @@ static void gpioirq (unsigned long data) wake_up(&cibuf->queue); iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - saa7146_wait_for_debi_done(av7110->dev, 0); + saa7146_wait_for_debi_done(av7110->dev); saa7146_write(av7110->dev, IER, saa7146_read(av7110->dev, IER) | MASK_19 ); if (len < 5) @@ -617,10 +539,10 @@ static void gpioirq (unsigned long data) iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); break; } - dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len); + DEB_D(("GPIO0 PES_PLAY len=%04x\n", len)); iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - saa7146_wait_for_debi_done(av7110->dev, 0); + saa7146_wait_for_debi_done(av7110->dev); saa7146_write(av7110->dev, IER, saa7146_read(av7110->dev, IER) | MASK_19 ); @@ -647,7 +569,7 @@ static void gpioirq (unsigned long data) memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len); av7110->bmpp+=len; av7110->bmplen-=len; - saa7146_wait_for_debi_done(av7110->dev, 0); + saa7146_wait_for_debi_done(av7110->dev); saa7146_write(av7110->dev, IER, saa7146_read(av7110->dev, IER) | MASK_19 ); if (len < 5) @@ -669,7 +591,7 @@ static void gpioirq (unsigned long data) case DATA_TS_RECORD: case DATA_PES_RECORD: - saa7146_wait_for_debi_done(av7110->dev, 0); + saa7146_wait_for_debi_done(av7110->dev); saa7146_write(av7110->dev, IER, saa7146_read(av7110->dev, IER) | MASK_19); irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len); @@ -677,7 +599,7 @@ static void gpioirq (unsigned long data) return; case DATA_DEBUG_MESSAGE: - saa7146_wait_for_debi_done(av7110->dev, 0); + saa7146_wait_for_debi_done(av7110->dev); if (!len || len>0xff) { iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); break; @@ -695,7 +617,7 @@ static void gpioirq (unsigned long data) break; default: - printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n", + printk("gpioirq unknown type=%d len=%d\n", av7110->debitype, av7110->debilen); break; } @@ -712,12 +634,10 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file, struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n", av7110)); if (cmd == OSD_SEND_CMD) return av7110_osd_cmd(av7110, (osd_cmd_t *) parg); - if (cmd == OSD_GET_CAPABILITY) - return av7110_osd_capability(av7110, (osd_cap_t *) parg); return -EINVAL; } @@ -743,7 +663,7 @@ static struct dvb_device dvbdev_osd = { static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, u16 subpid, u16 pcrpid) { - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n", av7110)); if (vpid == 0x1fff || apid == 0x1fff || ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) { @@ -761,7 +681,7 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, u16 subpid, u16 pcrpid) { - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n", av7110)); if (down_interruptible(&av7110->pid_mutex)) return; @@ -800,7 +720,7 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) // u16 mode=0x0320; u16 mode=0xb96a; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); if (dvbdmxfilter->type == DMX_TYPE_SEC) { if (hw_sections) { @@ -823,13 +743,9 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) buf[3] = mode; ret = av7110_fw_request(av7110, buf, 20, &handle, 1); - if (ret != 0 || handle >= 32) { - printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " - "ret %x handle %04x\n", - __FUNCTION__, buf[0], buf[1], buf[2], buf[3], - ret, handle); - dvbdmxfilter->hw_handle = 0xffff; - return -1; + if (ret < 0) { + printk("StartHWFilter error\n"); + return ret; } av7110->handle2filter[handle] = dvbdmxfilter; @@ -846,12 +762,13 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) int ret; u16 handle; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n", av7110)); handle = dvbdmxfilter->hw_handle; - if (handle >= 32) { - printk("%s tried to stop invalid filter %04x, filter type = %x\n", - __FUNCTION__, handle, dvbdmxfilter->type); + if (handle > 32) { + DEB_S(("dvb: StopHWFilter tried to stop invalid filter %d.\n", + handle)); + DEB_S(("dvb: filter type = %d\n", dvbdmxfilter->type)); return 0; } @@ -861,11 +778,11 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) buf[1] = 1; buf[2] = handle; ret = av7110_fw_request(av7110, buf, 3, answ, 2); - if (ret != 0 || answ[1] != handle) { - printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x " - "resp %04x %04x pid %d\n", - __FUNCTION__, buf[0], buf[1], buf[2], ret, - answ[0], answ[1], dvbdmxfilter->feed->pid); + if (ret) + printk("StopHWFilter error\n"); + + if (answ[1] != handle) { + DEB_S(("dvb: filter %d shutdown error :%d\n", handle, answ[1])); ret = -1; } return ret; @@ -879,7 +796,7 @@ static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) u16 *pid = dvbdmx->pids, npids[5]; int i; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff; i = dvbdmxfeed->pes_type; @@ -912,7 +829,7 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) u16 *pid = dvbdmx->pids, npids[5]; int i; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n", av7110)); if (dvbdmxfeed->pes_type <= 1) { av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); @@ -943,9 +860,9 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) static int av7110_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = demux->priv; + struct av7110 *av7110 = (struct av7110 *) demux->priv; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n", av7110)); if (!demux->dmx.frontend) return -EINVAL; @@ -1001,9 +918,9 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) static int av7110_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = demux->priv; + struct av7110 *av7110 = (struct av7110 *) demux->priv; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); if (feed->type == DMX_TYPE_TS) { if (feed->ts_type & TS_DECODER) { @@ -1045,7 +962,7 @@ static void restart_feeds(struct av7110 *av7110) int mode; int i; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); mode = av7110->playing; av7110->playing = 0; @@ -1078,7 +995,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, BUG(); av7110 = (struct av7110 *) dvbdemux->priv; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); if (num != 0) return -EINVAL; @@ -1088,14 +1005,14 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__); return -EIO; } - dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", - fwstc[0], fwstc[1], fwstc[2], fwstc[3]); + DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n", + fwstc[0], fwstc[1], fwstc[2], fwstc[3])); *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) | (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]); *base = 1; - dprintk(4, "stc = %lu\n", (unsigned long)*stc); + DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc)); return 0; } @@ -1105,44 +1022,71 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, * SEC device file operations ******************************************************************************/ - -static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int av7110_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) { - struct av7110* av7110 = (struct av7110*) fe->dvb->priv; + struct av7110 *av7110 = fe->before_after_data; + + DEB_EE(("av7110: %p\n", av7110)); - switch (tone) { + switch (cmd) { + case FE_SET_TONE: + switch ((fe_sec_tone_mode_t) arg) { case SEC_TONE_ON: Set22K(av7110, 1); break; case SEC_TONE_OFF: Set22K(av7110, 0); break; - default: return -EINVAL; +}; + break; + + case FE_DISEQC_SEND_MASTER_CMD: + { + struct dvb_diseqc_master_cmd *cmd = arg; + av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); + break; } + case FE_DISEQC_SEND_BURST: + av7110_diseqc_send(av7110, 0, NULL, (unsigned long) arg); + break; + + default: + return -EOPNOTSUPP; +}; + return 0; } -static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) + +static void av7110_before_after_tune (fe_status_t s, void *data) { - struct av7110* av7110 = fe->dvb->priv; + struct av7110 *av7110 = data; - av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); + DEB_EE(("av7110: %p\n",av7110)); - return 0; -} + av7110->fe_synced = (s & FE_HAS_LOCK) ? 1 : 0; -static int av7110_diseqc_send_burst(struct dvb_frontend* fe, - fe_sec_mini_cmd_t minicmd) -{ - struct av7110* av7110 = fe->dvb->priv; + if (av7110->playing) + return; - av7110_diseqc_send(av7110, 0, NULL, minicmd); + if (down_interruptible(&av7110->pid_mutex)) + return; - return 0; + if (av7110->fe_synced) { + SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], + av7110->pids[DMX_PES_AUDIO], + av7110->pids[DMX_PES_TELETEXT], 0, + av7110->pids[DMX_PES_PCR]); + av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); + } else { + SetPIDs(av7110, 0, 0, 0, 0, 0); + av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, FlushTSQueue, 0); + } + + up(&av7110->pid_mutex); } @@ -1151,13 +1095,22 @@ static int av7110_register(struct av7110 *av7110) int ret, i; struct dvb_demux *dvbdemux=&av7110->demux; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); if (av7110->registered) return -1; av7110->registered=1; + dvb_add_frontend_notifier (av7110->dvb_adapter, + av7110_before_after_tune, av7110); + + /** + * init DiSEqC stuff + */ + dvb_add_frontend_ioctls (av7110->dvb_adapter, + av7110_diseqc_ioctl, NULL, av7110); + dvbdemux->priv = (void *) av7110; for (i=0; i<32; i++) @@ -1217,7 +1170,7 @@ static void dvb_unregister(struct av7110 *av7110) { struct dvb_demux *dvbdemux=&av7110->demux; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); if (!av7110->registered) return; @@ -1231,8 +1184,12 @@ static void dvb_unregister(struct av7110 *av7110) dvb_dmxdev_release(&av7110->dmxdev); dvb_dmx_release(&av7110->demux); - if (av7110->fe != NULL) - dvb_unregister_frontend(av7110->fe); + dvb_remove_frontend_notifier (av7110->dvb_adapter, + av7110_before_after_tune); + + dvb_remove_frontend_ioctls (av7110->dvb_adapter, + av7110_diseqc_ioctl, NULL); + dvb_unregister_device(av7110->osd_dev); av7110_av_unregister(av7110); av7110_ca_unregister(av7110); @@ -1246,18 +1203,19 @@ static void dvb_unregister(struct av7110 *av7110) int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) { u8 msg[2] = { reg, val }; + struct dvb_i2c_bus *i2c = av7110->i2c_bus; struct i2c_msg msgs; msgs.flags = 0; msgs.addr = id / 2; msgs.len = 2; msgs.buf = msg; - return i2c_transfer(&av7110->i2c_adap, &msgs, 1); + return i2c->xfer(i2c, &msgs, 1); } -#if 0 u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) { + struct dvb_i2c_bus *i2c = av7110->i2c_bus; u8 mm1[] = {0x00}; u8 mm2[] = {0x00}; struct i2c_msg msgs[2]; @@ -1268,11 +1226,16 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) mm1[0] = reg; msgs[0].len = 1; msgs[1].len = 1; msgs[0].buf = mm1; msgs[1].buf = mm2; - i2c_transfer(&av7110->i2c_adap, msgs, 2); + i2c->xfer(i2c, msgs, 2); return mm2[0]; } -#endif + +static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) +{ + struct saa7146_dev *dev = i2c->data; + return saa7146_i2c_transfer(dev, msgs, num, 6); +} /**************************************************************************** * INITIALIZATION @@ -1347,616 +1310,44 @@ static int get_firmware(struct av7110* av7110) /* request the av7110 firmware, this will block until someone uploads it */ ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); if (ret) { - if (ret == -ENOENT) { - printk(KERN_ERR "dvb-ttpci: could not load firmware," - " file not found: dvb-ttpci-01.fw\n"); - printk(KERN_ERR "dvb-ttpci: usually this should be in" - " /usr/lib/hotplug/firmware\n"); - printk(KERN_ERR "dvb-ttpci: and can be downloaded here" - " http://www.linuxtv.org/download/dvb/firmware/\n"); - } else - printk(KERN_ERR "dvb-ttpci: cannot request firmware" - " (error %i)\n", ret); + printk("dvb-ttpci: cannot request firmware!\n"); return -EINVAL; } - if (fw->size <= 200000) { printk("dvb-ttpci: this firmware is way too small.\n"); - release_firmware(fw); return -EINVAL; } - /* check if the firmware is available */ av7110->bin_fw = (unsigned char*) vmalloc(fw->size); if (NULL == av7110->bin_fw) { - dprintk(1, "out of memory\n"); - release_firmware(fw); + DEB_D(("out of memory\n")); return -ENOMEM; } - memcpy(av7110->bin_fw, fw->data, fw->size); av7110->size_fw = fw->size; if ((ret = check_firmware(av7110))) vfree(av7110->bin_fw); - - release_firmware(fw); return ret; } #endif - -static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = (struct av7110*) fe->dvb->priv; - u8 pwr = 0; - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; - - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; - else pwr = 2; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = ((div & 0x18000) >> 10) | 0x95; - buf[3] = (pwr << 6) | 0x30; - - // NOTE: since we're using a prescaler of 2, we set the - // divisor frequency to 62.5kHz and divide by 125 above - - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1x93_config alps_bsrv2_config = { - .demod_address = 0x08, - .xin = 90100000UL, - .invert_pwm = 0, - .pll_set = alps_bsrv2_pll_set, -}; - - -static u8 alps_bsru6_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x52, - 0xff, 0xff -}; - -static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg (fe, 0x13, aclk); - stv0299_writereg (fe, 0x14, bclk); - stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); - - return 0; -} - -static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = (struct av7110*) fe->dvb->priv; - int ret; - u8 data[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - data[3] = 0xC4; - - if (params->frequency > 1530000) data[3] = 0xc0; - - ret = i2c_transfer (&av7110->i2c_adap, &msg, 1); - if (ret != 1) - return -EIO; - return 0; -} - -static struct stv0299_config alps_bsru6_config = { - - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .enhanced_tuning = 0, - .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsru6_set_symbol_rate, - .pll_set = alps_bsru6_pll_set, -}; - - - -static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (params->frequency + 35937500 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1820_config alps_tdbe2_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, - .pll_set = alps_tdbe2_pll_set, -}; - - - - -static int grundig_29504_451_pll_set(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = params->frequency / 125; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = 0x00; - - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct tda8083_config grundig_29504_451_config = { - .demod_address = 0x68, - .pll_set = grundig_29504_451_pll_set, -}; - - - -static int philips_cd1516_pll_set(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u32 f = params->frequency; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (f + 36125000 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); - - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1820_config philips_cd1516_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, - .pll_set = philips_cd1516_pll_set, -}; - - - -static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div, pwr; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (params->frequency + 36200000) / 166666; - - if (params->frequency <= 782000000) - pwr = 1; - else - pwr = 2; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85; - data[3] = pwr << 6; - - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) -{ - struct av7110* av7110 = (struct av7110*) fe->dvb->priv; - - return request_firmware(fw, name, &av7110->dev->pci->dev); -} - -static struct sp8870_config alps_tdlb7_config = { - - .demod_address = 0x71, - .pll_set = alps_tdlb7_pll_set, - .request_firmware = alps_tdlb7_request_firmware, -}; - - - -static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) }; - struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 }; - int i; - - div = (params->frequency + 36150000 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0xce; - - if (params->frequency < 45000000) - return -EINVAL; - else if (params->frequency < 137000000) - data[3] = 0x01; - else if (params->frequency < 403000000) - data[3] = 0x02; - else if (params->frequency < 860000000) - data[3] = 0x04; - else - return -EINVAL; - - stv0297_enable_plli2c(fe); - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) { - printk("nexusca: pll transfer failed!\n"); - return -EIO; - } - - // wait for PLL lock - for(i=0; i< 20; i++) { - - stv0297_enable_plli2c(fe); - if (i2c_transfer (&av7110->i2c_adap, &readmsg, 1) == 1) - if (data[0] & 0x40) break; - msleep(10); - } - - return 0; -} - -static struct stv0297_config nexusca_stv0297_config = { - - .demod_address = 0x1C, - .pll_set = nexusca_stv0297_pll_set, -}; - - -static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) -{ - int synced = (status & FE_HAS_LOCK) ? 1 : 0; - - av7110->fe_status = status; - - if (av7110->fe_synced == synced) - return; - - av7110->fe_synced = synced; - - if (av7110->playing) - return; - - if (down_interruptible(&av7110->pid_mutex)) - return; - - if (av7110->fe_synced) { - SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], - av7110->pids[DMX_PES_AUDIO], - av7110->pids[DMX_PES_TELETEXT], 0, - av7110->pids[DMX_PES_PCR]); - av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); - } else { - SetPIDs(av7110, 0, 0, 0, 0, 0); - av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); - av7110_wait_msgstate(av7110, GPMQBusy); - } - - up(&av7110->pid_mutex); -} - -static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_set_frontend(fe, params); -} - -static int av7110_fe_init(struct dvb_frontend* fe) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_init(fe); -} - -static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct av7110* av7110 = fe->dvb->priv; - int ret; - - /* call the real implementation */ - ret = av7110->fe_read_status(fe, status); - if (ret) - return ret; - - if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) { - av7110_fe_lock_fix(av7110, *status); - } - - return 0; -} - -static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_diseqc_reset_overload(fe); -} - -static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_diseqc_send_master_cmd(fe, cmd); -} - -static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_diseqc_send_burst(fe, minicmd); -} - -static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_set_tone(fe, tone); -} - -static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_set_voltage(fe, voltage); -} - -static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - av7110_fe_lock_fix(av7110, 0); - return av7110->fe_dishnetwork_send_legacy_command(fe, cmd); -} - -static u8 read_pwm(struct av7110* av7110) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, - { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; - - if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - -static void frontend_init(struct av7110 *av7110) -{ - if (av7110->dev->pci->subsystem_vendor == 0x110a) { - switch(av7110->dev->pci->subsystem_device) { - case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) - av7110->fe = ves1820_attach(&philips_cd1516_config, - &av7110->i2c_adap, read_pwm(av7110)); - break; - } - - } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) { - switch(av7110->dev->pci->subsystem_device) { - case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X - case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X - case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE - - // try the ALPS BSRV2 first of all - av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops->set_tone = av7110_set_tone; - break; - } - - // try the ALPS BSRU6 now - av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops->set_tone = av7110_set_tone; - break; - } - - // Try the grundig 29504-451 - av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops->set_tone = av7110_set_tone; - break; - } - - /* Try DVB-C cards */ - switch(av7110->dev->pci->subsystem_device) { - case 0x0000: - /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ - av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, - read_pwm(av7110)); - break; - case 0x0003: - /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */ - av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, - read_pwm(av7110)); - break; - } - break; - - case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X - - // ALPS TDLB7 - av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); - break; - - case 0x0002: // Hauppauge/TT DVB-C premium rev2.X - - av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); - break; - - case 0x000A: // Hauppauge/TT Nexus-CA rev1.X - - av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b); - if (av7110->fe) { - /* set TDA9819 into DVB mode */ - saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD) - saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) - - /* tuner on this needs a slower i2c bus speed */ - av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - break; - } - } - } - - if (av7110->fe == NULL) { - printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", - av7110->dev->pci->vendor, - av7110->dev->pci->device, - av7110->dev->pci->subsystem_vendor, - av7110->dev->pci->subsystem_device); - } else { - FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init); - FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status); - FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); - FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); - FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); - FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone); - FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) - FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); - FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); - - if (dvb_register_frontend(av7110->dvb_adapter, av7110->fe)) { - printk("av7110: Frontend registration failed!\n"); - if (av7110->fe->ops->release) - av7110->fe->ops->release(av7110->fe); - av7110->fe = NULL; - } - } -} - static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) { struct av7110 *av7110 = NULL; int ret = 0; - dprintk(4, "dev: %p\n", dev); + DEB_EE(("dev: %p\n", dev)); /* prepare the av7110 device struct */ if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) { - dprintk(1, "out of memory\n"); + printk ("%s: out of memory!\n", __FUNCTION__); return -ENOMEM; } - + DEB_EE(("av7110: %p\n", av7110)); memset(av7110, 0, sizeof(struct av7110)); av7110->card_name = (char*)pci_ext->ext_priv; - av7110->dev = dev; + av7110->dev=(struct saa7146_dev *)dev; dev->ext_priv = av7110; if ((ret = get_firmware(av7110))) { @@ -1970,22 +1361,18 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d get recognized before the main driver is fully loaded */ saa7146_write(dev, GPIO_CTRL, 0x500000); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else - av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif - strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); + saa7146_i2c_adapter_prepare(dev, NULL, 0, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ - saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ + av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, + av7110->dvb_adapter, 0); - if (i2c_add_adapter(&av7110->i2c_adap) < 0) { + if (!av7110->i2c_bus) { dvb_unregister_adapter (av7110->dvb_adapter); kfree(av7110); return -ENOMEM; } - ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac); + ttpci_eeprom_parse_mac(av7110->i2c_bus); saa7146_write(dev, PCI_BT_V1, 0x1c00101f); saa7146_write(dev, BCS_CTRL, 0x80400040); @@ -2007,11 +1394,11 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d /* locks for data transfers from/to AV7110 */ spin_lock_init (&av7110->debilock); sema_init(&av7110->dcomlock, 1); + av7110->debilock=SPIN_LOCK_UNLOCKED; av7110->debitype=-1; /* default OSD window */ av7110->osdwin=1; - sema_init(&av7110->osd_sema, 1); /* ARM "watchdog" */ init_waitqueue_head(&av7110->arm_wait); @@ -2047,21 +1434,63 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d } if (FW_VERSION(av7110->arm_app)<0x2501) - printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " + printk ("av7110: Warning, firmware version 0x%04x is too old. " "System might be unstable!\n", FW_VERSION(av7110->arm_app)); if (kernel_thread(arm_thread, (void *) av7110, 0) < 0) { - printk("dvb-ttpci: failed to start arm_mon kernel thread @ card %d\n", + printk(KERN_ERR "av7110(%d): faile to start arm_mon kernel thread\n", av7110->dvb_adapter->num); goto err2; } - /* set initial volume in mixer struct */ - av7110->mixer.volume_left = volume; - av7110->mixer.volume_right = volume; + /* set internal volume control to maximum */ + av7110->adac_type = DVB_ADAC_TI; + av7110_set_volume(av7110, 0xff, 0xff); + + av7710_set_video_mode(av7110, vidmode); + + /* handle different card types */ + /* remaining inits according to card and frontend type */ + av7110->has_analog_tuner = 0; + av7110->current_input = 0; + if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) { + printk ("av7110(%d): Crystal audio DAC detected\n", + av7110->dvb_adapter->num); + av7110->adac_type = DVB_ADAC_CRYSTAL; + i2c_writereg(av7110, 0x20, 0x01, 0xd2); + i2c_writereg(av7110, 0x20, 0x02, 0x49); + i2c_writereg(av7110, 0x20, 0x03, 0x00); + i2c_writereg(av7110, 0x20, 0x04, 0x00); - init_av7110_av(av7110); + /** + * some special handling for the Siemens DVB-C cards... + */ + } else if (0 == av7110_init_analog_module(av7110)) { + /* done. */ + } + else if (dev->pci->subsystem_vendor == 0x110a) { + printk("av7110(%d): DVB-C w/o analog module detected\n", + av7110->dvb_adapter->num); + av7110->adac_type = DVB_ADAC_NONE; + } + else { + av7110->adac_type = adac; + printk("av7110(%d): adac type set to %d\n", + av7110->dvb_adapter->num, av7110->adac_type); + } + if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { + // 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) + saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 + //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 + } + + av7110_set_volume(av7110, 0xff, 0xff); + + av7110_setup_irc_config (av7110, 0); av7110_register(av7110); /* special case DVB-C: these cards have an analog tuner @@ -2072,10 +1501,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d if (ret) goto err3; - av7110->dvb_adapter->priv = av7110; - frontend_init(av7110); - - printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num); + printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num); av7110->device_initialized = 1; av7110_num++; return 0; @@ -2084,12 +1510,13 @@ err3: av7110->arm_rmmod = 1; wake_up_interruptible(&av7110->arm_wait); while (av7110->arm_thread) - msleep(1); + dvb_delay(1); err2: av7110_ca_exit(av7110); av7110_av_exit(av7110); err: - i2c_del_adapter(&av7110->i2c_adap); + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, + av7110->i2c_bus->id); dvb_unregister_adapter (av7110->dvb_adapter); @@ -2107,7 +1534,7 @@ err: static int av7110_detach (struct saa7146_dev* saa) { struct av7110 *av7110 = (struct av7110*)saa->ext_priv; - dprintk(4, "%p\n", av7110); + DEB_EE(("av7110: %p\n",av7110)); if( 0 == av7110->device_initialized ) { return 0; @@ -2119,12 +1546,15 @@ static int av7110_detach (struct saa7146_dev* saa) wake_up_interruptible(&av7110->arm_wait); while (av7110->arm_thread) - msleep(1); + dvb_delay(1); dvb_unregister(av7110); - SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03); - SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03); + IER_DISABLE(saa, (MASK_19 | MASK_03)); +// saa7146_write (av7110->dev, IER, +// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03)); + + saa7146_write(av7110->dev, ISR,(MASK_19 | MASK_03)); av7110_ca_exit(av7110); av7110_av_exit(av7110); @@ -2133,8 +1563,7 @@ static int av7110_detach (struct saa7146_dev* saa) pci_free_consistent(saa->pci, 8192, av7110->debi_virt, av7110->debi_bus); - i2c_del_adapter(&av7110->i2c_adap); - + dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); dvb_unregister_adapter (av7110->dvb_adapter); av7110_num--; @@ -2151,7 +1580,9 @@ static int av7110_detach (struct saa7146_dev* saa) static void av7110_irq(struct saa7146_dev* dev, u32 *isr) { - struct av7110 *av7110 = dev->ext_priv; + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; + +// DEB_INT(("dev: %p, av7110: %p\n",dev,av7110)); if (*isr & MASK_19) tasklet_schedule (&av7110->debi_tasklet); @@ -2168,29 +1599,33 @@ static struct saa7146_pci_extension_data x_var = { \ .ext_priv = x_name, \ .ext = &av7110_extension } -MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X"); -MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X"); -MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X"); -MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X"); -MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X"); -MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV Nexus-S rev1.3"); -MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); +MAKE_AV7110_INFO(fs_1_5, "Siemens cable card PCI rev1.5"); +MAKE_AV7110_INFO(fs_1_3, "Siemens/Technotrend/Hauppauge PCI rev1.3"); +MAKE_AV7110_INFO(tt_1_6, "Technotrend/Hauppauge PCI rev1.3 or 1.6"); +MAKE_AV7110_INFO(tt_2_1, "Technotrend/Hauppauge PCI rev2.1"); +MAKE_AV7110_INFO(tt_t, "Technotrend/Hauppauge PCI DVB-T"); +MAKE_AV7110_INFO(unkwn0, "Technotrend/Hauppauge PCI rev?(unknown0)?"); +MAKE_AV7110_INFO(unkwn1, "Technotrend/Hauppauge PCI rev?(unknown1)?"); +MAKE_AV7110_INFO(unkwn2, "Technotrend/Hauppauge PCI rev?(unknown2)?"); +MAKE_AV7110_INFO(nexus, "Technotrend/Hauppauge Nexus PCI DVB-S"); +MAKE_AV7110_INFO(dvboc11,"Octal/Technotrend DVB-C for iTV"); static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000), - MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), - MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), - MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), - MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), - MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), - MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), - -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0006), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-S v???? -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0008), UNDEFINED CARD */ // TT/Hauppauge WinTV DVB-T v???? -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? - + MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0xffff), + MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0x0000), + MAKE_EXTENSION_PCI(fs_1_3, 0x13c2, 0x0000), + MAKE_EXTENSION_PCI(unkwn0, 0x13c2, 0x1002), + MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0001), + MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0002), + MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0003), + MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0004), + MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0006), + MAKE_EXTENSION_PCI(tt_t, 0x13c2, 0x0008), + MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x1102), + MAKE_EXTENSION_PCI(unkwn1, 0xffc2, 0x0000), + MAKE_EXTENSION_PCI(unkwn2, 0x00a1, 0x00a1), + MAKE_EXTENSION_PCI(nexus, 0x00a1, 0xa1a0), + MAKE_EXTENSION_PCI(dvboc11,0x13c2, 0x000a), { .vendor = 0, } @@ -2249,3 +1684,15 @@ MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); MODULE_LICENSE("GPL"); +MODULE_PARM(av7110_debug,"i"); +MODULE_PARM(vidmode,"i"); +MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC"); +MODULE_PARM(pids_off,"i"); +MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed"); +MODULE_PARM(adac,"i"); +MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)"); +MODULE_PARM(hw_sections, "i"); +MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware"); +MODULE_PARM(rgb_on, "i"); +MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" + " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");