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

📄 via-ircc.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	case 0x01:		/* Differential serial interface */		break;	case 0x02:		/* same as */	case 0x03:		/* Reserved */		break;	case 0x04:		/* Sharp RY5HD01 */		break;	case 0x05:		/* Reserved, but this is what the Thinkpad reports */		break;	case 0x06:		/* Single-ended serial interface */		break;	case 0x07:		/* Consumer-IR only */		break;	case 0x08:		/* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */		UseOneRX(iobase, ON);	// use one RX pin   RX1,RX2		InvertTX(iobase, OFF);		InvertRX(iobase, OFF);		EnRX2(iobase, ON);	//sir to rx2		EnGPIOtoRX2(iobase, OFF);		if (IsSIROn(iobase)) {	//sir			// Mode select Off			SlowIRRXLowActive(iobase, ON);			udelay(1000);			SlowIRRXLowActive(iobase, OFF);		} else {			if (IsMIROn(iobase)) {	//mir				// Mode select On				SlowIRRXLowActive(iobase, OFF);				udelay(20);			} else {	// fir				if (IsFIROn(iobase)) {	//fir					// Mode select On					SlowIRRXLowActive(iobase, OFF);					udelay(20);				}			}		}		break;	case 0x09:		/* IBM31T1100 or Temic TFDS6000/TFDS6500 */		UseOneRX(iobase, ON);	//use ONE RX....RX1		InvertTX(iobase, OFF);		InvertRX(iobase, OFF);	// invert RX pin		EnRX2(iobase, ON);		EnGPIOtoRX2(iobase, OFF);		if (IsSIROn(iobase)) {	//sir			// Mode select On			SlowIRRXLowActive(iobase, ON);			udelay(20);			// Mode select Off			SlowIRRXLowActive(iobase, OFF);		}		if (IsMIROn(iobase)) {	//mir			// Mode select On			SlowIRRXLowActive(iobase, OFF);			udelay(20);			// Mode select Off			SlowIRRXLowActive(iobase, ON);		} else {	// fir			if (IsFIROn(iobase)) {	//fir				// Mode select On				SlowIRRXLowActive(iobase, OFF);				// TX On				WriteTX(iobase, ON);				udelay(20);				// Mode select OFF				SlowIRRXLowActive(iobase, ON);				udelay(20);				// TX Off				WriteTX(iobase, OFF);			}		}		break;	case 0x0d:		UseOneRX(iobase, OFF);	// use two RX pin   RX1,RX2		InvertTX(iobase, OFF);		InvertRX(iobase, OFF);		SlowIRRXLowActive(iobase, OFF);		if (IsSIROn(iobase)) {	//sir			EnGPIOtoRX2(iobase, OFF);			WriteGIO(iobase, OFF);			EnRX2(iobase, OFF);	//sir to rx2		} else {	// fir mir			EnGPIOtoRX2(iobase, OFF);			WriteGIO(iobase, OFF);			EnRX2(iobase, OFF);	//fir to rx		}		break;	case 0x0ff:		/* Vishay */		if (IsSIROn(iobase))			mode = 0;		else if (IsMIROn(iobase))			mode = 1;		else if (IsFIROn(iobase))			mode = 2;		else if (IsVFIROn(iobase))			mode = 5;	//VFIR-16		SI_SetMode(iobase, mode);	}	WriteReg(iobase, I_ST_CT_0, 0x80);}/* * Function via_ircc_change_speed (self, baud) * *    Change the speed of the device * */static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed){	struct net_device *dev = self->netdev;	u16 iobase;	u8 value = 0, bTmp;	iobase = self->io.fir_base;	/* Update accounting for new speed */	self->io.speed = speed;#ifdef	DBGMSG	DBG(printk(KERN_INFO "change_speed =%x......\n", speed));#endif#ifdef	DBG_IO	if (self->io.speed > 0x2580)		outb(0xaa, 0x90);	else		outb(0xbb, 0x90);#endif	/* Controller mode sellection */	switch (speed) {	case 9600:		value = 11;		SetSIR(iobase, ON);		CRC16(iobase, ON);		break;	case 19200:		value = 5;		SetSIR(iobase, ON);		CRC16(iobase, ON);		break;	case 38400:		value = 2;		SetSIR(iobase, ON);		CRC16(iobase, ON);		break;	case 57600:		value = 1;		SetSIR(iobase, ON);		CRC16(iobase, ON);		break;	case 115200:		value = 0;		SetSIR(iobase, ON);		CRC16(iobase, ON);		break;	case 576000:		value = 0;		SetSIR(iobase, ON);		CRC16(iobase, ON);		break;	case 1152000:		value = 0;		SetMIR(iobase, ON);		break;	case 4000000:		value = 0;		SetFIR(iobase, ON);		SetPulseWidth(iobase, 0);		SetSendPreambleCount(iobase, 14);		CRC16(iobase, OFF);		EnTXCRC(iobase, ON);		break;	case 16000000:		value = 0;		SetVFIR(iobase, ON);		break;	default:		value = 0;		break;	}	/* Set baudrate to 0x19[2..7] */	bTmp = (ReadReg(iobase, I_CF_H_1) & 0x03);	bTmp = bTmp | (value << 2);	WriteReg(iobase, I_CF_H_1, bTmp);	via_ircc_change_dongle_speed(iobase, speed, self->io.dongle_id);// EnTXFIFOHalfLevelInt(iobase,ON);	/* Set FIFO size to 64 */	SetFIFO(iobase, 64);	/* Enable some interrupts so we can receive frames */	//EnAllInt(iobase,ON);	if (IsSIROn(iobase)) {		SIRFilter(iobase, ON);		SIRRecvAny(iobase, ON);	} else {		SIRFilter(iobase, OFF);		SIRRecvAny(iobase, OFF);	}	if (speed > 115200) {		/* Install FIR xmit handler */		dev->hard_start_xmit = via_ircc_hard_xmit_fir;		via_ircc_dma_receive(self);	} else {		/* Install SIR xmit handler */		dev->hard_start_xmit = via_ircc_hard_xmit_sir;	}	netif_wake_queue(dev);}/* * Function via_ircc_hard_xmit (skb, dev) * *    Transmit the frame! * */static int via_ircc_hard_xmit_sir(struct sk_buff *skb,				  struct net_device *dev){	struct via_ircc_cb *self;	unsigned long flags;	u16 iobase;	__u32 speed;	self = (struct via_ircc_cb *) dev->priv;	ASSERT(self != NULL, return 0;);	iobase = self->io.fir_base;	netif_stop_queue(dev);	/* Check if we need to change the speed */	speed = irda_get_next_speed(skb);	if ((speed != self->io.speed) && (speed != -1)) {		/* Check for empty frame */		if (!skb->len) {			via_ircc_change_speed(self, speed);			dev->trans_start = jiffies;			dev_kfree_skb(skb);			return 0;		} else			self->new_speed = speed;	}	InitCard(iobase);	CommonInit(iobase);	SIRFilter(iobase, ON);	SetSIR(iobase, ON);	CRC16(iobase, ON);	EnTXCRC(iobase, 0);	WriteReg(iobase, I_ST_CT_0, 0x00);	spin_lock_irqsave(&self->lock, flags);	self->tx_buff.data = self->tx_buff.head;	self->tx_buff.len =	    async_wrap_skb(skb, self->tx_buff.data,			   self->tx_buff.truesize);	self->stats.tx_bytes += self->tx_buff.len;	SetBaudRate(iobase, speed);	SetPulseWidth(iobase, 12);	SetSendPreambleCount(iobase, 0);	WriteReg(iobase, I_ST_CT_0, 0x80);	EnableTX(iobase, ON);	EnableRX(iobase, OFF);	ResetChip(iobase, 0);	ResetChip(iobase, 1);	ResetChip(iobase, 2);	ResetChip(iobase, 3);	ResetChip(iobase, 4);	EnAllInt(iobase, ON);	EnTXDMA(iobase, ON);	EnRXDMA(iobase, OFF);	setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len,		  DMA_TX_MODE);	SetSendByte(iobase, self->tx_buff.len);	RXStart(iobase, OFF);	TXStart(iobase, ON);	dev->trans_start = jiffies;	spin_unlock_irqrestore(&self->lock, flags);	dev_kfree_skb(skb);	return 0;}static int via_ircc_hard_xmit_fir(struct sk_buff *skb,				  struct net_device *dev){	struct via_ircc_cb *self;	u16 iobase;	__u32 speed;	unsigned long flags;	self = (struct via_ircc_cb *) dev->priv;	iobase = self->io.fir_base;	if (self->st_fifo.len)		return 0;	if (self->chip_id == 0x3076)		iodelay(1500);	else		udelay(1500);	netif_stop_queue(dev);	speed = irda_get_next_speed(skb);	if ((speed != self->io.speed) && (speed != -1)) {		if (!skb->len) {			via_ircc_change_speed(self, speed);			dev->trans_start = jiffies;			dev_kfree_skb(skb);			return 0;		} else			self->new_speed = speed;	}	spin_lock_irqsave(&self->lock, flags);	self->tx_fifo.queue[self->tx_fifo.free].start = self->tx_fifo.tail;	self->tx_fifo.queue[self->tx_fifo.free].len = skb->len;	self->tx_fifo.tail += skb->len;	self->stats.tx_bytes += skb->len;	memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data,	       skb->len);	self->tx_fifo.len++;	self->tx_fifo.free++;//F01   if (self->tx_fifo.len == 1) {	via_ircc_dma_xmit(self, iobase);//F01   }//F01   if (self->tx_fifo.free < (MAX_TX_WINDOW -1 )) netif_wake_queue(self->netdev);	dev->trans_start = jiffies;	dev_kfree_skb(skb);	spin_unlock_irqrestore(&self->lock, flags);	return 0;}static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase){//      int i;//      u8 *ch;	EnTXDMA(iobase, OFF);	self->io.direction = IO_XMIT;	EnPhys(iobase, ON);	EnableTX(iobase, ON);	EnableRX(iobase, OFF);	ResetChip(iobase, 0);	ResetChip(iobase, 1);	ResetChip(iobase, 2);	ResetChip(iobase, 3);	ResetChip(iobase, 4);	EnAllInt(iobase, ON);	EnTXDMA(iobase, ON);	EnRXDMA(iobase, OFF);	setup_dma(self->io.dma,		  self->tx_fifo.queue[self->tx_fifo.ptr].start,		  self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE);#ifdef	DBGMSG	DBG(printk	    (KERN_INFO "dma_xmit:tx_fifo.ptr=%x,len=%x,tx_fifo.len=%x..\n",	     self->tx_fifo.ptr, self->tx_fifo.queue[self->tx_fifo.ptr].len,	     self->tx_fifo.len));/*   	ch = self->tx_fifo.queue[self->tx_fifo.ptr].start;	for(i=0 ; i < self->tx_fifo.queue[self->tx_fifo.ptr].len ; i++) {	    DBG(printk(KERN_INFO "%x..\n",ch[i]));	}*/#endif	SetSendByte(iobase, self->tx_fifo.queue[self->tx_fifo.ptr].len);	RXStart(iobase, OFF);	TXStart(iobase, ON);	return 0;}/* * Function via_ircc_dma_xmit_complete (self) * *    The transfer of a frame in finished. This function will only be called  *    by the interrupt handler * */static int via_ircc_dma_xmit_complete(struct via_ircc_cb *self){	int iobase;	int ret = TRUE;	u8 Tx_status;	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);	iobase = self->io.fir_base;	/* Disable DMA *///      DisableDmaChannel(self->io.dma);	/* Check for underrrun! */	/* Clear bit, by writing 1 into it */	Tx_status = GetTXStatus(iobase);	if (Tx_status & 0x08) {		self->stats.tx_errors++;		self->stats.tx_fifo_errors++;		hwreset(self);// how to clear underrrun ?	} else {		self->stats.tx_packets++;		ResetChip(iobase, 3);		ResetChip(iobase, 4);	}	/* Check if we need to change the speed */	if (self->new_speed) {		via_ircc_change_speed(self, self->new_speed);		self->new_speed = 0;	}	/* Finished with this frame, so prepare for next */	if (IsFIROn(iobase)) {		if (self->tx_fifo.len) {			self->tx_fifo.len--;			self->tx_fifo.ptr++;		}	}#ifdef	DBGMSG	DBG(printk	    (KERN_INFO	     "via_ircc_dma_xmit_complete:tx_fifo.len=%x ,tx_fifo.ptr=%x,tx_fifo.free=%x...\n",	     self->tx_fifo.len, self->tx_fifo.ptr, self->tx_fifo.free));#endif/* F01_S	// Any frames to be sent back-to-back? 	if (self->tx_fifo.len) {		// Not finished yet! 	  	via_ircc_dma_xmit(self, iobase);		ret = FALSE;	} else { F01_E*/	// Reset Tx FIFO info 	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;	self->tx_fifo.tail = self->tx_buff.head;//F01   }	// Make sure we have room for more frames //F01   if (self->tx_fifo.free < (MAX_TX_WINDOW -1 )) {	// Not busy transmitting anymore 	// Tell the network layer, that we can accept more frames 	netif_wake_queue(self->netdev);//F01   }	return ret;}/* * Function via_ircc_dma_receive (self) * *    Set configuration for receive a frame. * */static int via_ircc_dma_receive(struct via_ircc_cb *self){	int iobase;	iobase = self->io.fir_base;	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;	self->tx_fifo.tail = self->tx_buff.head;	self->RxDataReady = 0;	self->io.direction = IO_RECV;	self->rx_buff.data = self->rx_buff.head;	self->st_fifo.len = self->st_fifo.pending_bytes = 0;	self->st_fifo.tail = self->st_fifo.head = 0;	EnPhys(iobase, ON);	EnableTX(iobase, OFF);	EnableRX(iobase, ON);	ResetChip(iobase, 0);	ResetChip(iobase, 1);	ResetChip(iobase, 2);	ResetChip(iobase, 3);	ResetChip(iobase, 4);	EnAllInt(iobase, ON);	EnTXDMA(iobase, OFF);	EnRXDMA(iobase, ON);	setup_dma(self->io.dma2, self->rx_buff.data,		  self->rx_buff.truesize, DMA_RX_MODE);	TXStart(iobase, OFF);	RXStart(iobase, ON);	return 0;}/* * Function via_ircc_dma_receive_complete (self) * *    Controller Finished with receiving frames, *    and this routine is call by ISR *     */static int via_ircc_dma_receive_complete(struct via_ircc_cb *self,					 int iobase){	struct st_fifo *st_fifo;	struct sk_buff *skb;	int len, i;	u8 status = 0;	iobase = self->io.fir_base;	st_fifo = &self->st_fifo;	if (self->io.speed < 4000000) {	//Speed below FIR		len = GetRecvByte(iobase, self);		skb = dev_alloc_skb(len + 1);		if (skb == NULL)			return FALSE;		// Make sure IP header gets aligned 		skb_reserve(skb, 1);		skb_put(skb, len - 2);		if (self->chip_id == 0x3076) {			for (i = 0; i < len - 2; i++)				skb->data[i] = self->rx_buff.data[i * 2];		} else {			if (self->chip_id == 0x3096) {				for (i = 0; i < len - 2; i++)					skb->data[i] =					    self->rx_buff.data[i];			}		}		// Move to next frame 		self->rx_buff.data += len;		self->stats.rx_bytes += len;		self->stats.rx_packets++;		skb->dev = self->netdev;		skb->mac.raw = skb->data;		skb->protocol = htons(ETH_P_IRDA);		netif_rx(skb);		return TRUE;	}	else {			//FIR mode		len = GetRecvByte(iobase, self);		if (len == 0)			return TRUE;	//interrupt only, data maybe move by RxT  		if (((len - 4) < 2) || ((len - 4) > 2048)) {#ifdef	DBGMSG			DBG(printk			    (KERN_INFO			     "receive_comple:Trouble:len=%x,CurCount=%x,LastCount=%x..\n",			     len, RxCurCount(iobase, self),			     self->RxLastCount));#endif			hwreset(self);			return FALSE;		}#ifdef	DBGMSG		DBG(printk

⌨️ 快捷键说明

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