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

📄 wcfxs.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
📖 第 1 页 / 共 5 页
字号:
	wcfxs_restart_dma(span->pvt);#endif	return 0;}static int wcfxs_close(struct zt_chan *chan){	struct wcfxs *wc = chan->pvt;	wc->usecount--;#ifndef LINUX26	MOD_DEC_USE_COUNT;#else	module_put(THIS_MODULE);#endif	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS)		wc->mod.fxs.idletxhookstate[chan->chanpos - 1] = 1;	/* If we're dead, release us now */	if (!wc->usecount && wc->dead) 		wcfxs_release(wc);	return 0;}static int wcfxs_hooksig(struct zt_chan *chan, zt_txsig_t txsig){	struct wcfxs *wc = chan->pvt;	int reg=0;	if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {		/* XXX Enable hooksig for FXO XXX */		switch(txsig) {		case ZT_TXSIG_START:		case ZT_TXSIG_OFFHOOK:			wc->mod.fxo.offhook[chan->chanpos - 1] = 1;			wcfxs_setreg(wc, chan->chanpos - 1, 5, 0x9);			break;		case ZT_TXSIG_ONHOOK:			wc->mod.fxo.offhook[chan->chanpos - 1] = 0;			wcfxs_setreg(wc, chan->chanpos - 1, 5, 0x8);			break;		default:			printk("wcfxo: Can't set tx state to %d\n", txsig);		}	} else {		switch(txsig) {		case ZT_TXSIG_ONHOOK:			wcfxs_set_led(wc, chan->chanpos, FX_LED_GREEN);			switch(chan->sig) {			case ZT_SIG_EM:			case ZT_SIG_FXOKS:			case ZT_SIG_FXOLS:				wc->mod.fxs.lasttxhook[chan->chanpos-1] = wc->mod.fxs.idletxhookstate[chan->chanpos-1];				break;			case ZT_SIG_FXOGS:				wc->mod.fxs.lasttxhook[chan->chanpos-1] = 3;				break;			}			break;		case ZT_TXSIG_OFFHOOK:			wcfxs_set_led(wc, chan->chanpos, FX_LED_GREEN);			switch(chan->sig) {			case ZT_SIG_EM:				wc->mod.fxs.lasttxhook[chan->chanpos-1] = 5;				break;			default:				wc->mod.fxs.lasttxhook[chan->chanpos-1] = wc->mod.fxs.idletxhookstate[chan->chanpos-1];				break;			}			break;		case ZT_TXSIG_START:			wcfxs_set_led(wc, chan->chanpos, FX_LED_RED);			wc->mod.fxs.lasttxhook[chan->chanpos-1] = 4;			break;		case ZT_TXSIG_KEWL:			wc->mod.fxs.lasttxhook[chan->chanpos-1] = 0;			break;		default:			printk("wcfxs: Can't set tx state to %d\n", txsig);		}		if (debug)			printk("Setting FXS hook state to %d (%02x)\n", txsig, reg);#if 1		wcfxs_setreg(wc, chan->chanpos - 1, 64, wc->mod.fxs.lasttxhook[chan->chanpos-1]);#endif	}	return 0;}static int wcfxs_initialize(struct wcfxs *wc){	int x;	/* Zapata stuff */	sprintf(wc->span.name, "WCTDM/%d", wc->pos);	sprintf(wc->span.desc, "%s Board %d", wc->variety, wc->pos + 1);	wc->span.deflaw = ZT_LAW_MULAW;	for (x=0;x<wc->cards;x++) {		sprintf(wc->chans[x].name, "WCTDM/%d/%d", wc->pos, x);		wc->chans[x].sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_SF | ZT_SIG_EM | ZT_SIG_CLEAR;		wc->chans[x].sigcap |= ZT_SIG_FXSKS | ZT_SIG_FXSLS | ZT_SIG_SF | ZT_SIG_CLEAR;		wc->chans[x].chanpos = x+1;		wc->chans[x].pvt = wc;	}	wc->span.chans = wc->chans;	wc->span.channels = wc->cards;	wc->span.hooksig = wcfxs_hooksig;	wc->span.open = wcfxs_open;	wc->span.close = wcfxs_close;	wc->span.flags = ZT_FLAG_RBS;	wc->span.ioctl = wcfxs_ioctl;	wc->span.watchdog = wcfxs_watchdog;	init_waitqueue_head(&wc->span.maintq);	wc->span.pvt = wc;	if (zt_register(&wc->span, 0)) {		printk("Unable to register span with zaptel\n");		return -1;	}	return 0;}static void wcfxs_post_initialize(struct wcfxs *wc){	int x;	/* Finalize signalling  */	for (x=0;x<wc->cards;x++) {		if (wc->cardflag & (1 << x)) {			if (wc->modtype[x] == MOD_TYPE_FXO)				wc->chans[x].sigcap = ZT_SIG_FXSKS | ZT_SIG_FXSLS | ZT_SIG_SF | ZT_SIG_CLEAR;			else				wc->chans[x].sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_SF | ZT_SIG_EM | ZT_SIG_CLEAR;		}	}}int wcfxs_proc_read(char *buf, char **start, off_t offset, 		    int count, int *eof, void *data){	int len;	len = sprintf(buf, 		      "3050 reg5.....: 0x%x\n"		      "3050 reg12....: 0x%x\n"		      "3050 loop_i...: 0x%x\n"		      "3050 line_v...: 0x%x\n",		      reg5, reg12, loop_i, line_v);	*eof=1;	return len;}static int wcfxs_hardware_init(struct wcfxs *wc){	/* Hardware stuff */	unsigned char x;	char          port_type[FX_MAX_PORTS];        int           i;        #ifdef CONFIG_4FX_SPI_INTERFACE	bfsi_spi_init(SPI_BAUDS, (1<<SPI_NCSA) | (1<<SPI_NCSB));        #else        sport_interface_init ( SPI_BAUDS, (1<<SPI_NCSA) | (1<<SPI_NCSB) );        #endif        	// select port 1 SPI device	//bfsi_spi_write_8_bits(2, 2);        create_proc_read_entry("wcfxs", 0, NULL, wcfxs_proc_read, NULL);	bfsi_sport_init(regular_interrupt_processing, ZT_CHUNKSIZE, debug);	bfsi_reset(RESET_BIT);	#ifdef DAISY	/* put 3210 in daisy chain mode */	__write_8bits(wc, 0x00); /* reg 0 write */	__write_8bits(wc, 0x80); /* value to write (set bit 7) */	#endif	/* auto-detect each port type */	fx_auto_detect(port_type, RESET_BIT);	for(i=0; i<FX_MAX_PORTS; i++) {	  printk("port: %d port_type: %c\n", i+1, port_type[i]);	}	bfsi_reset(RESET_BIT);	//{ u8 reg;        //reg = fx_read_fxs(1);	//printk("reg = 0x%x\n", reg);	//}#define NEW_CODE#ifdef NEW_CODE	/* configure daughter cards */	for (x=0;x<wc->cards;x++) {	  int sane=0,ret=0,readi=0;	  if (port_type[x] == 'O') {	    if (!(ret = wcfxs_init_voicedaa(wc, x, 0, 0, sane))) {	      wc->cardflag |= (1 << x);	      printk("Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);	    } else	      printk("Module %d: Not installed\n", x);	  }	  else {			    sane=0;	    /* Init with Automatic Calibaration */	    if (!(ret = wcfxs_init_proslic(wc, x, 0, 0, sane))) {	      wc->cardflag |= (1 << x);	      if (debug) {		readi = wcfxs_getreg(wc,x,LOOP_I_LIMIT);		printk("Proslic module %d loop current is %dmA\n",x,		       ((readi*3)+20));	      }	      printk("Module %d: Installed -- AUTO FXS\n",x);	    } 	    else 	    {	          if(ret != -2) 		   {			sane=1;			/* Init with Manual Calibration */			if (!wcfxs_init_proslic(wc, x, 0, 1, sane)) 			{				wc->cardflag |= (1 << x);                            if (debug) 				{                                   readi = wcfxs_getreg(wc,x,LOOP_I_LIMIT);                                    printk("Proslic module %d loop current is %dmA\n",x,                                    ((readi*3)+20));                            }				printk("Module %d: Installed -- MANUAL FXS\n",x);			} 			else 			{				printk("Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");			} 		  } 	    } 	  }	}#endif	//#define OLD_CODE#ifdef OLD_CODE	for (x=0;x<wc->cards;x++) {		int sane=0,ret=0,readi=0;		/* Init with Auto Calibration */		if (!(ret=wcfxs_init_proslic(wc, x, 0, 0, sane))) {			wc->cardflag |= (1 << x);                        if (debug) {                                readi = wcfxs_getreg(wc,x,LOOP_I_LIMIT);                                printk("Proslic module %d loop current is %dmA\n",x,                                ((readi*3)+20));                        }			printk("Module %d: Installed -- AUTO FXS/DPO\n",x);		} else {			if(ret!=-2) {				sane=1;				/* Init with Manual Calibration */				if (!wcfxs_init_proslic(wc, x, 0, 1, sane)) {					wc->cardflag |= (1 << x);                                if (debug) {                                        readi = wcfxs_getreg(wc,x,LOOP_I_LIMIT);                                        printk("Proslic module %d loop current is %dmA\n",x,                                        ((readi*3)+20));                                }					printk("Module %d: Installed -- MANUAL FXS\n",x);				} else {					printk("Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");				} 			} else { 				if (!(ret = wcfxs_init_voicedaa(wc, x, 0, 0, sane))) {					wc->cardflag |= (1 << x);					printk("Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);				} else					printk("Module %d: Not installed\n", x);			}		}	}#endif	/* Return error if nothing initialized okay. */	if (!wc->cardflag && !timingonly) {	        printk("couldn't init OK...returning -1\n");		bfsi_sport_close();		return -1;	}	return 0;}static int wcfxs_init_one(struct wcfxs_desc *d){	int res;	struct wcfxs *wc;	int x;	int y;	static int initd_ifaces=0;		wcfxs_init_ok = 0;	if(initd_ifaces){		memset((void *)ifaces,0,(sizeof(struct wcfxs *))*WC_MAX_IFACES);		initd_ifaces=1;	}	for (x=0;x<WC_MAX_IFACES;x++)		if (!ifaces[x]) break;	if (x >= WC_MAX_IFACES) {		printk("Too many interfaces\n");		return -EIO;	}		wc = kmalloc(sizeof(struct wcfxs), GFP_KERNEL);	if (wc) {		ifaces[x] = wc;		memset(wc, 0, sizeof(struct wcfxs));		spin_lock_init(&wc->lock);		wc->curcard = -1;		wc->cards = NUM_CARDS;		wc->pos = x;		wc->variety = d->name;		wc->irq = IRQ_SPORT0_RX;		devs = wc;		for (y=0;y<NUM_CARDS;y++)			wc->flags[y] = d->flags;		if (wcfxs_initialize(wc)) {			printk("wcfxs: Unable to intialize FXS\n");			kfree(wc);			return -EIO;		}		if (wcfxs_hardware_init(wc)) {			zt_unregister(&wc->span);			printk("wcfxs_hardware_init() failed...\n");			kfree(wc);			return -EIO;		} 		wcfxs_init_ok = 1;		wcfxs_post_initialize(wc);					printk("Found: %s (%d modules)\n", wc->variety, wc->cards);		res = 0;	} else		res = -ENOMEM;		return res;}static void wcfxs_release(struct wcfxs *wc){  	printk("wcfxs_init_ok = %d\n", wcfxs_init_ok);	if (wcfxs_init_ok) {	  /* disable serial port, this will stop DMA and interrupts */	  bfsi_sport_close();	  zt_unregister(&wc->span);	  kfree(wc);	}        remove_proc_entry("wcfxs", NULL);	printk("Freed a Wildcard\n");}static int __init wcfxs_init(void){	int x;        printk(KERN_ALERT "Code test: code function addr = 0x%p\n", zt_ec_chunk);	for (x=0;x<(sizeof(fxo_modes) / sizeof(fxo_modes[0])); x++) {		if (!strcmp(fxo_modes[x].name, opermode))			break;	}	if (x < sizeof(fxo_modes) / sizeof(fxo_modes[0])) {		_opermode = x;	} else {		printk("Invalid/unknown operating mode '%s' specified.  Please choose one of:\n", opermode);		for (x=0;x<sizeof(fxo_modes) / sizeof(fxo_modes[0]); x++)			printk("  %s\n", fxo_modes[x].name);		printk("Note this option is CASE SENSITIVE!\n");		return -ENODEV;	}	wcfxs_init_one(&wcfxs_bf);      	wait_just_a_bit(10);        printk("wcfxs_init_ok = %d\n", wcfxs_init_ok);	return 0;}static void __exit wcfxs_cleanup(void){	wcfxs_release(devs);	#ifdef OLD_DR	if (loopback) {		for(r=0; r<ZT_CHUNKSIZE*2; r++) {			printk("[%03d] ", r*8);			for(c=0; c<8; c++) {				printk("0x%02x 0x%02x  ", 				       iTxBuffer1[r*8+c]&0xff, 				       iRxBuffer1[r*8+c]&0xff);			}			printk("\n");		}		//for(r=0; r<10; r++) {		//	printk("[%03d] 0x%04x 0x%04x %d\n", r, logdma1[r], logdma2[r], logdma3[r]);		//}		for(r=0; r<LOG_LEN; r++) {			printk("[%03d] %d\n", r, logdma1[r]);		}		printk("serialnum = %d ilogdma = %d\n",serialnum, ilogdma);	}	#endif}module_param(debug, int, 0600);module_param(loopcurrent, int, 0600);module_param(robust, int, 0600);module_param(_opermode, int, 0600);module_param(opermode, charp, 0600);module_param(timingonly, int, 0600);module_param(lowpower, int, 0600);module_param(boostringer, int, 0600);module_param(fxshonormode, int, 0600);module_param(loopback, int, 0600); /* uCasterisk test mode *///module_param(internalclock, int, 0600); /* uCasterisk test mode */MODULE_DESCRIPTION("Wildcard TDM400P Zaptel Driver");MODULE_AUTHOR("Mark Spencer <markster@digium.com>");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifmodule_init(wcfxs_init);module_exit(wcfxs_cleanup);

⌨️ 快捷键说明

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