[Asterisk-cvs] zaptel pciradio_vhdl.tar.gz, NONE, 1.1 pciradio.c, 1.4, 1.5 pciradio.rbt, 1.2, 1.3 zaptel.h, 1.39, 1.40 ztcfg.c, 1.18, 1.19 pciradio.ucf, 1.2, NONE pciradio.vhd, 1.2, NONE

jim at lists.digium.com jim at lists.digium.com
Tue Dec 21 23:48:40 CST 2004


Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv22014

Modified Files:
	pciradio.c pciradio.rbt zaptel.h ztcfg.c 
Added Files:
	pciradio_vhdl.tar.gz 
Removed Files:
	pciradio.ucf pciradio.vhd 
Log Message:
Changed out VHDL code so that interrupt handling would be much more efficient
and fully handle all functions


--- NEW FILE: pciradio_vhdl.tar.gz ---
(This appears to be a binary file; contents omitted.)

Index: pciradio.c
===================================================================
RCS file: /usr/cvsroot/zaptel/pciradio.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- pciradio.c	23 Nov 2004 02:04:12 -0000	1.4
+++ pciradio.c	22 Dec 2004 04:44:26 -0000	1.5
@@ -37,9 +37,8 @@
 
 /* Latency tests:
 
-Without driver:	308208
-Without int:	304096  (1.3 %)
-With PL check:	267722  (13.2 % -- will be much improved with new Xilinx)
+Without driver:	308496
+With driver:	303826  (1.5 %)
 
 */
 
@@ -90,11 +89,6 @@
 
 #define RAD_REGBASE	0xc0
 
-#define BIT_CS		(1 << 2)
-#define BIT_SCLK	(1 << 3)
-#define BIT_SDI		(1 << 4)
-#define BIT_SDO		(1 << 5)
-
 #define	RAD_CTCSSMASK	0xf
 #define	RAD_CTCSSOTHER	0xf
 #define	RAD_CTCSSVALID	0x10
@@ -103,16 +97,6 @@
 
 #define	RAD_GOTRX_DEBOUNCE_TIME 75
 
-/* bits for port 0 in */
-#define	MX828_DOUT	0x10		/* Data from MX828 */
-/* bits for port 0 out */
-#define MX828_DIN	0x2		/* Data to MX828 */
-#define	MX828_CS0	0x10		/* MX828 CS Channel 0 */
-#define MX828_CS1	0x20		/* MX828 CS Channel 1 */
-#define MX828_CS2	0x40		/* MX828 CS Channel 2 */
-#define	MX828_CS3	0x80		/* MX828 CS Channel 3 */
-#define MX828_SCLK	0x1		/* MX828 Serial Clock */
-
 /*
 * MX828 Commands
 */
@@ -134,6 +118,22 @@
 #define MX828_IRQ_FLAG          0x8F            /* R */
                                                                                 
 
+struct encdec
+{
+	unsigned char state;  /* 0 = idle */
+	int chan;
+	unsigned char req[NUM_CHANS];
+	unsigned char dcsrx[NUM_CHANS];
+	unsigned char ctrx[NUM_CHANS];
+	unsigned char dcstx[NUM_CHANS];
+	unsigned char cttx[NUM_CHANS];
+	unsigned char saudio_ctrl[NUM_CHANS];
+	unsigned char saudio_setup[NUM_CHANS];
+	unsigned char txcode[NUM_CHANS];
+	int myindex[NUM_CHANS];
+} ;
+
+
 struct pciradio {
 	struct pci_dev *dev;
 	struct zt_span span;
@@ -145,9 +145,9 @@
 	int freeregion;
 	int nchans;
 	spinlock_t lock;
-	unsigned char p0save;
-	unsigned char p1save;
-	unsigned char p2save;
+	spinlock_t rbilock;
+	unsigned char pasave;
+	unsigned char pfsave;
 	unsigned long ioaddr;
 	dma_addr_t 	readdma;
 	dma_addr_t	writedma;
@@ -164,6 +164,7 @@
 	int debouncetime[NUM_CHANS];
 	int bursttime[NUM_CHANS];
 	int bursttimer[NUM_CHANS];
+	unsigned char remmode[NUM_CHANS];
 	unsigned short present_code[NUM_CHANS];
 	unsigned short last_code[NUM_CHANS];
 	unsigned short rxcode[NUM_CHANS][NUM_CODES + 1];
@@ -178,6 +179,9 @@
 #define	RADMODE_NOENCODE 32
 	unsigned char corthresh[NUM_CHANS];
 	struct zt_chan chans[NUM_CHANS];
+	unsigned char mx828_addr;
+	struct encdec encdec;
+	unsigned long lastremcmd;
 };
 
 
@@ -449,35 +453,25 @@
 	return inb(rad->ioaddr + RAD_REGBASE + ((reg & 0xf) << 2));
 }
 
-static void wait_just_a_bit(int foo)
+
+void rbi_out(struct pciradio *rad, int n, unsigned char *rbicmd)
 {
-	long newjiffies;
-	newjiffies = jiffies + foo;
-	while(jiffies < newjiffies);
-}
+int	x;
+DECLARE_WAIT_QUEUE_HEAD(mywait);
 
-/*
-* Output a byte to the MX828 PL encoder/decoder chip
-*/
 
-void mx828_set_serdata(struct pciradio *rad,int bit)
-{
-	rad->p0save &= ~MX828_DIN;
-	if(bit)
-		rad->p0save |= MX828_DIN;
-	__pciradio_setcreg(rad,0,rad->p0save);
+	spin_lock(&rad->rbilock);
+	while(__pciradio_getcreg(rad,0xc) & 2) interruptible_sleep_on_timeout(&mywait,2);
+	/* enable and address RBI serializer */
+	__pciradio_setcreg(rad,0xf,rad->pfsave | (n << 4) | 0x40);
+	/* output commands */
+	for(x = 0; x < 5; x++) __pciradio_setcreg(rad,0xc,rbicmd[x]);
+	/* output it */
+	__pciradio_setcreg(rad,0xb,1);
+	spin_unlock(&rad->rbilock);
+	return;
 }
 
-void mx828_wiggle_sclk(struct pciradio *rad)
-{
-	rad->p0save &= ~MX828_SCLK;	/* SCLK 1 -> 0 */
-	__pciradio_setcreg(rad,0,rad->p0save);
-	udelay(1);
-        rad->p0save |= MX828_SCLK; /* SCLK 0 -> 1 */
-	__pciradio_setcreg(rad,0,rad->p0save);
-	udelay(1);
-}
-	
 
 /*
 * Output a command to the MX828 over the serial bus
@@ -487,192 +481,156 @@
 void mx828_command(struct pciradio *rad,int channel, unsigned char command, unsigned char *byte1, unsigned char *byte2)
 {
 
-	int i, param = 1, wr = 1, word = 0;
-	unsigned char byte;
-
 	if(channel > 3)
 		return;
 
-	/* Pull the transfer info from the command code */
-
-	switch(command){
-		case MX828_GEN_RESET: /* Commands with no param */
-			param = 0;
-			break;
-
-		case MX828_SAUDIO_CTRL: /* 8 bit write commands */
-		case MX828_SAUDIO_SETUP:
-		case MX828_DCS1:
-		case MX828_DCS2:
-		case MX828_DCS3:
-		case MX828_IRQ_MASK:
-		case MX828_GEN_CTRL:
-		case MX828_GPT:
-			break;
-
-		case MX828_SAUDIO_STATUS: /* 8 bit read commands */
-		case MX828_IRQ_FLAG:
-		case 0:
-			wr = 0;
-			break;
+	rad->mx828_addr = channel;
+	__pciradio_setcreg(rad,0,channel);
+	if (byte1) __pciradio_setcreg(rad,1,*byte1);
+	if (byte2) __pciradio_setcreg(rad,2,*byte2);
+	__pciradio_setcreg(rad,3,command);
+	
+}
 
-		case MX828_TX_TONE:	/* 16 bit write commands */
-		case MX828_RX_TONE:
-		case MX828_AUD_CTRL:
-		case MX828_SELCALL:
-			word = 1;
-			break;
+void mx828_command_wait(struct pciradio *rad,int channel, unsigned char command, unsigned char *byte1, unsigned char *byte2)
+{
+unsigned int flags;
+DECLARE_WAIT_QUEUE_HEAD(mywait);
 
-		default:
+	for(;;)
+	{
+		spin_lock_irqsave(&rad->lock,flags);
+		if ((!(__pciradio_getcreg(rad,0xc) & 1)) &&
+		    (!(rad->encdec.state)))
+		{
+			mx828_command(rad,channel,command,byte1,byte2);
+			spin_unlock_irqrestore(&rad->lock,flags);
 			return;
+		}
+		spin_unlock_irqrestore(&rad->lock,flags);
+		interruptible_sleep_on_timeout(&mywait,5);
 	}
-		
+}
 
-	mx828_set_serdata(rad,1);	/* Start with data = 1 */
 
-	udelay(2);
-	
-	/* Set the proper CS */
-
-	byte = (unsigned char ) 1 << (channel + 4);
-	
-	rad->p0save |= (MX828_CS0 | MX828_CS1 | MX828_CS2 | MX828_CS3);
-	rad->p0save &= ~byte;
-	__pciradio_setcreg(rad,0,rad->p0save);
+static void _do_encdec(struct pciradio *rad, int n)
+{
+int	i;
+unsigned char byte1,byte2;
 
-		
-	udelay(2);
-	
-	/* Output the command byte */
+	/* return doing nothing if busy */
+	if (__pciradio_getcreg(rad,0xc) & 1) return;
+	switch(rad->encdec.state)
+	{
+	    case 0:
+		if (!rad->encdec.req[n]) return;
+		rad->encdec.req[n] = 0;
+		rad->encdec.dcsrx[n] = 0;
+		rad->encdec.ctrx[n] = 0;
+		rad->encdec.dcstx[n] = 0;
+		rad->encdec.cttx[n] = 0;
+		rad->encdec.myindex[n] = 0;
+		rad->encdec.req[n] = 0;
+		rad->encdec.chan = n;
 
-	byte = command;
-	
-	for( i = 0 ; i < 8 ; i++){
-		udelay(2);
-		mx828_set_serdata(rad,0x80 & byte); /* MSB first */
-		byte <<= 1;
-		mx828_wiggle_sclk(rad);
-	}
-	if(param){
-		udelay(4);
-		if(wr){
-			byte = *byte1;
-			for( i = 0 ; i < 8 ; i++){
-				udelay(2);
-                		mx828_set_serdata(rad,0x80 & byte);
-                		byte <<= 1;
-                		mx828_wiggle_sclk(rad);
-        		}
-			if(word){
-				udelay(4);
-	                        byte = *byte2;
-        	                for( i = 0 ; i < 8 ; i++){
-					udelay(2);
-                	                mx828_set_serdata(rad,0x80 & byte);
-                        	        byte <<= 1;
-                                	mx828_wiggle_sclk(rad);
-                        	}
+		/* if something in code 0 for rx, is DCS */
+		if (rad->rxcode[n][0]) rad->encdec.dcsrx[n] = 1;
+		else { /* otherwise, if something in other codes, is CT rx */
+			for(i = 1; i <= NUM_CODES; i++)
+			{
+				if (rad->rxcode[n][1]) rad->encdec.ctrx[n] = 1;
 			}
+		}		
+		/* get index for tx code. Will be 0 if not receiving a CT */
+		rad->encdec.myindex[n] = 0;
+		if (rad->gotrx[n] && rad->encdec.ctrx[n] && (rad->present_code[n])) 
+			rad->encdec.myindex[n] = rad->present_code[n];
+		/* get actual tx code from array */
+		rad->encdec.txcode[n] = rad->txcode[n][rad->encdec.myindex[n]];
+		if (rad->encdec.txcode[n] & 0x8000) rad->encdec.dcstx[n] = 1;
+		     else if (rad->encdec.txcode[n]) rad->encdec.cttx[n] = 1;
+		if (rad->radmode[n] & RADMODE_NOENCODE) 
+			rad->encdec.dcstx[n] = rad->encdec.cttx[n] = 0;
+		if ((!rad->gottx[n]) || rad->bursttimer[n]) 
+			rad->encdec.dcstx[n] = rad->encdec.cttx[n] = 0;
+		rad->encdec.saudio_ctrl[n] = 0;
+		rad->encdec.saudio_setup[n] = 0;
+		rad->encdec.state = 1;
+		break;
+	    case 1:
+		if (rad->encdec.dcstx[rad->encdec.chan] && (!rad->encdec.dcsrx[rad->encdec.chan])) /* if to transmit DCS */
+		{
+			rad->encdec.saudio_setup[rad->encdec.chan] |= 3;
+			rad->encdec.saudio_ctrl[rad->encdec.chan] |= 0x80;
+			byte1 = dcstable[rad->encdec.txcode[rad->encdec.chan] & 0x7fff].b1;
+			mx828_command(rad,rad->encdec.chan, MX828_DCS1, &byte1, &byte2 );
+			rad->encdec.state = 2;
+			break;
+		} 
+		rad->encdec.state = 4;
+		break;
+	    case 2:	
+		byte1 = dcstable[rad->encdec.txcode[rad->encdec.chan] & 0x7fff].b2;
+		mx828_command(rad,rad->encdec.chan, MX828_DCS2, &byte1, &byte2 );
+		rad->encdec.state = 3;
+		break;
+	    case 3:
+		byte1 = dcstable[rad->encdec.txcode[rad->encdec.chan] & 0x7fff].b3;
+		mx828_command(rad,rad->encdec.chan, MX828_DCS3, &byte1, &byte2 );
+		rad->encdec.state = 4;
+		break;
+	    case 4:
+		if (rad->encdec.cttx[rad->encdec.chan])
+		{
+			rad->encdec.saudio_ctrl[rad->encdec.chan] |= 0x80;
+			byte1 = cttable_tx[rad->encdec.txcode[rad->encdec.chan]].b1;
+			byte2 = cttable_tx[rad->encdec.txcode[rad->encdec.chan]].b2;
+			mx828_command(rad,rad->encdec.chan, MX828_TX_TONE, &byte1, &byte2 );
 		}
-		else { /* rd */
-			byte = 0;
-			for( i = 0 ; i < 8 ; i++){	
-				mx828_wiggle_sclk(rad);
-				byte <<= 1;
-				udelay(2);
-				if(__pciradio_getcreg(rad,0) & MX828_DOUT)
-					byte |= 0x01;
-			}
-			*byte1 = byte;
-			if(word){
-				byte = 0;
-				udelay(4);
-				for( i = 0 ; i < 8 ; i++){
-					mx828_wiggle_sclk(rad);
-	                                byte <<= 1;
-					udelay(2);
-        	                        if(__pciradio_getcreg(rad,0) & MX828_DOUT)
-						byte |= 0x01;
-                	        }
-				*byte2 = byte;
-                        }
-                                                                                      
+		rad->encdec.state = 5;
+		break;
+	    case 5:
+		if (rad->encdec.dcsrx[rad->encdec.chan])
+		{
+			rad->encdec.saudio_setup[rad->encdec.chan] |= 1;
+			rad->encdec.saudio_ctrl[rad->encdec.chan] |= 0x41;
+			byte1 = dcstable[rad->rxcode[rad->encdec.chan][0]].b1;
+			mx828_command(rad,rad->encdec.chan, MX828_DCS1, &byte1, &byte2 );
+			rad->encdec.state = 6;
+			break;
 		}
-	}
-
-	udelay(4);
-
-	/* Release chip selects */
-        rad->p0save |= (MX828_CS0 | MX828_CS1 | MX828_CS2 | MX828_CS3);
-	__pciradio_setcreg(rad,0,rad->p0save);
-}			
-		
-
-static void _set_encdec(struct pciradio *rad, int n)
-{
-int	i,myindex;
-char	dcsrx = 0, ctrx = 0, dcstx = 0, cttx = 0;
-unsigned char byte1,byte2,saudio_ctrl,saudio_setup;
-unsigned short txcode;
-
-
-	/* if something in code 0 for rx, is DCS */
-	if (rad->rxcode[n][0]) dcsrx = 1;
-	else { /* otherwise, if something in other codes, is CT rx */
-		for(i = 1; i <= NUM_CODES; i++)
+		rad->encdec.state = 8;
+		break;
+	    case 6:
+		byte1 = dcstable[rad->rxcode[rad->encdec.chan][0]].b2;
+		mx828_command(rad,rad->encdec.chan, MX828_DCS2, &byte1, &byte2 );
+		rad->encdec.state = 7;
+		break;
+	    case 7:
+		byte1 = dcstable[rad->rxcode[rad->encdec.chan][0]].b3;
+		mx828_command(rad,rad->encdec.chan, MX828_DCS3, &byte1, &byte2 );
+		rad->encdec.state = 8;
+		break;
+	    case 8:
+		if (rad->encdec.ctrx[rad->encdec.chan])
 		{
-			if (rad->rxcode[n][1]) ctrx = 1;
+			rad->encdec.saudio_setup[rad->encdec.chan] |= 0x80;
+			rad->encdec.saudio_ctrl[rad->encdec.chan] |= 0x60;
 		}
-	}		
-	/* get index for tx code. Will be 0 if not receiving a CT */
-	myindex = 0;
-	if (rad->gotrx[n] && ctrx && (rad->present_code[n])) myindex = rad->present_code[n];
-	/* get actual tx code from array */
-	txcode = rad->txcode[n][myindex];
-	if (txcode & 0x8000) dcstx = 1; else if (txcode) cttx = 1;
-	if (rad->radmode[n] & RADMODE_NOENCODE) dcstx = cttx = 0;
-	if ((!rad->gottx[n]) || rad->bursttimer[n]) dcstx = cttx = 0; 
-	saudio_ctrl = 0;
-	saudio_setup = 0;
-	if (dcstx && (!dcsrx)) /* if to transmit DCS */
-	{
-		saudio_setup |= 3;
-		saudio_ctrl |= 0x80;
-		byte1 = dcstable[txcode & 0x7fff].b1;
-		mx828_command(rad,n, MX828_DCS1, &byte1, &byte2 );
-		byte1 = dcstable[txcode & 0x7fff].b2;
-		mx828_command(rad,n, MX828_DCS2, &byte1, &byte2 );
-		byte1 = dcstable[txcode & 0x7fff].b3;
-		mx828_command(rad,n, MX828_DCS3, &byte1, &byte2 );
-	}
-	if (cttx)
-	{
-		saudio_ctrl |= 0x80;
-		byte1 = cttable_tx[txcode].b1;
-		byte2 = cttable_tx[txcode].b2;
-		mx828_command(rad,n, MX828_TX_TONE, &byte1, &byte2 );
-	}
-	if (dcsrx)
-	{
-		saudio_setup |= 1;
-		saudio_ctrl |= 0x41;
-		byte1 = dcstable[rad->rxcode[n][0]].b1;
-		mx828_command(rad,n, MX828_DCS1, &byte1, &byte2 );
-		byte1 = dcstable[rad->rxcode[n][0]].b2;
-		mx828_command(rad,n, MX828_DCS2, &byte1, &byte2 );
-		byte1 = dcstable[rad->rxcode[n][0]].b3;
-		mx828_command(rad,n, MX828_DCS3, &byte1, &byte2 );
-	}
-	if (ctrx)
-	{
-		saudio_setup |= 0x80;
-		saudio_ctrl |= 0x60;
+		byte1 = rad->encdec.saudio_setup[rad->encdec.chan];
+		mx828_command(rad,rad->encdec.chan, MX828_SAUDIO_SETUP, &byte1, &byte2 );
+		rad->encdec.state = 9;
+		break;
+	    case 9:
+		byte1 = rad->encdec.saudio_ctrl[rad->encdec.chan];
+		mx828_command(rad,rad->encdec.chan, MX828_SAUDIO_CTRL, &byte1, &byte2 );
+		rad->encdec.state = 10;
+		break;
+	    case 10:
+		rad->encdec.chan = 0;
+		rad->encdec.state = 0;
+		break;
 	}
-	byte1 = saudio_setup;
-	mx828_command(rad,n, MX828_SAUDIO_SETUP, &byte1, &byte2 );
-	byte1 = saudio_ctrl;
-	mx828_command(rad,n, MX828_SAUDIO_CTRL, &byte1, &byte2 );
-	return;
 }
 
 static inline void pciradio_transmitprep(struct pciradio *rad, unsigned char ints)
@@ -767,10 +725,15 @@
 	if (ints & 0x0f) {
 		rad->intcount++;
 		x = rad->intcount % rad->nchans;
-		mx828_command(rad, x, MX828_SAUDIO_STATUS, &byte1, &byte2);
+		/* freeze */
+		__pciradio_setcreg(rad,0,rad->mx828_addr | 4);
+		/* read SAUDIO_STATUS for the proper channel */
+		byte1 = __pciradio_getcreg(rad,x);
+		/* thaw */
+		__pciradio_setcreg(rad,0,rad->mx828_addr);
 		rad->saudio_status[x] = byte1;
 		/* get COR input */
-		byte2 = __pciradio_getcreg(rad,0);
+		byte2 = __pciradio_getcreg(rad,9);
 		/* get bit for this channel */
 		gotcor = byte2 & (1 << x);
 		if (rad->radmode[x] & RADMODE_INVERTCOR) gotcor = !gotcor;
@@ -805,18 +768,22 @@
 		} else if (gotslowctcss) rad->present_code[x] = (byte1 & RAD_CTCSSMASK) + 1;
 		if (rad->radmode[x] & RADMODE_EXTTONE)
 		{
-			unsigned mask = 1 << (x + 4);
+			unsigned mask = 1 << (x + 4); /* they're on the UIOB's */
 			unsigned char byteuio;
 
+			/* set UIOB as input */
+			byteuio = __pciradio_getcreg(rad,0xe);
+			byteuio |= mask;
+			__pciradio_setcreg(rad,0xe,byteuio);
 			/* get UIO input */
-			byteuio = __pciradio_getcreg(rad,1);
+			byteuio = __pciradio_getcreg(rad,8);
 			if (rad->radmode[x] & RADMODE_EXTINVERT)
 				gotctcss = gotslowctcss = ((byteuio & mask) == 0);
 			else
 				gotctcss = gotslowctcss = ((byteuio & mask) != 0);
 		}
 		rad->gotct[x] = gotslowctcss;
-		if (rad->radmode[x] & RADMODE_IGNORECT)
+		if ((rad->radmode[x] & RADMODE_IGNORECT) || (!ctcss))
 		{
 			gotctcss = 1;
 			gotslowctcss = 1;
@@ -830,9 +797,10 @@
 		rad->gotrx[x] = gotrx;
 		if (rad->present_code[x] != rad->last_code[x])
 		{
-			_set_encdec(rad,x);
+			rad->encdec.req[x] = 1;
 			rad->last_code[x] = rad->present_code[x];
 		}
+		_do_encdec(rad,x);
 		for(x = 0; x < rad->nchans; x++)
 		{
 			unsigned char mask = 1 << x;
@@ -842,22 +810,22 @@
 				if (rad->gottx[x])
 				{
 					rad->bursttimer[x] = 0;
-					rad->p1save |= mask;
-					__pciradio_setcreg(rad, 1, rad->p1save);
+					rad->pasave |= mask;
+					__pciradio_setcreg(rad, 0xa, rad->pasave);
 				}
 				else
 				{
 					if (!rad->bursttime[x])
 					{
-						rad->p1save &= ~mask;
-						__pciradio_setcreg(rad, 1, rad->p1save);
+						rad->pasave &= ~mask;
+						__pciradio_setcreg(rad, 0xa, rad->pasave);
 					}
 					else
 					{
 						rad->bursttimer[x] = rad->bursttime[x];
 					}
 				}
-				_set_encdec(rad,x);
+				rad->encdec.req[x] = 1;
 				rad->lasttx[x] = rad->gottx[x];
 			}
 			if (rad->bursttimer[x])
@@ -867,8 +835,8 @@
 				{
 					unsigned char mask = 1 << x;
 
-					rad->p1save &= ~mask;
-					__pciradio_setcreg(rad, 1, rad->p1save);
+					rad->pasave &= ~mask;
+					__pciradio_setcreg(rad, 0xa, rad->pasave);
 				}
 			}
 
@@ -881,9 +849,9 @@
 					unsigned char mask;
 
 					mask = 1 << (x + 4);
-					rad->p1save &= ~mask;
-					if (gotctcss) rad->p1save |= mask;
-					__pciradio_setcreg(rad, 1, rad->p1save);
+					rad->pasave &= ~mask;
+					if (gotctcss) rad->pasave |= mask;
+					__pciradio_setcreg(rad, 0xa, rad->pasave);
 
 					if (rad->gotrx[x] != rad->gotrx1[x])
 					{
@@ -901,7 +869,7 @@
 						    if (debug) printk("Chan %d lost rx\n",x + 1);
 						    zt_qevent_lock(&rad->chans[x], ZT_EVENT_ONHOOK);
 						}
-						_set_encdec(rad,x);
+						rad->encdec.req[x] = 1;
 					}
 					rad->gotrx1[x] = rad->gotrx[x];
 				}
@@ -920,13 +888,14 @@
 {
 	int i,mycode;
 	unsigned long flags;
-	unsigned char byte1,byte2;
+	unsigned char byte1,byte2,mask;
 	union {
 		struct zt_radio_stat s;
 		struct zt_radio_param p;
 	} stack;
 
 	struct pciradio *rad = chan->pvt;
+	DECLARE_WAIT_QUEUE_HEAD(mywait);
 
 	switch (cmd) {
 	case ZT_RADIO_GETPARAM:
@@ -997,6 +966,21 @@
 		case ZT_RADPAR_BURSTTIME:
 			stack.p.data = rad->bursttime[chan->chanpos - 1];
 			break;
+		case ZT_RADPAR_UIODATA:
+			stack.p.data = 0;
+			byte1 = __pciradio_getcreg(rad,8);
+			if (byte1 & (1 << (chan->chanpos - 1))) stack.p.data |= 1;
+			if (byte1 & (1 << (chan->chanpos + 3))) stack.p.data |= 2;
+			break;
+		case ZT_RADPAR_UIOMODE:
+			stack.p.data = 0;
+			byte1 = __pciradio_getcreg(rad,0xe);
+			if (byte1 & (1 << (chan->chanpos - 1))) stack.p.data |= 1;
+			if (byte1 & (1 << (chan->chanpos + 3))) stack.p.data |= 2;
+			break;
+		case ZT_RADPAR_REMMODE:
+			stack.p.data = rad->remmode[chan->chanpos - 1];
+			break;
 		default:
 			spin_unlock_irqrestore(&rad->lock,flags);
 			return -EINVAL;
@@ -1038,6 +1022,8 @@
 				return -EINVAL;
 			}
 			rad->corthresh[chan->chanpos - 1] = stack.p.data;
+			byte1 = 0xc0 | (rad->corthresh[chan->chanpos - 1] << 2);
+			mx828_command_wait(rad,chan->chanpos - 1, MX828_GEN_CTRL, &byte1, &byte2);
 			break;
 		case ZT_RADPAR_EXTRXTONE:
 			if (stack.p.data)
@@ -1061,11 +1047,11 @@
 			{
 				/* set to no encode/decode */
 				byte1 = 0;
-				mx828_command(rad,chan->chanpos - 1, MX828_SAUDIO_CTRL, &byte1, &byte2 );
+				mx828_command_wait(rad,chan->chanpos - 1, MX828_SAUDIO_CTRL, &byte1, &byte2 );
 				/* set rx tone to none */
 				byte1 = i << 4;
 				byte2 = 0;
-				mx828_command(rad,chan->chanpos - 1, MX828_RX_TONE, &byte1, &byte2 );
+				mx828_command_wait(rad,chan->chanpos - 1, MX828_RX_TONE, &byte1, &byte2 );
 			}
 		case ZT_RADPAR_RXTONE:
 			if (!stack.p.index) /* if RX DCS mode */
@@ -1080,7 +1066,7 @@
 					return -EINVAL;
 				}
 				rad->rxcode[chan->chanpos - 1][0] = mycode;
-				_set_encdec(rad,chan->chanpos - 1);
+				rad->encdec.req[chan->chanpos - 1] = 1;
 				break;
 			}
 			if ((stack.p.index < 1) || (stack.p.index > NUM_CODES)) {
@@ -1095,10 +1081,10 @@
 			rad->rxcode[chan->chanpos - 1][stack.p.index] = mycode;
 			byte1 = cttable_rx[mycode].b1 | ((stack.p.index - 1) << 4);
 			byte2 = cttable_rx[mycode].b2;
-			mx828_command(rad,chan->chanpos - 1, MX828_RX_TONE, &byte1, &byte2 );
+			mx828_command_wait(rad,chan->chanpos - 1, MX828_RX_TONE, &byte1, &byte2 );
 			/* zot out DCS one if there */
 			rad->rxcode[chan->chanpos - 1][0] = 0;
-			_set_encdec(rad,chan->chanpos - 1);
+			rad->encdec.req[chan->chanpos - 1] = 1;
 			break;
 		case ZT_RADPAR_RXTONECLASS:
 			if ((stack.p.index < 1) || (stack.p.index > NUM_CODES)) {
@@ -1122,7 +1108,7 @@
 			}
 			if (stack.p.data & 0x8000) mycode |= 0x8000;
 			rad->txcode[chan->chanpos - 1][stack.p.index] = mycode;
-			_set_encdec(rad,chan->chanpos - 1);
+			rad->encdec.req[chan->chanpos - 1] = 1;
 			break;
 		case ZT_RADPAR_DEBOUNCETIME:
 			rad->debouncetime[chan->chanpos - 1] = stack.p.data;
@@ -1130,6 +1116,53 @@
 		case ZT_RADPAR_BURSTTIME:
 			rad->bursttime[chan->chanpos - 1] = stack.p.data;
 			break;
+		case ZT_RADPAR_UIODATA:
+			spin_lock_irqsave(&rad->lock,flags);
+			byte1 = __pciradio_getcreg(rad,8);
+			byte1 &= ~(1 << (chan->chanpos - 1));
+			byte1 &= ~(1 << (chan->chanpos + 3));
+			if (stack.p.data & 1) byte1 |= (1 << (chan->chanpos - 1));
+			if (stack.p.data & 2) byte1 |= (1 << (chan->chanpos + 3));
+			__pciradio_setcreg(rad,8,byte1);
+			spin_unlock_irqrestore(&rad->lock,flags);
+			break;
+		case ZT_RADPAR_UIOMODE:
+			spin_lock_irqsave(&rad->lock,flags);
+			byte1 = __pciradio_getcreg(rad,0xe);
+			byte1 &= ~(1 << (chan->chanpos - 1));
+			byte1 &= ~(1 << (chan->chanpos + 3));
+			if (stack.p.data & 1) byte1 |= (1 << (chan->chanpos - 1));
+			if (stack.p.data & 2) byte1 |= (1 << (chan->chanpos + 3));
+			__pciradio_setcreg(rad,0xe,byte1);
+			spin_unlock_irqrestore(&rad->lock,flags);
+			break;
+		case ZT_RADPAR_REMMODE:
+			rad->remmode[chan->chanpos - 1] = stack.p.data;
+			break;
+		case ZT_RADPAR_REMCOMMAND:
+			i = 0;
+			/* set UIOA and UIOB for output */
+			spin_lock_irqsave(&rad->lock,flags);
+			byte1 = __pciradio_getcreg(rad,0xe);
+			mask = (1 << (chan->chanpos - 1)) | 
+				(1 << (chan->chanpos + 3));
+			byte2 = byte1 & (~mask);
+			i = (byte2 != byte1);
+			__pciradio_setcreg(rad,0xe,byte2);
+			byte1 = __pciradio_getcreg(rad,8);
+			mask = 1 << (chan->chanpos - 1);
+			byte2 = byte1 | mask;
+			i = (byte2 != byte1);
+			__pciradio_setcreg(rad,8,byte2);
+			spin_unlock_irqrestore(&rad->lock,flags);
+			if (i || (jiffies < rad->lastremcmd + 10))
+				interruptible_sleep_on_timeout(&mywait,10);
+			rad->lastremcmd = jiffies;
+			if (rad->remmode[chan->chanpos - 1])
+			{
+				rbi_out(rad,chan->chanpos - 1,(unsigned char *)&stack.p.data);
+			}
+			break;
 		default:
 			spin_unlock_irqrestore(&rad->lock,flags);
 			return -EINVAL;
@@ -1243,7 +1276,7 @@
 		break;
 	}
 	if (debug)
-		printk("pciradio: Setting Radio hook state to %d\n", txsig);
+		printk("pciradio: Setting Radio hook state to %d on chan %d\n", txsig, chan->chanpos);
 	return 0;
 }
 
@@ -1280,6 +1313,13 @@
 	return 0;
 }
 
+static void wait_just_a_bit(int foo)
+{
+	long newjiffies;
+	newjiffies = jiffies + foo;
+	while(jiffies < newjiffies);
+}
+
 static int pciradio_hardware_init(struct pciradio *rad)
 {
 unsigned char byte1,byte2;
@@ -1367,11 +1407,16 @@
 	printk("Xilinx Chip successfully loaded, configured and started!!\n");
 
 
-	rad->p0save = 0xf0;
-	__pciradio_setcreg(rad,0,rad->p0save);
+	rad->pasave = 0;
+	__pciradio_setcreg(rad,0xa,rad->pasave);
+
+	__pciradio_setcreg(rad,8,0);
+	__pciradio_setcreg(rad,9,0x55);
+	__pciradio_setcreg(rad,0xe,0);
+	rad->pfsave = 0;
+	__pciradio_setcreg(rad,0xf,rad->pfsave);
+
 
-	rad->p1save = 0;
-	__pciradio_setcreg(rad,1,rad->p1save);
 
 	/* Back to normal, with automatic DMA wrap around */
 	outb(0x30 | 0x01, rad->ioaddr + RAD_CNTL);
@@ -1402,20 +1447,20 @@
 
 	for(x = 0; x < rad->nchans; x++)
 	{
-		mx828_command(rad,x, MX828_GEN_RESET, &byte1, &byte2 );
+		mx828_command_wait(rad,x, MX828_GEN_RESET, &byte1, &byte2 );
 		byte1 = 0x3f;
 		byte2 = 0x3f;
-		mx828_command(rad,x, MX828_AUD_CTRL, &byte1, &byte2 );
+		mx828_command_wait(rad,x, MX828_AUD_CTRL, &byte1, &byte2 );
 		byte1 = 0;
-		mx828_command(rad,x, MX828_SAUDIO_SETUP, &byte1, &byte2 );
+		mx828_command_wait(rad,x, MX828_SAUDIO_SETUP, &byte1, &byte2 );
 		byte1 = 0;
-		mx828_command(rad,x, MX828_SAUDIO_CTRL, &byte1, &byte2 );
-		byte1 = 0xc0;
-		mx828_command(rad,x, MX828_GEN_CTRL, &byte1, &byte2);
+		mx828_command_wait(rad,x, MX828_SAUDIO_CTRL, &byte1, &byte2 );
+		byte1 = 0xc8;  /* default COR thresh is 2 */
+		mx828_command_wait(rad,x, MX828_GEN_CTRL, &byte1, &byte2);
+		rad->corthresh[x] = 2;
 	}
 
 
-
 	return 0;
 }
 
@@ -1489,6 +1534,7 @@
 			ifaces[x] = rad;
 			memset(rad, 0, sizeof(struct pciradio));
 			spin_lock_init(&rad->lock);
+			spin_lock_init(&rad->rbilock);
 			rad->nchans = 4;
 			rad->ioaddr = pci_resource_start(pdev, 0);
 			rad->dev = pdev;

Index: pciradio.rbt
===================================================================
RCS file: /usr/cvsroot/zaptel/pciradio.rbt,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- pciradio.rbt	23 Nov 2004 02:04:12 -0000	1.2
+++ pciradio.rbt	22 Dec 2004 04:44:26 -0000	1.3
@@ -1,9 +1,9 @@
 Xilinx ASCII Bitstream
 Created by Bitstream E.33
-Design name: 	pciradio.ncd
+Design name: 	pciradio_xilinx.ncd
 Architecture:	spartan2
 Part:        	2s30vq100
-Date:        	Mon Nov 22 18:40:36 2004
+Date:        	Mon Dec 20 20:30:21 2004
 Bits:        	336768
 11111111111111111111111111111111
 10101010100110010101010101100110
[...14384 lines suppressed...]
@@ -9187,8 +9187,8 @@
 00000000000000000000000000000000
 00001000000100000000000000000111
 00110000000000011100110000000000
-01110011000000000001110011000000
-00000111001100000000000111001100
+01000000000000000001110011000000
+00000100000000000000000111001100
 00000000011100110000000000011100
 11000000000001110011000000000001
 11001100000000000111001100000000
@@ -10506,7 +10506,7 @@
 00000000000000000000000000000000
 00000000000000000000000000000000
 00110000000000000000000000000001
-00000000000000000001010100111001
+00000000000000001011100001100010
 00110000000000001000000000000001
 00000000000000000000000000000011
 00110000000000000100000000001001

Index: zaptel.h
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.h,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- zaptel.h	4 Nov 2004 20:04:53 -0000	1.39
+++ zaptel.h	22 Dec 2004 04:44:26 -0000	1.40
@@ -1473,7 +1473,8 @@
 struct zt_radio_param {
 	unsigned short radpar;	/* param identifier */
 	unsigned short index;	/* tone number */
-	int data;		/* pointer to param */
+	int data;		/* param */
+	int data2;		/* param 2 */
 };
 
 
@@ -1522,9 +1523,6 @@
 #define	ZT_RADPAR_BURSTTIME 13	/* end of transmit with no CT tone in
 				   milliseconds (0-999) */
 
-#if	0
-The following are not implemented in the prototype version of the card:
-(UIO will always be an input for external CTCSS decode input)
 
 #define	ZT_RADPAR_UIODATA 14	/* read/write UIOA and UIOB data. Bit 0 is
 				   UIOA, bit 1 is UIOB */
@@ -1535,12 +1533,11 @@
 				   mode for UIOA is overridden when in
 				   EXTRXTONE mode. */
 
-#define	ZT_RADPAR_EXTDATA 16	/* read/write external byte, set index also
-				   (0-2) */
-#define	ZT_RADPAR_EXTMODE 17	/* set mode for external byte, bitwise a 1
-				    means write, and 0 means read, set index
-				    also (0-2) */
+#define	ZT_RADPAR_REMMODE 16	/* Remote control data mode */
+	#define	ZT_RADPAR_REM_NONE 0 	/* no remote control data mode */
+	#define	ZT_RADPAR_REM_RBI1 1	/* Doug Hall RBI-1 data mode */				   
+
+#define	ZT_RADPAR_REMCOMMAND 17	/* Remote conrtol write data block & do cmd */
 
-#endif
 
 #endif /* _LINUX_ZAPTEL_H */

Index: ztcfg.c
===================================================================
RCS file: /usr/cvsroot/zaptel/ztcfg.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- ztcfg.c	5 Nov 2004 02:55:58 -0000	1.18
+++ ztcfg.c	22 Dec 2004 04:44:26 -0000	1.19
@@ -806,7 +806,7 @@
 	if (res != 1) {
 		error("Invalid value '%s', should be a number > 0.\n", realargs[0]);
 	}
-	corthresh = x;
+	corthresh = x + 1;
 	return 0;
 }
 
@@ -881,11 +881,13 @@
 		return -1;
 	for (x=1;x<ZT_MAX_CHANNELS;x++) {
 		if (chans[x]) {
-
 			p.radpar = ZT_RADPAR_NUMTONES;
 			if (ind_ioctl(x,fd,ZT_RADIO_GETPARAM,&p) == -1)
 				error("Cannot get number of tones chanel %d\n",x);
 			n = p.data;
+			p.radpar = ZT_RADPAR_INITTONE;
+			if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
+				error("Cannot init tones chanel %d\n",x);
 			if (!rxtones[0]) for(i = 1; i <= n; i++)
 			{
 				if (rxtones[i])
@@ -912,12 +914,15 @@
 					if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
 						error("Cannot set txtone on channel %d\n",x);
 				}
-			} else { /* if we have DCS receive */
-				p.radpar = ZT_RADPAR_RXTONE;
-				p.index = 0;
-				p.data = rxtones[0];
-				if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
-					error("Cannot set DCS rxtone on channel %d\n",x);
+			} else { /* if we may have DCS receive */
+				if (rxtones[0])
+				{
+					p.radpar = ZT_RADPAR_RXTONE;
+					p.index = 0;
+					p.data = rxtones[0];
+					if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
+						error("Cannot set DCS rxtone on channel %d\n",x);
+				}
 			}
 			if (txtones[0])
 			{
@@ -955,10 +960,13 @@
 				if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
 					error("Cannot set exttone on channel %d\n",x);
 			}
-			p.radpar = ZT_RADPAR_CORTHRESH;
-			p.data = corthresh;
-			if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
-				error("Cannot set corthresh on channel %d\n",x);
+			if (corthresh)
+			{
+				p.radpar = ZT_RADPAR_CORTHRESH;
+				p.data = corthresh - 1;
+				if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1)
+					error("Cannot set corthresh on channel %d\n",x);
+			}
 		}
 	}
 	clear_fields();

--- pciradio.ucf DELETED ---

--- pciradio.vhd DELETED ---




More information about the svn-commits mailing list