static void sa1100_irda_shutdown(struct sa1100_irda *si)
{
	/*
	 * Stop all DMA activity.
	 */
	sa1100_stop_dma(si->rxdma);
	sa1100_stop_dma(si->txdma);

	/* Disable the port. */
	Ser2UTCR3 = 0;
	Ser2HSCR0 = 0;
}
示例#2
0
/*
 * FIR format interrupt service routine.  We only have to
 * handle RX events; transmit events go via the TX DMA handler.
 *
 * No matter what, we disable RX, process, and the restart RX.
 */
static void sa1100_irda_fir_irq(struct net_device *dev)
{
	struct sa1100_irda *si = dev->priv;

	/*
	 * Stop RX DMA
	 */
	sa1100_stop_dma(si->rxdma);

	/*
	 * Framing error - we throw away the packet completely.
	 * Clearing RXE flushes the error conditions and data
	 * from the fifo.
	 */
	if (Ser2HSSR0 & (HSSR0_FRE | HSSR0_RAB)) {
		si->stats.rx_errors++;

		if (Ser2HSSR0 & HSSR0_FRE)
			si->stats.rx_frame_errors++;

		/*
		 * Clear out the DMA...
		 */
		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;

		/*
		 * Clear selected status bits now, so we
		 * don't miss them next time around.
		 */
		Ser2HSSR0 = HSSR0_FRE | HSSR0_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 (Ser2HSSR0 & HSSR0_EIF)
		sa1100_irda_fir_error(si, dev);

	/*
	 * No matter what happens, we must restart reception.
	 */
	sa1100_irda_rx_dma_start(si);
}
示例#3
0
/*
 * Set the IrDA communications speed.
 */
static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
{
	unsigned long flags;
	int brd, ret = -EINVAL;

	switch (speed) {
	case 9600:	case 19200:	case 38400:
	case 57600:	case 115200:
		brd = 3686400 / (16 * speed) - 1;

		/*
		 * Stop the receive DMA.
		 */
		if (IS_FIR(si))
			sa1100_stop_dma(si->rxdma);

		local_irq_save(flags);

		Ser2UTCR3 = 0;
		Ser2HSCR0 = HSCR0_UART;

		Ser2UTCR1 = brd >> 8;
		Ser2UTCR2 = brd;

		/*
		 * Clear status register
		 */
		Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
		Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;

		if (si->pdata->set_speed)
			si->pdata->set_speed(si->dev, speed);

		si->speed = speed;

		local_irq_restore(flags);
		ret = 0;
		break;

	case 4000000:
		local_irq_save(flags);

		si->hscr0 = 0;

		Ser2HSSR0 = 0xff;
		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
		Ser2UTCR3 = 0;

		si->speed = speed;

		if (si->pdata->set_speed)
			si->pdata->set_speed(si->dev, speed);

		sa1100_irda_rx_alloc(si);
		sa1100_irda_rx_dma_start(si);

		local_irq_restore(flags);

		break;

	default:
		break;
	}

	return ret;
}
/*
 * Set the IrDA communications speed.
 */
static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
{
	unsigned long flags;
	int brd, ret = -EINVAL;

	switch (speed) {
	case 9600:	case 19200:	case 38400:
	case 57600:	case 115200:
		brd = 3686400 / (16 * speed) - 1;

		/*
		 * Stop the receive DMA.
		 */
		if (IS_FIR(si))
			sa1100_stop_dma(si->rxdma);

		local_irq_save(flags);

		Ser2UTCR3 = 0;
		Ser2HSCR0 = HSCR0_UART;

		Ser2UTCR1 = brd >> 8;
		Ser2UTCR2 = brd;

		/*
		 * Clear status register
		 */
		Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
		Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;

		if (machine_is_assabet())
			ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
		if (machine_is_h3xxx())
			clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
		if (machine_is_yopy())
			PPSR &= ~GPIO_IRDA_FIR;

		si->speed = speed;

		local_irq_restore(flags);
		ret = 0;
		break;

	case 4000000:
		local_irq_save(flags);

		si->hscr0 = 0;

		Ser2HSSR0 = 0xff;
		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
		Ser2UTCR3 = 0;

		si->speed = speed;

		if (machine_is_assabet())
			ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
		if (machine_is_h3xxx())
			set_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
		if (machine_is_yopy())
			PPSR |= GPIO_IRDA_FIR;

		sa1100_irda_rx_alloc(si);
		sa1100_irda_rx_dma_start(si);

		local_irq_restore(flags);

		break;

	default:
		break;
	}

	return ret;
}
示例#5
0
void udc_ep2_int_hndlr(struct sausb_dev *usb)
{
	u32 status = Ser0UDCCS2;

	// check for stupid silicon bug.
	if (Ser0UDCAR != usb->ctl->address)
		Ser0UDCAR = usb->ctl->address;

	udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0);

	if (!(status & UDCCS2_TPC)) {
	    char *buf = (char *) usb->ep[1].bufdma;
	    int len = usb->ep[1].buflen;
		printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
printk("%s: hmm, what to do here?\n",__FUNCTION__);	
//		udc_ep2_send_reset(usb);
printk("%s: Buffer is %x length %d\n",__FUNCTION__,(int)buf,len);	
    if (buf && len) {
printk("%s: Retransmitting\n",__FUNCTION__);	
		udc_ep2_send(usb, buf, len);
    }
		return;
	}

	sa1100_stop_dma(usb->ep[1].dmach);

	if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
		printk("usb_send: transmit error %x\n", status);
		usb->ep[1].fifo_errs ++;
		udc_ep2_done(usb, -EIO);
	} else {
		unsigned int imp;
#if 1		// 22Feb01ww/Oleg
		imp = ep2_curdmalen;
#else
		// this is workaround for case when setting
		// of Ser0UDCIMP was failed
		imp = Ser0UDCIMP + 1;
#endif
		usb->ep[1].pktdma += imp;
		ep2_remain -= imp;

		usb->ep[1].bytes += imp;
		usb->ep[1].packets++;

		sa1100_clear_dma(usb->ep[1].dmach);

#if 0
    /* induce horrible 5ms delay */
	    {
		udelay(1000);
		udelay(1000);
		udelay(1000);
		udelay(1000);
		udelay(1000);
	    }
#endif

		if (ep2_remain != 0) {
			ep2_start(usb);
		} else {
			udc_ep2_done(usb, 0);
		}
	}
}
示例#6
0
void ep1_int_hndlr()
{
	dma_addr_t dma_addr;
	unsigned int len;
	int status = Ser0UDCCS1;

	PRINTKD( "[%lu]Ep1 int %d\n", (jiffies-start_time)*10, status);
	
	if ( naking )
		printk( "%sEh? in ISR but naking = %d\n", "usbrx: ", naking );

	// Reive packet complete
	if (status & UDCCS1_RPC) {
		if (!ep1_curdmalen) {
			printk("usb_recv: RPC for non-existent buffer\n");
			naking = 1;
			return;
		}

		sa1100_stop_dma(dmachn_rx);

		if (status & UDCCS1_SST) {
			printk("usb_recv: stall sent OMP=%d\n",Ser0UDCOMP);
			UDC_flip(Ser0UDCCS1, UDCCS1_SST);
			ep1_done(-EIO); // UDC aborted current transfer, so we do
			return;
		}

		if (status & UDCCS1_RPE) {
		    printk("usb_recv: RPError %x\n", status);
			UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
			ep1_done(-EIO);
			return;
		}

		dma_addr = sa1100_get_dma_pos(dmachn_rx);
		pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen, PCI_DMA_FROMDEVICE);
		
		len = dma_addr - ep1_curdmapos;

		if (len < ep1_curdmalen) {
			char *buf = ep1_curdmabuf + len;
			while (Ser0UDCCS1 & UDCCS1_RNE) {
				if (len >= ep1_curdmalen) {
					printk("usb_recv: too much data in fifo\n");
					break;
				}
				*buf++ = Ser0UDCDR;
				len++;
			}
		} else if (Ser0UDCCS1 & UDCCS1_RNE) {
			printk("usb_recv: fifo screwed, shouldn't contain data\n");
			len = 0;
		}
		ep1_curdmalen = 0;  /* dma unmap already done */
		ep1_remain -= len;
		naking = 1;
		ep1_done((len) ? 0 : -EPIPE);
	}
	/* else, you can get here if we are holding NAK */
}