📄 usb_ctl_pxa.c
字号:
return -EPERM; } /* mask everything */ /* disable suspend/resume, reset */ udc_set_mask_UDCCR( UDCCR_SRM | UDCCR_REM); /* disable ep0, ep1, ep2 */ UICR0 |= (UICR0_IM0 | UICR0_IM1 | UICR0_IM2) ; ep1_reset(); ep2_reset(); udc_disable(); //if( usb_debug) printk( "%sStopped %s\n", pszMe, usbd_info.client_name ); return 0;}/* Tell PXA core client is through using it */intpxa_usb_close( void ){ if ( usbd_info.client_name == NULL ) { /* printk( "%s%s - no client registered\n", pszMe, __FUNCTION__ ); */ return -EPERM; } //printk( "%s%s closed.\n", pszMe, (char*)usbd_info.client_name ); usbd_info.client_name = NULL; return 0;}/* set a proc to be called when device is configured */usb_notify_t pxa_set_configured_callback( usb_notify_t func ){ usb_notify_t retval = configured_callback; configured_callback = func; return retval;}/*==================================================== * Descriptor Manipulation. * Use these between open() and start() above to setup * the descriptors for your device. * *//* get pointer to static default descriptor */desc_t *pxa_usb_get_descriptor_ptr( void ) { return &desc; }/* optional: set a string descriptor */intpxa_usb_set_string_descriptor( int i, string_desc_t * p ){ int retval; if ( i < MAX_STRING_DESC ) { string_desc_array[i] = p; retval = 0; } else { retval = -EINVAL; } return retval;}/* optional: get a previously set string descriptor */string_desc_t *pxa_usb_get_string_descriptor( int i ){ return ( i < MAX_STRING_DESC ) ? string_desc_array[i] : NULL;}config_desc_t *pxa_usb_get_config(int cfgval) { int i; desc_t * pdesc = pxa_usb_get_descriptor_ptr(); config_desc_t *cfg = (config_desc_t*) (pdesc->cdb); for( i=0; i<pdesc->dev.bNumConfigurations; i++) { if( cfg->bConfigurationValue == cfgval ) return cfg; cfg = (config_desc_t*) ((unsigned char*)cfg + cfg->wTotalLength); } return NULL;}intf_desc_t *pxa_usb_get_interface( config_desc_t *cfg, int idx){ int i; intf_desc_t *intf = (intf_desc_t*) (cfg + 1); for( i=0; i < cfg->bNumInterfaces; i++) { if( idx == intf->bInterfaceNumber) return intf; intf++; } return NULL;}ep_desc_t *pxa_usb_get_endpoint( intf_desc_t *intf, int idx){ int i; ep_desc_t *ep = (ep_desc_t *) (intf+1); for( i=0; i< intf->bNumEndpoints; i++) { if( idx == (ep->bEndpointAddress & 0xF) ) return ep; ep++; } return NULL;}//////////////////////////////////////////////////////////////////////////////// Exports to rest of driver///////////////////////////////////////////////////////////////////////////////* called by the int handler here and the two endpoint files when interesting .."events" happen */intusbctl_next_state_on_event( int event ){ int next_state = device_state_machine[ sm_state ][ event ]; if ( next_state != kError ) { int next_device_state = sm_state_to_device_state[ next_state ]; /* if( usb_debug) printk( "%s%s --> [%s] --> %s. Device in %s state.\n", pszMe, state_names[ sm_state ], event_names[ event ], state_names[ next_state ], device_state_names[ next_device_state ] ); */ /* SerialOutputString(pszMe); SerialOutputString(state_names[sm_state]); SerialOutputString(" --> "); SerialOutputString(event_names[event]); SerialOutputString(" --> "); SerialOutputString(state_names[next_state]); SerialOutputString("device in state:"); SerialOutputString(device_state_names[next_device_state]); SerialOutputString("\n"); */ sm_state = next_state; if ( usbd_info.state != next_device_state ) { if ( configured_callback != NULL && next_device_state == USB_STATE_CONFIGURED && usbd_info.state != USB_STATE_SUSPENDED ) { configured_callback(); } usbd_info.state = next_device_state; ep1_state_change_notify( next_device_state ); ep2_state_change_notify( next_device_state ); } } /* else printk( "%s%s --> [%s] --> ??? is an error.\n", pszMe, state_names[ sm_state ], event_names[ event ] ); */ return next_state;}//////////////////////////////////////////////////////////////////////////////// Private Helpers///////////////////////////////////////////////////////////////////////////////* setup default descriptors */static voidinitialize_descriptors(void){ desc.dev.bLength = sizeof( device_desc_t ); desc.dev.bDescriptorType = USB_DESC_DEVICE; desc.dev.bcdUSB = 0x100; /* 1.0 */ desc.dev.bDeviceClass = 0xFF; /* vendor specific */ desc.dev.bDeviceSubClass = 0; desc.dev.bDeviceProtocol = 0; desc.dev.bMaxPacketSize0 = 16; /* ep0 max fifo size */ desc.dev.idVendor = 0; /* vendor ID undefined */ desc.dev.idProduct = 0; /* product */ desc.dev.bcdDevice = 0; /* vendor assigned device release num */ desc.dev.iManufacturer = 0; /* index of manufacturer string */ desc.dev.iProduct = 0; /* index of product description string */ desc.dev.iSerialNumber = 0; /* index of string holding product s/n */ desc.dev.bNumConfigurations = 1; /* configurations we have */ /* desc.b.cfg.bLength = sizeof( config_desc_t ); desc.b.cfg.bDescriptorType = USB_DESC_CONFIG; desc.b.cfg.wTotalLength = make_word_c( sizeof(struct cdb) ); desc.b.cfg.bNumInterfaces = 1; desc.b.cfg.bConfigurationValue = 1; desc.b.cfg.iConfiguration = 0; desc.b.cfg.bmAttributes = USB_CONFIG_BUSPOWERED; desc.b.cfg.MaxPower = USB_POWER( 500 ); desc.b.intf.bLength = sizeof( intf_desc_t ); desc.b.intf.bDescriptorType = USB_DESC_INTERFACE; desc.b.intf.bInterfaceNumber = 0; desc.b.intf.bAlternateSetting = 0; desc.b.intf.bNumEndpoints = 2; desc.b.intf.bInterfaceClass = 0xFF; desc.b.intf.bInterfaceSubClass = 0; desc.b.intf.bInterfaceProtocol = 0; desc.b.intf.iInterface = 0; *//* * FIXME... * The host usbnet driver expects EP1=out EP2=in. On the PXA UDC EP1=in, EP2=out */ /* desc.b.ep1.bLength = sizeof( ep_desc_t ); desc.b.ep1.bDescriptorType = USB_DESC_ENDPOINT; desc.b.ep1.bEndpointAddress = USB_EP_ADDRESS( 1, USB_IN ); desc.b.ep1.bmAttributes = USB_EP_BULK; desc.b.ep1.wMaxPacketSize = make_word_c( 64 ); desc.b.ep1.bInterval = 0; desc.b.ep2.bLength = sizeof( ep_desc_t ); desc.b.ep2.bDescriptorType = USB_DESC_ENDPOINT; desc.b.ep2.bEndpointAddress = USB_EP_ADDRESS( 2, USB_OUT ); desc.b.ep2.bmAttributes = USB_EP_BULK; desc.b.ep2.wMaxPacketSize = make_word_c( 64 ); desc.b.ep2.bInterval = 0; */// FIXME: Add support for all endpoint... /* set language */ /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */ sd_zero.bDescriptorType = USB_DESC_STRING; sd_zero.bLength = sizeof( string_desc_t ); sd_zero.bString[0] = make_word_c( 0x409 ); /* American English */ pxa_usb_set_string_descriptor( 0, &sd_zero );}/* soft_connect_hook() * Some devices have platform-specific circuitry to make USB * not seem to be plugged in, even when it is. This allows * software to control when a device 'appears' on the USB bus * (after Linux has booted and this driver has loaded, for * example). If you have such a circuit, control it here. */static voidsoft_connect_hook( int enable ){}/* disable the UDC at the source */static voidudc_disable(void){ soft_connect_hook( 0 ); /* clear UDC-enable */ udc_clear_mask_UDCCR( UDCCR_UDE); /* Disable clock for USB device */ CKEN &= ~CKEN11_USB;}/* enable the udc at the source */static voidudc_enable(void){ /* Enable clock for USB device */ CKEN |= CKEN11_USB; /* try to clear these bits before we enable the udc */ udc_ack_int_UDCCR( UDCCR_SUSIR); udc_ack_int_UDCCR( UDCCR_RSTIR); udc_ack_int_UDCCR( UDCCR_RESIR); /* set UDC-enable */ udc_set_mask_UDCCR( UDCCR_UDE); if( (UDCCR & UDCCR_UDA) == 0) { /* There's a reset on the bus, * clear the interrupt bit and keep going */ SerialOutputString("reset on bus\n"); udc_ack_int_UDCCR( UDCCR_RSTIR); } /* "USB test mode" to work around errata 40-42 (stepping a0, a1) * which could result in missing packets and interrupts. * Supposedly this turns off double buffering for all endpoints. */ //if( usb_debug) printk( "USB RES1=%x RES2=%x RES3=%x\n", UDC_RES1, UDC_RES2, UDC_RES3); /* SerialOutputString(" RES1="); SerialOutputHex(UDC_RES1); SerialOutputString(" RES2="); SerialOutputHex(UDC_RES2); SerialOutputString(" RES3="); SerialOutputHex(UDC_RES3); SerialOutputString("\n"); */ UDC_RES1 = 0x00; UDC_RES2 = 0x00; //if( usb_debug) printk( "USB RES1=%x RES2=%x RES3=%x\n", UDC_RES1, UDC_RES2, UDC_RES3); /* SerialOutputString(" RES1="); SerialOutputHex(UDC_RES1); SerialOutputString(" RES2="); SerialOutputHex(UDC_RES2); SerialOutputString(" RES3="); SerialOutputHex(UDC_RES3); SerialOutputString("\n"); */}//////////////////////////////////////////////////////////////////////////////// Module Initialization and Shutdown///////////////////////////////////////////////////////////////////////////////* * usbctl_init() * Module load time. Allocate dma and interrupt resources. Setup /proc fs * entry. Leave UDC disabled. */int usbctl_init( void ){ int retval = 0, rc; udc_disable(); memset( &usbd_info, 0, sizeof( usbd_info ) ); //printk( "PXA USB Controller Core Initialized\n"); //SerialOutputString("PXA USB Controller Core Initialized\n"); rc = pxa_usb_open("myusb"); pxa_usb_start(); return 0;}/* * usbctl_exit() * Release DMA and interrupt resources */void usbctl_exit( void ){ //printk("Unloading PXA USB Controller\n"); udc_disable();}__initlist(usbctl_init, INIT_LEVEL_INITIAL_HARDWARE);__exitlist(usbctl_exit, INIT_LEVEL_INITIAL_HARDWARE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -