[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