Merge branch 'master' of git://git.denx.de/u-boot-usb

* 'master' of git://git.denx.de/u-boot-usb:
  Enable high speed support for USB device framework and usbtty
This commit is contained in:
Wolfgang Denk 2012-03-30 23:56:04 +02:00
commit a7ed871b72
7 changed files with 116 additions and 7 deletions

8
README
View File

@ -1151,6 +1151,14 @@ The following options need to be configured:
Define this to have a tty type of device available to Define this to have a tty type of device available to
talk to the UDC device talk to the UDC device
CONFIG_USBD_HS
Define this to enable the high speed support for usb
device and usbtty. If this feature is enabled, a routine
int is_usbd_high_speed(void)
also needs to be defined by the driver to dynamically poll
whether the enumeration has succeded at high speed or full
speed.
CONFIG_SYS_CONSOLE_IS_IN_ENV CONFIG_SYS_CONSOLE_IS_IN_ENV
Define this if you want stdin, stdout &/or stderr to Define this if you want stdin, stdout &/or stderr to
be set to usbtty. be set to usbtty.

View File

@ -133,6 +133,19 @@ static struct usb_device_descriptor device_descriptor = {
}; };
#if defined(CONFIG_USBD_HS)
static struct usb_qualifier_descriptor qualifier_descriptor = {
.bLength = sizeof(struct usb_qualifier_descriptor),
.bDescriptorType = USB_DT_QUAL,
.bcdUSB = cpu_to_le16(USB_BCD_VERSION),
.bDeviceClass = COMMUNICATIONS_DEVICE_CLASS,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
.bNumConfigurations = NUM_CONFIGS
};
#endif
/* /*
* Static CDC ACM specific descriptors * Static CDC ACM specific descriptors
*/ */
@ -638,6 +651,9 @@ static void usbtty_init_instances (void)
memset (device_instance, 0, sizeof (struct usb_device_instance)); memset (device_instance, 0, sizeof (struct usb_device_instance));
device_instance->device_state = STATE_INIT; device_instance->device_state = STATE_INIT;
device_instance->device_descriptor = &device_descriptor; device_instance->device_descriptor = &device_descriptor;
#if defined(CONFIG_USBD_HS)
device_instance->qualifier_descriptor = &qualifier_descriptor;
#endif
device_instance->event = usbtty_event_handler; device_instance->event = usbtty_event_handler;
device_instance->cdc_recv_setup = usbtty_cdc_setup; device_instance->cdc_recv_setup = usbtty_cdc_setup;
device_instance->bus = bus_instance; device_instance->bus = bus_instance;
@ -751,6 +767,10 @@ static void usbtty_init_terminal_type(short type)
device_descriptor.idProduct = device_descriptor.idProduct =
cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM); cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
#if defined(CONFIG_USBD_HS)
qualifier_descriptor.bDeviceClass =
COMMUNICATIONS_DEVICE_CLASS;
#endif
/* Assign endpoint indices */ /* Assign endpoint indices */
tx_endpoint = ACM_TX_ENDPOINT; tx_endpoint = ACM_TX_ENDPOINT;
rx_endpoint = ACM_RX_ENDPOINT; rx_endpoint = ACM_RX_ENDPOINT;
@ -779,7 +799,9 @@ static void usbtty_init_terminal_type(short type)
device_descriptor.bDeviceClass = 0xFF; device_descriptor.bDeviceClass = 0xFF;
device_descriptor.idProduct = device_descriptor.idProduct =
cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL); cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
#if defined(CONFIG_USBD_HS)
qualifier_descriptor.bDeviceClass = 0xFF;
#endif
/* Assign endpoint indices */ /* Assign endpoint indices */
tx_endpoint = GSERIAL_TX_ENDPOINT; tx_endpoint = GSERIAL_TX_ENDPOINT;
rx_endpoint = GSERIAL_RX_ENDPOINT; rx_endpoint = GSERIAL_RX_ENDPOINT;
@ -932,6 +954,9 @@ static int usbtty_configured (void)
static void usbtty_event_handler (struct usb_device_instance *device, static void usbtty_event_handler (struct usb_device_instance *device,
usb_device_event_t event, int data) usb_device_event_t event, int data)
{ {
#if defined(CONFIG_USBD_HS)
int i;
#endif
switch (event) { switch (event) {
case DEVICE_RESET: case DEVICE_RESET:
case DEVICE_BUS_INACTIVE: case DEVICE_BUS_INACTIVE:
@ -942,6 +967,29 @@ static void usbtty_event_handler (struct usb_device_instance *device,
break; break;
case DEVICE_ADDRESS_ASSIGNED: case DEVICE_ADDRESS_ASSIGNED:
#if defined(CONFIG_USBD_HS)
/*
* is_usbd_high_speed routine needs to be defined by
* specific gadget driver
* It returns TRUE if device enumerates at High speed
* Retuns FALSE otherwise
*/
for (i = 0; i < NUM_ENDPOINTS; i++) {
if (((ep_descriptor_ptrs[i]->bmAttributes &
USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)
&& is_usbd_high_speed()) {
ep_descriptor_ptrs[i]->wMaxPacketSize =
CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE;
}
endpoint_instance[i + 1].tx_packetSize =
ep_descriptor_ptrs[i]->wMaxPacketSize;
endpoint_instance[i + 1].rcv_packetSize =
ep_descriptor_ptrs[i]->wMaxPacketSize;
}
#endif
usbtty_init_endpoints (); usbtty_init_endpoints ();
default: default:

View File

@ -70,6 +70,10 @@
#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE #define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE
#define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE #define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE
#if defined(CONFIG_USBD_HS)
#define CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE UDC_BULK_HS_PACKET_SIZE
#endif
#define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS #define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS
#define USBTTY_BCD_DEVICE 0x00 #define USBTTY_BCD_DEVICE 0x00

View File

@ -212,7 +212,6 @@ struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_i
return (device->device_descriptor); return (device->device_descriptor);
} }
/** /**
* usbd_device_configuration_descriptor * usbd_device_configuration_descriptor
* @device: which device * @device: which device

View File

@ -338,12 +338,27 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
} }
break; break;
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
#if defined(CONFIG_USBD_HS)
{ {
/* If a USB device supports both a full speed and low speed operation struct usb_qualifier_descriptor *qualifier_descriptor =
* we must send a Device_Qualifier descriptor here device->qualifier_descriptor;
*/
if (!qualifier_descriptor)
return -1; return -1;
/* copy descriptor for this device */
copy_config(urb, qualifier_descriptor,
sizeof(struct usb_qualifier_descriptor),
max);
} }
dbg_ep0(3, "copied qualifier descriptor, actual_length: 0x%x",
urb->actual_length);
#else
return -1;
#endif
break;
default: default:
return -1; return -1;
} }

View File

@ -241,6 +241,21 @@ struct usb_device_descriptor {
u8 bNumConfigurations; u8 bNumConfigurations;
} __attribute__ ((packed)); } __attribute__ ((packed));
#if defined(CONFIG_USBD_HS)
struct usb_qualifier_descriptor {
u8 bLength;
u8 bDescriptorType;
u16 bcdUSB;
u8 bDeviceClass;
u8 bDeviceSubClass;
u8 bDeviceProtocol;
u8 bMaxPacketSize0;
u8 bNumConfigurations;
u8 breserved;
} __attribute__ ((packed));
#endif
struct usb_string_descriptor { struct usb_string_descriptor {
u8 bLength; u8 bLength;
u8 bDescriptorType; /* 0x03 */ u8 bDescriptorType; /* 0x03 */

View File

@ -210,6 +210,10 @@ struct usb_bus_instance;
#define USB_DT_INTERFACE 0x04 #define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05 #define USB_DT_ENDPOINT 0x05
#if defined(CONFIG_USBD_HS)
#define USB_DT_QUAL 0x06
#endif
#define USB_DT_HID (USB_TYPE_CLASS | 0x01) #define USB_DT_HID (USB_TYPE_CLASS | 0x01)
#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02) #define USB_DT_REPORT (USB_TYPE_CLASS | 0x02)
#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) #define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
@ -291,7 +295,11 @@ struct usb_bus_instance;
* USB Spec Release number * USB Spec Release number
*/ */
#if defined(CONFIG_USBD_HS)
#define USB_BCD_VERSION 0x0200
#else
#define USB_BCD_VERSION 0x0110 #define USB_BCD_VERSION 0x0110
#endif
/* /*
@ -565,6 +573,9 @@ struct usb_device_instance {
/* generic */ /* generic */
char *name; char *name;
struct usb_device_descriptor *device_descriptor; /* per device descriptor */ struct usb_device_descriptor *device_descriptor; /* per device descriptor */
#if defined(CONFIG_USBD_HS)
struct usb_qualifier_descriptor *qualifier_descriptor;
#endif
void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data); void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data);
@ -657,8 +668,17 @@ struct usb_class_report_descriptor *usbd_device_class_report_descriptor_index( s
struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *, int, int, int, int, int); struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *, int, int, int, int, int);
int usbd_device_endpoint_transfersize (struct usb_device_instance *, int, int, int, int, int); int usbd_device_endpoint_transfersize (struct usb_device_instance *, int, int, int, int, int);
struct usb_string_descriptor *usbd_get_string (u8); struct usb_string_descriptor *usbd_get_string (u8);
struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *, int); struct usb_device_descriptor *usbd_device_device_descriptor(struct
usb_device_instance *, int);
#if defined(CONFIG_USBD_HS)
/*
* is_usbd_high_speed routine needs to be defined by specific gadget driver
* It returns TRUE if device enumerates at High speed
* Retuns FALSE otherwise
*/
int is_usbd_high_speed(void);
#endif
int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint); int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint);
void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad); void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
void usbd_tx_complete (struct usb_endpoint_instance *endpoint); void usbd_tx_complete (struct usb_endpoint_instance *endpoint);