Hi, below is a patch against the 2.6.13 dvb code to fix some problems I had with a Pinnacle PCTV-Sat, mainly the fifo overrun errors. I've added some error recovery that works often but is pretty noisy. The best result is to simply not enable those status interrupts. Due to resyncs added to the risc-code the dma-controller seems to always recover from fifo overruns. To get all status irqs back one has to set bt878_debug now. Further, I've added a sleep function which turns off the IF-relay. So now it's possible to connect another receiver to the IF-out connector and when the card is not used (for 5 seconds) the external box gets the antenna. The new relay handling also fixes a problem when trying to use analog video-in and dvb at the same time. Formerly, at the moment you open the video dev the relay was turn off and the frontend got no signal any more. That works correct now - you can watch digital and analog tv at the same time. And then there are a couple of cleanups - code, comments, whitespaces, error checks, log levels, ... Comments welcome ... Ciao, ET. PS: Do I have to sends the couple of lines that touch the bttv driver to the bttv-maintainer or is anyone collecting dvb-related bttv patches and forwards them? diff -rup linux-2.6.13/drivers/media-orig/dvb/bt8xx/bt878.c linux-2.6.13/drivers/media/dvb/bt8xx/bt878.c --- linux-2.6.13/drivers/media-orig/dvb/bt8xx/bt878.c 2005-08-30 03:56:52 +0200 +++ linux-2.6.13/drivers/media/dvb/bt8xx/bt878.c 2005-09-01 19:34:56 +0200 @@ -78,7 +78,7 @@ EXPORT_SYMBOL(bt878); #if defined(dprintk) #undef dprintk #endif -#define dprintk if(bt878_debug) printk +#define dprintk(args...) do { if (bt878_debug) printk(KERN_DEBUG args); } while (0) static void bt878_mem_free(struct bt878 *bt) { @@ -142,9 +142,9 @@ static int bt878_mem_alloc(struct bt878 #define RISC_SYNC_VRO 0x0C #define RISC_FLUSH() bt->risc_pos = 0 -#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) +#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32((instr)) -static int bt878_make_risc(struct bt878 *bt) +static int bt878_calc_line_size(struct bt878 *bt) { bt->block_bytes = bt->buf_size >> 4; bt->block_count = 1 << 4; @@ -157,35 +157,34 @@ static int bt878_make_risc(struct bt878 } if (bt->line_count > 255) { - printk("bt878: buffer size error!\n"); + printk(KERN_ERR "bt878: buffer size error!\n"); return -EINVAL; } return 0; } -static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin) +static void bt878_risc_program(struct bt878 *bt) { u32 buf_pos = 0; u32 line; RISC_FLUSH(); - RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); + RISC_INSTR(RISC_SYNC | RISC_SYNC_RESYNC | RISC_SYNC_FM1); RISC_INSTR(0); dprintk("bt878: risc len lines %u, bytes per line %u\n", bt->line_count, bt->line_bytes); for (line = 0; line < bt->line_count; line++) { - // At the beginning of every block we issue an IRQ with previous (finished) block number set + // At the beginning of every block we issue an IRQ + // with previous (finished) block number set if (!(buf_pos % bt->block_bytes)) RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | RISC_IRQ | - RISC_STATUS(((buf_pos / - bt->block_bytes) + - (bt->block_count - - 1)) % - bt->block_count) | bt-> - line_bytes); + RISC_STATUS(((buf_pos / bt->block_bytes) + + bt->block_count - 1) + % bt->block_count) | + bt->line_bytes); else RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | bt->line_bytes); @@ -193,7 +192,7 @@ static void bt878_risc_program(struct bt buf_pos += bt->line_bytes; } - RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO); + RISC_INSTR(RISC_SYNC | RISC_SYNC_RESYNC | RISC_SYNC_VRO); RISC_INSTR(0); RISC_INSTR(RISC_JUMP); @@ -206,38 +205,34 @@ static void bt878_risc_program(struct bt /* Start/Stop grabbing funcs */ /*****************************/ -void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, - u32 irq_err_ignore) +void bt878_start(struct bt878 *bt, u32 controlreg) { u32 int_mask; dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg); + /* complete the writing of the risc dma program now we have * the card specifics */ - bt878_risc_program(bt, op_sync_orin); controlreg &= ~0x1f; - controlreg |= 0x1b; - - btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START); - - /* original int mask had : - * 6 2 8 4 0 - * 1111 1111 1000 0000 0000 - * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI - * Hacked for DST to: - * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI - */ - int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | - BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | - BT878_AFBUS | BT878_ARISCI; + btwrite(controlreg, BT878_AGPIO_DMA_CTL); + bt878_risc_program(bt); + btwrite(bt->risc_dma, BT878_ARISC_START); + bt->last_block = bt->block_count - 1; - /* ignore pesky bits */ - int_mask &= ~irq_err_ignore; + bt->errors = 0; + int_mask = BT878_ARISCI; + if (bt878_debug) + int_mask |= BT878_ASCERR | BT878_AOCERR | + BT878_APABORT | BT878_ARIPERR | BT878_APPERR | + BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS; + btwrite(int_mask, BT878_AINT_STAT); btwrite(int_mask, BT878_AINT_MASK); - btwrite(controlreg, BT878_AGPIO_DMA_CTL); + + /* start dma (with fifo threshold at minimum) */ + btor(0x13, BT878_AGPIO_DMA_CTL); } void bt878_stop(struct bt878 *bt) @@ -270,7 +265,7 @@ EXPORT_SYMBOL(bt878_stop); static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs) { - u32 stat, astat, mask; + u32 stat, astat; int count; struct bt878 *bt; @@ -279,63 +274,76 @@ static irqreturn_t bt878_irq(int irq, vo count = 0; while (1) { stat = btread(BT878_AINT_STAT); - mask = btread(BT878_AINT_MASK); - if (!(astat = (stat & mask))) - return IRQ_NONE; /* this interrupt is not for me */ -/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */ - btwrite(astat, BT878_AINT_STAT); /* try to clear interupt condition */ + astat = stat & btread(BT878_AINT_MASK); + if (!astat) + break; + + btwrite(astat, BT878_AINT_STAT); + if (astat & BT878_ARISCI) { + bt->finished_block = (stat & BT878_ARISCS) >> 28; + tasklet_schedule(&bt->tasklet); + } if (astat & (BT878_ASCERR | BT878_AOCERR)) { if (bt878_verbose) { - printk("bt878(%d): irq%s%s risc_pc=%08x\n", + printk(KERN_ERR + "bt878(%d): irq%s%s risc_pc=%08x\n", bt->nr, - (astat & BT878_ASCERR) ? " SCERR" : - "", - (astat & BT878_AOCERR) ? " OCERR" : - "", btread(BT878_ARISC_PC)); + (astat & BT878_ASCERR) ? " SCERR" : "", + (astat & BT878_AOCERR) ? " OCERR" : "", + btread(BT878_ARISC_PC)); } } if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) { if (bt878_verbose) { - printk - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", - bt->nr, - (astat & BT878_APABORT) ? " PABORT" : - "", - (astat & BT878_ARIPERR) ? " RIPERR" : - "", - (astat & BT878_APPERR) ? " PPERR" : - "", btread(BT878_ARISC_PC)); + printk(KERN_ERR + "bt878(%d): irq%s%s%s risc_pc=%08x\n", + bt->nr, + (astat & BT878_APABORT) ? " PABORT" : "", + (astat & BT878_ARIPERR) ? " RIPERR" : "", + (astat & BT878_APPERR) ? " PPERR" : "", + btread(BT878_ARISC_PC)); } } if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) { if (bt878_verbose) { - printk - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", - bt->nr, - (astat & BT878_AFDSR) ? " FDSR" : "", - (astat & BT878_AFTRGT) ? " FTRGT" : - "", - (astat & BT878_AFBUS) ? " FBUS" : "", - btread(BT878_ARISC_PC)); + printk(KERN_ERR + "bt878(%d): irq%s%s%s risc_pc=%08x\n", + bt->nr, + (astat & BT878_AFDSR) ? " FDSR" : "", + (astat & BT878_AFTRGT) ? " FTRGT" : "", + (astat & BT878_AFBUS) ? " FBUS" : "", + btread(BT878_ARISC_PC)); } } - if (astat & BT878_ARISCI) { - bt->finished_block = (stat & BT878_ARISCS) >> 28; - tasklet_schedule(&bt->tasklet); - break; + if (astat & ~BT878_ARISCI) { + if (time_after(jiffies, bt->error_expire)) + bt->errors = 0; + bt->error_expire = jiffies + 5*HZ; + bt->errors++; + if (bt->errors == 10 || bt->errors == 15) { + printk(KERN_ERR "bt878(%d): too many errors, " + "resetting dma\n", bt->nr); + /* reset dma and set fifo-trigger to minimum */ + btand(~0x1f, BT878_AGPIO_DMA_CTL); + btor(0x13, BT878_AGPIO_DMA_CTL); + } + if (bt->errors == 20) { + printk(KERN_ERR "bt878(%d): too many errors, " + "shutting up\n", bt->nr); + btwrite(BT878_ARISCI, BT878_AINT_MASK); + } } count++; - if (count > 20) { + if (count > 30) { btwrite(0, BT878_AINT_MASK); - printk(KERN_ERR - "bt878(%d): IRQ lockup, cleared int mask\n", - bt->nr); + printk(KERN_ERR "bt878(%d): IRQ lockup, " + "device disabled\n", bt->nr); break; } } - return IRQ_HANDLED; + return IRQ_RETVAL(count); } int @@ -395,8 +403,7 @@ static int __devinit bt878_probe(struct unsigned int cmd; #endif - printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", - bt878_num); + printk(KERN_INFO "bt878(%d): DVB interface found.\n", bt878_num); if (pci_enable_device(dev)) return -EIO; @@ -416,10 +423,10 @@ static int __devinit bt878_probe(struct pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", + printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, " + "irq: %d, latency: %d, memory: 0x%lx\n", bt878_num, bt->id, bt->revision, dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - printk("irq: %d, latency: %d, memory: 0x%lx\n", + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), bt->irq, lat, bt->bt878_adr); @@ -437,25 +444,24 @@ static int __devinit bt878_probe(struct bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000); #endif - /* clear interrupt mask */ - btwrite(0, BT848_INT_MASK); + /* disable interrupts and dma */ + btwrite(0, BT878_AINT_MASK); + btwrite(0, BT878_AGPIO_DMA_CTL); result = request_irq(bt->irq, bt878_irq, SA_SHIRQ | SA_INTERRUPT, "bt878", (void *) bt); - if (result == -EINVAL) { - printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", - bt878_num); - goto fail1; - } if (result == -EBUSY) { printk(KERN_ERR "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n", bt878_num, bt->irq); goto fail1; } - if (result < 0) + if (result < 0) { + printk(KERN_ERR "bt878(%d): Bad irq number or handler (%d)\n", + bt878_num, result); goto fail1; + } pci_set_master(dev); pci_set_drvdata(dev, bt); @@ -467,12 +473,11 @@ static int __devinit bt878_probe(struct */ if ((result = bt878_mem_alloc(bt))) { - printk("bt878: failed to allocate memory!\n"); + printk(KERN_ERR "bt878: failed to allocate memory!\n"); goto fail2; } - bt878_make_risc(bt); - btwrite(0, BT878_AINT_MASK); + bt878_calc_line_size(bt); bt878_num++; return 0; @@ -493,7 +498,7 @@ static void __devexit bt878_remove(struc struct bt878 *bt = pci_get_drvdata(pci_dev); if (bt878_verbose) - printk("bt878(%d): unloading\n", bt->nr); + printk(KERN_INFO "bt878(%d): unloading\n", bt->nr); /* turn off all capturing, DMA and IRQs */ btand(~0x13, BT878_AGPIO_DMA_CTL); @@ -504,12 +509,11 @@ static void __devexit bt878_remove(struc /* disable PCI bus-mastering */ pci_read_config_byte(bt->dev, PCI_COMMAND, &command); - /* Should this be &=~ ?? */ command &= ~PCI_COMMAND_MASTER; pci_write_config_byte(bt->dev, PCI_COMMAND, command); free_irq(bt->irq, bt); - printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem); + dprintk("bt878_mem: 0x%p.\n", bt->bt878_mem); if (bt->bt878_mem) iounmap(bt->bt878_mem); @@ -553,7 +557,7 @@ static int bt878_init_module(void) bt878_num = 0; bt878_pci_driver_registered = 0; - printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", + printk(KERN_INFO "bt878: DVB driver version %d.%d.%d loaded\n", (BT878_VERSION_CODE >> 16) & 0xff, (BT878_VERSION_CODE >> 8) & 0xff, BT878_VERSION_CODE & 0xff); diff -rup linux-2.6.13/drivers/media-orig/dvb/bt8xx/bt878.h linux-2.6.13/drivers/media/dvb/bt8xx/bt878.h --- linux-2.6.13/drivers/media-orig/dvb/bt8xx/bt878.h 2005-06-17 21:48:29 +0200 +++ linux-2.6.13/drivers/media/dvb/bt8xx/bt878.h 2005-09-01 00:37:57 +0200 @@ -28,7 +28,7 @@ #include "bt848.h" #include "bttv.h" -#define BT878_VERSION_CODE 0x000000 +#define BT878_VERSION_CODE 0x000001 #define BT878_AINT_STAT 0x100 #define BT878_ARISCS (0xf<<28) @@ -75,19 +75,7 @@ #define BT878_ARISC_PC 0x120 -/* BT878 FUNCTION 0 REGISTERS */ -#define BT878_GPIO_DMA_CTL 0x10c - -/* Interrupt register */ -#define BT878_INT_STAT 0x100 -#define BT878_INT_MASK 0x104 -#define BT878_I2CRACK (1<<25) -#define BT878_I2CDONE (1<<8) - #define BT878_MAX 4 - -#define BT878_RISC_SYNC_MASK (1 << 15) - extern int bt878_num; struct bt878 { @@ -119,14 +107,16 @@ struct bt878 { dma_addr_t risc_dma; u32 risc_pos; + unsigned int errors; + unsigned long error_expire; + struct tasklet_struct tasklet; int shutdown; }; extern struct bt878 bt878[BT878_MAX]; -void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, - u32 irq_err_ignore); +void bt878_start(struct bt878 *bt, u32 controlreg); void bt878_stop(struct bt878 *bt); #if defined(__powerpc__) /* big-endian */ diff -rup linux-2.6.13/drivers/media-orig/dvb/bt8xx/dvb-bt8xx.c linux-2.6.13/drivers/media/dvb/bt8xx/dvb-bt8xx.c --- linux-2.6.13/drivers/media-orig/dvb/bt8xx/dvb-bt8xx.c 2005-06-17 21:48:29 +0200 +++ linux-2.6.13/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2005-08-31 23:32:04 +0200 @@ -79,8 +79,7 @@ static int dvb_bt8xx_start_feed(struct d card->nfeeds++; rc = card->nfeeds; if (card->nfeeds == 1) - bt878_start(card->bt, card->gpio_mode, - card->op_sync_orin, card->irq_err_ignore); + bt878_start(card->bt, card->gpio_mode); up(&card->lock); return rc; } @@ -196,7 +195,7 @@ static int cx24108_pll_set(struct dvb_fr 0x00120000,0x00140000}; #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ - printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); + dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); /* This is really the bit driving the tuner chip cx24108 */ @@ -205,7 +204,7 @@ static int cx24108_pll_set(struct dvb_fr /* decide which VCO to use for the input frequency */ for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); - printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); + dprintk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); band=bandsel[i]; /* the gain values must be set by SetSymbolrate */ /* compute the pll divider needed, from Conexant data sheet, @@ -221,7 +220,7 @@ static int cx24108_pll_set(struct dvb_fr ((a&0x1f)<<11); /* everything is shifted left 11 bits to left-align the bits in the 32bit word. Output to the tuner goes MSB-aligned, after all */ - printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); + dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); cx24110_pll_write(fe,band); /* set vga and vca to their widest-band settings, as a precaution. SetSymbolrate might not be called to set this up */ @@ -235,7 +234,19 @@ static int cx24108_pll_set(struct dvb_fr static int pinnsat_pll_init(struct dvb_frontend* fe) { - return 0; + struct dvb_bt8xx_card *card = fe->dvb->priv; + + bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ + bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ + return 0; +} + +static int pinnsat_sleep(struct dvb_frontend* fe) +{ + struct dvb_bt8xx_card *card = fe->dvb->priv; + + bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ + return 0; } @@ -244,6 +255,7 @@ static struct cx24110_config pctvsat_con .demod_address = 0x55, .pll_init = pinnsat_pll_init, .pll_set = cx24108_pll_set, + .sleep = pinnsat_sleep, }; @@ -670,16 +682,12 @@ static int dvb_bt8xx_probe(struct device card->gpio_mode = 0x0400c060; /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ - card->op_sync_orin = 0; - card->irq_err_ignore = 0; break; #ifdef BTTV_DVICO_DVBT_LITE case BTTV_DVICO_DVBT_LITE: #endif card->gpio_mode = 0x0400C060; - card->op_sync_orin = 0; - card->irq_err_ignore = 0; /* 26, 15, 14, 6, 5 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA * DA_APP(parallel) */ @@ -691,41 +699,27 @@ static int dvb_bt8xx_probe(struct device case BTTV_NEBULA_DIGITV: #endif case BTTV_AVDVBT_761: - card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + case BTTV_AVDVBT_771: + card->gpio_mode = 0x04004020; /* A_PWRDN DA_SBR DA_APP (high speed serial) */ break; - case BTTV_AVDVBT_771: //case 0x07711461: - card->gpio_mode = 0x0400402B; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = 0; - /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ - break; - case BTTV_TWINHAN_DST: - card->gpio_mode = 0x2204f2c; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | - BT878_APPERR | BT878_AFBUS; + card->gpio_mode = 0x2204f20; /* 25,21,14,11,10,9,8,3,2 then * 0x33 = 5,4,1,0 * A_SEL=SML, DA_MLB, DA_SBR, - * DA_SDR=f, fifo trigger = 32 DWORDS + * DA_SDR=f, * IOM = 0 == audio A/D * DPM = 0 == digital audio mode * == async data parallel port * then 0x33 (13 is set by start_capture) * DA_APP = async data parallel port, - * ACAP_EN = 1, - * RISC+FIFO ENABLE */ + */ break; case BTTV_PC_HDTV: - card->gpio_mode = 0x0100EC7B; - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + card->gpio_mode = 0x0100EC60; break; default: diff -rup linux-2.6.13/drivers/media-orig/dvb/bt8xx/dvb-bt8xx.h linux-2.6.13/drivers/media/dvb/bt8xx/dvb-bt8xx.h --- linux-2.6.13/drivers/media-orig/dvb/bt8xx/dvb-bt8xx.h 2005-06-17 21:48:29 +0200 +++ linux-2.6.13/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2005-08-31 23:33:02 +0200 @@ -48,8 +48,6 @@ struct dvb_bt8xx_card { struct dmx_frontend fe_hw; struct dmx_frontend fe_mem; u32 gpio_mode; - u32 op_sync_orin; - u32 irq_err_ignore; struct i2c_adapter *i2c_adapter; struct dvb_net dvbnet; diff -rup linux-2.6.13/drivers/media-orig/dvb/frontends/cx24110.c linux-2.6.13/drivers/media/dvb/frontends/cx24110.c --- linux-2.6.13/drivers/media-orig/dvb/frontends/cx24110.c 2005-06-17 21:48:29 +0200 +++ linux-2.6.13/drivers/media/dvb/frontends/cx24110.c 2005-09-01 06:24:51 +0200 @@ -337,7 +337,7 @@ int cx24110_pll_write (struct dvb_fronte while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) ; - /* send another 8 bytes */ + /* send another 8 bits */ cx24110_writereg(state,0x72,(data>>16)&0xff); while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) ; @@ -371,6 +371,15 @@ static int cx24110_initfe(struct dvb_fro return 0; } +static int cx24110_sleep(struct dvb_frontend *fe) +{ + struct cx24110_state *state = fe->demodulator_priv; + + if (state->config->sleep) + return state->config->sleep(fe); + return 0; +} + static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) { struct cx24110_state *state = fe->demodulator_priv; @@ -414,6 +423,9 @@ static int cx24110_send_diseqc_msg(struc int i, rv; struct cx24110_state *state = fe->demodulator_priv; + if (cmd->msg_len < 3 || cmd->msg_len > 6) + return -EINVAL; + for (i = 0; i < cmd->msg_len; i++) cx24110_writereg(state, 0x79 + i, cmd->msg[i]); @@ -631,6 +643,7 @@ static struct dvb_frontend_ops cx24110_o .release = cx24110_release, .init = cx24110_initfe, + .sleep = cx24110_sleep, .set_frontend = cx24110_set_frontend, .get_frontend = cx24110_get_frontend, .read_status = cx24110_read_status, diff -rup linux-2.6.13/drivers/media-orig/dvb/frontends/cx24110.h linux-2.6.13/drivers/media/dvb/frontends/cx24110.h --- linux-2.6.13/drivers/media-orig/dvb/frontends/cx24110.h 2005-06-17 21:48:29 +0200 +++ linux-2.6.13/drivers/media/dvb/frontends/cx24110.h 2005-08-31 19:03:04 +0200 @@ -35,6 +35,7 @@ struct cx24110_config /* PLL maintenance */ int (*pll_init)(struct dvb_frontend* fe); int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + int (*sleep)(struct dvb_frontend *fe); }; extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, diff -rup linux-2.6.13/drivers/media-orig/video/bttv-cards.c linux-2.6.13/drivers/media/video/bttv-cards.c --- linux-2.6.13/drivers/media-orig/video/bttv-cards.c 2005-08-29 19:21:12 +0200 +++ linux-2.6.13/drivers/media/video/bttv-cards.c 2005-09-01 19:46:13 +0200 @@ -1633,10 +1633,7 @@ struct tvcard bttv_tvcards[] = { .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .gpiomask = 0x01, - .audiomux = { 0, 0, 0, 0, 1 }, .muxsel = { 3, 0, 1, 2}, - .needs_tvaudio = 0, .pll = PLL_28, .no_gpioirq = 1, .has_dvb = 1, @@ -2618,6 +2615,7 @@ void __devinit bttv_init_card1(struct bt break; case BTTV_TWINHAN_DST: case BTTV_AVDVBT_771: + case BTTV_PINNACLESAT: btv->use_i2c_hw = 1; break; case BTTV_ADLINK_RTV24: @@ -2802,8 +2800,8 @@ void __devinit bttv_init_card2(struct bt btv->has_radio=1; if (bttv_tvcards[btv->c.type].has_remote) btv->has_remote=1; - if (bttv_tvcards[btv->c.type].no_gpioirq) - btv->gpioirq=0; + if (!bttv_tvcards[btv->c.type].no_gpioirq) + btv->gpioirq=1; if (bttv_tvcards[btv->c.type].audio_hook) btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; diff -rup linux-2.6.13/drivers/media-orig/video/bttv-driver.c linux-2.6.13/drivers/media/video/bttv-driver.c --- linux-2.6.13/drivers/media-orig/video/bttv-driver.c 2005-08-29 19:21:12 +0200 +++ linux-2.6.13/drivers/media/video/bttv-driver.c 2005-08-31 18:22:58 +0200 @@ -3863,7 +3863,6 @@ static int __devinit bttv_probe(struct p btv->tuner_type = UNSET; btv->pinnacle_id = UNSET; btv->new_input = UNSET; - btv->gpioirq = 1; btv->has_radio=radio[btv->c.nr]; /* pci stuff (init, get irq/mmio, ... */ <EOF>