[linux-dvb] [PATCH 0/6] DVB-PinnSat: Pinnacle PCTV-Sat update
for 2.6.15
Sigmund Augdal Helberg
sigmund at snap.tv
Wed Jan 11 19:25:09 CET 2006
On Sun, 2006-01-08 at 02:45 +0100, Edgar Toernig wrote:
> These patches are my collection of changes for the
> dvb_bt8xx and especially the Pinnacle PCTV-Sat driver
> for kernel version 2.6.15. The current 2.6.15 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
I've tested these patches a bit (with a big bunch of twinhan VP1030A
cards) and have so far found no regressions. Without this patch I got
about 15 "irq FDSR" messages in the log for a 30 minute test. With this
patch they are all gone.
I read through part 6/6 (had to manually apply because of stupid mailer)
and I didn't like how it was presented. It mixes potentially very
important semantic changes (like how the pci accesses are done) with
quite complex cosmetic changes like this:
> - 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);
These kinds of changes are in my opinion very difficult to check for
whether they actually change anything or are only cleanup, and should
belong in commits that have _only_ cleanup changes.
Also, some people complain about lacking Signed-off-by: lines...
Regards,
Sigmund
>
>
> Ciao, ET.
>
> ---
>
> Combined patch:
>
> bt8xx/bt878.c | 186 +++++++++++++++++++---------------------
> bt8xx/bt878.h | 19 +---
> 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, 151 insertions(+), 182 deletions(-)
>
> --- 0.1/drivers/media/dvb/frontends/cx24110.h Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/f/41_cx24110.h 1.1 644)
> +++ 0.7/drivers/media/dvb/frontends/cx24110.h Sat, 07 Jan 2006 01:12:16 +0100 froese (kernel-dvb/f/41_cx24110.h 1.2 644)
> @@ -35,6 +35,7 @@
> /* 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,
> --- 0.1/drivers/media/dvb/frontends/cx24110.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/f/42_cx24110.c 1.1 644)
> +++ 0.7/drivers/media/dvb/frontends/cx24110.c Sat, 07 Jan 2006 20:21:12 +0100 froese (kernel-dvb/f/42_cx24110.c 1.4 644)
> @@ -251,7 +251,7 @@
> 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)
> @@ -372,6 +372,15 @@
> 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;
> @@ -419,6 +428,9 @@
> 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]);
>
> @@ -640,6 +652,7 @@
> .release = cx24110_release,
>
> .init = cx24110_initfe,
> + .sleep = cx24110_sleep,
> .set_frontend = cx24110_set_frontend,
> .get_frontend = cx24110_get_frontend,
> .read_status = cx24110_read_status,
> --- 0.1/drivers/media/dvb/dvb-core/dvb_frontend.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/g/41_dvb_fronte 1.1 644)
> +++ 0.7/drivers/media/dvb/dvb-core/dvb_frontend.c Sat, 07 Jan 2006 20:22:38 +0100 froese (kernel-dvb/g/41_dvb_fronte 1.2 644)
> @@ -50,13 +50,13 @@
>
> 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
> --- 0.1/drivers/media/dvb/bt8xx/dvb-bt8xx.h Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/8_dvb-bt8xx. 1.1 644)
> +++ 0.7/drivers/media/dvb/bt8xx/dvb-bt8xx.h Sat, 07 Jan 2006 02:03:06 +0100 froese (kernel-dvb/h/8_dvb-bt8xx. 1.2 644)
> @@ -49,8 +49,6 @@
> 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;
>
> --- 0.1/drivers/media/dvb/bt8xx/dvb-bt8xx.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/9_dvb-bt8xx. 1.1 644)
> +++ 0.7/drivers/media/dvb/bt8xx/dvb-bt8xx.c Sat, 07 Jan 2006 02:03:06 +0100 froese (kernel-dvb/h/9_dvb-bt8xx. 1.4 644)
> @@ -52,8 +52,6 @@
> {
> 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 @@
> 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 @@
> 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 @@
>
> /* 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 @@
> ((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 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 @@
> .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)
> @@ -615,7 +625,7 @@
> 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;
> #endif
>
> @@ -667,7 +677,7 @@
>
> /* 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;
> @@ -688,14 +698,14 @@
> }
>
> 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;
> @@ -707,7 +717,7 @@
> 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;
> @@ -726,7 +736,7 @@
> 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;
> @@ -737,7 +747,7 @@
> 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);
> @@ -747,7 +757,7 @@
> 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);
> @@ -758,7 +768,7 @@
> 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);
> @@ -768,7 +778,7 @@
> }
>
> 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);
> @@ -805,73 +815,33 @@
>
> 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;
> -
> -#ifdef BTTV_BOARD_DVICO_DVBT_LITE
> case BTTV_BOARD_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) */
> - break;
> -
> -#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
> case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
> -#endif
> - 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;
>
> -#ifdef BTTV_BOARD_TWINHAN_VP3021
> - case BTTV_BOARD_TWINHAN_VP3021:
> -#else
> case BTTV_BOARD_NEBULA_DIGITV:
> -#endif
> 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*/
> + 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;
> + 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_BOARD_PC_HDTV:
> - card->gpio_mode = 0x0100EC7B;
> - card->op_sync_orin = 0;
> - card->irq_err_ignore = 0;
> + card->gpio_mode = 0x0100EC60;
> break;
>
> default:
> @@ -884,15 +854,15 @@
> 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);
> --- 0.1/drivers/media/dvb/bt8xx/bt878.h Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/15_bt878.h 1.1 644)
> +++ 0.7/drivers/media/dvb/bt8xx/bt878.h Sun, 08 Jan 2006 01:45:15 +0100 froese (kernel-dvb/h/15_bt878.h 1.3 644)
> @@ -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,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)
> -
> extern int bt878_num;
>
> struct bt878 {
> @@ -119,14 +108,16 @@
> 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 */
> --- 0.1/drivers/media/dvb/bt8xx/bt878.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/16_bt878.c 1.1 644)
> +++ 0.7/drivers/media/dvb/bt8xx/bt878.c Sun, 08 Jan 2006 01:45:15 +0100 froese (kernel-dvb/h/16_bt878.c 1.4 644)
> @@ -78,7 +78,8 @@
> #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 @@
> #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 @@
> }
>
> 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 @@
> 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 @@
> /* 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 @@
>
> 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 @@
> 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
> @@ -395,8 +400,7 @@
> unsigned int cmd;
> #endif
>
> - printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
> - bt878_num);
> + printk(KERN_INFO "bt878: DVB interface found (%d).\n", bt878_num);
> if (pci_enable_device(dev))
> return -EIO;
>
> @@ -437,42 +441,35 @@
> 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;
> @@ -493,7 +490,7 @@
> 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,7 +501,6 @@
>
> /* 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);
>
> @@ -553,7 +549,7 @@
> 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-dvb mailing list
> linux-dvb at linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb
More information about the linux-dvb
mailing list