📄 ixj-redhat.c
字号:
} } if (!j->flags.ringing) { if (ixj_hookstate(board)) { if (j->dsp.low != 0x20 && j->pld_slicr.bits.state != PLD_SLIC_STATE_ACTIVE) // Internet LineJACK { SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board); } LineMonitor(board); read_filters(board); ixj_WriteDSPCommand(0x511B, board); j->proc_load = j->ssr.high << 8 | j->ssr.low; if (!j->m_hook) { j->m_hook = j->ex.bits.hookstate = 1; if (j->async_queue) kill_fasync(ixj[board].async_queue, SIGIO, POLL_IN); } } else { if (j->dsp.low != 0x20 && j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE) // Internet LineJACK { SLIC_SetState(PLD_SLIC_STATE_STANDBY, board); } if (j->ex.bits.dtmf_ready) { j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0; } if (j->m_hook) { j->m_hook = 0; j->ex.bits.hookstate = 1; if (j->async_queue) kill_fasync(ixj[board].async_queue, SIGIO, POLL_IN); } } } if (j->cardtype == 300) { if (j->flags.pstn_present) { j->pld_scrr.byte = inb_p(j->XILINXbase); if (jiffies >= j->pstn_sleeptil && j->pld_scrr.bits.daaflag) { daa_int_read(board); if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) { if (!j->flags.pstn_ringing) { j->flags.pstn_ringing = 1; if (j->daa_mode != SOP_PU_RINGING) daa_set_mode(board, SOP_PU_RINGING); } } if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { j->pstn_winkstart = 0; if (j->flags.pstn_ringing && !j->pstn_envelope) { j->ex.bits.pstn_ring = 0; j->pstn_envelope = 1; j->pstn_ring_start = jiffies; } } else { if (j->flags.pstn_ringing && j->pstn_envelope && jiffies > j->pstn_ring_start + ((hertz * 15) / 10)) { j->ex.bits.pstn_ring = 1; j->pstn_envelope = 0; } else if (j->daa_mode == SOP_PU_CONVERSATION) { if (!j->pstn_winkstart) { j->pstn_winkstart = jiffies; } else if (jiffies > j->pstn_winkstart + (hertz * j->winktime / 1000)) { daa_set_mode(board, SOP_PU_SLEEP); j->pstn_winkstart = 0; j->ex.bits.pstn_wink = 1; } } else { j->ex.bits.pstn_ring = 0; } } if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) { if (j->daa_mode == SOP_PU_RINGING) { daa_set_mode(board, SOP_PU_SLEEP); j->flags.pstn_ringing = 0; j->ex.bits.pstn_ring = 0; } } if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) { if (j->daa_mode == SOP_PU_RINGING && j->flags.pstn_ringing) { j->pstn_cid_intr = 1; j->pstn_cid_recieved = jiffies; } } } else { if (j->pld_scrr.bits.daaflag) { daa_int_read(board); } j->ex.bits.pstn_ring = 0; if (j->pstn_cid_intr && jiffies > j->pstn_cid_recieved + (hertz * 3)) { if (j->daa_mode == SOP_PU_RINGING) { ixj_daa_cid_read(board); j->ex.bits.caller_id = 1; } j->pstn_cid_intr = 0; } else { j->ex.bits.caller_id = 0; } if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { if (j->flags.pstn_ringing && j->pstn_envelope) { j->ex.bits.pstn_ring = 1; j->pstn_envelope = 0; } else if (j->daa_mode == SOP_PU_CONVERSATION) { if (!j->pstn_winkstart) { j->pstn_winkstart = jiffies; } else if (jiffies > j->pstn_winkstart + (hertz * 320 / 1000)) { daa_set_mode(board, SOP_PU_SLEEP); j->pstn_winkstart = 0; j->ex.bits.pstn_wink = 1; } } } } } } if (j->ex.bytes) { wake_up_interruptible(&j->poll_q); // Wake any blocked selects if (j->async_queue) kill_fasync(ixj[board].async_queue, SIGIO, POLL_IN); } } else { break; } } ixj_add_timer();}static int ixj_status_wait(int board){ unsigned long jif; jif = jiffies; while (!IsStatusReady(board)) { if (jiffies - jif > (60 * (hertz / 100))) { return -1; } } return 0;}static int ixj_PCcontrol_wait(int board){ unsigned long jif; jif = jiffies; while (!IsPCControlReady(board)) { if (jiffies - jif > (60 * (hertz / 100))) { return -1; } } return 0;}int ixj_WriteDSPCommand(unsigned short cmd, int board){ BYTES bytes; unsigned long jif; bytes.high = (cmd & 0xFF00) >> 8; bytes.low = cmd & 0x00FF; jif = jiffies; while (!IsControlReady(board)) { if (jiffies - jif > (60 * (hertz / 100))) { return -1; } } outb_p(bytes.low, ixj[board].DSPbase + 6); outb_p(bytes.high, ixj[board].DSPbase + 7); if (ixj_status_wait(board)) { ixj[board].ssr.low = 0xFF; ixj[board].ssr.high = 0xFF; return -1; }/* Read Software Status Register */ ixj[board].ssr.low = inb_p(ixj[board].DSPbase + 2); ixj[board].ssr.high = inb_p(ixj[board].DSPbase + 3); return 0;}/***************************************************************************** General Purpose IO Register read routine****************************************************************************/extern __inline__ int ixj_gpio_read(int board){ if (ixj_WriteDSPCommand(0x5143, board)) return -1; ixj[board].gpio.bytes.low = ixj[board].ssr.low; ixj[board].gpio.bytes.high = ixj[board].ssr.high; return 0;}extern __inline__ void LED_SetState(int state, int board){ if (ixj[board].cardtype == 300) { ixj[board].pld_scrw.bits.led1 = state & 0x1 ? 1 : 0; ixj[board].pld_scrw.bits.led2 = state & 0x2 ? 1 : 0; ixj[board].pld_scrw.bits.led3 = state & 0x4 ? 1 : 0; ixj[board].pld_scrw.bits.led4 = state & 0x8 ? 1 : 0; outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase); }}/********************************************************************** GPIO Pins are configured as follows on the Quicknet Internet* PhoneJACK Telephony Cards* * POTS Select GPIO_6=0 GPIO_7=0* Mic/Speaker Select GPIO_6=0 GPIO_7=1* Handset Select GPIO_6=1 GPIO_7=0** SLIC Active GPIO_1=0 GPIO_2=1 GPIO_5=0* SLIC Ringing GPIO_1=1 GPIO_2=1 GPIO_5=0* SLIC Open Circuit GPIO_1=0 GPIO_2=0 GPIO_5=0** Hook Switch changes reported on GPIO_3*********************************************************************/static int ixj_set_port(int board, int arg){ IXJ *j = &ixj[board]; if (j->cardtype == 400) { if (arg != PORT_POTS) return 10; else return 0; } if (j->cardtype == 600) { if (arg != PORT_SPEAKER) return 11; else return 0; } switch (arg) { case PORT_POTS: j->port = PORT_POTS; switch (j->cardtype) { case 500: j->pld_slicw.pcib.mic = 0; j->pld_slicw.pcib.spk = 0; outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); break; case 300: if (ixj_WriteDSPCommand(0xC528, board)) /* Write CODEC config to Software Control Register */ return 2; j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync outb_p(j->pld_scrw.byte, j->XILINXbase); j->pld_clock.byte = 0; outb_p(j->pld_clock.byte, j->XILINXbase + 0x04); j->pld_slicw.bits.rly1 = 1; j->pld_slicw.bits.spken = 0; outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); SLIC_SetState(PLD_SLIC_STATE_STANDBY, board); break; case 100: j->gpio.bytes.high = 0x0B; j->gpio.bits.gpio6 = 0; j->gpio.bits.gpio7 = 0; ixj_WriteDSPCommand(j->gpio.word, board); break; } break; case PORT_PSTN: if (j->cardtype == 300) { ixj_WriteDSPCommand(0xC534, board); /* Write CODEC config to Software Control Register */ j->pld_slicw.bits.rly3 = 0; j->pld_slicw.bits.rly1 = 1; j->pld_slicw.bits.spken = 0; outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); j->port = PORT_PSTN; } else { return 4; } break; case PORT_SPEAKER: j->port = PORT_SPEAKER; switch (j->cardtype) { case 500: j->pld_slicw.pcib.mic = 1; j->pld_slicw.pcib.spk = 1; outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); break; case 600: case 300: break; case 100: j->gpio.bytes.high = 0x0B; j->gpio.bits.gpio6 = 0; j->gpio.bits.gpio7 = 1; ixj_WriteDSPCommand(j->gpio.word, board); break; } break; case PORT_HANDSET: if (j->cardtype == 300 || j->cardtype == 500) { return 5; } else { j->gpio.bytes.high = 0x0B; j->gpio.bits.gpio6 = 1; j->gpio.bits.gpio7 = 0; ixj_WriteDSPCommand(j->gpio.word, board); j->port = PORT_HANDSET; } break; default: return 6; break; } return 0;}static int ixj_set_pots(int board, int arg){ IXJ *j = &ixj[board]; if (j->cardtype == 300) { if (arg) { if (j->port == PORT_PSTN) { j->pld_slicw.bits.rly1 = 0; outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); return 1; } else { return 0; } } else { j->pld_slicw.bits.rly1 = 1; outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); return 1; } } else { return 0; }}static void ixj_ring_on(int board){ IXJ *j = &ixj[board]; if (j->dsp.low == 0x20) // Internet PhoneJACK { if (ixjdebug > 0) printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", board); j->gpio.bytes.high = 0x0B; j->gpio.bytes.low = 0x00; j->gpio.bits.gpio1 = 1; j->gpio.bits.gpio2 = 1; j->gpio.bits.gpio5 = 0; ixj_WriteDSPCommand(j->gpio.word, board); /* send the ring signal */ } else // Internet LineJACK, Internet PhoneJACK Lite or // Internet PhoneJACK PCI { if (ixjdebug > 0) printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", board); SLIC_SetState(PLD_SLIC_STATE_RINGING, board); }}static int ixj_pcmcia_cable_check(int board){ IXJ *j = &ixj[board]; j->pccr1.byte = inb_p(j->XILINXbase + 0x03); if (!j->pccr1.bits.drf) { j->psccr.bits.dev = 3; j->psccr.bits.rw = 1; outb(j->psccr.byte, j->XILINXbase + 0x01); if (ixj_PCcontrol_wait(board)) return 0; else { if (!j->flags.pcmciascp) { j->flags.pcmciascp = 1; // Set Cable Present Flag j->flags.pcmciasct = inb_p(j->XILINXbase + 0x01); // Get Cable Type j->sic1.bits.cpd = 0; // Chip Power Down j->sic1.bits.mpd = 0; // MIC Bias Power Down j->sic1.bits.hpd = 0; // Handset Bias Power Down j->sic1.bits.lpd = 0; // Line Bias Power Down j->sic1.bits.spd = 1; // Speaker Drive Power Down j->psccr.bits.addr = 1; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(j->sic1.byte, j->XILINXbase + 0x00); outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->sic2.bits.al = 0; // Analog Loopback DAC analog -> ADC analog j->sic2.bits.dl2 = 0; // Digital Loopback DAC -> ADC one bit j->sic2.bits.dl1 = 0; // Digital Loopback ADC -> DAC one bit j->sic2.bits.pll = 0; // 1 = div 10, 0 = div 5 j->sic2.bits.hpd = 0; // HPF disable j->psccr.bits.addr = 2; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(j->sic2.byte, j->XILINXbase + 0x00); outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->psccr.bits.addr = 3; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(0x00, j->XILINXbase + 0x00); // PLL Divide N1 outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->psccr.bits.addr = 4; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(0x09, j->XILINXbase + 0x00); // PLL Multiply M1 outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->sirxg.bits.lig = 1; // Line In Gain j->sirxg.bits.lim = 1; // Line In Mute j->sirxg.bits.mcg = 3; // MIC In Gain j->sirxg.bits.mcm = 0; // MIC In Mute j->sirxg.bits.him = 0; // Handset In Mute j->sirxg.bits.iir = 1; // IIR j->psccr.bits.addr = 5; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(j->sirxg.byte, j->XILINXbase + 0x00); outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->siadc.bits.hom = 0; // Handset Out Mute j->siadc.bits.lom = 0; // Line Out Mute j->siadc.bits.rxg = (0xC000 - 0x41C8) / 0x4EF; // RX PGA Gain j->psccr.bits.addr = 6; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(j->siadc.byte, j->XILINXbase + 0x00); outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->sidac.bits.srm = 1; // Speaker Right Mute j->sidac.bits.slm = 1; // Speaker Left Mute j->sidac.bits.txg = (0xC000 - 0x45E4) / 0x5D3; // TX PGA Gain j->psccr.bits.addr = 7; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(j->sidac.byte, j->XILINXbase + 0x00); outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); j->siaatt.bits.sot = 0; j->psccr.bits.addr = 9; // R/W Smart Cable Register Address j->psccr.bits.rw = 0; // Read / Write flag j->psccr.bits.dev = 0; outb(j->siaatt.byte, j->XILINXbase + 0x00); outb(j->psccr.byte, j->XILINXbase + 0x01); ixj_PCcontrol_wait(board); } } return 1; } else { j->flags.pcmciascp = 0; return 0; }}static int ixj_hookstate(int board){ unsigned long det; IXJ *j = &ixj[board]; int fOffHook = 0; switch (j->cardtype) { case 100: ixj_gpio_read(board); fOffHook = j->gpio.bits.gpio3read ? 1 : 0; break; case 300: case 400: case 500: SLIC_GetState(board); if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE || j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) { if (j->flags.ringing) { if (!in_interrupt()) { det = jiffies + (hertz / 50); while (time_before(jiffies, det)) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); } } SLIC_GetState(board); if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) { ixj_ring_on(board); } } if (j->cardtype == 500) { j->pld_scrr.byte = inb_p(j->XILINXbase); fOffHook = j->pld_scrr.pcib.det ? 1 : 0; } else fOffHook = j->pld_slicr.bits.det ? 1 : 0; } break; case 600: fOffHook = ixj_pcmcia_cable_check(board); break; } if (j->r_hook != fOffHook) { j->r_hook = fOffHook; if (j->port != PORT_POTS || j->cardtype == 600) { j->ex.bits.hookstate = 1; if (j->async_queue) kill_fasync(ixj[board].async_queue, SIGIO, POLL_IN); } } if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION) fOffHook |= 2; if (j->port == PORT_SPEAKER) fOffHook |= 2; if (j->port == PORT_HANDSET)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -