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

📄 wcfxs.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (abs(b) < BATT_THRESH) {		wc->mod.fxo.nobatttimer[card]++;#if 0		if (wc->mod.fxo.battery[card])			printk("Battery loss: %d (%d debounce)\n", b, wc->mod.fxo.battdebounce[card]);#endif		if (wc->mod.fxo.battery[card] && !wc->mod.fxo.battdebounce[card]) {			if (debug)				printk("NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);			wc->mod.fxo.battery[card] =  0;#ifdef	JAPAN			if ((!wc->ohdebounce) && wc->offhook) {				zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);				if (debug)					printk("Signalled On Hook\n");#ifdef	ZERO_BATT_RING				wc->onhook++;#endif			}#else			zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);#endif			wc->mod.fxo.battdebounce[card] = BATT_DEBOUNCE;		} else if (!wc->mod.fxo.battery[card])			wc->mod.fxo.battdebounce[card] = BATT_DEBOUNCE;	} else if (abs(b) > BATT_THRESH) {		if (!wc->mod.fxo.battery[card] && !wc->mod.fxo.battdebounce[card]) {			if (debug)				printk("BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1, 					(b < 0) ? "-" : "+");			    #ifdef	ZERO_BATT_RING			if (wc->onhook) {				wc->onhook = 0;				zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);				if (debug)					printk("Signalled Off Hook\n");			}#else			zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);#endif			wc->mod.fxo.battery[card] = 1;			wc->mod.fxo.nobatttimer[card] = 0;			wc->mod.fxo.battdebounce[card] = BATT_DEBOUNCE;		} else if (wc->mod.fxo.battery[card])			wc->mod.fxo.battdebounce[card] = BATT_DEBOUNCE;		if (wc->mod.fxo.lastpol[card] >= 0) {		    if (b < 0) {			wc->mod.fxo.lastpol[card] = -1;			wc->mod.fxo.polaritydebounce[card] = POLARITY_DEBOUNCE;		    }		} 		if (wc->mod.fxo.lastpol[card] <= 0) {		    if (b > 0) {			wc->mod.fxo.lastpol[card] = 1;			wc->mod.fxo.polaritydebounce[card] = POLARITY_DEBOUNCE;		    }		}	} else {		/* It's something else... */		wc->mod.fxo.battdebounce[card] = BATT_DEBOUNCE;	}	if (wc->mod.fxo.battdebounce[card])		wc->mod.fxo.battdebounce[card] -= (NUM_CARDS/4);	if (wc->mod.fxo.polaritydebounce[card]) {	        wc->mod.fxo.polaritydebounce[card]--;		if (wc->mod.fxo.polaritydebounce[card] < 1) {		    if (wc->mod.fxo.lastpol[card] != wc->mod.fxo.polarity[card]) {			if (debug)				printk("%lu Polarity reversed (%d -> %d)\n", jiffies, 			       wc->mod.fxo.polarity[card], 			       wc->mod.fxo.lastpol[card]);			if (wc->mod.fxo.polarity[card])			    zt_qevent_lock(&wc->chans[card], ZT_EVENT_POLARITY);			wc->mod.fxo.polarity[card] = wc->mod.fxo.lastpol[card];		    }		}	}}static inline void wcfxs_proslic_check_hook(struct wcfxs *wc, int card){	char res;	int hook;	/* For some reason we have to debounce the	   hook detector.  */	res = wcfxs_getreg(wc, card, 68);	hook = (res & 1);	if (hook != wc->mod.fxs.lastrxhook[card]) {		/* Reset the debounce (must be multiple of 4ms) */		wc->mod.fxs.debounce[card] = 8 * (4 * 8);#if 0		printk("Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod.fxs.debounce[card]);#endif	} else {		if (wc->mod.fxs.debounce[card] > 0) {			wc->mod.fxs.debounce[card]-= 4 * ZT_CHUNKSIZE;#if 0			printk("Sustaining hook %d, %d\n", hook, wc->mod.fxs.debounce[card]);#endif			if (!wc->mod.fxs.debounce[card]) {#if 0				printk("Counted down debounce, newhook: %d...\n", hook);#endif				wc->mod.fxs.debouncehook[card] = hook;			}			if (!wc->mod.fxs.oldrxhook[card] && wc->mod.fxs.debouncehook[card]) {				/* Off hook */#if 1				if (debug)#endif									printk("wcfxs: Card %d Going off hook\n", card);				zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);				if (robust)					wcfxs_init_proslic(wc, card, 1, 0, 1);				wc->mod.fxs.oldrxhook[card] = 1;						} else if (wc->mod.fxs.oldrxhook[card] && !wc->mod.fxs.debouncehook[card]) {				/* On hook */#if 1				if (debug)#endif									printk("wcfxs: Card %d Going on hook\n", card);				zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);				wc->mod.fxs.oldrxhook[card] = 0;			}		}	}	wc->mod.fxs.lastrxhook[card] = hook;	}static inline void wcfxs_proslic_recheck_sanity(struct wcfxs *wc, int card){	int res;	/* Check loopback */	res = wcfxs_getreg(wc, card, 8);	if (res) {		printk("Ouch, part reset, quickly restoring reality (%d)\n", card);		wcfxs_init_proslic(wc, card, 1, 0, 1);	} else {		res = wcfxs_getreg(wc, card, 64);		if (!res && (res != wc->mod.fxs.lasttxhook[card])) {			if (wc->mod.fxs.palarms[card]++ < MAX_ALARMS) {				printk("Power alarm on module %d, resetting!\n", card + 1);				if (wc->mod.fxs.lasttxhook[card] == 4)					wc->mod.fxs.lasttxhook[card] = 1;				wcfxs_setreg(wc, card, 64, wc->mod.fxs.lasttxhook[card]);			} else {				if (wc->mod.fxs.palarms[card] == MAX_ALARMS)					printk("Too many power alarms on card %d, NOT resetting!\n", card + 1);			}		}	}}/* handles regular interrupt processing, called every time we get a DMA   interrupt which is every 1ms with ZT_CHUNKSIZE == 8 */void regular_interrupt_processing(u8 *read_samples, u8 *write_samples) {  struct wcfxs *wc = devs;	int x;	wc->intcount++;	x = wc->intcount % NUM_CARDS;	/* as ISR is started before chips initialised we nee this test           to ensure we don't test the hook switch and ring detect           before chips initialised */	if (wcfxs_init_ok) {	  /* check hook switch (FXS) and ringing (FXO) */	  if ((x < wc->cards) && (wc->cardflag & (1 << x))) {	    if (wc->modtype[x] == MOD_TYPE_FXS) {	      wcfxs_proslic_check_hook(wc, x);	      if (!(wc->intcount & 0xfc))		wcfxs_proslic_recheck_sanity(wc, x);	    } else if (wc->modtype[x] == MOD_TYPE_FXO) {	      /* ring detection, despite name */	      wcfxs_voicedaa_check_hook(wc, x); 	    }	  }	  if (!(wc->intcount % 10000)) {	    /* Accept an alarm once per 10 seconds */	    for (x=0;x<4;x++) 	      if (wc->modtype[x] == MOD_TYPE_FXS) {		if (wc->mod.fxs.palarms[x])		  wc->mod.fxs.palarms[x]--;	      }	  }	}	/* handle speech samples */	wcfxs_transmitprep(wc, write_samples);	wcfxs_receiveprep(wc, read_samples);}static int wcfxs_voicedaa_insane(struct wcfxs *wc, int card){	int blah;	blah = wcfxs_getreg(wc, card, 2);		if (debug) {		printk("Testing for DAA...\n");	}	if (blah != 0x3) {		printk("  DAA not found! (blah = 0x%x)\n", blah);		return -2;	}	blah = wcfxs_getreg(wc, card, 11);	if (debug)		printk("  VoiceDAA System: %02x\n", blah & 0xf);	return 0;}static int wcfxs_proslic_insane(struct wcfxs *wc, int card){	int blah,insane_report,blah1;	insane_report=0;	blah = wcfxs_getreg(wc, card, 0);	if (debug) {		printk("Testing for ProSLIC card = %d blah = 0x%x blah1 = 0x%x\n", card, blah, blah1);	}#if 0	if ((blah & 0x30) >> 4) {		printk("ProSLIC on module %d is not a 3210.\n", card);		return -1;	}#endif	if (((blah & 0xf) == 0) || ((blah & 0xf) == 0xf)) {		if (debug) {			    printk("  ProSLIC not loaded...\n");		}		return -1;	}	if (debug) {		printk("ProSLIC module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));	}	if ((blah & 0xf) < 2) {		printk("ProSLIC 3210 version %d is too old\n", blah & 0xf);		return -1;	}	if (wcfxs_getreg(wc, card, 1) & 0x80){		/* ProSLIC 3215, not a 3210 */		wc->flags[card] |= FLAG_3215;              printk("ProSLIC module is Si3215\n");	}	blah = wcfxs_getreg(wc, card, 8);	if (blah != 0x2) {		printk("ProSLIC on module %d insane (1) %d should be 2\n", card, blah);		return -1;	} else if ( insane_report)		printk("ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);	blah = wcfxs_getreg(wc, card, 64);	if (blah != 0x0) {		printk("ProSLIC on module %d insane (2)\n", card);		return -1;	} else if ( insane_report)		printk("ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);	blah = wcfxs_getreg(wc, card, 11);	if (blah != 0x33) {		printk("ProSLIC on module %d insane (3)\n", card);		return -1;	} else if ( insane_report)		printk("ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);	/* Just be sure it's setup right. */	wcfxs_setreg(wc, card, 30, 0);	if (debug) 		printk("ProSLIC on module %d seems sane.\n", card);	return 0;}static int wcfxs_proslic_powerleak_test(struct wcfxs *wc, int card){	unsigned long origjiffies;	unsigned char vbat;	/* Turn off linefeed */	wcfxs_setreg(wc, card, 64, 0);	/* Power down */	wcfxs_setreg(wc, card, 14, 0x10);	/* Wait for one second */	origjiffies = jiffies;	while((vbat = wcfxs_getreg(wc, card, 82)) > 0x6) {		if ((jiffies - origjiffies) >= (HZ/2))			break;;	}	if (vbat < 0x06) {		printk("Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,		       376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ));		return -1;	} else if (debug) {		printk("Post-leakage voltage: %d volts\n", 376 * vbat / 1000);	}	return 0;}static int wcfxs_powerup_proslic(struct wcfxs *wc, int card, int fast){	unsigned char vbat;	unsigned long origjiffies;	int lim;	/* Set period of DC-DC converter to 1/64 khz */	wcfxs_setreg(wc, card, 92, 0xff /* was 0xff */);	/* Wait for VBat to powerup */	origjiffies = jiffies;	/* Disable powerdown */	wcfxs_setreg(wc, card, 14, 0);	/* If fast, don't bother checking anymore */	if (fast)		return 0;	while((vbat = wcfxs_getreg(wc, card, 82)) < 0xc0) {		/* Wait no more than 500ms */		if ((jiffies - origjiffies) > HZ/2) {			break;		}	}	printk("reg 0: 0x%x \n", wcfxs_getreg(wc, card, 0));	printk("reg 14: 0x%x \n", wcfxs_getreg(wc, card, 14));	printk("reg 74: 0x%x \n", wcfxs_getreg(wc, card, 74));	printk("reg 80: 0x%x \n", wcfxs_getreg(wc, card, 80));	printk("reg 81: 0x%x \n", wcfxs_getreg(wc, card, 81));	printk("reg 92: 0x%x \n", wcfxs_getreg(wc, card, 92));	printk("reg 82: 0x%x \n", wcfxs_getreg(wc, card, 82));	printk("reg 83: 0x%x \n", wcfxs_getreg(wc, card, 83));        //return -1;	if (vbat < 0xc0) {		printk("ProSLIC on module %d failed to powerup within %d ms (%d mV only)\n\n -- DID YOU REMEMBER TO PLUG IN THE HD POWER CABLE TO THE TDM400P??\n",		       card, (int)(((jiffies - origjiffies) * 1000 / HZ)),			vbat * 375);		return -1;	} else if (debug) {		printk("ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));	}        /* Proslic max allowed loop current, reg 71 LOOP_I_LIMIT */        /* If out of range, just set it to the default value     */        lim = (loopcurrent - 20) / 3;        if ( loopcurrent > 41 ) {                lim = 0;                if (debug)                        printk("Loop current out of range! Setting to default 20mA!\n");        }        else if (debug)                        printk("Loop current set to %dmA!\n",(lim*3)+20);        wcfxs_setreg(wc,card,LOOP_I_LIMIT,lim);	/* Engage DC-DC converter */	wcfxs_setreg(wc, card, 93, 0x19 /* was 0x19 */);#if 0	origjiffies = jiffies;	while(0x80 & wcfxs_getreg(wc, card, 93)) {		if ((jiffies - origjiffies) > 2 * HZ) {			printk("Timeout waiting for DC-DC calibration on module %d\n", card);			return -1;		}	}#if 0	/* Wait a full two seconds */	while((jiffies - origjiffies) < 2 * HZ);	/* Just check to be sure */	vbat = wcfxs_getreg(wc, card, 82);	printk("ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",		       card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));#endif#endif	return 0;}static int wcfxs_proslic_manual_calibrate(struct wcfxs *wc, int card){	unsigned long origjiffies;	unsigned char i;	printk("Start manual calibration\n");	wcfxs_setreg(wc, card, 21, 0);//(0)  Disable all interupts in DR21	wcfxs_setreg(wc, card, 22, 0);//(0)Disable all interupts in DR21	wcfxs_setreg(wc, card, 23, 0);//(0)Disable all interupts in DR21	wcfxs_setreg(wc, card, 64, 0);//(0)	wcfxs_setreg(wc, card, 97, 0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration.	wcfxs_setreg(wc, card, 96, 0x47); //(0x47)	Calibrate common mode and differential DAC mode DAC + ILIM	origjiffies=jiffies;	while( wcfxs_getreg(wc,card,96)!=0 ){		if((jiffies-origjiffies)>80)			return -1;	}//Initialized DR 98 and 99 to get consistant results.// 98 and 99 are the results registers and the search should have same intial conditions./*******************************The following is the manual gain mismatch calibration****************************//*******************************This is also available as a function *******************************************/	// Delay 10ms	origjiffies=jiffies; 	while((jiffies-origjiffies)<1);	wcfxs_proslic_setreg_indirect(wc, card, 88,0);	wcfxs_proslic_setreg_indirect(wc,card,89,0);	wcfxs_proslic_setreg_indirect(wc,card,90,0);	wcfxs_proslic_setreg_indirect(wc,card,91,0);	wcfxs_proslic_setreg_indirect(wc,card,92,0);	wcfxs_proslic_setreg_indirect(wc,card,93,0);	wcfxs_setreg(wc, card, 98,0x10); // This is necessary if the calibration occurs other than at reset time	wcfxs_setreg(wc, card, 99,0x10);	for ( i=0x1f; i>0; i--)	{		wcfxs_setreg(wc, card, 98,i);		origjiffies=jiffies; 		while((jiffies-origjiffies)<4);		if((wcfxs_getreg(wc,card,88)) == 0)			break;	} // for

⌨️ 快捷键说明

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