From 1699b655be978ba8bc1d09f6c01b3255e0efe734 Mon Sep 17 00:00:00 2001 From: markster Date: Sun, 23 Dec 2001 21:45:09 +0000 Subject: Version 0.1.4 from FTP git-svn-id: http://svn.digium.com/svn/zaptel/trunk@43 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- torisa.c | 519 ++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 365 insertions(+), 154 deletions(-) (limited to 'torisa.c') 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;ipvt; 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(); -- cgit v1.2.3