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

📄 wcusb.c

📁 This a SOFTWARE pbx DRIVER
💻 C
📖 第 1 页 / 共 3 页
字号:
	p->dr.wLength = cpu_to_le16(size);#else	urb_t *urb = &p->control;	memset(urb, 0, sizeof(urb_t));		p->dr.requesttype = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;	p->dr.request = REQUEST_NORMAL;	p->dr.value = 0;	p->dr.index = cpu_to_le16(ind);	p->dr.length = cpu_to_le16(size);#endif	FILL_CONTROL_URB(urb, p->dev, usb_sndctrlpipe(p->dev, 0), (unsigned char *)&p->dr, data, len, complete, p);#ifdef LINUX26	if (usb_submit_urb(urb, GFP_KERNEL)) #else		if (usb_submit_urb(urb)) #endif		{		printk("wcusb_async_write: control URB died\n");		return -1;	}	p->controlstate = state;	p->urbcount++;	return 0;}/***	Write register to Wc560*/static int wcoutp(struct usb_device *dev, unsigned char address, unsigned char data){	if (!Wcusb_WriteWcRegs(dev, address, &data, 1))		return 0;	return -1;}/***	read register from Wc560*/static int wcinp(struct usb_device *dev, unsigned char address, unsigned char* data ){	if (!Wcusb_ReadWcRegs(dev, address, data, 1))		return 0;	return -1;}static int waitForProSlicIndirectRegAccess(struct usb_device *dev){    unsigned char count, data;    count = 0;    while (count++ < 3)	 {		data = 0;		readProSlicDirectReg(dev, I_STATUS, &data);		if (!data)			return 0;	 }    if(count > 2) printk(" ##### Loop error #####\n");	return -1;}static int writeProSlicInDirectReg(struct usb_device *dev, unsigned char address, unsigned short data){	   if(!waitForProSlicIndirectRegAccess(dev))	{		if (!writeProSlicDirectReg(dev, IDA_LO,(unsigned char)(data & 0xFF)))		{			if(!writeProSlicDirectReg(dev, IDA_HI,(unsigned char)((data & 0xFF00)>>8)))			{				if(!writeProSlicDirectReg(dev, IAA,address))					return 0;			}		}	}	return -1;}/***	Read register from ProSlic*/int readProSlicDirectReg(struct usb_device *dev, unsigned char address, unsigned char* dataRead){	unsigned char data[4];	data[0] = address | 0x80;	data[1] = 0;	data[2] = 0;	data[3] = 0x67;	// write to WC register 0x26	Wcusb_WriteWcRegs(dev, WCUSB_SPORT0, data, 4);	Wcusb_ReadWcRegs(dev, WCUSB_SPORT1, data, 1);	*dataRead = data[0];	return 0;}/***	Write register to ProSlic*/int writeProSlicDirectReg(struct usb_device *dev, unsigned char address, unsigned char RegValue){	unsigned char data[4];	data[0] = address & 0x7f;	data[1] = RegValue;	data[2] = 0;	data[3] = 0x27;	// write to WC register 0x26	return Wcusb_WriteWcRegs(dev, WCUSB_SPORT0, data, 4);}static int readProSlicInDirectReg(struct usb_device *dev, unsigned char address, unsigned short *data){     if (!waitForProSlicIndirectRegAccess(dev))	 {		if (!writeProSlicDirectReg(dev,IAA,address))		{			if(!waitForProSlicIndirectRegAccess(dev))			{				unsigned char data1, data2;				if (!readProSlicDirectReg(dev,IDA_LO, &data1) && !readProSlicDirectReg (dev, IDA_HI, &data2))				{					*data = data1 | (data2 << 8);					return 0;				} else 					printk("Failed to read direct reg\n");			} else				printk("Failed to wait inside\n");		} else			printk("failed write direct IAA\n");	 } else	 	printk("failed to wait\n");    return -1;}static int initializeIndirectRegisters(struct usb_device *dev){	unsigned char i;	for (i=0; i<43; i++)	{		if(writeProSlicInDirectReg(dev, i,indirect_regs[i].initial))			return -1;	}	return 0;}static int verifyIndirectRegisters(struct usb_device *dev){ 	int passed = 1;	unsigned short i,j, initial;	for (i=0; i<43; i++) 	{		if(readProSlicInDirectReg(dev, (unsigned char) i, &j)) {			printk("Failed to read indirect register %d\n", i);			return -1;		}		initial= indirect_regs[i].initial;		if ( j != initial )		{			 printk("!!!!!!! %s  iREG %X = %X  should be %X\n",				indirect_regs[i].name,i,j,initial );			 passed = 0;		}		}    if (passed) {		if (debug)			printk("Init Indirect Registers completed successfully.\n");    } else {		printk(" !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");    }	return 0;}static int calibrateAndActivateProSlic(struct usb_device *dev){ 	unsigned char x;	if(writeProSlicDirectReg(dev, 92, 0xc8))		 return -1;	if(writeProSlicDirectReg(dev, 97, 0))		 return -1;	if(writeProSlicDirectReg(dev, 93, 0x19))		 return -1;	if(writeProSlicDirectReg(dev, 14, 0))		 return -1;	if(writeProSlicDirectReg(dev, 93, 0x99))		 return -1;	if(!readProSlicDirectReg (dev, 93, &x))	{		if (debug)			printk("DC Cal x=%x\n",x);		if (!writeProSlicDirectReg(dev, 97, 0))		{		   if(!writeProSlicDirectReg(dev, CALIBR1, CALIBRATE_LINE))			{				unsigned char data;				 if(!readProSlicDirectReg(dev, CALIBR1, &data))						 return writeProSlicDirectReg(dev, LINE_STATE,ACTIVATE_LINE);			}		}	}	return -1;}static int InitProSlic(struct usb_device *dev){    if (writeProSlicDirectReg(dev, 67, 0x0e)) 		/* Disable Auto Power Alarm Detect and other "features" */		 return -1;    if (initializeIndirectRegisters(dev)) {		printk(KERN_INFO "Indirect Registers failed to initialize.\n");		 return -1;	}    if (verifyIndirectRegisters(dev)) {		printk(KERN_INFO "Indirect Registers failed verification.\n");		 return -1;	}    if (calibrateAndActivateProSlic(dev)) {		printk(KERN_INFO "ProSlic Died on Activation.\n");		 return -1;	}    if (writeProSlicInDirectReg(dev, 97, 0x0)) { // Stanley: for the bad recording fix		 printk(KERN_INFO "ProSlic IndirectReg Died.\n");		 return -1;	}    if (writeProSlicDirectReg(dev, 1, 0x2a)) { // U-Law GCI 8-bit interface		 printk(KERN_INFO "ProSlic DirectReg Died.\n");		 return -1;	}    if (writeProSlicDirectReg(dev, 2, 0))    // Tx Start count low byte  0		 return -1;    if (writeProSlicDirectReg(dev, 3, 0))    // Tx Start count high byte 0		 return -1;    if (writeProSlicDirectReg(dev, 4, 0))    // Rx Start count low byte  0		 return -1;    if (writeProSlicDirectReg(dev, 5, 0))    // Rx Start count high byte 0		 return -1;    if (writeProSlicDirectReg(dev, 8, 0x0))    // disable loopback		 return -1;    if (writeProSlicDirectReg(dev, 18, 0xff))     // clear all interrupt		 return -1;    if (writeProSlicDirectReg(dev, 19, 0xff)) 		 return -1;    if (writeProSlicDirectReg(dev, 20, 0xff)) 		 return -1;    if (writeProSlicDirectReg(dev, 21, 0x00)) 	// enable interrupt		 return -1;    if (writeProSlicDirectReg(dev, 22, 0x02)) 	// Loop detection interrupt		 return -1;    if (writeProSlicDirectReg(dev, 23, 0x01)) 	// DTMF detection interrupt		 return -1;    if (writeProSlicDirectReg(dev, 72, 0x20))	    	return -1;#ifdef BOOST_RINGER	/* Beef up Ringing voltage to 89V */	if (writeProSlicInDirectReg(dev, 23, 0x1d1))			return -1;#endif	return 0;}static int init_hardware(struct wc_usb_pvt *p){	struct usb_device *dev = p->dev;	switch (p->devclass) {	case WC_PROSLIC:		if (wcoutp(dev, 0x12, 0x00))	/* AUX6 as output, set to low */			return -1;    		if (wcoutp(dev, 0x13, 0x40))	/* AUX6 is output */      			return -1;    		if (wcoutp(dev, 0, 0x50))	/* extrst, AUX2 is suspend */      			return -1;    		if (wcoutp(dev, 0x29, 0x20))	/* enable SerialUP AUX pin definition */      			return -1;    		if (wcoutp(dev, 0, 0x51))	/* no extrst, AUX2 is suspend */      			return -1;		/* Make sure there is no gain */    		if (wcoutp(dev, 0x22, 0x00))			return -1;    		if (wcoutp(dev, 0x23, 0xf2))        		return -1;    		if (wcoutp(dev, 0x24, 0x00))			return -1;    		if (wcoutp(dev, 0x25, 0xc9))			return -1;		if (InitProSlic(dev)) {			printk("wcusb: Failed to initialize proslic\n");			return -1;		}	case WC_KEYPAD:		set_aux_ctrl(p, WC_AUX0, 1);		set_aux_ctrl(p, WC_AUX1, 1);		set_aux_ctrl(p, WC_AUX2, 1);		set_aux_ctrl(p, WC_AUX3, 1);	}	if (debug) printk("wcusb: Setting correct interfaces.\n");	/* Setup correct settings (8000 Hz, signed linear) */	if (usb_set_interface(dev, 2, 1)) {		printk("wcusb: Unable to setup USB interface 2 to altsetting 1\n");		return -1;	}	if (usb_set_interface(dev, 3, 1)) {		printk("wcusb: Unable to setup USB interface 3 to altsetting 1\n");		return -1;	}	return 0; }/* Don't call from an interrupt context */static int set_aux_ctrl(struct wc_usb_pvt *p, char uauxpins, int on){	char udata12 = 0;	char udata13 = 0;	wcinp(p->dev, 0x12, &udata12);	wcinp(p->dev, 0x13, &udata13);	wcoutp(p->dev, 0x12, on ? (uauxpins | udata12) : (~uauxpins & udata12));	wcoutp(p->dev, 0x13, uauxpins | udata13);	return 0;}	static void wcusb_check_keypad(struct wc_usb_pvt *p){	struct wc_keypad_data *d = p->pvt_data;	if (!d->running) {		printk("Stopping keypad stream\n");		return;	}	if (debug) printk("Launched a packet\n");	d->state = STATE_FOR_LOOP_1_OUT;	d->data = -1;	d->data12 = -1;	d->scanned_event = -1;	d->i = 0;	wcusb_async_read(p, 0x12, &d->data12, 1, 0, keypad_check_done);	return;}static char wc_dtmf(struct wc_usb_pvt *p){	struct wc_keypad_data *d = p->pvt_data;	short linsample = 0;	if (!d) {		printk("NULL pointer, go away\n");		return 0;	}	linsample = zt_tone_nextsample(&d->ts, d->tone);	return ZT_LIN2MU(linsample);}#ifdef LINUX26static void wcusb_read_complete(struct urb *q, struct pt_regs *regs)#elsestatic void wcusb_read_complete(struct urb *q)#endif{	struct wc_usb_pvt *p = q->context;	short *chunk = q->transfer_buffer;	int x;	if (!p->flags & FLAG_RUNNING) {		/* Stop sending URBs since we're not running anymore */		p->urbcount--;		return;	}	switch (p->sample) {		case STREAM_NORMAL:			for (x = 0; x < ZT_CHUNKSIZE; x++) {				p->chan.readchunk[x] = ZT_LIN2MU(le16_to_cpu(chunk[x]));			}			break;		case STREAM_DTMF:			for (x = 0; x < ZT_CHUNKSIZE; x++) {				p->chan.readchunk[x] = wc_dtmf(p);			}			break;	}	/* XXX We could probably optimize some here XXX */	zt_ec_chunk(&p->chan, p->chan.readchunk, p->chan.writechunk);	zt_receive(&p->span);	q->dev = p->dev;	#ifdef LINUX26	if (usb_submit_urb(q, GFP_KERNEL)) #else		if (usb_submit_urb(q)) #endif		{		printk("wcusb: Read cycle failed\n");	}	if (p->timer && !--p->timer) {		if (p->devclass == WC_KEYPAD) {			if(debug) printk("Checking keypad\n");			wcusb_check_keypad(p);		} else {			wcusb_check_interrupt(p);		}	}#ifdef PROSLIC_POWERSAVE	if (p->devclass != WC_KEYPAD) {		if (p->lowpowertimer && !--p->lowpowertimer) {			/* Switch back into low power mode */			p->idletxhookstate = 1;			if (p->txhook == 2)				p->newtxhook = p->idletxhookstate;		}	}#endif		return;}#ifdef LINUX26static void wcusb_write_complete(struct urb *q, struct pt_regs *regs)#elsestatic void wcusb_write_complete(struct urb *q)#endif{	struct wc_usb_pvt *p = q->context;	short *chunk = q->transfer_buffer;	int x;	if (!p->flags & FLAG_RUNNING) {		/* Stop sending URBs since we're not running anymore */		p->urbcount--;		return;	}	zt_transmit(&p->span);	for (x = 0; x < ZT_CHUNKSIZE; x++) {		chunk[x] = cpu_to_le16(ZT_MULAW(p->chan.writechunk[x]));	}	q->dev = p->dev;	#ifdef LINUX26	if (usb_submit_urb(q, GFP_KERNEL)) #else		if (usb_submit_urb(q)) #endif		{		printk("wcusb: Write cycle failed\n");	}	return;}static int StopTransmit(struct wc_usb_pvt *p){	p->flags &= ~FLAG_RUNNING;	if (p->devclass == WC_KEYPAD) {		struct wc_keypad_data *d = p->pvt_data;		d->running = 0;	}	while(p->urbcount) {

⌨️ 快捷键说明

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