> From: Vipin KUMAR <vipin.ku...@st.com>
> 
> 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 <vipin.ku...@st.com>
> Signed-off-by: Amit Virdi <amit.vi...@st.com>
> ---
>  README                    |    8 +++++++
>  drivers/serial/usbtty.c   |   50
> ++++++++++++++++++++++++++++++++++++++++++++- drivers/serial/usbtty.h   | 
>   4 +++
>  drivers/usb/gadget/core.c |   14 ++++++++++++
>  drivers/usb/gadget/ep0.c  |   24 ++++++++++++++++++---
>  include/usbdescriptors.h  |   15 +++++++++++++
>  include/usbdevice.h       |   24 ++++++++++++++++++++-
>  7 files changed, 133 insertions(+), 6 deletions(-)
> 
> diff --git a/README b/README
> index eba6378..d54bb68 100644
> --- a/README
> +++ b/README
> @@ -1165,6 +1165,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.
> diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c
> index 550bc58..0374c7d 100644
> --- a/drivers/serial/usbtty.c
> +++ b/drivers/serial/usbtty.c
> @@ -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
>   */
> @@ -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;
> @@ -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;
> @@ -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;
> @@ -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:
> @@ -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 = 1; i <= NUM_ENDPOINTS; i++) {

Start with i = 0 and end with i < NUM_ENDPOINTS to avoid these i-1 below. Then 
fix those [i] with [i+1], there's less of those.

> +                     if (((ep_descriptor_ptrs[i - 1]->bmAttributes &
> +                           USB_ENDPOINT_XFERTYPE_MASK) ==
> +                           USB_ENDPOINT_XFER_BULK)
> +                         && is_usbd_high_speed()) {
> +
> +                             ep_descriptor_ptrs[i - 1]->wMaxPacketSize =
> +                                     CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE;
> +                     }
> +
> +                     endpoint_instance[i].tx_packetSize =
> +                             ep_descriptor_ptrs[i - 1]->wMaxPacketSize;
> +                     endpoint_instance[i].rcv_packetSize =
> +                             ep_descriptor_ptrs[i - 1]->wMaxPacketSize;
> +             }
> +#endif
>               usbtty_init_endpoints ();
> 
>       default:
> diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
> index 6731c38..bd3bcbc 100644
> --- a/drivers/serial/usbtty.h
> +++ b/drivers/serial/usbtty.h
> @@ -72,6 +72,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
> diff --git a/drivers/usb/gadget/core.c b/drivers/usb/gadget/core.c
> index 4f2ebab..b2212b4 100644
> --- a/drivers/usb/gadget/core.c
> +++ b/drivers/usb/gadget/core.c
> @@ -212,6 +212,20 @@ struct usb_device_descriptor
> *usbd_device_device_descriptor (struct usb_device_i return
> (device->device_descriptor);
>  }
> 
> +#if defined(CONFIG_USBD_HS)
> +/**
> + * usbd_device_qualifier_descriptor
> + * @device: which device
> + * @port: which port
> + *
> + * Return the specified qualifier descriptor for the specified device.
> + */
> +struct usb_qualifier_descriptor *usbd_device_qualifier_descriptor(
> +             struct usb_device_instance *device, int port)

Make this static, but do you really need this function at all?

Otherwise seems ok

> +{
> +     return device->qualifier_descriptor;
> +}
> +#endif
> 
>  /**
>   * usbd_device_configuration_descriptor
> diff --git a/drivers/usb/gadget/ep0.c b/drivers/usb/gadget/ep0.c
> index 22499d3..ba8f906 100644
> --- a/drivers/usb/gadget/ep0.c
> +++ b/drivers/usb/gadget/ep0.c
> @@ -338,12 +338,28 @@ 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;
> +
> +                     qualifier_descriptor = usbd_device_qualifier_descriptor
> +                             (device, port);
> +                     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;
>       }
> diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h
> index 2dec3b9..de1069f 100644
> --- a/include/usbdescriptors.h
> +++ b/include/usbdescriptors.h
> @@ -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 */
> diff --git a/include/usbdevice.h b/include/usbdevice.h
> index 9eb8849..e3eb748 100644
> --- a/include/usbdevice.h
> +++ b/include/usbdevice.h
> @@ -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)
> @@ -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
> 
> 
>  /*
> @@ -567,6 +575,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);
> 
> @@ -659,8 +670,19 @@ 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)
> +struct usb_qualifier_descriptor *usbd_device_qualifier_descriptor(
> +             struct usb_device_instance *, int);
> +/*
> + * 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);
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to