📄 wcte11xp.c
字号:
__t1_framer_out(wc,0x70 + b + 6,c); } else if (wc->span.lineconfig & ZT_CONFIG_ESF) { n = chan->chanpos - 1; b = (n/2); c = wc->txsigs[b]; m = ((n % 2) << 2); /* nibble selector */ c &= (0xf << m); /* keep the other nibble */ c |= (bits & 0xf) << (4 - m); /* put our new nibble here */ wc->txsigs[b] = c; /* output them to the chip */ __t1_framer_out(wc,0x70 + b,c); } spin_unlock_irqrestore(&wc->lock, flags); if (debug > 1) printk("Finished setting RBS bits\n"); return 0;}static void __t1_check_sigbits(struct t1 *wc){ int a,i,rxs; if (!(wc->span.flags & ZT_FLAG_RUNNING)) return; if (wc->spantype == TYPE_E1) { for (i = 0; i < 15; i++) { a = __t1_framer_in(wc, 0x71 + i); /* Get high channel in low bits */ rxs = (a & 0xf); if (!(wc->span.chans[i+16].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i+16].rxsig != rxs) zt_rbsbits(&wc->span.chans[i+16], rxs); } rxs = (a >> 4) & 0xf; if (!(wc->span.chans[i].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i].rxsig != rxs) zt_rbsbits(&wc->span.chans[i], rxs); } } } else if (wc->span.lineconfig & ZT_CONFIG_D4) { for (i = 0; i < 24; i+=4) { a = __t1_framer_in(wc, 0x70 + (i>>2)); /* Get high channel in low bits */ rxs = (a & 0x3) << 2; if (!(wc->span.chans[i+3].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i+3].rxsig != rxs) zt_rbsbits(&wc->span.chans[i+3], rxs); } rxs = (a & 0xc); if (!(wc->span.chans[i+2].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i+2].rxsig != rxs) zt_rbsbits(&wc->span.chans[i+2], rxs); } rxs = (a >> 2) & 0xc; if (!(wc->span.chans[i+1].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i+1].rxsig != rxs) zt_rbsbits(&wc->span.chans[i+1], rxs); } rxs = (a >> 4) & 0xc; if (!(wc->span.chans[i].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i].rxsig != rxs) zt_rbsbits(&wc->span.chans[i], rxs); } } } else { for (i = 0; i < 24; i+=2) { a = __t1_framer_in(wc, 0x70 + (i>>1)); /* Get high channel in low bits */ rxs = (a & 0xf); if (!(wc->span.chans[i+1].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i+1].rxsig != rxs) zt_rbsbits(&wc->span.chans[i+1], rxs); } rxs = (a >> 4) & 0xf; if (!(wc->span.chans[i].sig & ZT_SIG_CLEAR)) { if (wc->span.chans[i].rxsig != rxs) zt_rbsbits(&wc->span.chans[i], rxs); } } }}static void t4_serial_setup(struct t1 *wc){ printk("TE110P: Setting up global serial parameters for %s %s\n", wc->spantype == TYPE_E1 ? "E1" : "T1", wc->spanflags & FLAG_FALC12 ? "FALC V1.2" : "FALC V2.1"); t1_framer_out(wc, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */ t1_framer_out(wc, 0x08, 0x05); /* IPC: Interrupt push/pull active low */ if (wc->spanflags & FLAG_FALC12) { t1_framer_out(wc, 0x92, 0x00); t1_framer_out(wc, 0x93, 0x58); t1_framer_out(wc, 0x94, 0xd2); t1_framer_out(wc, 0x95, 0xc2); t1_framer_out(wc, 0x96, 0x03); t1_framer_out(wc, 0x97, 0x10); } else {#ifdef TRUST_INFINEON_ERRATA if (wc->spantype == TYPE_E1) { /* Global clocks (8.192 Mhz CLK) */ t1_framer_out(wc, 0x92, 0x00); t1_framer_out(wc, 0x93, 0x00); t1_framer_out(wc, 0x94, 0x00); t1_framer_out(wc, 0x95, 0x00); t1_framer_out(wc, 0x96, 0x00); t1_framer_out(wc, 0x97, 0x0F); t1_framer_out(wc, 0x98, 0x80); t1_framer_out(wc, 0x99, 0x00); } else { /* Global clocks (8.192 Mhz CLK) */ t1_framer_out(wc, 0x92, 0x00); t1_framer_out(wc, 0x93, 0x10); t1_framer_out(wc, 0x94, 0xfb); t1_framer_out(wc, 0x95, 0x03); t1_framer_out(wc, 0x96, 0x00); t1_framer_out(wc, 0x97, 0x0b); t1_framer_out(wc, 0x98, 0x8c); t1_framer_out(wc, 0x99, 0x80); }#else t1_framer_out(wc, 0x92, 0x66); t1_framer_out(wc, 0x93, 0x0e); t1_framer_out(wc, 0x94, 0x3f); t1_framer_out(wc, 0x95, 0x0f); t1_framer_out(wc, 0x96, 0x04); t1_framer_out(wc, 0x97, 0x3c); t1_framer_out(wc, 0x98, 0x9c); t1_framer_out(wc, 0x99, 0x90); #endif } /* Configure interrupts */ t1_framer_out(wc, 0x46, 0x40); /* GCR: Interrupt on Activation/Deactivation of AIX, LOS */ /* Configure system interface */ t1_framer_out(wc, 0x3e, 0x02); /* SIC1: 4.096 Mhz clock/bus, double buffer receive / transmit, byte interleaved */ t1_framer_out(wc, 0x3f, 0x00); /* SIC2: No FFS, no center receive eliastic buffer, phase 0 */ t1_framer_out(wc, 0x40, 0x04); /* SIC3: Edges for capture */ t1_framer_out(wc, 0x44, 0x30); /* CMR1: RCLK is at 8.192 Mhz dejittered */ t1_framer_out(wc, 0x45, 0x00); /* CMR2: We provide sync and clock for tx and rx. */ t1_framer_out(wc, 0x22, 0x00); /* XC0: Normal operation of Sa-bits */ t1_framer_out(wc, 0x23, 0x04); /* XC1: 0 offset */ t1_framer_out(wc, 0x24, 0x07); /* RC0: Just shy of 255 */ if (wc->spanflags & FLAG_FALC12) t1_framer_out(wc, 0x25, 0x04); /* RC1: The rest of RC0 */ else t1_framer_out(wc, 0x25, 0x06); /* RC1: The rest of RC0 */ /* Configure ports */ t1_framer_out(wc, 0x80, 0x00); /* PC1: SPYR/SPYX input on RPA/XPA */ t1_framer_out(wc, 0x81, 0x22); /* PC2: RMFB/XSIG output/input on RPB/XPB */ t1_framer_out(wc, 0x82, 0x65); /* PC3: Some unused stuff */ t1_framer_out(wc, 0x83, 0x35); /* PC4: Some more unused stuff */ t1_framer_out(wc, 0x84, 0x31); /* PC5: XMFS active low, SCLKR is input, RCLK is output */ t1_framer_out(wc, 0x86, 0x03); /* PC6: CLK1 is Tx Clock output, CLK2 is 8.192 Mhz from DCO-R */ t1_framer_out(wc, 0x3b, 0x00); /* Clear LCR1 */ printk("TE110P: Successfully initialized serial bus for card\n");}static void __t1_configure_t1(struct t1 *wc, int lineconfig, int txlevel){ unsigned int fmr4, fmr2, fmr1, fmr0, lim2; char *framing, *line; int mytxlevel; if ((txlevel > 7) || (txlevel < 4)) mytxlevel = 0; else mytxlevel = txlevel - 4; fmr1 = 0x1c; /* FMR1: Mode 0, T1 mode, CRC on for ESF, 2.048 Mhz system data rate, no XAIS */ fmr2 = 0x22; /* FMR2: no payload loopback, auto send yellow alarm */ if (loopback) fmr2 |= 0x4; fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */ lim2 = 0x21; /* LIM2: 50% peak is a "1", Advanced Loss recovery */ lim2 |= (mytxlevel << 6); /* LIM2: Add line buildout */ __t1_framer_out(wc, 0x1d, fmr1); __t1_framer_out(wc, 0x1e, fmr2); /* Configure line interface */ if (lineconfig & ZT_CONFIG_AMI) { line = "AMI"; fmr0 = 0xa0; } else { line = "B8ZS"; fmr0 = 0xf0; } if (lineconfig & ZT_CONFIG_D4) { framing = "D4"; } else { framing = "ESF"; fmr4 |= 0x2; fmr2 |= 0xc0; } __t1_framer_out(wc, 0x1c, fmr0); __t1_framer_out(wc, 0x20, fmr4); __t1_framer_out(wc, 0x21, 0x40); /* FMR5: Enable RBS mode */ __t1_framer_out(wc, 0x37, 0xf8); /* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */ __t1_framer_out(wc, 0x36, 0x08); /* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */ __t1_framer_out(wc, 0x02, 0x50); /* CMDR: Reset the receiver and transmitter line interface */ __t1_framer_out(wc, 0x02, 0x00); /* CMDR: Reset the receiver and transmitter line interface */ __t1_framer_out(wc, 0x3a, lim2); /* LIM2: 50% peak amplitude is a "1" */ __t1_framer_out(wc, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */ __t1_framer_out(wc, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */ /* Generate pulse mask for T1 */ switch(mytxlevel) { case 3: __t1_framer_out(wc, 0x26, 0x07); /* XPM0 */ __t1_framer_out(wc, 0x27, 0x01); /* XPM1 */ __t1_framer_out(wc, 0x28, 0x00); /* XPM2 */ break; case 2: __t1_framer_out(wc, 0x26, 0x8c); /* XPM0 */ __t1_framer_out(wc, 0x27, 0x11); /* XPM1 */ __t1_framer_out(wc, 0x28, 0x01); /* XPM2 */ break; case 1: __t1_framer_out(wc, 0x26, 0x8c); /* XPM0 */ __t1_framer_out(wc, 0x27, 0x01); /* XPM1 */ __t1_framer_out(wc, 0x28, 0x00); /* XPM2 */ break; case 0: default: __t1_framer_out(wc, 0x26, 0xd7); /* XPM0 */ __t1_framer_out(wc, 0x27, 0x22); /* XPM1 */ __t1_framer_out(wc, 0x28, 0x01); /* XPM2 */ break; } printk("TE110P: Span configured for %s/%s\n", framing, line);}static void __t1_configure_e1(struct t1 *wc, int lineconfig){ unsigned int fmr2, fmr1, fmr0; unsigned int cas = 0; char *crc4 = ""; char *framing, *line; fmr1 = 0x44; /* FMR1: E1 mode, Automatic force resync, PCM30 mode, 8.192 Mhz backplane, no XAIS */ fmr2 = 0x03; /* FMR2: Auto transmit remote alarm, auto loss of multiframe recovery, no payload loopback */ if (loopback) fmr2 |= 0x4; if (lineconfig & ZT_CONFIG_CRC4) { fmr1 |= 0x08; /* CRC4 transmit */ fmr2 |= 0xc0; /* CRC4 receive */ crc4 = "/CRC4"; } __t1_framer_out(wc, 0x1d, fmr1); __t1_framer_out(wc, 0x1e, fmr2); /* Configure line interface */ if (lineconfig & ZT_CONFIG_AMI) { line = "AMI"; fmr0 = 0xa0; } else { line = "HDB3"; fmr0 = 0xf0; } if (lineconfig & ZT_CONFIG_CCS) { framing = "CCS"; } else { framing = "CAS"; cas = 0x40; } __t1_framer_out(wc, 0x1c, fmr0); __t1_framer_out(wc, 0x37, 0xf0 /*| 0x6 */ ); /* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */ __t1_framer_out(wc, 0x36, 0x08); /* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */ __t1_framer_out(wc, 0x02, 0x50); /* CMDR: Reset the receiver and transmitter line interface */ __t1_framer_out(wc, 0x02, 0x00); /* CMDR: Reset the receiver and transmitter line interface */ /* Condition receive line interface for E1 after reset */ __t1_framer_out(wc, 0xbb, 0x17); __t1_framer_out(wc, 0xbc, 0x55); __t1_framer_out(wc, 0xbb, 0x97); __t1_framer_out(wc, 0xbb, 0x11); __t1_framer_out(wc, 0xbc, 0xaa); __t1_framer_out(wc, 0xbb, 0x91); __t1_framer_out(wc, 0xbb, 0x12); __t1_framer_out(wc, 0xbc, 0x55); __t1_framer_out(wc, 0xbb, 0x92); __t1_framer_out(wc, 0xbb, 0x0c); __t1_framer_out(wc, 0xbb, 0x00); __t1_framer_out(wc, 0xbb, 0x8c); __t1_framer_out(wc, 0x3a, 0x20); /* LIM2: 50% peak amplitude is a "1" */ __t1_framer_out(wc, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */ __t1_framer_out(wc, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */ __t1_framer_out(wc, 0x20, 0x9f); /* XSW: Spare bits all to 1 */ __t1_framer_out(wc, 0x21, 0x1c|cas); /* XSP: E-bit set when async. AXS auto, XSIF to 1 */ /* Generate pulse mask for E1 */ __t1_framer_out(wc, 0x26, 0x54); /* XPM0 */ __t1_framer_out(wc, 0x27, 0x02); /* XPM1 */ __t1_framer_out(wc, 0x28, 0x00); /* XPM2 */ printk("TE110P: Span configured for %s/%s%s\n", framing, line, crc4);}static void t1xxp_framer_start(struct t1 *wc, struct zt_span *span){ int alreadyrunning = wc->span.flags & ZT_FLAG_RUNNING; unsigned long flags; spin_lock_irqsave(&wc->lock, flags); if (wc->spantype == TYPE_E1) { /* if this is an E1 card */ __t1_configure_e1(wc, span->lineconfig); } else { /* is a T1 card */ __t1_configure_t1(wc, span->lineconfig, span->txlevel); __t1xxp_set_clear(wc); } if (!alreadyrunning) wc->span.flags |= ZT_FLAG_RUNNING; spin_unlock_irqrestore(&wc->lock, flags);}static int t1xxp_startup(struct zt_span *span){ struct t1 *wc = span->pvt; int i,alreadyrunning = span->flags & ZT_FLAG_RUNNING; /* initialize the start value for the entire chunk of last ec buffer */ for(i = 0; i < span->channels; i++) { memset(wc->ec_chunk1[i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); memset(wc->ec_chunk2[i], ZT_LIN2X(0,&span->chans[i]),ZT_CHUNKSIZE); } /* Reset framer with proper parameters and start */ t1xxp_framer_start(wc, span); printk("Calling startup (flags is %d)\n", span->flags); if (!alreadyrunning) { /* Only if we're not already going */ t1xxp_enable_interrupts(wc); t1xxp_start_dma(wc); span->flags |= ZT_FLAG_RUNNING; } return 0;}static int t1xxp_shutdown(struct zt_span *span){ struct t1 *wc = span->pvt; unsigned long flags; spin_lock_irqsave(&wc->lock, flags); t1_framer_out(wc, 0x46, 0x41); /* GCR: Interrupt on Activation/Deactivation of AIX, LOS */ __t1xxp_stop_dma(wc); __t1xxp_disable_interrupts(wc); span->flags &= ~ZT_FLAG_RUNNING; spin_unlock_irqrestore(&wc->lock, flags); return 0;}static int t1xxp_chanconfig(struct zt_chan *chan, int sigtype){ struct t1 *wc = chan->pvt; unsigned long flags; int alreadyrunning = chan->span->flags & ZT_FLAG_RUNNING; spin_lock_irqsave(&wc->lock, flags); if (alreadyrunning && (wc->spantype != TYPE_E1)) __t1xxp_set_clear(wc); spin_unlock_irqrestore(&wc->lock, flags); return 0;}static int t1xxp_spanconfig(struct zt_span *span, struct zt_lineconfig *lc){ struct t1 *wc = span->pvt; span->lineconfig = lc->lineconfig; span->txlevel = lc->lbo; span->rxlevel = 0; /* Do we want to SYNC on receive or not */ wc->sync = lc->sync; /* If already running, apply changes immediately */ if (span->flags & ZT_FLAG_RUNNING) return t1xxp_startup(span); return 0;}static int t1xxp_software_init(struct t1 *wc){ int x; /* Find position */ for (x=0;x<WC_MAX_CARDS;x++) { if (!cards[x]) { cards[x] = wc; break; } } if (x >= WC_MAX_CARDS) return -1; t4_serial_setup(wc); wc->num = x; sprintf(wc->span.name, "WCT1/%d", wc->num); sprintf(wc->span.desc, "%s Card %d", wc->variety, wc->num); wc->span.spanconfig = t1xxp_spanconfig; wc->span.chanconfig = t1xxp_chanconfig; wc->span.startup = t1xxp_startup; wc->span.shutdown = t1xxp_shutdown; wc->span.rbsbits = t1xxp_rbsbits; wc->span.maint = t1xxp_maint; wc->span.open = t1xxp_open; wc->span.close = t1xxp_close; if (wc->spantype == TYPE_E1) wc->span.channels = 31; else wc->span.channels = 24; wc->span.chans = wc->chans; wc->span.flags = ZT_FLAG_RBS; wc->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_B8ZS | ZT_CONFIG_D4 | ZT_CONFIG_ESF; wc->span.ioctl = t1xxp_ioctl; wc->span.pvt = wc; if (wc->spantype == TYPE_E1) wc->span.deflaw = ZT_LAW_ALAW; else wc->span.deflaw = ZT_LAW_MULAW; init_waitqueue_head(&wc->span.maintq); for (x=0;x<wc->span.channels;x++) { sprintf(wc->chans[x].name, "WCT1/%d/%d", wc->num, x + 1); wc->chans[x].sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_EM_E1 | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_SF; wc->chans[x].pvt = wc; wc->chans[x].chanpos = x + 1; } if (zt_register(&wc->span, 0)) { printk("Unable to register span with zaptel\n"); return -1; } return 0;}static inline void __handle_leds(struct t1 *wc){ int oldreg; if (wc->span.alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE)) { /* Red/Blue alarm */ wc->blinktimer++;#ifdef FANCY_ALARM if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) { wc->ledtestreg = (wc->ledtestreg | BIT_LED1) & ~BIT_LED0; __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); } if (wc->blinktimer >= 0xf) { wc->ledtestreg = wc->ledtestreg & ~(BIT_LED0 | BIT_LED1); __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); wc->blinktimer = -1; wc->alarmpos++; if (wc->alarmpos >= (sizeof(altab) / sizeof(altab[0]))) wc->alarmpos = 0; }#else if (wc->blinktimer == 160) { wc->ledtestreg = (wc->ledtestreg | BIT_LED1) & ~BIT_LED0; __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); } else if (wc->blinktimer == 480) { wc->ledtestreg = wc->ledtestreg & ~(BIT_LED0 | BIT_LED1); __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); wc->blinktimer = 0; }#endif } else if (wc->span.alarms & ZT_ALARM_YELLOW) { /* Yellow Alarm */ if (!(wc->blinktimer % 2)) wc->ledtestreg = (wc->ledtestreg | BIT_LED1) & ~BIT_LED0; else wc->ledtestreg = (wc->ledtestreg | BIT_LED0) & ~BIT_LED1; __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); } else { /* No Alarm */ oldreg = wc->ledtestreg; if (wc->span.maintstat != ZT_MAINT_NONE) wc->ledtestreg |= BIT_TEST; else wc->ledtestreg &= ~BIT_TEST; if (wc->span.flags & ZT_FLAG_RUNNING) wc->ledtestreg = (wc->ledtestreg | BIT_LED0) & ~BIT_LED1; else wc->ledtestreg = wc->ledtestreg & ~(BIT_LED0 | BIT_LED1); if (oldreg != wc->ledtestreg) __control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); }}static void t1xxp_transmitprep(struct t1 *wc, int ints){ volatile unsigned char *txbuf; int x,y; int pos; if (ints & 0x04 /* 0x01 */) { /* We just finished sending the first buffer, start filling it now */ txbuf = wc->writechunk; } else { /* Just finished sending second buffer, fill it now */ txbuf = wc->writechunk + 32 * ZT_CHUNKSIZE; } zt_transmit(&wc->span); for (x=0;x<wc->offset;x++) txbuf[x] = wc->tempo[x]; for (y=0;y<ZT_CHUNKSIZE;y++) { for (x=0;x<wc->span.channels;x++) { pos = y * 32 + wc->chanmap[x] + wc->offset; /* Put channel number as outgoing data */ if (pos < 32 * ZT_CHUNKSIZE) txbuf[pos] = wc->chans[x].writechunk[y]; else wc->tempo[pos - 32 * ZT_CHUNKSIZE] = wc->chans[x].writechunk[y]; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -