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

📄 dm320.c.svn-base

📁 TI DM320处理器支持的linux usb device侧驱动程序
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
{	int 					iInterruptFlags,i;	int     				iInterrupt;	int     				iCount;	unsigned char   		ucCSR0;	struct dm320 			*dev = the_controller;	unsigned long		flags;	spin_lock_irqsave (&dev->lock, flags);		iInterruptFlags = dm320_read_intr_regs( );	do	{		iInterrupt = dm320_get_intr_by_priority( iInterruptFlags );		switch( iInterrupt ) 		{			case USB_RESET:									printk("Event: RESET Interrupt\n" );					paddr_status  = 0 ;#if 0					if( )					{											}#endif				break;							case USB_SESSREQ:				break;							case USB_VBUSERR:				printk("INT VBUSERR\n" );				break;							case USB_CONNECTED:				printk( "INT CONNECT\n" );				break;			case USB_RESUME:				printk(  "INT RESUME\n" );				break;			case USB_CONTROL:				writeb( USB_EP0_SELECT, USB_INDEX );				ucCSR0	= readb( USB_PER_CSR0 );							dm320_info( "ucCSR0 : 0x%02X\n", ucCSR0 );				if( ucCSR0 == 0x00 )		// response complete interrupt 				{					char	chNewAddr;					if(paddr_status  == 0 )					{						if( ( chNewAddr = dm320_get_peripheral_addr(dev) ) > 0 )						{							dm320_set_addr_reg( chNewAddr & 0xFF );							 paddr_status  = 1;						}						break;					}				}				if( ( ucCSR0 & USB_CSR0_RXPKTRDY ) != 0 )				{								    	dm320_info("dm320:%s: USB_CSR0_RXPKTRDY set\n", __FUNCTION__);						iCount = readb( USB_COUNT0 );			// number of received bytes					dm320_control_service(dev);				}				else if( ( ucCSR0 & USB_CSR0_SENTST ) != 0 )				{					dm320_info( KERN_INFO "INT TXFIFO0 stall.[%04x].\n", ucCSR0 ); 					writeb( 0, USB_PER_CSR0 );						}				else if( ( ucCSR0 & USB_CSR0_SETEND ) != 0 )				{					dm320_info( KERN_INFO "INT TXFIFO0 setend from HOST[%04x].\n", ucCSR0 );					*(unsigned char *)USB_PER_CSR0 = USB_CSR0_CLRSETEND;				}				else if( ( ucCSR0 & USB_CSR0_TXPKTRDY ) != 0 )				{					dm320_info( KERN_INFO "INT TXPKTRDY\n" );					// Nothing to do now...				}				else				{					// ----- FIXME -----					// Now ignore these unknown interrupts...					dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND ); // Vishal: added this$#$					//printk( KERN_INFO "Attention: Unknown USB Core Interrupt encountered!\n" );				}								break;            case USB_RXFIFO:				//	printk("%s: USB_RXFIFO interrupt\n", __FUNCTION__);                    dm320_rx_service(dev);                    break;            case USB_TXFIFO:                    //if(dm320_tx_service(dev))		    //printk ("USB_TXFIFO\n");                    	dm320_tx_service(dev);                break;			case USB_SOF:			      do_pending_transfers();	//	      printk("%s: SOF \n", __FUNCTION__);				  break;				case USB_DISCONNECTED:				printk("dm320: DISCONNECT Intr.\n" );				dm320_disconnect_service( );				break;			case USB_SUSPEND:				printk("dm320: SUSPEND Intr.\n" );					dm320_suspend_service( );				break;			default:				//printk("UNKNOWN USB core interrupt!\n" );				break;		}		iInterruptFlags = iInterruptFlags & ~iInterrupt;		} 	while( iInterruptFlags != USB_NO_INTERRUPT );		spin_unlock_irqrestore(&dev->lock, flags);	return IRQ_HANDLED;}static int     dm320_connection_status( void ){    unsigned short      usGIO;	mdelay(50);    usGIO   = inw( IO_GIO_BITSET0 );    if( ( usGIO & ( 1 << GIO_USB_ATTACH ) ) == 0 )  // check if USB device was connected or disconnected    {		if(the_controller->last_event == HOST_DISCONNECT)			return -1;		else		{			the_controller->last_event = HOST_DISCONNECT;			return 0;                                           // 0 : DISCONNECTED		}    }	else /* Connect Event */	{			if(the_controller->last_event == HOST_CONNECT)			return -1;		else		{			the_controller->last_event = HOST_CONNECT;			return 1;                                           // 0 : DISCONNECTED		}	}	return -1;}static irqreturn_t  handle_attach_irqs (int irq, void *_dev, struct pt_regs * r){	u8			tmp, mask;	struct dm320		*dev = _dev;	int i, connect;//	spin_lock (&dev->lock);	connect=dm320_connection_status();#if 0	if(connect == HOST_CONNECT )		printk("%s: Device Connected\n", __FUNCTION__);	else if (connect == HOST_DISCONNECT)		printk("%s: Device DisConnected\n", __FUNCTION__);#endif    if(connect < 0 )	   	{		printk("%s: Debounce detected\n", __FUNCTION__);		return 0;	}			if (connect == HOST_DISCONNECT) {			stop_activity(dev, dev->driver);   /* Vishal : Stop activity...haha!!*/			printk("%s: Disconnect the USB device\n", __FUNCTION__);			dev->gadget.speed = USB_SPEED_UNKNOWN;			outw( inw( IO_CLK_LPCTL1 ) | 0x0010, IO_CLK_LPCTL1 ); 			printk("Disconnect: USB device\n");//			spin_unlock (&dev->lock);			if((readb(USB_PER_TXCSR1) & USB_TXCSR1_FIFOEMP) )			{				writeb(USB_TXCSR1_FLFIFO , USB_PER_TXCSR1);		 		mdelay(5);			}			return IRQ_HANDLED;	}	if(the_controller)	{		printk("dm320.c: Controller exists. Initializing\n");	    usb_reset (the_controller);		outw(inw(IO_INTC_FISEL0) & 0x7F, IO_INTC_FISEL0);		outw(inw(IO_INTC_EINT0) |  0x80, IO_INTC_EINT0);		dm320_reconnect_init(dev);		//usb_reinit (the_controller);       //writeb( USB_DEVCTL_SESSREQ, USB_DEVCTL );  // For 'B' device initiate session request protocol	}//	spin_unlock (&dev->lock);	printk("dm320 : Connect event handled\n");	return IRQ_HANDLED;}static void gadget_release (struct device *_dev){	struct dm320	*dev = dev_get_drvdata (_dev);	printk("%s: released\n", __FUNCTION__);	kfree (dev);}static int dm320_remove (struct dm320 *dev){	/* clean up resources allocated during probe() */	dev = the_controller;	    printk("%s: Disconnect the USB device\n", __FUNCTION__);    dev->gadget.speed = USB_SPEED_UNKNOWN;    outw( inw( IO_CLK_LPCTL1 ) | 0x0010, IO_CLK_LPCTL1 );    printk("Disconnect: USB device\n");	if (dev->attach_irq)	   	free_irq( IRQ_USB_ATTACH, handle_attach_irqs );	if (dev->core_irq)    	free_irq( IRQ_USB_CORE, handle_core_irqs );	gio_disable_irq( GIO_USB_ATTACH );    unrequest_gio( GIO_USB_ATTACH );    unrequest_gio( GIO_DP_PULLUP );    stop_activity (dev, dev->driver);   /* Vishal : Stop activity...!!*/	device_unregister (&dev->gadget.dev);	if (dev->driver) {		/* should have been done already by driver model core */		printk("WARNING: remove, driver '%s' is still registered\n",				dev->driver->driver.name);		usb_gadget_unregister_driver (dev->driver);	}	kfree(the_controller);	the_controller = NULL;		return 0;}static void dm320_reset_ep(unsigned int index)  /*  */{	writeb(index,USB_INDEX );                writeb( USB_CSR0_CLRSETEND | USB_CSR0_CLRRXRDY, USB_PER_CSR0 );    writeb( USB_CSR2_FLFIFO, USB_CSR2 );            // flush FIFO    writeb( USB_CSR2_FLFIFO, USB_CSR2 );            // flush FIFO for double buffer}static void dm320_setup_ep_regs(struct dm320 *dev)   /* Setup Conrol Endpoint, EP1 and EP2 */{	int i;	int		nBufPos;	writeb( USB_EP0_SELECT, USB_INDEX );            // select EP0    writeb( USB_CSR0_CLRSETEND | USB_CSR0_CLRRXRDY, USB_PER_CSR0 );    writeb( USB_CSR2_FLFIFO, USB_CSR2 );            // flush FIFO    writeb( USB_CSR2_FLFIFO, USB_CSR2 );            // flush FIFO for double buffer    writeb( nBufPos & 0xFF,     USB_TXFIFO1 );      // TX ADDL = 0x00    writeb( nBufPos & 0xFF,     USB_RXFIFO1 );      // RX ADDL = 0x00    writeb( USB_TXFIFO2_SZ_64,  USB_TXFIFO2 );      // TX fixed 64 bytes, single buffer, ADDH = 0    writeb( USB_TXFIFO2_SZ_64,  USB_RXFIFO2 );      // RX fixed 64 bytes, single buffer, ADDH = 0    writeb( EP0_FIFO_SIZE / 8 ,  USB_TXMAXP );       // max TX packet size = 8 * 8 = 64 bytes    writeb( EP0_FIFO_SIZE / 8 ,  USB_RXMAXP );       // max RX packet size = 8 * 8 = 64 bytes    nBufPos = EP0_FIFO_SIZE;                        // move to next buffer position	/*  Setup  bulk-in, bulk-out, iso-in, iso-out, and intr endpoints *	    These endpoints will be configured using the stEndpointInfo[] array		if you need to add a new end poing to change the confiuration 		for an existing endpoint, you will need to change that array	*/    for( i = 0; i < NUM_OF_ENDPOINTS ; i++ )    {        writeb( stEndpointInfo[i].fAddr & 0x0F, USB_INDEX );        if( stEndpointInfo[i].nSize )        {            char    fLowAddr    = ( nBufPos / 8 ) & 0xFF;            char    fHighAddr   = ( nBufPos >= 2048 ) ? 1 : 0;            char    fPacketSize = 0x00;            char    fIsDualBuf  = ( stEndpointInfo[i].fBufMode == EP_BUF_SINGLE ) ? 0x00 : 0x10;            switch( stEndpointInfo[i].nSize )            {                case 16:        fPacketSize = USB_TXFIFO2_SZ_16;        break;                case 32:        fPacketSize = USB_TXFIFO2_SZ_32;        break;                case 64:        fPacketSize = USB_TXFIFO2_SZ_64;        break;                case 128:       fPacketSize = USB_TXFIFO2_SZ_128;       break;                case 256:       fPacketSize = USB_TXFIFO2_SZ_256;       break;                case 512:       fPacketSize = USB_TXFIFO2_SZ_512;       break;                case 1024:      fPacketSize = USB_TXFIFO2_SZ_1024;      break;            }		    // DM320 USB registers  :   OUT direction            // USB specification    :   IN direction that mean device-to-host            if( stEndpointInfo[i].fAddr & 0x80 )            {                writeb( USB_TXCSR1_CLRDATTOG | USB_TXCSR1_FLFIFO | USB_TXCSR1_UNDERRUN, USB_PER_TXCSR1 );                writeb( USB_TXCSR1_FLFIFO, USB_PER_TXCSR1 );    // clear FIFO for double buffer                writeb( USB_TXCSR2_FRDATTOG | USB_TXCSR2_MODE_TX, USB_TXCSR2 );                       // no DMA sending                writeb( fLowAddr,                               USB_TXFIFO1 );                writeb( fHighAddr | fPacketSize | fIsDualBuf,   USB_TXFIFO2 );                writeb( stEndpointInfo[i].nSize / 8,            USB_TXMAXP );            }            // DM320 USB registers  :   IN direction            // USB specification    :   OUT direction that mean host-to-device            else            {                // clear Data toggle, FIFO, OVERRUN of RXCSR1                writeb( USB_RXCSR1_CLRDATTOG | USB_RXCSR1_FLFIFO, USB_PER_RXCSR1 );                                           writeb( USB_RXCSR1_FLFIFO, USB_PER_RXCSR1 );    // clear FIFO for double buffer                writeb( 0x00, USB_PER_RXCSR2);                                 // no DMA receiving//              writeb( USB_RXCSR2_AUTOCLR, USB_PER_RXCSR2 );                                 // AUTOCLR for DMA receiving                writeb( fLowAddr,                               USB_RXFIFO1 );                writeb( fHighAddr | fPacketSize | fIsDualBuf,   USB_RXFIFO2 );                Vishal: writeb( stEndpointInfo[i].nSize / 8,            USB_RXMAXP );            }            nBufPos += stEndpointInfo[i].nSize;        }        else            writeb( 0x00, USB_RXMAXP );    }}static void dm320_init_per_mode(){    outw( inw( IO_CLK_MOD2 ) | 0x0060, IO_CLK_MOD2 );           // 		0x0040 : USB clock enable	                                                            // 		0x0020 : GIO clock enable	outw( inw( IO_CLK_LPCTL1 ) & 0xFFEF, IO_CLK_LPCTL1 );       // USB Power down mode off																// 		0x0010 : Set USB power down mode.	writel( 0x00000000, AHB_USBCTL );                     		// USB controller in peripheral mode. ( 0x00000008 : host mode )	writeb( USB_DEVCTL_SESSREQ, USB_DEVCTL );     /* ATTENTION : vishal :for bug fix only!!    **ATTENTION** */	// Setup USB core registers	writeb( 0x00, USB_FADDR );									// reset peripheral address register	writeb( 0x00, USB_POWER );									// reset power control register}static void dm320_clear_intrs(){	outw( ( 1 << IRQ_USB_DMA  ), IO_INTC_IRQ0 );				// clear USB core interrupt flag	outw( ( 1 << IRQ_USB_CORE ), IO_INTC_IRQ0 );				// clear USB DMA interrupt flag	readb( USB_INTRTX1 );                    					// clear TX interrupt flags	readb( USB_INTRRX1 );                       				// clear RX interrupt flags	readb( USB_INTRUSB );                      					// clear control interrupt flags	readb( USBDMA_INTR );}static void dm320_enable_intrs(){	writeb( ( BULK_OUT_EP << 1 ) | USB_EP0, USB_INTRTX1E );		// enable endpoint transmmit interrupt ( including EP0 RX/TX )	writeb( ( BULK_IN_EP << 1 ), USB_INTRRX1E );   				// enable endpoint receving interrupt	writeb( USB_RESET | USB_RESUME | USB_SUSPEND | USB_SESSREQ | USB_SOF , USB_INTRUSBE );		// Peripheral mode & 'B' type( slave )	}static void dm320_reconnect_init(struct dm320 *dev){    dev->gadget.speed = USB_SPEED_UNKNOWN;	printk("device speed is UNKNOWN\n");    paddr_status  = 0 ;    dev->peripheral_addr = 0;}static void 	dm320_usb_hw_init(struct dm320 *dev ){    dm320_init_per_mode();	dm320_clear_intrs();		dm320_enable_intrs();	dm320_setup_ep_regs(dev);	dev->peripheral_addr = 0;	dm320_set_addr_reg(0);	writeb( USB_EP0_SELECT, USB_INDEX );         	// set default endpoint as EP0}static void usb_reset (struct dm320 *dev){	printk("dm320  : %s\n", __FUNCTION__);;	dev->gadget.speed = USB_SPEED_UNKNOWN; 	dm320_usb_hw_init(dev );	printk("device speed is UNKNOWN\n");	INIT_LIST_HEAD (&dev->gadget.ep_list);    list_add_tail (&dev->ep [1].ep.ep_list, &dev->gadget.ep_list);    list_add_tail (&dev->ep [2].ep.ep_list, &dev->gadget.ep_list);    list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list);}static int  dm320_init_gio(){	outw( inw( IO_CLK_DIV4 ) | ( ( ( 4 ) - 1 ) << 8 ) | ( ( 1 ) - 1 ), IO_CLK_DIV4 );    if(request_gio( GIO_DP_PULLUP )!=0 )            // D+ pullup control GIO    {        printk(" dm320  : GIO for D+ Pullup already taken\n");        return -EBUSY;     }    gio_set_dir( GIO_DP_PULLUP, 0 );        // output direction    gio_set_bitset( GIO_DP_PULLUP );        // set D+ pullup    if(request_gio( GIO_USB_ATTACH )!=0)    {        printk(" dm320  : USB Attach Interrupt handler GIO Interrupt already taken\n");        return -EBUSY;    }    gio_enable_irq( GIO_USB_ATTACH, GIO_ANY_EDGE );    outw(inw(IO_GIO_CHAT0) | (1 << GIO_USB_ATTACH),IO_GIO_CHAT0);	return 0;}static int dm320_register_irqs(){    if( request_irq( IRQ_USB_ATTACH, handle_attach_irqs, SA_INTERRUPT, "usb_external", handle_attach_irqs )!= 0 )    {        printk("dm320 USB: Attach IRQ could not be registered  \n");        return -EBUSY;    }        // Register USB core control interrupt handler    if(request_irq( IRQ_USB_CORE, handle_core_irqs, SA_INTERRUPT, "usb_core", handle_core_irqs )!=0 )    {        printk("dm320 USB: Core IRQ could not be registered\n");        return -EBUSY;    }	return 0;}static int dm320_probe (void){	int			retval;	if (the_controller!= NULL) {  		/* Check if the driver for the DM320 device mode is already running */		printk(" dm320: driver already running.\n");		return -EBUSY;		/* return busy status and exit driver...am i addicted to commenting code? */		}	the_controller = kmalloc (sizeof(struct dm320), SLAB_KERNEL);	if (the_controller == NULL) {		printk("dm320: cannot allocate memory for USB function driver!\n");		retval = -ENOMEM;		goto done;	}	memset (the_controller, 0, sizeof(struct dm320));	spin_lock_init (&the_controller->lock);	the_controller->gadget.ops = &dm320_ops;    	the_controller->gadget.is_dualspeed = 0;  /* The DM320 is a full speed controlelr only!! */	strcpy (the_controller->gadget.dev.bus_id, "DM320 Gadget");	the_controller->gadget.dev.release = gadget_release;		the_controller->gadget.name = driver_name;	the_controller->enabled = 1;	the_controller->chiprev = inw( IO_BUSC_REVR );	printk("dm320: %s :Board revision : %d.%d\n",__FUNCTION__, the_controller->chiprev >> 4, the_controller->chiprev & 0xF );	outw( inw( IO_CLK_MOD2 ) | 0x0060, IO_CLK_MOD2 );           // Enable USB clock & GIO clock  	if(dm320_init_gio() != 0 )		goto done;   	if(dm320_register_irqs() != 0 )		goto done;    the_controller->attach_irq = IRQ_USB_ATTACH;    the_controller->core_irq = IRQ_USB_CORE;	usb_reset (the_controller);	usb_reinit (the_controller);    if( (dm320_connection_status( ) ) > 0 )	{#if 0		usb_reset (the_controller);        outw(inw(IO_INTC_FISEL0) & 0x7F, IO_INTC_FISEL0);        outw(inw(IO_INTC_EINT0) |  0x80, IO_INTC_EINT0);        dm320_reconnect_init(the_controller);#endif	}       writeb( USB_DEVCTL_SESSREQ, USB_DEVCTL );  // For 'B' device initiate session request protocol		INFO (the_controller, "%s\n", driver_desc);	INFO (the_controller, "core irq %d, attach irq %d, dma irq %d\n",			the_controller->core_irq, the_controller->attach_irq, the_controller->dma_irq);	INFO (the_controller, "version: %s\n", DRIVER_VERSION);	device_register (&the_controller->gadget.dev);		return 0;done:	if (the_controller)		dm320_remove (the_controller);	}static int __init init (void){	return dm320_probe ();}static void __exit cleanup (void){ 	dm320_remove (the_controller);    }module_init (init);module_exit (cleanup);MODULE_DESCRIPTION (DRIVER_DESC);MODULE_AUTHOR ("Ingenient Technologies");MODULE_LICENSE ("GPL");

⌨️ 快捷键说明

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