📄 usb_ctl.c
字号:
if (usbd_info.client_name != NULL) return -EBUSY; usbd_info.client_name = (char *) client; memset(&usbd_info.stats, 0, sizeof(struct usb_stats_t)); memset(string_desc_array, 0, sizeof(string_desc_array)); /* hack to start in zombie suspended state */#if 0 sm_state = kStateZombieSuspend; usbd_info.state = USB_STATE_SUSPENDED;#endif /* create descriptors for enumeration */ initialize_descriptors(); LOG("%sOpened for %s\n", pszMe, client); return 0;}/* Start running. Must have called usb_open (above) first */int s3c24x0_usb_start(void){ unsigned long tmp; LOG("\n"); if (usbd_info.client_name == NULL) { printf("%s%s - no client registered\n", pszMe, __FUNCTION__); return -EPERM; } /* start UDC internal machinery running */ udelay(100); /* clear stall - receiver seems to start stalled? */ if (DNW) { UD_INDEX = UD_INDEX_EP3; } else { UD_INDEX = UD_INDEX_EP2; // EP2 input } tmp = UD_ICSR1; tmp &= ~(UD_ICSR1_SENTSTL | UD_ICSR1_FFLUSH | UD_ICSR1_UNDRUN); tmp &= ~(UD_ICSR1_PKTRDY | UD_ICSR1_SENDSTL); UD_ICSR1 = tmp; UD_INDEX = UD_INDEX_EP1; // EP1 output tmp = UD_OCSR1; tmp &= ~(UD_OCSR1_SENTSTL | UD_OCSR1_FFLUSH | UD_OCSR1_OVRRUN); tmp &= ~(UD_OCSR1_PKTRDY | UD_OCSR1_SENDSTL); UD_OCSR1 = tmp; /* flush DMA and fire through some -EAGAINs */ // ep2_init( usbd_info.dmach_tx ); // ep1_init( usbd_info.dmach_rx ); /* clear all top-level sources */ if (DNW) { UD_INT = UD_INT_EP0 | UD_INT_EP1 | UD_INT_EP3; } else { UD_INT = UD_INT_EP0 | UD_INT_EP1 | UD_INT_EP2; } UD_USBINT = UD_USBINT_RESET | UD_USBINT_RESUM | UD_USBINT_SUSPND; LOG("%sStarted for %s\n", pszMe, usbd_info.client_name); usbd_dn_cnt = 0; printf("USB Device started for download, counter=%d.\n", usbd_dn_cnt); return 0;}/* Stop USB core from running */int s3c24x0_usb_stop(void){ LOG("name=%s\n", usbd_info.client_name ? usbd_info.client_name : "NULL"); if (usbd_info.client_name == NULL) { printf("%s%s - no client registered\n", pszMe, __FUNCTION__); return -EPERM; }#if 0 /* It may be default value of S3C24x0 USBD and makes only RESET be enalble */ UD_INTM = 0x13f;#endif ep1_reset(); ep2_reset(); printf("%sStopped \n", pszMe); return 0;}/* Tell S3C24x0 core client is through using it */int s3c24x0_usb_close(void){ if (usbd_info.client_name == NULL) { printf("%s%s - no client registered\n", pszMe, __FUNCTION__); return -EPERM; } usbd_info.client_name = NULL; return 0;}/* set a proc to be called when device is configured */usb_notify_t s3c24x0_set_configured_callback(usb_notify_t func){ usb_notify_t retval = configured_callback; LOG("\n"); 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 *s3c24x0_usb_get_descriptor_ptr(void){ return &desc;}/* optional: set a string descriptor */int s3c24x0_usb_set_string_descriptor(int i, string_desc_t * p){ int retval; LOG("\n"); 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 *s3c24x0_usb_get_string_descriptor(int i){ LOG("\n"); return (i < MAX_STRING_DESC) ? string_desc_array[i] : NULL;}/* optional: kmalloc and unicode up a string descriptor */string_desc_t *s3c24x0_usb_kmalloc_string_descriptor(const char *p){ string_desc_t *pResult = NULL; LOG("\n"); if (p) { int len = strlen(p); int uni_len = len * sizeof(__u16); // pResult = (string_desc_t*) kmalloc( uni_len + 2, GFP_KERNEL ); /* ugh! */ if (pResult != NULL) { int i; pResult->bLength = uni_len + 2; pResult->bDescriptorType = USB_DESC_STRING; for (i = 0; i < len; i++) { pResult->bString[i] = make_word((__u16) p[i]); } } } return pResult;}//////////////////////////////////////////////////////////////////////////////// Exports to rest of driver///////////////////////////////////////////////////////////////////////////////* called by the int handler here and the two endpoint files when interesting .."events" happen */int usbctl_next_state_on_event(int event){ return 1;#if 0 int next_state = device_state_machine[sm_state][event]; LOG("\n"); if (next_state != kError) { int next_device_state = sm_state_to_device_state[next_state]; printf("%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]); 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; } }#if 0 else printf("%s%s --> [%s] --> ??? is an error.\n", pszMe, state_names[sm_state], event_names[event]);#endif return next_state;#endif}//////////////////////////////////////////////////////////////////////////////// Private Helpers////////////////////////////////////////////////////////////////////////////////* setup default descriptors */static void initialize_descriptors(void){ LOG("\n"); desc.dev.bLength = sizeof(device_desc_t); desc.dev.bDescriptorType = USB_DESC_DEVICE; desc.dev.bcdUSB = 0x100; /* 1.1 */ desc.dev.bDeviceClass = 0xFF; /* vendor specific */ desc.dev.bDeviceSubClass = 0x0; desc.dev.bDeviceProtocol = 0x0; desc.dev.bMaxPacketSize0 = 0x8; /* ep0 max fifo size in s3c24x0 */ desc.dev.idVendor = 0x49f; /* vendor ID undefined */ desc.dev.idProduct = 0x505a; /* product */ desc.dev.bcdDevice = 0x01; /* 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 = 0x1; 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 = 0x0; /* unique intf index */ desc.b.intf.bAlternateSetting = 0x0; desc.b.intf.bNumEndpoints = 2; /* endpoint number excluding ep0 */ desc.b.intf.bInterfaceClass = 0xFF; /* vendor specific */ desc.b.intf.bInterfaceSubClass = 0x0; desc.b.intf.bInterfaceProtocol = 0x0; desc.b.intf.iInterface = 0x0; desc.b.ep1.bLength = sizeof(ep_desc_t); desc.b.ep1.bDescriptorType = USB_DESC_ENDPOINT; if (DNW) { desc.b.ep1.bEndpointAddress = USB_EP_ADDRESS(1, USB_IN); } else { desc.b.ep1.bEndpointAddress = USB_EP_ADDRESS(1, USB_OUT); } desc.b.ep1.bmAttributes = USB_EP_BULK; desc.b.ep1.wMaxPacketSize = make_word_c(64); desc.b.ep1.bInterval = 0x0; desc.b.ep2.bLength = sizeof(ep_desc_t); desc.b.ep2.bDescriptorType = USB_DESC_ENDPOINT; if (DNW) { desc.b.ep2.bEndpointAddress = USB_EP_ADDRESS(3, USB_OUT); } else { desc.b.ep2.bEndpointAddress = USB_EP_ADDRESS(2, USB_IN); } desc.b.ep2.bmAttributes = USB_EP_BULK; desc.b.ep2.wMaxPacketSize = make_word_c(64); desc.b.ep2.bInterval = 0x0; /* 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 */ s3c24x0_usb_set_string_descriptor(0, &sd_zero);}//////////////////////////////////////////////////////////////////////////////// Module Initialization and Shutdown///////////////////////////////////////////////////////////////////////////////* * usbctl_init() * Module load time. Allocate dma and interrupt resources. Setup /proc fs * entry. Leave UDC disabled. *bctl_init() * Module load time. Allocate dma and interrupt resources. Setup /proc fs * entry. Leave UDC disabled. */int usbctl_init( void ){ memset( &usbd_info, 0, sizeof( usbd_info ) ); /* MISC. register */ //MISCCR &= ~MISCCR_USBPAD; /* S3C24x0, S3C2440a */ CLKCON |= CLKCON_USBD;#if 0 UPLLCON = FInsrt(60, fPLL_MDIV) | FInsrt(4, fPLL_PDIV) | FInsrt(2, fPLL_SDIV);#endif#if 0 printf("EXNERNAL FIN (%8d ) 0x%08X \n",CONFIG_SYS_CLK_FREQ,CONFIG_SYS_CLK_FREQ); printf("UPLLCON 0x%08X CLKDIVN 0x%08X CAMDIVN 0x%08X MISCCR 0x%08X\n", UPLLCON,CLKDIVN,CAMDIVN, MISCCR);#endif /* interrupt enable */ INTMSK &= ~(BIT_USBD);#if 0 printf("INTMSK 0x%08X CLKSLOW 0x%08X \n", INTMSK, CLKSLOW);#endif LOG( "S3C24x0 USB Controller Core Initialized"); usbd_dn_cnt=0; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -