Example #1
0
/* FIR Transmit DMA interrupt handler */
static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
{
	struct net_device *dev = data;
	struct pxa_irda *si = netdev_priv(dev);
	int dcsr;

	dcsr = DCSR(channel);
	DCSR(channel) = dcsr & ~DCSR_RUN;

	if (dcsr & DCSR_ENDINTR)  {
		si->stats.tx_packets++;
		si->stats.tx_bytes += si->dma_tx_buff_len;
	} else {
		si->stats.tx_errors++;
	}

	while (ICSR1 & ICSR1_TBY)
		cpu_relax();
	si->last_oscr = OSCR;

	/*
	 * HACK: It looks like the TBY bit is dropped too soon.
	 * Without this delay things break.
	 */
	udelay(120);

	if (si->newspeed) {
		pxa_irda_set_speed(si, si->newspeed);
		si->newspeed = 0;
	} else {
		int i = 64;

		ICCR0 = 0;
		pxa_irda_fir_dma_rx_start(si);
		while ((ICSR1 & ICSR1_RNE) && i--)
			(void)ICDR;
		ICCR0 = ICCR0_ITR | ICCR0_RXE;

		if (i < 0)
			printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
	}
	netif_wake_queue(dev);
}
Example #2
0
/* FIR interrupt handler */
static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct pxa_irda *si = netdev_priv(dev);
	int icsr0, i = 64;

	/* stop RX DMA */
	DCSR(si->rxdma) &= ~DCSR_RUN;
	si->last_oscr = OSCR;
	icsr0 = ICSR0;

	if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) {
		if (icsr0 & ICSR0_FRE) {
		        printk(KERN_DEBUG "pxa_ir: fir receive frame error\n");
			si->stats.rx_frame_errors++;
		} else {
			printk(KERN_DEBUG "pxa_ir: fir receive abort\n");
			si->stats.rx_errors++;
		}
		ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB);
	}

	if (icsr0 & ICSR0_EIF) {
		/* An error in FIFO occured, or there is a end of frame */
		pxa_irda_fir_irq_eif(si, dev, icsr0);
	}

	ICCR0 = 0;
	pxa_irda_fir_dma_rx_start(si);
	while ((ICSR1 & ICSR1_RNE) && i--)
		(void)ICDR;
	ICCR0 = ICCR0_ITR | ICCR0_RXE;

	if (i < 0)
		printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");

	return IRQ_HANDLED;
}
Example #3
0
/*
 * Set the IrDA communications speed.
 */
static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
{
	unsigned long flags;
	unsigned int divisor;

	switch (speed) {
	case 9600:	case 19200:	case 38400:
	case 57600:	case 115200:

		/* refer to PXA250/210 Developer's Manual 10-7 */
		/*  BaudRate = 14.7456 MHz / (16*Divisor) */
		divisor = 14745600 / (16 * speed);

		local_irq_save(flags);

		if (IS_FIR(si)) {
			/* stop RX DMA */
			DCSR(si->rxdma) &= ~DCSR_RUN;
			/* disable FICP */
			ICCR0 = 0;
			pxa_irda_disable_clk(si);

			/* set board transceiver to SIR mode */
			si->pdata->transceiver_mode(si->dev, IR_SIRMODE);

			/* enable the STUART clock */
			pxa_irda_enable_sirclk(si);
		}

		/* disable STUART first */
		STIER = 0;

		/* access DLL & DLH */
		STLCR |= LCR_DLAB;
		STDLL = divisor & 0xff;
		STDLH = divisor >> 8;
		STLCR &= ~LCR_DLAB;

		si->speed = speed;
		STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
		STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;

		local_irq_restore(flags);
		break;

	case 4000000:
		local_irq_save(flags);

		/* disable STUART */
		STIER = 0;
		STISR = 0;
		pxa_irda_disable_clk(si);

		/* disable FICP first */
		ICCR0 = 0;

		/* set board transceiver to FIR mode */
		si->pdata->transceiver_mode(si->dev, IR_FIRMODE);

		/* enable the FICP clock */
		pxa_irda_enable_firclk(si);

		si->speed = speed;
		pxa_irda_fir_dma_rx_start(si);
		ICCR0 = ICCR0_ITR | ICCR0_RXE;

		local_irq_restore(flags);
		break;

	default:
		return -EINVAL;
	}

	return 0;
}
static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
{
	unsigned long flags;
	unsigned int divisor;

	switch (speed) {
	case 9600:	case 19200:	case 38400:
	case 57600:	case 115200:

		
		
		divisor = 14745600 / (16 * speed);

		local_irq_save(flags);

		if (IS_FIR(si)) {
			
			DCSR(si->rxdma) &= ~DCSR_RUN;
			
			ICCR0 = 0;
			pxa_irda_disable_clk(si);

			
			pxa_irda_set_mode(si, IR_SIRMODE);

			
			pxa_irda_enable_sirclk(si);
		}

		
		STIER = 0;

		
		STLCR |= LCR_DLAB;
		STDLL = divisor & 0xff;
		STDLH = divisor >> 8;
		STLCR &= ~LCR_DLAB;

		si->speed = speed;
		STISR = IrSR_IR_RECEIVE_ON | IrSR_XMODE_PULSE_1_6;
		STIER = IER_UUE | IER_RLSE | IER_RAVIE | IER_RTIOE;

		local_irq_restore(flags);
		break;

	case 4000000:
		local_irq_save(flags);

		
		STIER = 0;
		STISR = 0;
		pxa_irda_disable_clk(si);

		
		ICCR0 = 0;

		
		pxa_irda_set_mode(si, IR_FIRMODE);

		
		pxa_irda_enable_firclk(si);

		si->speed = speed;
		pxa_irda_fir_dma_rx_start(si);
		ICCR0 = ICCR0_ITR | ICCR0_RXE;

		local_irq_restore(flags);
		break;

	default:
		return -EINVAL;
	}

	return 0;
}