📄 pc300_drv.c
字号:
while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) { if (i++ >= PC300_FALC_MAXLOOP) { printk("%s: FALC command locked(cmd=0x%x).\n", card->chan[ch].d.name, cmd); break; } } cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);}void falc_intr_enable(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; falc_t *pfalc = (falc_t *) & chan->falc; uclong falcbase = card->hw.falcbase; /* Interrupt pins are open-drain */ cpc_writeb(falcbase + F_REG(IPC, ch), cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0); /* Conters updated each second */ cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM); /* Enable SEC and ES interrupts */ cpc_writeb(falcbase + F_REG(IMR3, ch), cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES)); if (conf->fr_mode == PC300_FR_UNFRAMED) { cpc_writeb(falcbase + F_REG(IMR4, ch), cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LOS)); } else { cpc_writeb(falcbase + F_REG(IMR4, ch), cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP)); } if (conf->media == IF_IFACE_T1) { cpc_writeb(falcbase + F_REG(IMR3, ch), cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); } else { cpc_writeb(falcbase + F_REG(IPC, ch), cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI); if (conf->fr_mode == PC300_FR_UNFRAMED) { cpc_writeb(falcbase + F_REG(IMR2, ch), cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_LOS)); } else { cpc_writeb(falcbase + F_REG(IMR2, ch), cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS)); if (pfalc->multiframe_mode) { cpc_writeb(falcbase + F_REG(IMR2, ch), cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_T400MS | IMR2_MFAR)); } else { cpc_writeb(falcbase + F_REG(IMR2, ch), cpc_readb(falcbase + F_REG(IMR2, ch)) | IMR2_T400MS | IMR2_MFAR); } } }}void falc_open_timeslot(pc300_t * card, int ch, int timeslot){ uclong falcbase = card->hw.falcbase; ucchar tshf = card->chan[ch].falc.offset; cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & ~(0x80 >> ((timeslot - tshf) & 0x07))); cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) | (0x80 >> (timeslot & 0x07))); cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) | (0x80 >> (timeslot & 0x07)));}void falc_close_timeslot(pc300_t * card, int ch, int timeslot){ uclong falcbase = card->hw.falcbase; ucchar tshf = card->chan[ch].falc.offset; cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | (0x80 >> ((timeslot - tshf) & 0x07))); cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) & ~(0x80 >> (timeslot & 0x07))); cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) & ~(0x80 >> (timeslot & 0x07)));}void falc_close_all_timeslots(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; uclong falcbase = card->hw.falcbase; cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff); cpc_writeb(falcbase + F_REG(TTR1, ch), 0); cpc_writeb(falcbase + F_REG(RTR1, ch), 0); cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff); cpc_writeb(falcbase + F_REG(TTR2, ch), 0); cpc_writeb(falcbase + F_REG(RTR2, ch), 0); cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff); cpc_writeb(falcbase + F_REG(TTR3, ch), 0); cpc_writeb(falcbase + F_REG(RTR3, ch), 0); if (conf->media == IF_IFACE_E1) { cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); cpc_writeb(falcbase + F_REG(TTR4, ch), 0); cpc_writeb(falcbase + F_REG(RTR4, ch), 0); }}void falc_open_all_timeslots(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; uclong falcbase = card->hw.falcbase; cpc_writeb(falcbase + F_REG(ICB1, ch), 0); if (conf->fr_mode == PC300_FR_UNFRAMED) { cpc_writeb(falcbase + F_REG(TTR1, ch), 0xff); cpc_writeb(falcbase + F_REG(RTR1, ch), 0xff); } else { /* Timeslot 0 is never enabled */ cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f); cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f); } cpc_writeb(falcbase + F_REG(ICB2, ch), 0); cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff); cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff); cpc_writeb(falcbase + F_REG(ICB3, ch), 0); cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff); cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff); if (conf->media == IF_IFACE_E1) { cpc_writeb(falcbase + F_REG(ICB4, ch), 0); cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff); cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff); } else { cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80); cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80); }}void falc_init_timeslot(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; falc_t *pfalc = (falc_t *) & chan->falc; int tslot; for (tslot = 0; tslot < pfalc->num_channels; tslot++) { if (conf->tslot_bitmap & (1 << tslot)) { // Channel enabled falc_open_timeslot(card, ch, tslot + 1); } else { // Channel disabled falc_close_timeslot(card, ch, tslot + 1); } }}void falc_enable_comm(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; falc_t *pfalc = (falc_t *) & chan->falc; if (pfalc->full_bandwidth) { falc_open_all_timeslots(card, ch); } else { falc_init_timeslot(card, ch); } // CTS/DCD ON cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));}void falc_disable_comm(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; falc_t *pfalc = (falc_t *) & chan->falc; if (pfalc->loop_active != 2) { falc_close_all_timeslots(card, ch); } // CTS/DCD OFF cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));}void falc_init_t1(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; falc_t *pfalc = (falc_t *) & chan->falc; uclong falcbase = card->hw.falcbase; ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); /* Switch to T1 mode (PCM 24) */ cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD); /* Wait 20 us for setup */ udelay(20); /* Transmit Buffer Size (1 frame) */ cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0); /* Clock mode */ if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); } else { /* Slave mode */ cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); cpc_writeb(falcbase + F_REG(LOOP, ch), cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); } cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) & ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); switch (conf->lcode) { case PC300_LC_AMI: cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_XC1 | FMR0_RC1); /* Clear Channel register to ON for all channels */ cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff); cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff); cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff); break; case PC300_LC_B8ZS: cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); break; case PC300_LC_NRZ: cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00); break; } cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS); cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); /* Set interface mode to 2 MBPS */ cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); switch (conf->fr_mode) { case PC300_FR_ESF: pfalc->multiframe_mode = 0; cpc_writeb(falcbase + F_REG(FMR4, ch), cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1); cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CRC | FMR1_EDL); cpc_writeb(falcbase + F_REG(XDL1, ch), 0); cpc_writeb(falcbase + F_REG(XDL2, ch), 0); cpc_writeb(falcbase + F_REG(XDL3, ch), 0); cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF); cpc_writeb(falcbase + F_REG(FMR2, ch), cpc_readb(falcbase + F_REG(FMR2,ch)) | FMR2_MCSP | FMR2_SSP); break; case PC300_FR_D4: pfalc->multiframe_mode = 1; cpc_writeb(falcbase + F_REG(FMR4, ch), cpc_readb(falcbase + F_REG(FMR4, ch)) & ~(FMR4_FM1 | FMR4_FM0)); cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF); cpc_writeb(falcbase + F_REG(FMR2, ch), cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP); break; } /* Enable Automatic Resynchronization */ cpc_writeb(falcbase + F_REG(FMR4, ch), cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO); /* Transmit Automatic Remote Alarm */ cpc_writeb(falcbase + F_REG(FMR2, ch), cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); /* Channel translation mode 1 : one to one */ cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM); /* No signaling */ cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM); cpc_writeb(falcbase + F_REG(FMR5, ch), cpc_readb(falcbase + F_REG(FMR5, ch)) & ~(FMR5_EIBR | FMR5_SRS)); cpc_writeb(falcbase + F_REG(CCR1, ch), 0); cpc_writeb(falcbase + F_REG(LIM1, ch), cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); switch (conf->lbo) { /* Provides proper Line Build Out */ case PC300_LBO_0_DB: cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a); cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f); cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); break; case PC300_LBO_7_5_DB: cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja)); cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11); cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02); cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); break; case PC300_LBO_15_DB: cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja)); cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e); cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); break; case PC300_LBO_22_5_DB: cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja)); cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09); cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); break; } /* Transmit Clock-Slot Offset */ cpc_writeb(falcbase + F_REG(XC0, ch), cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); /* Transmit Time-slot Offset */ cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); /* Receive Clock-Slot offset */ cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); /* Receive Time-slot offset */ cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); /* LOS Detection after 176 consecutive 0s */ cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); /* LOS Recovery after 22 ones in the time window of PCD */ cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); if (conf->fr_mode == PC300_FR_ESF_JAPAN) { cpc_writeb(falcbase + F_REG(RC1, ch), cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80); } falc_close_all_timeslots(card, ch);}void falc_init_e1(pc300_t * card, int ch){ pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; falc_t *pfalc = (falc_t *) & chan->falc; uclong falcbase = card->hw.falcbase; ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); /* Switch to E1 mode (PCM 30) */ cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD); /* Clock mode */ if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); } else { /* Slave mode */ cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); } cpc_writeb(falcbase + F_REG(LOOP, ch), cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_SFM); cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) & ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); switch (conf->lcode) { case PC300_LC_AMI: cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_XC1 | FMR0_RC1); break; case PC300_LC_HDB3: cpc_writeb(falcbase + F_REG(FMR0, ch), cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); break; case PC300_LC_NRZ: break; } cpc_writeb(falcbase + F_REG(LIM0, ch), cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); /* Set interface mode to 2 MBPS */ cpc_writeb(falcbase + F_REG(FMR1, ch), cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18); cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03); cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -