Skip to content

Commit

Permalink
Enable high speed support for USB device framework and usbtty
Browse files Browse the repository at this point in the history
This patch adds the support for high speed in usb device framework and usbtty
driver. This feature has been kept within a macro CONFIG_USBD_HS, so the board
configuration files have to define this macro to enable high speed support.

Along with that specific peripheral drivers also need to define a function to
let the framework know that the enumeration has happened at high speed.
This function prototype is "int is_usbd_high_speed(void)"

Signed-off-by: Vipin Kumar <[email protected]>
Signed-off-by: Amit Virdi <[email protected]>
  • Loading branch information
Vipin KUMAR authored and marex committed Mar 28, 2012
1 parent 7cb30b1 commit f9da0f8
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 7 deletions.
8 changes: 8 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,14 @@ The following options need to be configured:
Define this to have a tty type of device available to
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
Define this if you want stdin, stdout &/or stderr to
be set to usbtty.
Expand Down
50 changes: 49 additions & 1 deletion drivers/serial/usbtty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -638,6 +651,9 @@ static void usbtty_init_instances (void)
memset (device_instance, 0, sizeof (struct usb_device_instance));
device_instance->device_state = STATE_INIT;
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->cdc_recv_setup = usbtty_cdc_setup;
device_instance->bus = bus_instance;
Expand Down Expand Up @@ -751,6 +767,10 @@ static void usbtty_init_terminal_type(short type)
device_descriptor.idProduct =
cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);

#if defined(CONFIG_USBD_HS)
qualifier_descriptor.bDeviceClass =
COMMUNICATIONS_DEVICE_CLASS;
#endif
/* Assign endpoint indices */
tx_endpoint = ACM_TX_ENDPOINT;
rx_endpoint = ACM_RX_ENDPOINT;
Expand Down Expand Up @@ -779,7 +799,9 @@ static void usbtty_init_terminal_type(short type)
device_descriptor.bDeviceClass = 0xFF;
device_descriptor.idProduct =
cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);

#if defined(CONFIG_USBD_HS)
qualifier_descriptor.bDeviceClass = 0xFF;
#endif
/* Assign endpoint indices */
tx_endpoint = GSERIAL_TX_ENDPOINT;
rx_endpoint = GSERIAL_RX_ENDPOINT;
Expand Down Expand Up @@ -932,6 +954,9 @@ static int usbtty_configured (void)
static void usbtty_event_handler (struct usb_device_instance *device,
usb_device_event_t event, int data)
{
#if defined(CONFIG_USBD_HS)
int i;
#endif
switch (event) {
case DEVICE_RESET:
case DEVICE_BUS_INACTIVE:
Expand All @@ -942,6 +967,29 @@ static void usbtty_event_handler (struct usb_device_instance *device,
break;

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 ();

default:
Expand Down
4 changes: 4 additions & 0 deletions drivers/serial/usbtty.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_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_BCD_DEVICE 0x00
Expand Down
1 change: 0 additions & 1 deletion drivers/usb/gadget/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_i
return (device->device_descriptor);
}


/**
* usbd_device_configuration_descriptor
* @device: which device
Expand Down
23 changes: 19 additions & 4 deletions drivers/usb/gadget/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,27 @@ static int ep0_get_descriptor (struct usb_device_instance *device,
}
break;
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
#if defined(CONFIG_USBD_HS)
{
/* If a USB device supports both a full speed and low speed operation
* we must send a Device_Qualifier descriptor here
*/
return -1;
struct usb_qualifier_descriptor *qualifier_descriptor =
device->qualifier_descriptor;

if (!qualifier_descriptor)
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:
return -1;
}
Expand Down
15 changes: 15 additions & 0 deletions include/usbdescriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,21 @@ struct usb_device_descriptor {
u8 bNumConfigurations;
} __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 {
u8 bLength;
u8 bDescriptorType; /* 0x03 */
Expand Down
22 changes: 21 additions & 1 deletion include/usbdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ struct usb_bus_instance;
#define USB_DT_INTERFACE 0x04
#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_REPORT (USB_TYPE_CLASS | 0x02)
#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
Expand Down Expand Up @@ -291,7 +295,11 @@ struct usb_bus_instance;
* USB Spec Release number
*/

#if defined(CONFIG_USBD_HS)
#define USB_BCD_VERSION 0x0200
#else
#define USB_BCD_VERSION 0x0110
#endif


/*
Expand Down Expand Up @@ -565,6 +573,9 @@ struct usb_device_instance {
/* generic */
char *name;
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);

Expand Down Expand Up @@ -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);
int usbd_device_endpoint_transfersize (struct usb_device_instance *, int, int, int, int, int);
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);
void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
void usbd_tx_complete (struct usb_endpoint_instance *endpoint);
Expand Down

0 comments on commit f9da0f8

Please sign in to comment.