⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixj.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************** *    ixj.c * *    Device Driver for the Internet PhoneJACK and *    Internet LineJACK Telephony Cards. * *    (c) Copyright 1999-2000  Quicknet Technologies, Inc. * *    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 the Free Software Foundation; either version *    2 of the License, or (at your option) any later version. * * Author:          Ed Okerson, <eokerson@quicknet.net> * * Contributors:    Greg Herlein, <gherlein@quicknet.net> *                  David W. Erhart, <derhart@quicknet.net> *                  John Sellers, <jsellers@quicknet.net> *                  Mike Preston, <mpreston@quicknet.net> *     * Fixes: *                  Marc Boucher, <marc@mbsi.ca> *  * More information about the hardware related to this driver can be found   * at our website:    http://www.quicknet.net * * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *     * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * ***************************************************************************/static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.31 2000/04/14 19:24:47 jaugenst Exp $";static char ixj_c_revision[] = "$Revision: 3.31 $";//#define PERFMON_STATS#define IXJDEBUG 0#define MAXRINGS 5#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/kernel.h>	/* printk() */#include <linux/fs.h>		/* everything... */#include <linux/errno.h>	/* error codes */#include <linux/malloc.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/interrupt.h>#include <linux/tqueue.h>#include <linux/proc_fs.h>#include <linux/poll.h>#include <linux/timer.h>#include <linux/delay.h>#include <linux/pci.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/uaccess.h>#ifdef CONFIG_PCMCIA#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h>#endif#ifdef CONFIG_ISAPNP#include <linux/isapnp.h>#endif#include "ixj.h"#define TYPE(dev) (MINOR(dev) >> 4)#define NUM(dev) (MINOR(dev) & 0xf)static int ixjdebug = 0;static int hertz = HZ;static int samplerate = 100;MODULE_PARM(ixjdebug, "i");static IXJ ixj[IXJMAX];static struct timer_list ixj_timer;int ixj_convert_loaded = 0;/************************************************************************** These are function definitions to allow external modules to register* enhanced functionality call backs.*************************************************************************/static int Stub(IXJ * J, unsigned long arg){	return 0;}static IXJ_REGFUNC ixj_DownloadG729 = &Stub;static IXJ_REGFUNC ixj_DownloadTS85 = &Stub;static IXJ_REGFUNC ixj_PreRead = &Stub;static IXJ_REGFUNC ixj_PostRead = &Stub;static IXJ_REGFUNC ixj_PreWrite = &Stub;static IXJ_REGFUNC ixj_PostWrite = &Stub;static IXJ_REGFUNC ixj_PreIoctl = &Stub;static IXJ_REGFUNC ixj_PostIoctl = &Stub;static void ixj_read_frame(int board);static void ixj_write_frame(int board);static void ixj_init_timer(void);static void ixj_add_timer(void);static void ixj_timeout(unsigned long ptr);static int read_filters(int board);static int LineMonitor(int board);static int ixj_fasync(int fd, struct file *, int mode);static int ixj_set_port(int board, int arg);static int ixj_set_pots(int board, int arg);static int ixj_hookstate(int board);static int ixj_record_start(int board);static void ixj_record_stop(int board);static void set_rec_volume(int board, int volume);static void ixj_vad(int board, int arg);static int ixj_play_start(int board);static void ixj_play_stop(int board);static int ixj_set_tone_on(unsigned short arg, int board);static int ixj_set_tone_off(unsigned short, int board);static int ixj_play_tone(int board, char tone);static int idle(int board);static void ixj_ring_on(int board);static void ixj_ring_off(int board);static void aec_stop(int board);static void ixj_ringback(int board);static void ixj_busytone(int board);static void ixj_dialtone(int board);static void ixj_cpt_stop(int board);static char daa_int_read(int board);static int daa_set_mode(int board, int mode);static int ixj_linetest(int board);static int ixj_daa_write(int board);static int ixj_daa_cid_read(int board);static void DAA_Coeff_US(int board);static void DAA_Coeff_UK(int board);static void DAA_Coeff_France(int board);static void DAA_Coeff_Germany(int board);static void DAA_Coeff_Australia(int board);static void DAA_Coeff_Japan(int board);static int ixj_init_filter(int board, IXJ_FILTER * jf);static int ixj_init_tone(int board, IXJ_TONE * ti);static int ixj_build_cadence(int board, IXJ_CADENCE * cp);static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp);// Serial Control Interface funtionsstatic int SCI_Control(int board, int control);static int SCI_Prepare(int board);static int SCI_WaitHighSCI(int board);static int SCI_WaitLowSCI(int board);static DWORD PCIEE_GetSerialNumber(WORD wAddress);static int ixj_PCcontrol_wait(int board);static void ixj_write_cid(int board);static void ixj_write_cid_bit(int board, int bit);static int set_base_frame(int board, int size);static int set_play_codec(int board, int rate);/************************************************************************CT8020/CT8021 Host Programmers ModelHost address	Function					AccessDSPbase +0-1		Aux Software Status Register (reserved)		Read Only2-3		Software Status Register			Read Only4-5		Aux Software Control Register (reserved)	Read Write6-7		Software Control Register			Read Write8-9		Hardware Status Register			Read OnlyA-B		Hardware Control Register			Read WriteC-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write OnlyE-F Host Recieve (Read) Data Buffer Access Port (buffer input)	Read Only************************************************************************/extern __inline__ void ixj_read_HSR(int board){	ixj[board].hsr.bytes.low = inb_p(ixj[board].DSPbase + 8);	ixj[board].hsr.bytes.high = inb_p(ixj[board].DSPbase + 9);}extern __inline__ int IsControlReady(int board){	ixj_read_HSR(board);	return ixj[board].hsr.bits.controlrdy ? 1 : 0;}extern __inline__ int IsPCControlReady(int board){	ixj[board].pccr1.byte = inb_p(ixj[board].XILINXbase + 3);	return ixj[board].pccr1.bits.crr ? 1 : 0;}extern __inline__ int IsStatusReady(int board){	ixj_read_HSR(board);	return ixj[board].hsr.bits.statusrdy ? 1 : 0;}extern __inline__ int IsRxReady(int board){	ixj_read_HSR(board);#ifdef PERFMON_STATS	++ixj[board].rxreadycheck;#endif	return ixj[board].hsr.bits.rxrdy ? 1 : 0;}extern __inline__ int IsTxReady(int board){	ixj_read_HSR(board);#ifdef PERFMON_STATS	++ixj[board].txreadycheck;#endif	return ixj[board].hsr.bits.txrdy ? 1 : 0;}extern __inline__ void set_play_volume(int board, int volume){	ixj_WriteDSPCommand(0xCF02, board);	ixj_WriteDSPCommand(volume, board);}extern __inline__ int get_play_volume(int board){	ixj_WriteDSPCommand(0xCF00, board);	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;}extern __inline__ BYTE SLIC_GetState(int board){	IXJ *j = &ixj[board];	if (j->cardtype == 600) {		j->pccr1.byte = 0;		j->psccr.bits.dev = 3;		j->psccr.bits.rw = 1;		outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);		ixj_PCcontrol_wait(board);		j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;		ixj_PCcontrol_wait(board);		if (j->pslic.bits.powerdown)			return PLD_SLIC_STATE_OC;		else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)			return PLD_SLIC_STATE_ACTIVE;		else			return PLD_SLIC_STATE_RINGING;	} else {		j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);	}	return j->pld_slicr.bits.state;}static BOOL SLIC_SetState(BYTE byState, int board){	BOOL fRetVal = FALSE;	IXJ *j = &ixj[board];	if (j->cardtype == 600) {		if (j->flags.pcmciasct) {			switch (byState) {			case PLD_SLIC_STATE_TIPOPEN:			case PLD_SLIC_STATE_OC:				j->pslic.bits.powerdown = 1;				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;				fRetVal = TRUE;				break;			case PLD_SLIC_STATE_RINGING:				if (j->readers || j->writers) {					j->pslic.bits.powerdown = 0;					j->pslic.bits.ring0 = 1;					j->pslic.bits.ring1 = 0;					fRetVal = TRUE;				}				break;			case PLD_SLIC_STATE_OHT:	// On-hook transmit			case PLD_SLIC_STATE_STANDBY:			case PLD_SLIC_STATE_ACTIVE:				if (j->readers || j->writers) {					j->pslic.bits.powerdown = 0;				} else {					j->pslic.bits.powerdown = 1;				}				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;				fRetVal = TRUE;				break;			case PLD_SLIC_STATE_APR:	// Active polarity reversal			case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal			default:				fRetVal = FALSE;				break;			}			j->psccr.bits.dev = 3;			j->psccr.bits.rw = 0;			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);			ixj_PCcontrol_wait(board);		}	} else {		// Set the C1, C2, C3 & B2EN signals.		switch (byState) {		case PLD_SLIC_STATE_OC:			j->pld_slicw.bits.c1 = 0;			j->pld_slicw.bits.c2 = 0;			j->pld_slicw.bits.c3 = 0;			j->pld_slicw.bits.b2en = 0;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_RINGING:			j->pld_slicw.bits.c1 = 1;			j->pld_slicw.bits.c2 = 0;			j->pld_slicw.bits.c3 = 0;			j->pld_slicw.bits.b2en = 1;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_ACTIVE:			j->pld_slicw.bits.c1 = 0;			j->pld_slicw.bits.c2 = 1;			j->pld_slicw.bits.c3 = 0;			j->pld_slicw.bits.b2en = 0;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_OHT:	// On-hook transmit			j->pld_slicw.bits.c1 = 1;			j->pld_slicw.bits.c2 = 1;			j->pld_slicw.bits.c3 = 0;			j->pld_slicw.bits.b2en = 0;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_TIPOPEN:			j->pld_slicw.bits.c1 = 0;			j->pld_slicw.bits.c2 = 0;			j->pld_slicw.bits.c3 = 1;			j->pld_slicw.bits.b2en = 0;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_STANDBY:			j->pld_slicw.bits.c1 = 1;			j->pld_slicw.bits.c2 = 0;			j->pld_slicw.bits.c3 = 1;			j->pld_slicw.bits.b2en = 1;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_APR:	// Active polarity reversal			j->pld_slicw.bits.c1 = 0;			j->pld_slicw.bits.c2 = 1;			j->pld_slicw.bits.c3 = 1;			j->pld_slicw.bits.b2en = 0;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal			j->pld_slicw.bits.c1 = 1;			j->pld_slicw.bits.c2 = 1;			j->pld_slicw.bits.c3 = 1;			j->pld_slicw.bits.b2en = 0;			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);			fRetVal = TRUE;			break;		default:			fRetVal = FALSE;			break;		}	}	return fRetVal;}int ixj_register(int index, IXJ_REGFUNC regfunc){	int cnt;	int retval = 0;	switch (index) {	case G729LOADER:		ixj_DownloadG729 = regfunc;		for (cnt = 0; cnt < IXJMAX; cnt++)			ixj_DownloadG729(&ixj[cnt], 0L);		break;	case TS85LOADER:		ixj_DownloadTS85 = regfunc;		for (cnt = 0; cnt < IXJMAX; cnt++)			ixj_DownloadTS85(&ixj[cnt], 0L);		break;	case PRE_READ:		ixj_PreRead = regfunc;		break;	case POST_READ:		ixj_PostRead = regfunc;		break;	case PRE_WRITE:		ixj_PreWrite = regfunc;		break;	case POST_WRITE:		ixj_PostWrite = regfunc;		break;	case PRE_IOCTL:		ixj_PreIoctl = regfunc;		break;	case POST_IOCTL:		ixj_PostIoctl = regfunc;		break;	default:		retval = 1;	}	return retval;}int ixj_unregister(int index){	int retval = 0;	switch (index) {	case G729LOADER:		ixj_DownloadG729 = &Stub;		break;	case TS85LOADER:		ixj_DownloadTS85 = &Stub;		break;	case PRE_READ:		ixj_PreRead = &Stub;		break;	case POST_READ:		ixj_PostRead = &Stub;		break;	case PRE_WRITE:		ixj_PreWrite = &Stub;		break;	case POST_WRITE:		ixj_PostWrite = &Stub;		break;	case PRE_IOCTL:		ixj_PreIoctl = &Stub;		break;	case POST_IOCTL:		ixj_PostIoctl = &Stub;		break;	default:		retval = 1;	}	return retval;}static void ixj_init_timer(void){	init_timer(&ixj_timer);	ixj_timer.function = ixj_timeout;	ixj_timer.data = (int) NULL;}static void ixj_add_timer(void){	ixj_timer.expires = jiffies + (hertz / samplerate);	add_timer(&ixj_timer);}static void ixj_tone_timeout(int board){	IXJ *j = &ixj[board];	IXJ_TONE ti;	j->tone_state++;	if (j->tone_state == 3) {		j->tone_state = 0;		if (j->cadence_t) {			j->tone_cadence_state++;			if (j->tone_cadence_state >= j->cadence_t->elements_used) {				switch (j->cadence_t->termination) {				case PLAY_ONCE:					ixj_cpt_stop(board);					break;				case REPEAT_LAST_ELEMENT:					j->tone_cadence_state--;					ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);					break;				case REPEAT_ALL:					j->tone_cadence_state = 0;					if (j->cadence_t->ce[j->tone_cadence_state].freq0) {						ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;						ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;						ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;						ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;						ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;						ixj_init_tone(board, &ti);					}					ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -