From 85d82e003f9dd3cfbc8733a537746750dbd0e5e0 Mon Sep 17 00:00:00 2001 From: markster Date: Wed, 19 Jun 2002 18:53:18 +0000 Subject: Version 0.2.0 from FTP git-svn-id: http://svn.digium.com/svn/zaptel/trunk@85 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wct1xxp.c | 111 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 36 deletions(-) (limited to 'wct1xxp.c') diff --git a/wct1xxp.c b/wct1xxp.c index c612f59..45c72d9 100755 --- a/wct1xxp.c +++ b/wct1xxp.c @@ -124,6 +124,7 @@ struct t1xxp { char *variety; int intcount; int usecount; + int sync; int dead; int blinktimer; int alarmtimer; @@ -225,7 +226,13 @@ static int control_set_reg(struct t1xxp *wc, int reg, unsigned char val) static int __control_get_reg(struct t1xxp *wc, int reg) { unsigned char res; - __select_control(wc); + /* The following makes UTTERLY no sense, but what was happening + was that reads in some cases were not actually happening + on the physical bus. Why, we dunno. But in debugging, we found + that writing before reading (in this case to an unused position) + seems to get rid of the problem */ + __control_set_reg(wc,3,0x69); /* do magic here */ + /* now get the read byte from the Xilinx part */ res = inb(wc->ioaddr + WC_USERREG + ((reg & 0xf) << 2)); return res; } @@ -290,6 +297,20 @@ static void __t1xxp_disable_interrupts(struct t1xxp *wc) outb(0x00, wc->ioaddr + WC_MASK1); } +static void __t1xxp_set_clear(struct t1xxp *wc) +{ + /* Setup registers */ + int x,y; + unsigned char b; + for (x=0;x<3;x++) { + b = 0; + for (y=0;y<8;y++) + if (wc->chans[x * 8 + y].sig & ZT_SIG_CLEAR) + b |= (1 << y); + __t1_set_reg(wc, 0x39 + x, b); + } +} + static void t1xxp_framer_start(struct t1xxp *wc) { int i; @@ -327,6 +348,9 @@ static void t1xxp_framer_start(struct t1xxp *wc) printk("Using %s/%s coding/framing\n", coding, framing); if (!alreadyrunning) { + /* Setup the clear channels */ + __t1xxp_set_clear(wc); + /* Set LIRST bit to 1 */ __t1_set_reg(wc, 0x0a, 0x80); spin_unlock_irqrestore(&wc->lock, flags); @@ -368,7 +392,7 @@ static int t1xxp_framer_hard_reset(struct t1xxp *wc) spin_lock_irqsave(&wc->lock, flags); /* Initialize all registers to 0 */ - for (x=0x0;x<0x96;x++) + for (x=0x0;x<192;x++) __t1_set_reg(wc, x, 0); /* Full-on sync required */ @@ -390,6 +414,7 @@ static int t1xxp_framer_hard_reset(struct t1xxp *wc) __t1_set_reg(wc, 0x12, 0x22); __t1_set_reg(wc, 0x14, 0x80); __t1_set_reg(wc, 0x15, 0x80); + spin_unlock_irqrestore(&wc->lock, flags); return 0; } @@ -442,10 +467,13 @@ static int t1xxp_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long dat static int t1xxp_startup(struct zt_span *span) { struct t1xxp *wc = span->pvt; + + int alreadyrunning = span->flags & ZT_FLAG_RUNNING; /* Reset framer with proper parameters and start */ t1xxp_framer_start(wc); + printk("Calling startup (flags is %d)\n", span->flags); - if (!(span->flags & ZT_FLAG_RUNNING)) { + if (!alreadyrunning) { /* Only if we're not already going */ t1xxp_enable_interrupts(wc); t1xxp_start_dma(wc); @@ -475,20 +503,6 @@ static int t1xxp_maint(struct zt_span *span, int mode) return -1; } -static void __t1xxp_set_clear(struct t1xxp *wc) -{ - /* Setup registers */ - int x,y; - unsigned char b; - for (x=0;x<3;x++) { - b = 0; - for (y=0;y<8;y++) - if (wc->chans[x * 8 + y].sig & ZT_SIG_CLEAR) - b |= (1 << y); - __t1_set_reg(wc, 0x39 + x, b); - } -} - static int t1xxp_chanconfig(struct zt_chan *chan, int sigtype) { struct t1xxp *wc = chan->pvt; @@ -506,11 +520,13 @@ static int t1xxp_chanconfig(struct zt_chan *chan, int sigtype) static int t1xxp_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) { + struct t1xxp *wc = span->pvt; span->lineconfig = lc->lineconfig; span->txlevel = lc->lbo; span->rxlevel = 0; /* Do we want to SYNC on receive or not */ - span->syncsrc = lc->sync; + span->syncsrc = 0; + wc->sync = lc->sync; /* If already running, apply changes immediately */ if (span->flags & ZT_FLAG_RUNNING) return t1xxp_startup(span); @@ -553,7 +569,7 @@ static int t1xxp_software_init(struct t1xxp *wc) wc->chans[x].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; + ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS; wc->chans[x].pvt = wc; wc->chans[x].chanpos = x + 1; } @@ -568,6 +584,7 @@ static inline void __handle_leds(struct t1xxp *wc) { int oldreg; wc->blinktimer++; + if (wc->span.alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE)) { /* Red/Blue alarm */ #ifdef FANCY_ALARM @@ -639,7 +656,7 @@ static void t1xxp_receiveprep(struct t1xxp *wc, int ints) volatile unsigned char *rxbuf; int x; int y; - if (ints & 0x08) { + if (ints & 0x04) { /* Just received first buffer */ rxbuf = wc->readchunk; } else { @@ -663,6 +680,11 @@ static void t1xxp_receiveprep(struct t1xxp *wc, int ints) rxbuf[32 * y + ((chanmap[x] + WC_OFFSET + wc->offset) & 0x1f)]; } } + /* XXX We should apply echo cancellation closer -- we're wasting + 8 taps XXX */ + for (x=0;x<24;x++) + zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->chans[x].writechunk); + zt_receive(&wc->span); } @@ -671,7 +693,7 @@ static void __t1xxp_check_sigbits(struct t1xxp *wc, int x) int a,b,i,y,rxs; a = __t1_get_reg(wc, 0x60 + x); - b = __t1_get_reg(wc, 0x64 + x); + b = __t1_get_reg(wc, 0x63 + x); for (y=0;y<8;y++) { i = x * 8 + y; rxs = 0; @@ -688,7 +710,7 @@ static void __t1xxp_check_sigbits(struct t1xxp *wc, int x) static void __t1xxp_check_alarms(struct t1xxp *wc) { - unsigned char c; + unsigned char c,d; int alarms; int x,j; @@ -697,8 +719,8 @@ static void __t1xxp_check_alarms(struct t1xxp *wc) wc->span.rxlevel = c >> 6; /* Get status register s*/ - __t1_set_reg(wc, 0x20, 0xff); - c = __t1_get_reg(wc, 0x20); + __t1_set_reg(wc, 0x20, 0xff); + c = __t1_get_reg(wc, 0x20); /* Assume no alarms */ alarms = 0; @@ -722,32 +744,50 @@ static void __t1xxp_check_alarms(struct t1xxp *wc) alarms |= ZT_ALARM_BLUE; /* Keep track of recovering */ - if (!alarms && wc->span.alarms) + if ((!alarms) && wc->span.alarms) wc->alarmtimer = ZT_ALARMSETTLE_TIME; - if (wc->alarmtimer) - alarms |= ZT_ALARM_RECOVER; /* If receiving alarms, go into Yellow alarm state */ - if (alarms && !wc->span.alarms) { + if (alarms && (!wc->span.alarms)) { +#if 0 printk("Going into yellow alarm\n"); - __t1_set_reg(wc, 0x35, 0x11); +#endif + __t1_set_reg(wc, 0x35, 0x11); } + if (wc->span.alarms != alarms) { + d = __control_get_reg(wc, 0); + start_alarm(wc); + if (!(alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE | ZT_ALARM_LOOPBACK)) && + wc->sync) { + /* Use the recieve signalling */ + wc->span.syncsrc = wc->span.spanno; + d |= 1; + } else { + wc->span.syncsrc = 0; + d &= ~1; + } + __control_set_reg(wc, 0, d); + } + if (wc->alarmtimer) + alarms |= ZT_ALARM_RECOVER; if (c & 0x4) alarms |= ZT_ALARM_YELLOW; wc->span.alarms = alarms; + zt_alarm_notify(&wc->span); - } static void __t1xxp_do_counters(struct t1xxp *wc) { if (wc->alarmtimer) { if (!--wc->alarmtimer) { - wc->span.alarms &= ~ZT_ALARM_RECOVER; + wc->span.alarms &= ~(ZT_ALARM_RECOVER); /* Clear yellow alarm */ - printk("Coming out of yellow alarm\n"); +#if 0 + printk("Coming out of alarm\n"); +#endif __t1_set_reg(wc, 0x35, 0x10); zt_alarm_notify(&wc->span); } @@ -777,7 +817,9 @@ static void t1xxp_interrupt(int irq, void *dev_id, struct pt_regs *regs) } spin_lock_irqsave(&wc->lock, flags); +#if 1 __handle_leds(wc); +#endif /* Count down timers */ __t1xxp_do_counters(wc); @@ -788,10 +830,7 @@ static void t1xxp_interrupt(int irq, void *dev_id, struct pt_regs *regs) case 0: case 1: case 2: - case 3: -#if 0 __t1xxp_check_sigbits(wc, x); -#endif break; case 4: __t1xxp_check_alarms(wc); @@ -902,7 +941,7 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic /* Keep track of which device we are */ pci_set_drvdata(pdev, wc); - if (request_irq(pdev->irq, t1xxp_interrupt, SA_SHIRQ, "t1xxp", wc)) { + if (request_irq(pdev->irq, t1xxp_interrupt, SA_INTERRUPT | SA_SHIRQ, "t1xxp", wc)) { printk("t1xxp: Unable to request IRQ %d\n", pdev->irq); kfree(wc); return -EIO; -- cgit v1.2.3