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

📄 pxa_ir.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   if (status & (ICSR0_FRE | ICSR0_RAB)) {      DBG_IRQ("Framing error or RAB\n");             si->stats.rx_errors++;      if (ICSR0 & ICSR0_FRE)	 si->stats.rx_frame_errors++;      /* Clear RX fifo       * DMA will be cleared when we restart RX       * Should we check RNE after that?        */      ICCR0 &= ~ICCR0_RXE;            /*       * Clear selected status bits now, so we       * don't miss them next time around.       */      ICSR0 = status & (ICSR0_FRE | ICSR0_RAB);   }      /*    * Deal with any receive errors.  The any of the lowest    * 8 bytes in the FIFO may contain an error.  We must read    * them one by one.  The "error" could even be the end of    * packet!    */   if (ICSR0 & ICSR0_EIF)      pxa250_irda_fir_error(dev);   /*    * No matter what happens, we must restart reception.    */   ICCR0 = 0;   pxa250_start_rx_dma(dev);   pxa250_ficp_rx_start();   __ECHO_OUT;   return IRQ_HANDLED;}/************************************************************************** *			SIR 						  * **************************************************************************//* * HP-SIR format interrupt service routines. */static void pxa250_sir_transmit(struct net_device *dev){   struct pxa250_irda *si = dev->priv;      if (si->tx_buff.len)    {	/* Disable receiver and  enable transmiter*/            		STISR &= ~STISR_RCVEIR; //	        STISR |= STISR_XMITIR;						                disable_irq(dev->irq);				do 		{		   if (STLSR & LSR_TDRQ)		   {		      STTHR = *si->tx_buff.data++;		      si->tx_buff.len -= 1; 		      tx_count++;		   }		   				         		} while (si->tx_buff.len);						if (si->tx_buff.len == 0) 		{		   		   			si->stats.tx_packets++;			si->stats.tx_bytes += si->tx_buff.data -					      si->tx_buff.head;			/*			 * We need to ensure that the transmitter has			 * finished.			 */					        do			{			   udelay(1);			               		}							while ( ! (STLSR & LSR_TEMT) );                       									/*			 * Ok, we've finished transmitting.  Now enable			 * the receiver.  Sometimes we get a receive IRQ			 * immediately after a transmit...			 */			if (si->newspeed)			{				pxa250_irda_set_speed(dev, si->newspeed);				si->newspeed = 0;			}			/* I'm hungry! */			netif_wake_queue(dev);		}				enable_irq (dev->irq);                STIER = (IER_RAVIE | IER_UUE | IER_RTIOE);		STISR |= STISR_RCVEIR;//		STISR &= ~STISR_XMITIR;   }}static void pxa250_irda_hpsir_irq(struct net_device *dev){	struct pxa250_irda *si = dev->priv;	/*	 * Deal with any receive errors first.  The bytes in error may be	 * the only bytes in the receive FIFO, so we do this first.	 */  	__ECHO_IN; 		while (STLSR & LSR_FIFOE)	{		int stat, data;		stat = STLSR; 		data = STRBR;               		                if (stat & (LSR_FE | LSR_OE | LSR_PE)) 				{		        si->stats.rx_errors++;			if (stat & LSR_FE) 				si->stats.rx_frame_errors++;			if (stat & LSR_OE) 				si->stats.rx_fifo_errors++;					} else		{		   rx_count++;		   async_unwrap_char(dev, &si->stats, &si->rx_buff, data);                }			}	/*	 * We must clear certain bits.	 */	 	if (STLSR & (LSR_DR)) 	{		/*		 * Fifo contains at least 1 character.		 */		do		{		   int data;		   		   data = STRBR;		   		   async_unwrap_char(dev, &si->stats, &si->rx_buff,					  data); /* was Ser2UTDR); Clo */		   rx_count++;		   		} while (STLSR & LSR_DR); 				dev->last_rx = jiffies;	}  	__ECHO_OUT; }static void pxa250_sir_irda_shutdown(struct pxa250_irda *si){   STIER = 0;   STFCR = 0;   STISR = 0;   CKEN &= ~CKEN5_STUART; }/************************************************************************************//*Low level init/uninstall function PM control and IrDA protocol stack registration *//* * Set the IrDA communications speed. * Interrupt have to be disabled here. */static int pxa250_irda_startup(struct net_device *dev){      __ECHO_IN;   /*    * Ensure that the ports for this device are setup correctly.    */   pxa_gpio_mode (GPIO46_STRXD_MD);   pxa_gpio_mode (GPIO47_STTXD_MD);   STMCR = MCR_OUT2;   STLCR = LCR_WLS1 | LCR_WLS0;   SET_SIR_MODE;   CKEN |= CKEN5_STUART;   /* enable irq from stuart */   ICMR |= ( 1 << 20 );	   /*reset FIFO*/		/*	STFCR = FCR_TRFIFOE |  FCR_RESETTF | FCR_RESETRF;// | FCR_ITL_16;	STIER = IER_UUE | IER_RAVIE | IER_RTOIE;*/	   __ECHO_OUT;   return 0;	}#ifdef CONFIG_PM/* * Suspend the IrDA interface. */static int pxa250_irda_shutdown(struct pxa250_irda *si){   pxa250_sir_irda_shutdown(si);   return 0;   }static int pxa250_irda_suspend(struct device *_dev, u32 state, u32 level){	struct net_device *dev = dev_get_drvdata(_dev);	struct pxa250_irda *si = dev->priv;	if (si->dev == _dev && level == SUSPEND_DISABLE) {		if (si && si->open) {		   /*		    * Stop the transmit queue		    */		   if (IS_FIR(si))		      return -1;		   netif_stop_queue(dev);		   disable_irq(dev->irq);		   disable_irq(si->fir_irq);		   pxa250_sir_irda_shutdown(si);		}	}	return 0;}/* * Resume the IrDA interface. */static int pxa250_irda_resume(struct device *_dev, u32 level){	struct net_device *dev = dev_get_drvdata(_dev);	struct pxa250_irda *si = dev->priv;	__ECHO_IN;		if (si->dev == _dev && level == RESUME_ENABLE) {		if (si && si->open) {			/*			 * If we missed a speed change, initialise at the new speed			 * directly.  It is debatable whether this is actually			 * required, but in the interests of continuing from where			 * we left off it is desireable.  The converse argument is			 * that we should re-negotiate at 9600 baud again.			 */			if (si->newspeed) {				si->speed = si->newspeed;				si->newspeed = 0;			}			pxa250_irda_startup(dev);			enable_irq(dev->irq);			/*			 * This automatically wakes up the queue			 */			netif_wake_queue(dev);			pxa250_irda_set_speed(dev,si->speed = 9600);	//modified by hzh, 9600->115200				}	}	__ECHO_OUT;	return 0;}static int pxa250_irda_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data){	int ret;	struct device *_dev = ((struct pxa250_irda *)((struct net_device *)dev->data)->priv)->dev;		if (!dev->data)		return -EINVAL;	switch (rqst) {	case PM_SUSPEND:		ret = pxa250_irda_suspend(_dev, (u32)data, SUSPEND_DISABLE);		break;	case PM_RESUME:		ret = pxa250_irda_resume(_dev, RESUME_ENABLE);		break;	default:	   ret = -EINVAL;		break;	}	return ret;}#endifstatic irqreturn_t pxa250_irda_irq(int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = dev_id;		pxa250_irda_hpsir_irq(dev);		return IRQ_HANDLED;}static int pxa250_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev){	struct pxa250_irda *si = dev->priv;	int speed = irda_get_next_speed(skb);	int mtt;	  	__ECHO_IN; 	/*	 * Does this packet contain a request to change the interface	 * speed?  If so, remember it until we complete the transmission	 * of this frame.	 */	if (speed != si->speed && speed != -1)		si->newspeed = speed;	/*	 * If this is an empty frame, we can bypass a lot.	 */	if (skb->len == 0) {		if (si->newspeed) {			si->newspeed = 0;			pxa250_irda_set_speed(dev, speed);		}		dev_kfree_skb(skb);		return 0;	}  	DBG("stop queue\n"); 	netif_stop_queue(dev);	if(!IS_FIR(si))	{	   	   si->tx_buff.data = si->tx_buff.head;	   si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,						  si->tx_buff.truesize);        	   pxa250_sir_transmit(dev);			   dev_kfree_skb(skb);	   dev->trans_start = jiffies;	   return 0;	}	else /* FIR */	{	   DBG("Enter FIR transmit\n");	   /*	    * We must not be transmitting...	    */	   if (si->txskb)	      BUG();      	   disable_irq(si->fir_irq); 	   	   netif_stop_queue(dev);	   DBG("queue stoped\n");	   si->txskb = skb;	   /* we could not just map so we'll need some triks */	   /* skb->data may be not DMA capable -Sed- */	   if (skb->len > TXBUFF_MAX_SIZE)	   {	      printk (KERN_ERR "skb data too large\n");	      printk (KERN_ERR "len=%d",skb->len);	      BUG();	   }			   DBG("gonna copy %d bytes to txbuf\n",skb->len);	   memcpy (si->txbuf_dma_virt, skb->data , skb->len);	   	   /* Actual sending ;must not be receiving !!! */	   /* Write data and source address */	   DBG("ICSR1 & RNE =%d\n",(ICSR1 & ICSR1_RNE) ? 1 : 0 );	   /*Disable receiver and enable transifer */  	   ICCR0 &= ~ICCR0_RXE;      	   	   if (ICSR1 & ICSR1_TBY)	      BUG();    	   ICCR0 |= ICCR0_TXE;  			   DBG("FICP status %x\n",ICSR0);	   if (0){	      int i;		   	      DBG("sending packet\n");	      for (i=0;i<skb->len;i++)		 (i % 64) ? printk ("%2x ",skb->data[i]) : printk ("%2x \n",skb->data[i]) ;	      DBG(" done\n");   	   }	   /*	    * If we have a mean turn-around time, impose the specified	    * specified delay.  We could shorten this by timing from	    * the point we received the packet.	    */	   	   mtt = irda_get_mtt(skb); 	   if(mtt)    	      udelay(mtt);    	   	   DCSR(si->txdma_ch)=0;	   DCSR(si->txdma_ch)=DCSR_NODESC;	   DSADR(si->txdma_ch) = si->txbuf_dma; /* phisic address */	   DTADR(si->txdma_ch) = __PREG(ICDR);			   DCMD(si->txdma_ch) = DCMD_ENDIRQEN| DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1 | skb->len;	   DCSR(si->txdma_ch) = DCSR_ENDINTR | DCSR_BUSERR;	   DCSR(si->txdma_ch) = DCSR_RUN | DCSR_NODESC ;	   DBG("FICP status %x\n",ICSR0);	   return 0;	}	}static intpxa250_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd){	struct if_irda_req *rq = (struct if_irda_req *)ifreq;	struct pxa250_irda *si = dev->priv;	int ret = -EOPNOTSUPP;	__ECHO_IN;		switch (cmd) {	case SIOCSBANDWIDTH:		if (capable(CAP_NET_ADMIN)) {			/*			 * We are unable to set the speed if the			 * device is not running.			 */			if (si->open) {				ret = pxa250_irda_set_speed(dev,						rq->ifr_baudrate);			} else {				printk("pxa250_irda_ioctl: SIOCSBANDWIDTH: !netif_running\n");				ret = 0;			}		}		break;	case SIOCSMEDIABUSY:		ret = -EPERM;		if (capable(CAP_NET_ADMIN)) {			irda_device_set_media_busy(dev, TRUE);			ret = 0;		}		break;	case SIOCGRECEIVING:		rq->ifr_receiving = IS_FIR(si) ? 0					: si->rx_buff.state != OUTSIDE_FRAME;		break;	default:

⌨️ 快捷键说明

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