These patches are my collection of changes for the dvb_bt8xx and especially the Pinnacle PCTV-Sat driver for kernel version 2.6.16. The current 2.6.16 version of the PCTV-Sat driver is non-functional. This message contains the complete patch, the following six messages the broken down versions with details. [1/6] Clean up printks [2/6] Fix relay handling. [3/6] Remove op_sync_orin and irq_err_ignore [4/6] Check msg_len in cx24110_send_diseqc_msg [5/6] Change mode of module params to 0644 [6/6] Misc cleanup and robustness tweaks This is the same code I sent for 2.6.15, just rebased against 2.6.16. Ciao, ET. --- Combined patch: bt8xx/bt878.c | 186 +++++++++++++++++++--------------------- bt8xx/bt878.h | 20 +--- bt8xx/dvb-bt8xx.c | 102 +++++++-------------- bt8xx/dvb-bt8xx.h | 2 dvb-core/dvb_frontend.c | 8 - frontends/cx24110.c | 15 +++ frontends/cx24110.h | 1 7 files changed, 150 insertions(+), 184 deletions(-) --- linux-2.6.16/drivers/media/dvb/bt8xx/bt878.c 2006-03-22 02:12:43 +0100 +++ linux-2.6.16/drivers/media/dvb/bt8xx/bt878.c 2006-03-22 03:00:59 +0100 @@ -78,7 +78,8 @@ 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 +143,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 +158,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_FM1 | RISC_SYNC_RESYNC); 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 +193,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 +206,31 @@ 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(controlreg, BT878_AGPIO_DMA_CTL); btwrite(bt->risc_dma, BT878_ARISC_START); + bt->last_block = bt->block_count - 1; - /* 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; - - - /* 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) */ + /* just in case with a read-modify-write to flush prior writes */ + btor(0x13, BT878_AGPIO_DMA_CTL); } void bt878_stop(struct bt878 *bt) @@ -270,7 +263,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 +272,75 @@ 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; /* not for us */ + btwrite(astat, BT878_AINT_STAT); /* ack interrupt */ + 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 @@ -415,8 +420,7 @@ static int __devinit bt878_probe(struct unsigned short id; struct cards *dvb_cards; - 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; @@ -479,42 +483,35 @@ 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); -/* if(init_bt878(btv) < 0) { - bt878_remove(dev); - return -EIO; - } -*/ - 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_risc_program(bt); bt878_num++; return 0; @@ -535,7 +532,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); @@ -546,7 +543,6 @@ 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); @@ -595,7 +591,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); --- linux-2.6.16/drivers/media/dvb/bt8xx/bt878.h 2006-03-22 02:12:43 +0100 +++ linux-2.6.16/drivers/media/dvb/bt8xx/bt878.h 2006-03-22 03:00:59 +0100 @@ -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,20 +75,8 @@ #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) - - #define BTTV_BOARD_UNKNOWN 0x00 #define BTTV_BOARD_PINNACLESAT 0x5e #define BTTV_BOARD_NEBULA_DIGITV 0x68 @@ -136,14 +124,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 */ --- linux-2.6.16/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2006-03-22 02:12:43 +0100 +++ linux-2.6.16/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2006-03-22 03:00:51 +0100 @@ -52,8 +52,6 @@ static void dvb_bt8xx_task(unsigned long { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data; - //printk("%d ", card->bt->finished_block); - while (card->bt->last_block != card->bt->finished_block) { (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) (&card->demux, @@ -80,8 +78,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; } @@ -198,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 */ @@ -209,7 +206,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, @@ -225,7 +222,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 */ @@ -239,6 +236,18 @@ static int cx24108_pll_set(struct dvb_fr static int pinnsat_pll_init(struct dvb_frontend* fe) { + 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_pll_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; } @@ -246,6 +255,7 @@ static struct cx24110_config pctvsat_con .demod_address = 0x55, .pll_init = pinnsat_pll_init, .pll_set = cx24108_pll_set, + .pll_sleep = pinnsat_pll_sleep, }; static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) @@ -612,7 +622,7 @@ static void frontend_init(struct dvb_bt8 lgdt330x_reset(card); card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); if (card->fe != NULL) - dprintk ("dvb_bt8xx: lgdt330x detected\n"); + dprintk("dvb_bt8xx: lgdt330x detected\n"); break; case BTTV_BOARD_NEBULA_DIGITV: @@ -659,7 +669,7 @@ static void frontend_init(struct dvb_bt8 /* DST is not a frontend, attaching the ASIC */ if ((dst_attach(state, &card->dvb_adapter)) == NULL) { - printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__); + printk(KERN_ERR "%s: Could not find a Twinhan DST.\n", __FUNCTION__); break; } card->fe = &state->frontend; @@ -680,14 +690,14 @@ static void frontend_init(struct dvb_bt8 } if (card->fe == NULL) - printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", + printk(KERN_ERR "dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", card->bt->dev->vendor, card->bt->dev->device, card->bt->dev->subsystem_vendor, card->bt->dev->subsystem_device); else if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { - printk("dvb-bt8xx: Frontend registration failed!\n"); + printk(KERN_ERR "dvb-bt8xx: Frontend registration failed!\n"); if (card->fe->ops->release) card->fe->ops->release(card->fe); card->fe = NULL; @@ -699,7 +709,7 @@ static int __init dvb_bt8xx_load_card(st int result; if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) { - printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); + printk(KERN_ERR "dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); return result; } card->dvb_adapter.priv = card; @@ -718,7 +728,7 @@ static int __init dvb_bt8xx_load_card(st card->demux.write_to_decoder = NULL; if ((result = dvb_dmx_init(&card->demux)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); dvb_unregister_adapter(&card->dvb_adapter); return result; @@ -729,7 +739,7 @@ static int __init dvb_bt8xx_load_card(st card->dmxdev.capabilities = 0; if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) { - printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); + printk(KERN_ERR "dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); dvb_dmx_release(&card->demux); dvb_unregister_adapter(&card->dvb_adapter); @@ -739,7 +749,7 @@ static int __init dvb_bt8xx_load_card(st card->fe_hw.source = DMX_FRONTEND_0; if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); dvb_dmxdev_release(&card->dmxdev); dvb_dmx_release(&card->demux); @@ -750,7 +760,7 @@ static int __init dvb_bt8xx_load_card(st card->fe_mem.source = DMX_MEMORY_FE; if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); dvb_dmxdev_release(&card->dmxdev); @@ -760,7 +770,7 @@ static int __init dvb_bt8xx_load_card(st } if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); @@ -795,65 +805,23 @@ static int dvb_bt8xx_probe(struct bttv_s switch(sub->core->type) { case BTTV_BOARD_PINNACLESAT: - 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; - case BTTV_BOARD_DVICO_DVBT_LITE: - 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) */ - break; - case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: - card->gpio_mode = 0x0400c060; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + card->gpio_mode = 0x0400c060; /* high speed serial mode */ break; case BTTV_BOARD_NEBULA_DIGITV: case BTTV_BOARD_AVDVBT_761: - card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); - card->op_sync_orin = 0; - card->irq_err_ignore = 0; - /* A_PWRDN DA_SBR DA_APP (high speed serial) */ - break; - - case BTTV_BOARD_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*/ + case BTTV_BOARD_AVDVBT_771: + card->gpio_mode = 0x04004020; /* parallel mode */ break; case BTTV_BOARD_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; - /* 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 - * 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 */ + card->gpio_mode = 0x02204f20; break; case BTTV_BOARD_PC_HDTV: - card->gpio_mode = 0x0100EC7B; - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + card->gpio_mode = 0x0100EC60; break; default: @@ -866,15 +834,15 @@ static int dvb_bt8xx_probe(struct bttv_s dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name); if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) { - printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr); + printk(KERN_ERR "dvb_bt8xx: no pci device for card %d\n", card->bttv_nr); kfree(card); return -EFAULT; } if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) { - printk("dvb_bt8xx: unable to determine DMA core of card %d,\n", + printk(KERN_ERR "dvb_bt8xx: unable to determine DMA core of card %d,\n", card->bttv_nr); - printk("dvb_bt8xx: if you have the ALSA bt87x audio driver " + printk(KERN_ERR "dvb_bt8xx: if you have the ALSA bt87x audio driver " "installed, try removing it.\n"); kfree(card); --- linux-2.6.16/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2006-03-22 02:12:21 +0100 +++ linux-2.6.16/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2006-03-22 03:00:51 +0100 @@ -49,8 +49,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; --- linux-2.6.16/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-03-22 02:12:43 +0100 +++ linux-2.6.16/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-03-22 03:00:58 +0100 @@ -50,13 +50,13 @@ static int dvb_powerdown_on_sleep = 1; module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); -module_param(dvb_shutdown_timeout, int, 0444); +module_param(dvb_shutdown_timeout, int, 0644); MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); -module_param(dvb_force_auto_inversion, int, 0444); +module_param(dvb_force_auto_inversion, int, 0644); MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); -module_param(dvb_override_tune_delay, int, 0444); +module_param(dvb_override_tune_delay, int, 0644); MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); -module_param(dvb_powerdown_on_sleep, int, 0444); +module_param(dvb_powerdown_on_sleep, int, 0644); MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); #define dprintk if (dvb_frontend_debug) printk --- linux-2.6.16/drivers/media/dvb/frontends/cx24110.c 2006-03-22 02:12:43 +0100 +++ linux-2.6.16/drivers/media/dvb/frontends/cx24110.c 2006-03-22 03:00:54 +0100 @@ -250,7 +250,7 @@ static int cx24110_set_symbolrate (struc static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; int i; -dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); + dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); if (srate>90999000UL/2) srate=90999000UL/2; if (srate<500000) @@ -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->pll_sleep) + return state->config->pll_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; @@ -418,6 +427,9 @@ static int cx24110_send_diseqc_msg(struc struct cx24110_state *state = fe->demodulator_priv; unsigned long timeout; + if (cmd->msg_len < 3 || cmd->msg_len > 6) + return -EINVAL; /* not implemented */ + for (i = 0; i < cmd->msg_len; i++) cx24110_writereg(state, 0x79 + i, cmd->msg[i]); @@ -639,6 +651,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, --- linux-2.6.16/drivers/media/dvb/frontends/cx24110.h 2006-03-22 02:12:08 +0100 +++ linux-2.6.16/drivers/media/dvb/frontends/cx24110.h 2006-03-22 03:00:48 +0100 @@ -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 (*pll_sleep)(struct dvb_frontend* fe); }; extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, _______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb