[linux-dvb] [PATCH 0/6] DVB-PinnSat: Pinnacle PCTV-Sat update for 2.6.15

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

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);


[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux