summaryrefslogtreecommitdiff
path: root/torisa.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-12-23 21:45:09 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-12-23 21:45:09 +0000
commit1699b655be978ba8bc1d09f6c01b3255e0efe734 (patch)
treebb6bda6077c0b813fa6c5bbbd0b1c380864bc54e /torisa.c
parent321856cd083c77dbcbf71f12a6a6bc9691c81d57 (diff)
Version 0.1.4 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@43 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'torisa.c')
-rwxr-xr-xtorisa.c519
1 files changed, 365 insertions, 154 deletions
diff --git a/torisa.c b/torisa.c
index c4fa92d..71182d7 100755
--- a/torisa.c
+++ b/torisa.c
@@ -1,5 +1,5 @@
/*
- * Zapata Telephony "Tormenta" ISA card LINUX driver, version 2.0 X/X/01
+ * Zapata Telephony "Tormenta" ISA card LINUX driver, version 2.2 11/29/01
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,14 +44,15 @@
#define CTLREG 0x100 /* Control/Status Reg., 0x200 in byte offset */
/* Control register bits */
-#define MASTERCLOCK 0 /* Value for Master Clock */
#define OUTBIT 8 /* Status output bit (for external measurements) */
#define INTENA 4 /* Interrupt enable bit */
+#define MASTERVAL 0x41 /* Enable E1 master clock on Rev. B board */
#define ENA16 0x80 /* 16 bit bus cycle enable bit */
-/* signalling bits */
-#define TOR_ABIT 8
-#define TOR_BBIT 4
+#define TYPE_T1 1 /* is a T1 card */
+#define TYPE_E1 2 /* is an E1 card */
+
+#define E1SYNCSTABLETHRESH 15000 /* amount of samples needed for E1 Sync stability */
static int syncsrc;
@@ -59,13 +60,25 @@ static int syncs[2];
static int debug;
+#define MASTERCLOCK (*clockvals) /* value for master clock */
+
/* clock values */
-static u_char clockvals[] = {0,0x12,0x22,0};
+static u_char clockvals_t1[] = {MASTERVAL,0x12,0x22,MASTERVAL};
+static u_char clockvals_e1[] = {MASTERVAL,0x13,0x23,MASTERVAL};
+
+static u_char *clockvals;
/* translations of data channels for 24 channels in a 32 bit PCM highway */
-unsigned datxlt[] = { 0,
+unsigned datxlt_t1[] = { 0,
1 ,2 ,3 ,5 ,6 ,7 ,9 ,10,11,13,14,15,17,18,19,21,22,23,25,26,27,29,30,31 };
+/* translations of data channels for 30/31 channels in a 32 bit PCM highway */
+unsigned datxlt_e1[] = { 0,
+ 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+ 25,26,27,28,29,30,31 };
+
+unsigned int *datxlt;
+
/* This is the order that the data (audio) channels get
scanned in. This was done in this rather poopy manner because when outputting
(and inputting) a sine wave, such as in the case of TDD, any repeated samples
@@ -87,29 +100,38 @@ first thing we do in the interrupt handler. Worst case (30 microseconds)
is that the MT8920 has only moved 7 channels. That's where the 6 comes from.
*/
-static int chseq[] =
+static int chseq_t1[] =
{ 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,1,2,3,4,5 } ;
+static int chseq_e1[] =
+ { 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,1,2,3,4,5 } ;
+
+static int *chseq;
+
struct torisa_pvt {
int span;
};
static struct zt_span spans[2];
-static struct zt_chan chans[48];
-static struct torisa_pvt pvts[48];
-static u_char txsigs[2][6];
+static struct zt_chan chans[64];
+static struct torisa_pvt pvts[64];
+static u_char txsigs[2][16];
static int loopupcnt[2];
static int loopdowncnt[2];
static int alarmtimer[2];
+static int channels_per_span = 24;
+
+static int card_type = TYPE_T1;
+
static int prefmaster = 0;
static int spansstarted = 0;
static rwlock_t torisa;
-static u_char readdata[2][48][ZT_MAX_CHUNKSIZE];
-static u_char writedata[2][48][ZT_MAX_CHUNKSIZE];
+static u_char readdata[2][64][ZT_MAX_CHUNKSIZE];
+static u_char writedata[2][64][ZT_MAX_CHUNKSIZE];
static int curread;
static unsigned long base;
@@ -176,7 +198,7 @@ static void set_clear(void)
int i,j,s;
unsigned short val=0;
for (s=0;s<2;s++) {
- for (i=0;i<24;i++) {
+ for (i=0;i<channels_per_span;i++) {
j = (i/8);
if (spans[s].chans[i].flags & ZT_FLAG_CLEAR)
val |= 1 << (i % 8);
@@ -205,12 +227,15 @@ tor_probe(void)
status = -1; /* default status return is 'not present' */
+ clockvals = clockvals_t1;
+ datxlt = datxlt_t1;
+ chseq = chseq_t1;
+
/* initialize control register */
setctlreg(MASTERCLOCK);
/* init all the registers in first T-1 chip to 0 */
- for(i = 0x20; i < 0x40; i++) t1out(1,i,0); /* set register to 0 */
- for(i = 0x60; i < 0x80; i++) t1out(1,i,0); /* set register to 0 */
+ for(i = 0; i <= 0xff; i++) t1out(1,i,0); /* set register to 0 */
/* simple test that will fail if tried in an array of standard memory */
/* put an 0x55 here */
t1out(1,0x2b,0x55);
@@ -221,8 +246,26 @@ tor_probe(void)
/* get input from second location */
c2 = t1in(1,0x2c);
/* see if we read back what we put in */
- if ((c1 == 0x55) && (c2 == 0xaa))
- {
+ if ((c1 == 0x55) && (c2 == 0xaa)) {
+ /* We now need to determine card type */
+ /* This test is documented in Dallas app note 341 */
+ t1out(1, 0x7D, 0);
+ t1out(1, 0x36, 0);
+ t1out(1, 0x15, 0);
+ t1out(1, 0x19, 0);
+ t1out(1, 0x23, 0x55);
+ c1 = t1in(1, 0x23);
+ if (c1 == 0x55) { /* if this is an E-1 card */
+
+ clockvals = clockvals_e1;
+ chseq = chseq_e1;
+ channels_per_span = 31;
+ datxlt = datxlt_e1;
+ card_type = TYPE_E1;
+
+ /* initialize control register */
+ setctlreg(MASTERCLOCK);
+ }
/* Try to get the irq if the user didn't specify one */
if (irq < 1) {
autoirq_setup(0);
@@ -240,9 +283,12 @@ tor_probe(void)
status = 0; /* found */
if (debug)
- printk("ISA Tormenta Card found at base addr 0x%lx, irq %d\n",base,irq);
+ printk("ISA Tormenta %s Card found at base addr 0x%lx, irq %d\n",
+ ((card_type == TYPE_E1) ? "E1" : "T1"),
+ base,irq);
} else
- printk("ISA Tormenta Card found at base addr 0x%lx, but unable to determine IRQ. Try using irq= option\n", base);
+ printk("ISA Tormenta %s Card found at base addr 0x%lx, but unable to determine IRQ. Try using irq= option\n",
+ ((card_type == TYPE_E1) ? "E1" : "T1"), base );
}
return status;
}
@@ -252,8 +298,8 @@ static void make_chans(void)
int x,y;
int c;
for (x=0;x<2;x++)
- for (y=0;y<24;y++) {
- c = x * 24 + y;
+ for (y=0;y<channels_per_span;y++) {
+ c = x * channels_per_span + y;
sprintf(chans[c].name, "TorISA/%d/%d", x + 1, y + 1);
chans[c].sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS |
ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS;
@@ -270,9 +316,23 @@ static int torisa_rbsbits(struct zt_chan *chan, int bits)
int k,n,b;
struct torisa_pvt *p = chan->pvt;
unsigned int flags;
-#if 0
- printk("Setting bits to %d on channel %s\n", bits, chan->name);
-#endif
+#if 0
+ printk("Setting bits to %x hex on channel %s\n", bits, chan->name);
+#endif
+ if (card_type == TYPE_E1) { /* do it E1 way */
+ if (chan->chanpos > 30) return 0; /* cant do this for chan 31 */
+ n = chan->chanpos - 1;
+ k = p->span;
+ b = (n % 15) + 1;
+ c = txsigs[k][b];
+ m = (n / 15) * 4; /* nibble selector */
+ c &= (15 << m); /* keep the other nibble */
+ c |= (bits & 15) << (4 - m); /* put our new nibble here */
+ txsigs[k][b] = c;
+ /* output them into the chip */
+ t1out(k + 1,0x40 + b,c);
+ return 0;
+ }
n = chan->chanpos - 1;
k = p->span;
b = (n / 8); /* get byte number */
@@ -284,7 +344,6 @@ static int torisa_rbsbits(struct zt_chan *chan, int bits)
txsigs[k][b] = c;
write_lock_irqsave(&torisa, flags);
t1out(k + 1,0x70 + b,c);
- t1out(k + 1,0x76 + b,c);
b += 3; /* now points to b bit stuff */
/* get current signalling values */
c = txsigs[k][b];
@@ -295,7 +354,26 @@ static int torisa_rbsbits(struct zt_chan *chan, int bits)
txsigs[k][b] = c;
/* output them into the chip */
t1out(k + 1,0x70 + b,c);
- t1out(k + 1,0x76 + b,c);
+ b += 3; /* now points to c bit stuff */
+ /* get current signalling values */
+ c = txsigs[k][b];
+ c &= ~m; /* clear mask bit */
+ /* set mask bit, if bit is to be set */
+ if (bits & ZT_CBIT) c |= m;
+ /* save new signalling values */
+ txsigs[k][b] = c;
+ /* output them into the chip */
+ t1out(k + 1,0x70 + b,c);
+ b += 3; /* now points to d bit stuff */
+ /* get current signalling values */
+ c = txsigs[k][b];
+ c &= ~m; /* clear mask bit */
+ /* set mask bit, if bit is to be set */
+ if (bits & ZT_DBIT) c |= m;
+ /* save new signalling values */
+ txsigs[k][b] = c;
+ /* output them into the chip */
+ t1out(k + 1,0x70 + b,c);
write_unlock_irqrestore(&torisa, flags);
return 0;
}
@@ -327,10 +405,7 @@ static int torisa_shutdown(struct zt_span *span)
span->flags &= ~ZT_FLAG_RUNNING;
/* Zero out all registers */
- for (i = 0x20; i< 0x40; i++)
- t1out(tspan, i, 0);
- for (i = 0x60; i< 0x80; i++)
- t1out(tspan, i, 0);
+ for (i = 0; i< 0xff; i++) t1out(tspan, i, 0);
if (wasrunning)
spansstarted--;
write_unlock_irqrestore(&torisa, flags);
@@ -352,6 +427,7 @@ static int torisa_startup(struct zt_span *span)
unsigned int flags;
char *coding;
char *framing;
+ char *crcing;
int alreadyrunning;
tspan = getspan(span);
@@ -365,78 +441,137 @@ static int torisa_startup(struct zt_span *span)
alreadyrunning = span->flags & ZT_FLAG_RUNNING;
- if (!alreadyrunning) {
+ crcing = "";
+ if (card_type == TYPE_T1) { /* if its a T1 card */
+ if (!alreadyrunning) {
- setctlreg(MASTERCLOCK);
- /* Zero out all registers */
- for (i = 0x20; i< 0x40; i++)
- t1out(tspan, i, 0);
- for (i = 0x60; i< 0x80; i++)
- t1out(tspan, i, 0);
+ setctlreg(MASTERCLOCK);
+ /* Zero out all registers */
+ for (i = 0x20; i< 0x40; i++)
+ t1out(tspan, i, 0);
+ for (i = 0x60; i< 0x80; i++)
+ t1out(tspan, i, 0);
- /* Full-on Sync required (RCR1) */
- t1out(tspan, 0x2b, 8);
- /* RSYNC is an input (RCR2) */
- t1out(tspan, 0x2c, 8);
- /* RBS enable (TCR1) */
- t1out(tspan, 0x35, 0x10);
- /* TSYNC to be output (TCR2) */
- t1out(tspan, 0x36, 4);
- /* Tx & Rx Elastic store, sysclk = 2.048 mhz, loopback controls (CCR1) */
- t1out(tspan, 0x37, 0x8c);
- }
- /* Enable F bits pattern */
- i = 0x20;
- if (span->lineconfig & ZT_CONFIG_ESF)
- i = 0x88;
- if (span->lineconfig & ZT_CONFIG_B8ZS)
- i |= 0x44;
- t1out(tspan, 0x38, i);
- if (i & 0x80)
- coding = "ESF";
- else
- coding = "SF";
- if (i & 0x40)
- framing = "B8ZS";
- else {
- framing = "AMI";
- t1out(tspan,0x7e,0x1c); /* F bits pattern (0x1c) into FDL register */
- }
- t1out(tspan, 0x7c, span->txlevel << 5);
-
- if (!alreadyrunning) {
- /* LIRST to 1 in CCR3 */
- t1out(tspan, 0x30, 1);
+ /* Full-on Sync required (RCR1) */
+ t1out(tspan, 0x2b, 8);
+ /* RSYNC is an input (RCR2) */
+ t1out(tspan, 0x2c, 8);
+ /* RBS enable (TCR1) */
+ t1out(tspan, 0x35, 0x10);
+ /* TSYNC to be output (TCR2) */
+ t1out(tspan, 0x36, 4);
+ /* Tx & Rx Elastic store, sysclk = 2.048 mhz, loopback controls (CCR1) */
+ t1out(tspan, 0x37, 0x8c);
+ }
+ /* Enable F bits pattern */
+ i = 0x20;
+ if (span->lineconfig & ZT_CONFIG_ESF)
+ i = 0x88;
+ if (span->lineconfig & ZT_CONFIG_B8ZS)
+ i |= 0x44;
+ t1out(tspan, 0x38, i);
+ if (i & 0x80)
+ coding = "ESF";
+ else
+ coding = "SF";
+ if (i & 0x40)
+ framing = "B8ZS";
+ else {
+ framing = "AMI";
+ t1out(tspan,0x7e,0x1c); /* F bits pattern (0x1c) into FDL register */
+ }
+ t1out(tspan, 0x7c, span->txlevel << 5);
- /* Wait 100 ms */
- endjif = jiffies + 10;
- write_unlock_irqrestore(&torisa, flags);
+ if (!alreadyrunning) {
+ /* LIRST to 1 in CCR3 */
+ t1out(tspan, 0x30, 1);
+
+ /* Wait 100 ms */
+ endjif = jiffies + 10;
+ write_unlock_irqrestore(&torisa, flags);
- while(jiffies < endjif); /* wait 100 ms */
+ while(jiffies < endjif); /* wait 100 ms */
- write_lock_irqsave(&torisa, flags);
- t1out(tspan,0x30,0x40); /* set CCR3 to 0x40, resetting Elastic Store */
+ write_lock_irqsave(&torisa, flags);
+ t1out(tspan,0x30,0x40); /* set CCR3 to 0x40, resetting Elastic Store */
- span->flags |= ZT_FLAG_RUNNING;
- spansstarted++;
+ span->flags |= ZT_FLAG_RUNNING;
+ spansstarted++;
#if 0
- printk("Enabling interrupts: %d\n", clockvals[syncsrc] | INTENA);
+ printk("Enabling interrupts: %d\n", clockvals[syncsrc] | INTENA);
#endif
- /* output the clock info and enable interrupts */
- setctlreg(clockvals[syncsrc] | INTENA);
- }
+ /* output the clock info and enable interrupts */
+ setctlreg(clockvals[syncsrc] | INTENA);
+ }
+ set_clear(); /* this only applies to a T1 */
+ } else { /* if its an E1 card */
+ u_char ccr1 = 0, tcr1 = 0;
+
+ if (!alreadyrunning) {
+ t1out(tspan,0x1a,4); /* CCR2: set LOTCMC */
+ for(i = 0; i <= 8; i++) t1out(tspan,i,0);
+ for(i = 0x10; i <= 0x4f; i++) if (i != 0x1a) t1out(tspan,i,0);
+ t1out(tspan,0x10,0x20); /* RCR1: Rsync as input */
+ t1out(tspan,0x11,6); /* RCR2: Sysclk=2.048 Mhz */
+ t1out(tspan,0x12,8); /* TCR1: TSiS mode */
+ }
+ tcr1 = 8; /* base TCR1 value: TSis mode */
+ if (span->lineconfig & ZT_CONFIG_CCS) {
+ ccr1 |= 8; /* CCR1: Rx Sig mode: CCS */
+ coding = "CCS";
+ } else {
+ tcr1 |= 0x20;
+ coding = "CAS";
+ }
+ if (span->lineconfig & ZT_CONFIG_HDB3) {
+ ccr1 |= 0x44; /* CCR1: TX and RX HDB3 */
+ framing = "HDB3";
+ } else framing = "AMI";
+ if (span->lineconfig & ZT_CONFIG_CRC4) {
+ ccr1 |= 0x11; /* CCR1: TX and TX CRC4 */
+ crcing = "/CRC4";
+ }
+ t1out(tspan,0x12,tcr1);
+ t1out(tspan,0x14,ccr1);
+ t1out(tspan, 0x18, 0x80);
+
+ if (!alreadyrunning) {
+ t1out(tspan,0x1b,0x8a); /* CCR3: LIRST & TSCLKM */
+ t1out(tspan,0x20,0x1b); /* TAFR */
+ t1out(tspan,0x21,0x5f); /* TNAFR */
+ t1out(tspan,0x40,0xb); /* TSR1 */
+ for(i = 0x41; i <= 0x4f; i++) t1out(tspan,i,0x55);
+ for(i = 0x22; i <= 0x25; i++) t1out(tspan,i,0xff);
+ /* Wait 100 ms */
+ endjif = jiffies + 10;
+ write_unlock_irqrestore(&torisa, flags);
+ while(jiffies < endjif); /* wait 100 ms */
+ write_lock_irqsave(&torisa, flags);
+ t1out(tspan,0x1b,0x9a); /* CCR3: set also ESR */
+ t1out(tspan,0x1b,0x82); /* CCR3: TSCLKM only now */
+
+ /* output the clock info and enable interrupts */
+ setctlreg(clockvals[syncsrc] | INTENA);
+ }
- set_clear();
+ }
write_unlock_irqrestore(&torisa, flags);
if (debug) {
- if (alreadyrunning)
- printk("TorISA: Reconfigured span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
- else
- printk("TorISA: Startup span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
+ if (card_type == TYPE_T1) {
+ if (alreadyrunning)
+ printk("TorISA: Reconfigured span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
+ else
+ printk("TorISA: Startup span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel));
+ } else {
+ if (alreadyrunning)
+ printk("TorISA: Reconfigured span %d (%s/%s%s) 120 ohms\n", span->spanno, coding, framing, crcing);
+ else
+ printk("TorISA: Startup span %d (%s/%s%s) 120 ohms\n", span->spanno, coding, framing, crcing);
+ }
}
if (syncs[0] == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno);
if (syncs[1] == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
@@ -477,7 +612,7 @@ static int torisa_chanconfig(struct zt_chan *chan, int sigtype)
printk("TorISA: Configured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype);
}
write_lock_irqsave(&torisa, flags);
- if (alreadyrunning)
+ if (alreadyrunning && (card_type == TYPE_T1))
set_clear();
write_unlock_irqrestore(&torisa, flags);
return 0;
@@ -500,23 +635,26 @@ static int torisa_maint(struct zt_span *span, int cmd)
int tspan = getspan(span);
switch(cmd) {
- case ZT_MAINT_NONE:
- t1out(tspan,0x37,0x8c); /* clear system */
+ case ZT_MAINT_NONE:
+ t1out(tspan,0x1a,4); /* clear system */
break;
case ZT_MAINT_LOCALLOOP:
- t1out(tspan,0x37,0xcc); /* local loopback */
+ t1out(tspan,0x1a,5); /* local loopback */
break;
- case ZT_MAINT_REMOTELOOP:
- t1out(tspan,0x37,0x9c); /* remote loopback */
+ case ZT_MAINT_REMOTELOOP:
+ t1out(tspan,0x37,6); /* remote loopback */
break;
- case ZT_MAINT_LOOPUP:
+ case ZT_MAINT_LOOPUP:
+ if (card_type == TYPE_E1) return -ENOSYS;
t1out(tspan,0x30,2); /* send loopup code */
break;
- case ZT_MAINT_LOOPDOWN:
+ case ZT_MAINT_LOOPDOWN:
+ if (card_type == TYPE_E1) return -ENOSYS;
t1out(tspan,0x30,4); /* send loopdown code */
break;
case ZT_MAINT_LOOPSTOP:
- t1out(tspan,0x30,0); /* stop sending loopup code */
+ if (card_type == TYPE_T1)
+ t1out(tspan,0x30,0); /* stop sending loopup code */
break;
default:
printk("torisa: Unknown maint command: %d\n", cmd);
@@ -555,11 +693,11 @@ static int txerrors;
static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
{
- static unsigned int passno = 0;
- int n, n1, i, j, k, x;
- static unsigned short rxword[25],txword[25];
+ static unsigned int passno = 0, mysynccnt = 0, lastsyncsrc = -1;
+ int n, n1, i, j, k, x, mysyncsrc;
+ static unsigned short rxword[33],txword[33];
unsigned char txc, rxc, c;
- unsigned char abits, bbits;
+ unsigned char abits, bbits, cbits, dbits;
irqcount++;
@@ -584,18 +722,18 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
#endif
/* Do the actual transmit and receive in poopy order */
- for(n1 = 0; n1 < 24; n1++)
+ for(n1 = 0; n1 < channels_per_span; n1++)
{
n = chseq[n1];
maddr[DDATA + datxlt[n]] = txword[n];
rxword[n] = maddr[DDATA + datxlt[n]]; /* get rx word */
}
- setctlreg(clockvals[syncsrc] | OUTBIT); /* clear 16 bit mode */
+ setctlreg(clockvals[syncsrc] | OUTBIT); /* clear 16 bit mode */
/* Calculate the transmit, go thru all the chans */
- for(n1 = 0; n1 < 24; n1++)
+ for(n1 = 0; n1 < channels_per_span; n1++)
{
n = chseq[n1];
txword[n] = 0;
@@ -604,37 +742,62 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
{
/* enter the transmit stuff with i being channel number,
leaving with txc being character to transmit */
- txc = writedata[curread][j * 24 + n-1][passno % ZT_CHUNKSIZE];
+ txc = writedata[curread][j * channels_per_span + n-1][passno % ZT_CHUNKSIZE];
txword[n] |= txc << (j * 8);
}
}
-
/* do the receive for all chans, both spans */
- for(n1 = 0; n1 < 24; n1++)
+ for(n1 = 0; n1 < channels_per_span; n1++)
{
n = chseq[n1];
/* go thru both spans */
for(j = 0; j <= 1; j++)
{
- i = n + (j * 24); /* calc chan number */
+ i = n + (j * channels_per_span); /* calc chan number */
rxc = (rxword[n] >> (j * 8)) & 0xff;
- readdata[curread][j * 24 + n - 1][passno % ZT_CHUNKSIZE] = rxc;
+ readdata[curread][j * channels_per_span + n - 1][passno % ZT_CHUNKSIZE] = rxc;
}
}
i = passno & 511;
- if (i < 6) {
+ /* if an E1 card, do rx signalling for it */
+ if (i < 3 && (card_type == TYPE_E1)) { /* if an E1 card */
+ for(j = (i * 3); j < (i * 3) + 5; j++)
+ {
+ for(k = 1,x = j; k <= 2; k++,x += channels_per_span) {
+ c = t1in(k,0x31 + j);
+ rxc = c & 15;
+ if (rxc != chans[x + 15].rxsig) {
+ /* Check for changes in received bits */
+ if (!(chans[x + 15].sig & ZT_SIG_CLEAR))
+ zt_rbsbits(&chans[x + 15], rxc);
+ }
+ rxc = c >> 4;
+ if (rxc != chans[x].rxsig) {
+ /* Check for changes in received bits */
+ if (!(chans[x].sig & ZT_SIG_CLEAR))
+ zt_rbsbits(&chans[x], rxc);
+ }
+ }
+ }
+ }
+ /* if a t1 card, do rx signalling for it */
+ if ((i < 6) && (card_type == TYPE_T1)) {
k = (i / 3); /* get span */
n = (i % 3); /* get base */
abits = t1in(k + 1, 0x60 + n);
bbits = t1in(k + 1, 0x63 + n);
+ cbits = t1in(k + 1, 0x66 + n);
+ dbits = t1in(k + 1, 0x69 + n);
for (j=0; j< 8; j++) {
/* Get channel number */
i = (k * 24) + (n * 8) + j;
rxc = 0;
if (abits & (1 << j)) rxc |= ZT_ABIT;
if (bbits & (1 << j)) rxc |= ZT_BBIT;
+ if (cbits & (1 << j)) rxc |= ZT_CBIT;
+ if (dbits & (1 << j)) rxc |= ZT_DBIT;
if (chans[i].rxsig != rxc) {
/* Check for changes in received bits */
if (!(chans[i].sig & ZT_SIG_CLEAR))
@@ -652,7 +815,10 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
{
/* clear recover status */
spans[i].alarms &= ~ZT_ALARM_RECOVER;
- t1out(i + 1,0x35,0x10); /* turn off yel */
+ if (card_type == TYPE_T1)
+ t1out(i + 1,0x35,0x10); /* turn off yel */
+ else
+ t1out(i + 1,0x21,0x5f); /* turn off remote alarm */
zt_alarm_notify(&spans[i]); /* let them know */
}
}
@@ -664,40 +830,53 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
{
j = 0; /* clear this alarm status */
i -= 100;
- c = t1in(i + 1,0x31); /* get RIR2 */
- spans[i].rxlevel = c >> 6; /* get rx level */
- t1out(i + 1,0x20,0xff);
- c = t1in(i + 1,0x20); /* get the status */
- /* detect the code, only if we are not sending one */
- if ((!spans[i].mainttimer) && (c & 0x80)) /* if loop-up code detected */
- {
- /* set into remote loop, if not there already */
- if ((loopupcnt[i]++ > 80) &&
- (spans[i].maintstat != ZT_MAINT_REMOTELOOP))
+ if (card_type == TYPE_T1) {
+ c = t1in(i + 1,0x31); /* get RIR2 */
+ spans[i].rxlevel = c >> 6; /* get rx level */
+ t1out(i + 1,0x20,0xff);
+ c = t1in(i + 1,0x20); /* get the status */
+ /* detect the code, only if we are not sending one */
+ if ((!spans[i].mainttimer) && (c & 0x80)) /* if loop-up code detected */
+ {
+ /* set into remote loop, if not there already */
+ if ((loopupcnt[i]++ > 80) &&
+ (spans[i].maintstat != ZT_MAINT_REMOTELOOP))
+ {
+ t1out(i + 1,0x37,0x9c); /* remote loopback */
+ spans[i].maintstat = ZT_MAINT_REMOTELOOP;
+ }
+ } else loopupcnt[i] = 0;
+ /* detect the code, only if we are not sending one */
+ if ((!spans[i].mainttimer) && (c & 0x40)) /* if loop-down code detected */
+ {
+ /* if in remote loop, get out of it */
+ if ((loopdowncnt[i]++ > 80) &&
+ (spans[i].maintstat == ZT_MAINT_REMOTELOOP))
+ {
+ t1out(i + 1,0x37,0x8c); /* normal */
+ spans[i].maintstat = ZT_MAINT_NONE;
+ }
+ } else loopdowncnt[i] = 0;
+ if (c & 3) /* if red alarm */
{
- t1out(i + 1,0x37,0x9c); /* remote loopback */
- spans[i].maintstat = ZT_MAINT_REMOTELOOP;
+ j |= ZT_ALARM_RED;
}
- } else loopupcnt[i] = 0;
- /* detect the code, only if we are not sending one */
- if ((!spans[i].mainttimer) && (c & 0x40)) /* if loop-down code detected */
- {
- /* if in remote loop, get out of it */
- if ((loopdowncnt[i]++ > 80) &&
- (spans[i].maintstat == ZT_MAINT_REMOTELOOP))
+ if (c & 8) /* if blue alarm */
{
- t1out(i + 1,0x37,0x8c); /* normal */
- spans[i].maintstat = ZT_MAINT_NONE;
+ j |= ZT_ALARM_BLUE;
}
- } else loopdowncnt[i] = 0;
- if (c & 3) /* if red alarm */
- {
- j |= ZT_ALARM_RED;
- }
- if (c & 8) /* if blue alarm */
- {
- j |= ZT_ALARM_BLUE;
- }
+ } else { /* its an E1 card */
+ t1out(i + 1,6,0xff);
+ c = t1in(i + 1,6); /* get the status */
+ if (c & 9) /* if red alarm */
+ {
+ j |= ZT_ALARM_RED;
+ }
+ if (c & 2) /* if blue alarm */
+ {
+ j |= ZT_ALARM_BLUE;
+ }
+ }
/* only consider previous carrier alarm state */
spans[i].alarms &= (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_NOTOPEN);
n = 1; /* set to 1 so will not be in yellow alarm if we dont
@@ -706,7 +885,7 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
if (spans[i].lineconfig & ZT_CONFIG_NOTOPEN)
{
/* go thru all chans, and count # open */
- for(n = 0,k = (i * 24); k < (i * 24) + 24; k++)
+ for(n = 0,k = (i * channels_per_span); k < (i * channels_per_span) + channels_per_span; k++)
{
if ((chans[k].flags & ZT_FLAG_OPEN) ||
(chans[k].flags & ZT_FLAG_NETDEV)) n++;
@@ -720,8 +899,11 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
alarmtimer[i] = ZT_ALARMSETTLE_TIME;
}
if (alarmtimer[i]) j |= ZT_ALARM_RECOVER;
- /* if going into alarm state, set yellow alarm */
- if ((j) && (!spans[i].alarms)) t1out(i + 1,0x35,0x11);
+ /* if going into alarm state, set yellow (remote) alarm */
+ if ((j) && (!spans[i].alarms)) {
+ if (card_type == TYPE_T1) t1out(i + 1,0x35,0x11);
+ else t1out(i + 1,0x21,0x7f);
+ }
if (c & 4) /* if yellow alarm */
j |= ZT_ALARM_YELLOW;
if (spans[i].maintstat || spans[i].mainttimer) j |= ZT_ALARM_LOOPBACK;
@@ -733,32 +915,54 @@ static void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)
/* do both spans */
for(i = 1; i <= 2; i++)
{
- /* add this second's BPV count to total one */
- spans[i - 1].bpvcount += t1in(i,0x24) + (t1in(i,0x23) << 8);
+ if (card_type == TYPE_T1) {
+ /* add this second's BPV count to total one */
+ spans[i - 1].bpvcount += t1in(i,0x24) + (t1in(i,0x23) << 8);
+ } else {
+ /* add this second's BPV count to total one */
+ spans[i - 1].bpvcount += t1in(i,1) + (t1in(i,0) << 8);
+ }
}
}
/* re-evaluate active sync src */
- syncsrc = 0;
+ mysyncsrc = 0;
/* if primary sync specified, see if we can use it */
if (syncs[0])
{
/* if no alarms, use it */
if (!(spans[syncs[0] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE |
- ZT_ALARM_LOOPBACK))) syncsrc = syncs[0];
+ ZT_ALARM_LOOPBACK))) mysyncsrc = syncs[0];
}
/* if we dont have one yet, and there is a secondary, see if we can use it */
- if ((!syncsrc) && (syncs[1]))
+ if ((!mysyncsrc) && (syncs[1]))
{
/* if no alarms, use it */
if (!(spans[syncs[1] - 1].alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE |
- ZT_ALARM_LOOPBACK))) syncsrc = syncs[1];
+ ZT_ALARM_LOOPBACK))) mysyncsrc = syncs[1];
}
+ /* on the E1 card, the PLL takes a bit of time to lock going
+ between internal and external clocking. There needs to be some
+ settle time before actually changing the source, otherwise it will
+ oscillate between in and out of sync */
+ if (card_type == TYPE_E1)
+ {
+ /* if stable, add to count */
+ if (lastsyncsrc == mysyncsrc) mysynccnt++; else mysynccnt = 0;
+ lastsyncsrc = mysyncsrc;
+ /* if stable sufficiently long, change it */
+ if (mysynccnt >= E1SYNCSTABLETHRESH)
+ {
+ mysynccnt = 0;
+ syncsrc = mysyncsrc;
+ }
+ }
+ else syncsrc = mysyncsrc; /* otherwise on a T1 card, just use current value */
/* update sync src info */
spans[0].syncsrc = spans[1].syncsrc = syncsrc;
/* If this is the last pass, then prepare the next set */
if ((passno % ZT_CHUNKSIZE) == (ZT_CHUNKSIZE - 1)) {
/* Swap buffers */
- for (x = 0;x<48;x++) {
+ for (x = 0;x < (channels_per_span * 2);x++) {
chans[x].readchunk = readdata[curread][x];
chans[x].writechunk = writedata[curread][x];
}
@@ -829,7 +1033,7 @@ static int __init tor_init(void)
spans[0].maint = torisa_maint;
spans[0].open = torisa_open;
spans[0].close = torisa_close;
- spans[0].channels = 24;
+ spans[0].channels = channels_per_span;
spans[0].chans = &chans[0];
spans[0].flags = ZT_FLAG_RBS;
spans[0].linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF;
@@ -848,12 +1052,19 @@ static int __init tor_init(void)
spans[1].maint = torisa_maint;
spans[1].open = torisa_open;
spans[1].close = torisa_close;
- spans[1].channels = 24;
- spans[1].chans = &chans[24];
+ spans[1].channels = channels_per_span;
+ spans[1].chans = &chans[channels_per_span];
spans[1].flags = ZT_FLAG_RBS;
spans[1].linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF;
spans[1].ioctl = torisa_ioctl;
spans[1].irq = irq;
+ if (card_type == TYPE_E1) {
+ spans[0].deflaw = ZT_LAW_ALAW;
+ spans[1].deflaw = ZT_LAW_ALAW;
+ } else {
+ spans[0].deflaw = ZT_LAW_MULAW;
+ spans[1].deflaw = ZT_LAW_MULAW;
+ }
init_waitqueue_head(&spans[1].maintq);
make_chans();