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

📄 wcfxs.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
📖 第 1 页 / 共 5 页
字号:
extern int l1_data_A_sram_free(unsigned long addr);#endif#endifstatic int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast , int manual, int sane);static void wait_just_a_bit(int foo);#ifdef AUDIO_RINGCHECKstatic inline void ring_check(struct wcfxs *wc, int card){	int x;	short sample;	if (wc->modtype[card] != MOD_TYPE_FXO)		return;	wc->mod.fxo.pegtimer[card] += ZT_CHUNKSIZE;	for (x=0;x<ZT_CHUNKSIZE;x++) {		/* Look for pegging to indicate ringing */		sample = ZT_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card])));		if ((sample > 10000) && (wc->mod.fxo.peg[card] != 1)) {			if (debug > 1) printk("High peg!\n");			if ((wc->mod.fxo.pegtimer[card] < PEGTIME) && (wc->mod.fxo.pegtimer[card] > MINPEGTIME))				wc->mod.fxo.pegcount[card]++;			wc->mod.fxo.pegtimer[card] = 0;			wc->mod.fxo.peg[card] = 1;		} else if ((sample < -10000) && (wc->mod.fxo.peg[card] != -1)) {			if (debug > 1) printk("Low peg!\n");			if ((wc->mod.fxo.pegtimer[card] < (PEGTIME >> 2)) && (wc->mod.fxo.pegtimer[card] > (MINPEGTIME >> 2)))				wc->mod.fxo.pegcount[card]++;			wc->mod.fxo.pegtimer[card] = 0;			wc->mod.fxo.peg[card] = -1;		}	}	if (wc->mod.fxo.pegtimer[card] > PEGTIME) {		/* Reset pegcount if our timer expires */		wc->mod.fxo.pegcount[card] = 0;	}	/* Decrement debouncer if appropriate */	if (wc->mod.fxo.ringdebounce[card])		wc->mod.fxo.ringdebounce[card]--;	if (!wc->mod.fxo.offhook[card] && !wc->mod.fxo.ringdebounce[card]) {		if (!wc->mod.fxo.ring[card] && (wc->mod.fxo.pegcount[card] > PEGCOUNT)) {			/* It's ringing */			if (debug)				printk("RING on %d/%d!\n", wc->span.spanno, card + 1);			if (!wc->mod.fxo.offhook[card])				zt_hooksig(&wc->chans[card], ZT_RXSIG_RING);			wc->mod.fxo.ring[card] = 1;		}		if (wc->mod.fxo.ring[card] && !wc->mod.fxo.pegcount[card]) {			/* No more ring */			if (debug)				printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);			zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);			wc->mod.fxo.ring[card] = 0;		}	}}#endif//static char digital_milliwatt[] = {0x1e,0x0b,0x0b,0x1e,0x9e,0x8b,0x8b,0x9e};//int swi = 0;//static short sw[] = {2048, 1023, -1024, -2048, -1023, 1024};#define LOG_LEN 64#define LOG_START 0int logdma1[LOG_LEN];int logdma2[20];int logdma3[20];int ilogdma = 0;int serialnum = 0;int notzero=0;static inline void wcfxs_transmitprep(struct wcfxs *wc, u8 *writechunk){	int x;	/* Calculate Transmission */	zt_transmit(&wc->span);	for (x=0;x<ZT_CHUNKSIZE;x++) {		if (wc->cardflag & (1 << 7))			writechunk[8*x+7] = wc->chans[7].writechunk[x];		if (wc->cardflag & (1 << 6))			writechunk[8*x+6] = wc->chans[6].writechunk[x];		if (wc->cardflag & (1 << 5))			writechunk[8*x+5] = wc->chans[5].writechunk[x];		if (wc->cardflag & (1 << 4))			writechunk[8*x+4] = wc->chans[4].writechunk[x];		if (wc->cardflag & (1 << 3))			writechunk[8*x+3] = wc->chans[3].writechunk[x];		if (wc->cardflag & (1 << 2))			writechunk[8*x+2] = wc->chans[2].writechunk[x];		if (wc->cardflag & (1 << 1))			writechunk[8*x+1] = wc->chans[1].writechunk[x];		if (wc->cardflag & (1 << 0)) {			writechunk[8*x+0] = wc->chans[0].writechunk[x];			//writechunk[8*x+0] = ZT_LIN2MU(sw[swi++]);			//if (swi == 6) swi = 0;		}	}}static inline void wcfxs_receiveprep(struct wcfxs *wc, u8 *readchunk){	int x;	//int echo_before;	for (x=0;x<ZT_CHUNKSIZE;x++) {		if (wc->cardflag & (1 << 7))			wc->chans[7].readchunk[x] = readchunk[8*x+7];		if (wc->cardflag & (1 << 6))			wc->chans[6].readchunk[x] = readchunk[8*x+6];		if (wc->cardflag & (1 << 5))			wc->chans[5].readchunk[x] = readchunk[8*x+5];		if (wc->cardflag & (1 << 4))			wc->chans[4].readchunk[x] = readchunk[8*x+4];		if (wc->cardflag & (1 << 3))			wc->chans[3].readchunk[x] = readchunk[8*x+3];		if (wc->cardflag & (1 << 2))			wc->chans[2].readchunk[x] = readchunk[8*x+2];		if (wc->cardflag & (1 << 1))			wc->chans[1].readchunk[x] = readchunk[8*x+1];		if (wc->cardflag & (1 << 0))			wc->chans[0].readchunk[x] = readchunk[8*x+0];	}#ifdef AUDIO_RINGCHECK	for (x=0;x<wc->cards;x++)		ring_check(wc, x);#endif			/* XXX We're wasting 8 taps.  We should get closer :( */	//echo_before = cycles();	for (x=0;x<wc->cards;x++) {		if (wc->cardflag & (1 << x))			zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->chans[x].writechunk);	}	//echo_sams = cycles() - echo_before;	zt_receive(&wc->span);}/* we have only one card at the moment */static inline void __wcfxs_setcard(struct wcfxs *wc, int card){	if (wc->curcard != card) {	  //printk("wc->curcard: %d card: %d\n", wc->curcard, card);           #ifdef NOT_NEEDED	   __wcfxs_setcreg(wc, WC_CS, (1 << card));           #endif	   if (card < 4) {	     #ifdef CONFIG_4FX_SPI_INTERFACE	     bfsi_spi_write_8_bits(SPI_NCSB, card+1);	     #else	     sport_tx_byte(SPI_NCSB, card+1);	     #endif	   }	   else {	     #ifdef CONFIG_4FX_SPI_INTERFACE	     bfsi_spi_write_8_bits(SPI_NCSB, 0x40 + (card-4) + 1);	     #else	     sport_tx_byte(SPI_NCSB, 0x40 + (card-4) + 1);	     #endif	   }	   wc->curcard = card;	}}static void __wcfxs_setreg(struct wcfxs *wc, int card, unsigned char reg, unsigned char value){	__wcfxs_setcard(wc, card);	if (wc->modtype[card] == MOD_TYPE_FXO) {		__write_8bits(wc, 0x20);		__write_8bits(wc, reg & 0x7f);	} else {	  //#define DAISY	        #ifdef DAISY	        __write_8bits(wc, 0x01); // 3210 daisy chain mode		#endif		__write_8bits(wc, reg & 0x7f);	}	__write_8bits(wc, value);}static void wcfxs_setreg(struct wcfxs *wc, int card, unsigned char reg, unsigned char value){	unsigned long flags;	spin_lock_irqsave(&wc->lock, flags);	__wcfxs_setreg(wc, card, reg, value);	spin_unlock_irqrestore(&wc->lock, flags);}static inline void wcfxs_set_led(struct wcfxs *wc, int port, int colour){	unsigned long flags;	spin_lock_irqsave(&wc->lock, flags);	fx_set_led(port, colour);	wc->curcard = -1;                         /* leds mess up current card setting */		spin_unlock_irqrestore(&wc->lock, flags);}static unsigned char __wcfxs_getreg(struct wcfxs *wc, int card, unsigned char reg){	__wcfxs_setcard(wc, card);	if (wc->modtype[card] == MOD_TYPE_FXO) {		__write_8bits(wc, 0x60);		__write_8bits(wc, reg & 0x7f);	} else {	        #ifdef DAISY	        __write_8bits(wc, 0x01); // 3210 daisy chain mode		#endif		__write_8bits(wc, reg | 0x80);	}	return __read_8bits(wc);}static inline void reset_spi(struct wcfxs *wc, int card){	unsigned long flags;	spin_lock_irqsave(&wc->lock, flags);	__wcfxs_setcard(wc, card);	__reset_spi(wc);	__reset_spi(wc);	spin_unlock_irqrestore(&wc->lock, flags);}static unsigned char wcfxs_getreg(struct wcfxs *wc, int card, unsigned char reg){	unsigned long flags;	unsigned char res;	spin_lock_irqsave(&wc->lock, flags);	res = __wcfxs_getreg(wc, card, reg);	spin_unlock_irqrestore(&wc->lock, flags);	return res;}static int __wait_access(struct wcfxs *wc, int card){    unsigned char data;    long origjiffies;    int count = 0;    #define MAX 6000 /* attempts */    origjiffies = jiffies;    /* Wait for indirect access */    while (count++ < MAX)	 {		data = __wcfxs_getreg(wc, card, I_STATUS);		if (!data)			return 0;	 }    if(count > (MAX-1)) printk(" ##### Loop error (%02x) #####\n", data);	return 0;}static unsigned char translate_3215(unsigned char address){	int x;	for (x=0;x<sizeof(indirect_regs)/sizeof(indirect_regs[0]);x++) {		if (indirect_regs[x].address == address) {			address = indirect_regs[x].altaddr;			break;		}	}	return address;}static int wcfxs_proslic_setreg_indirect(struct wcfxs *wc, int card, unsigned char address, unsigned short data){	unsigned long flags;	int res = -1;	/* Translate 3215 addresses */	if (wc->flags[card] & FLAG_3215) {		address = translate_3215(address);		if (address == 255)			return 0;	}	spin_lock_irqsave(&wc->lock, flags);	if(!__wait_access(wc, card)) {		__wcfxs_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF));		__wcfxs_setreg(wc, card, IDA_HI,(unsigned char)((data & 0xFF00)>>8));		__wcfxs_setreg(wc, card, IAA,address);		res = 0;	};	spin_unlock_irqrestore(&wc->lock, flags);	return res;}static int wcfxs_proslic_getreg_indirect(struct wcfxs *wc, int card, unsigned char address){ 	unsigned long flags;	int res = -1;	char *p=NULL;	/* Translate 3215 addresses */	if (wc->flags[card] & FLAG_3215) {		address = translate_3215(address);		if (address == 255)			return 0;	}	spin_lock_irqsave(&wc->lock, flags);	if (!__wait_access(wc, card)) {		__wcfxs_setreg(wc, card, IAA, address);		if (!__wait_access(wc, card)) {			unsigned char data1, data2;			data1 = __wcfxs_getreg(wc, card, IDA_LO);			data2 = __wcfxs_getreg(wc, card, IDA_HI);			res = data1 | (data2 << 8);		} else			p = "Failed to wait inside\n";	} else		p = "failed to wait\n";	spin_unlock_irqrestore(&wc->lock, flags);	if (p)		printk(p);	return res;}static int wcfxs_proslic_init_indirect_regs(struct wcfxs *wc, int card){	unsigned char i;	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)	{		if(wcfxs_proslic_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))			return -1;	}	return 0;}static int wcfxs_proslic_verify_indirect_regs(struct wcfxs *wc, int card){ 	int passed = 1;	unsigned short i, initial;	int j;	for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++) 	{		if((j = wcfxs_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {			printk("Failed to read indirect register %d\n", i);			return -1;		}		initial= indirect_regs[i].initial;		if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255)))		{			 printk("!!!!!!! %s  iREG %X = %X  should be %X\n",				indirect_regs[i].name,indirect_regs[i].address,j,initial );			 passed = 0;		}		}    if (passed) {		if (debug)			printk("Init Indirect Registers completed successfully.\n");    } else {		printk(" !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");		return -1;    }    return 0;}static inline void wcfxs_voicedaa_check_hook(struct wcfxs *wc, int card){#ifndef AUDIO_RINGCHECK	unsigned char res;#endif		signed char b;	int poopy = 0;	/* Try to track issues that plague slot one FXO's */	b = wcfxs_getreg(wc, card, 5);	if ((b & 0x2) || !(b & 0x8)) {		/* Not good -- don't look at anything else */		if (debug)			printk("Poopy (%02x) on card %d!\n", b, card + 1); 		poopy++;	}	b &= 0x9b;	reg5 = b;	reg12 = wcfxs_getreg(wc, card, 12);	loop_i = wcfxs_getreg(wc, card, 28);	line_v = wcfxs_getreg(wc, card, 29);	if (wc->mod.fxo.offhook[card]) {		if (b != 0x9)			wcfxs_setreg(wc, card, 5, 0x9);	} else {		if (b != 0x8)			wcfxs_setreg(wc, card, 5, 0x8);	}	if (poopy)		return;#ifndef AUDIO_RINGCHECK	if (!wc->mod.fxo.offhook[card]) {		res = wcfxs_getreg(wc, card, 5);		if ((res & 0x60) && wc->mod.fxo.battery[card]) {			wc->mod.fxo.ringdebounce[card] += (ZT_CHUNKSIZE * NUM_CARDS);			if (wc->mod.fxo.ringdebounce[card] >= ZT_CHUNKSIZE * 64) {				if (!wc->mod.fxo.wasringing[card]) {					wc->mod.fxo.wasringing[card] = 1;					zt_hooksig(&wc->chans[card], ZT_RXSIG_RING);					wcfxs_set_led(wc, card+1, FX_LED_GREEN);					if (debug)						printk("RING on %d/%d!\n", wc->span.spanno, card + 1);				}				wc->mod.fxo.ringdebounce[card] = ZT_CHUNKSIZE * 64;			}		} else {			wc->mod.fxo.ringdebounce[card] -= ZT_CHUNKSIZE;			if (wc->mod.fxo.ringdebounce[card] <= 0) {				if (wc->mod.fxo.wasringing[card]) {					wc->mod.fxo.wasringing[card] =0;					zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);					wcfxs_set_led(wc, card+1, FX_LED_RED);					/* leds mess up current card setting */					wc->curcard = -1;					if (debug)						printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1);				}				wc->mod.fxo.ringdebounce[card] = 0;			}						}	}#endif	b = wcfxs_getreg(wc, card, 29);#if 0 	{		static int count = 0;		if (!(count++ % 100)) {			printk("Card %d: Voltage: %d  Debounce %d\n", card + 1, 			       b, wc->mod.fxo.battdebounce[card]);		}	}#endif	

⌨️ 快捷键说明

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