]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/serial/usbtty.c
am33xx: Update DT files, add am335x_gp_evm_config target
[karo-tx-uboot.git] / drivers / serial / usbtty.c
index e738c5627140f2855fdd14e127988d8004b21082..75f0ec31bbfb9a6faedeaf9cf137ea1212ceefd5 100644 (file)
@@ -5,33 +5,19 @@
  * (C) Copyright 2006
  * Bryan O'Donoghue, bodonoghue@codehermit.ie
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
- *
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-
+#include <config.h>
 #include <circbuf.h>
-#include <devices.h>
+#include <stdio_dev.h>
+#include <asm/unaligned.h>
 #include "usbtty.h"
 #include "usb_cdc_acm.h"
 #include "usbdescriptors.h"
-#include <config.h>            /* If defined, override Linux identifiers with
-                                * vendor specific ones */
 
-#if 0
+#ifdef DEBUG
 #define TTYDBG(fmt,args...)\
        serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
 #else
@@ -64,7 +50,7 @@
 /*
  * Buffers to hold input and output data
  */
-#define USBTTY_BUFFER_SIZE 256
+#define USBTTY_BUFFER_SIZE 2048
 static circbuf_t usbtty_input;
 static circbuf_t usbtty_output;
 
@@ -72,7 +58,7 @@ static circbuf_t usbtty_output;
 /*
  * Instance variables
  */
-static device_t usbttydev;
+static struct stdio_dev usbttydev;
 static struct usb_device_instance device_instance[1];
 static struct usb_bus_instance bus_instance[1];
 static struct usb_configuration_instance config_instance[NUM_CONFIGS];
@@ -96,7 +82,7 @@ static char serial_number[16];
  * Descriptors, Strings, Local variables.
  */
 
-/* defined and used by usbdcore_ep0.c */
+/* defined and used by gadget/ep0.c */
 extern struct usb_string_descriptor **usb_strings;
 
 /* Indicies, References */
@@ -134,6 +120,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
  */
@@ -152,8 +151,7 @@ struct acm_config_desc {
 
        /* Slave Interface */
        struct usb_interface_descriptor data_class_interface;
-       struct usb_endpoint_descriptor
-               data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed));
+       struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS-1];
 } __attribute__((packed));
 
 static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
@@ -218,7 +216,7 @@ static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
                        .bLength =
                                sizeof(struct usb_endpoint_descriptor),
                        .bDescriptorType        = USB_DT_ENDPOINT,
-                       .bEndpointAddress       = 0x01 | USB_DIR_IN,
+                       .bEndpointAddress       = UDC_INT_ENDPOINT | USB_DIR_IN,
                        .bmAttributes           = USB_ENDPOINT_XFER_INT,
                        .wMaxPacketSize
                                = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
@@ -244,7 +242,7 @@ static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
                                .bLength                =
                                        sizeof(struct usb_endpoint_descriptor),
                                .bDescriptorType        = USB_DT_ENDPOINT,
-                               .bEndpointAddress       = 0x02 | USB_DIR_OUT,
+                               .bEndpointAddress       = UDC_OUT_ENDPOINT | USB_DIR_OUT,
                                .bmAttributes           =
                                        USB_ENDPOINT_XFER_BULK,
                                .wMaxPacketSize         =
@@ -255,7 +253,7 @@ static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
                                .bLength                =
                                        sizeof(struct usb_endpoint_descriptor),
                                .bDescriptorType        = USB_DT_ENDPOINT,
-                               .bEndpointAddress       = 0x03 | USB_DIR_IN,
+                               .bEndpointAddress       = UDC_IN_ENDPOINT | USB_DIR_IN,
                                .bmAttributes           =
                                        USB_ENDPOINT_XFER_BULK,
                                .wMaxPacketSize         =
@@ -282,10 +280,8 @@ static struct rs232_emu rs232_desc={
 struct gserial_config_desc {
 
        struct usb_configuration_descriptor configuration_desc;
-       struct usb_interface_descriptor
-               interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed));
-       struct usb_endpoint_descriptor
-               data_endpoints[NUM_ENDPOINTS] __attribute__((packed));
+       struct usb_interface_descriptor interface_desc[NUM_GSERIAL_INTERFACES];
+       struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS];
 
 } __attribute__((packed));
 
@@ -326,7 +322,7 @@ gserial_configuration_descriptors[NUM_CONFIGS] ={
                                .bLength =
                                        sizeof(struct usb_endpoint_descriptor),
                                .bDescriptorType =      USB_DT_ENDPOINT,
-                               .bEndpointAddress =     0x01 | USB_DIR_OUT,
+                               .bEndpointAddress =     UDC_OUT_ENDPOINT | USB_DIR_OUT,
                                .bmAttributes =         USB_ENDPOINT_XFER_BULK,
                                .wMaxPacketSize =
                                        cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
@@ -336,7 +332,7 @@ gserial_configuration_descriptors[NUM_CONFIGS] ={
                                .bLength =
                                        sizeof(struct usb_endpoint_descriptor),
                                .bDescriptorType =      USB_DT_ENDPOINT,
-                               .bEndpointAddress =     0x02 | USB_DIR_IN,
+                               .bEndpointAddress =     UDC_IN_ENDPOINT | USB_DIR_IN,
                                .bmAttributes =         USB_ENDPOINT_XFER_BULK,
                                .wMaxPacketSize =
                                        cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
@@ -346,7 +342,7 @@ gserial_configuration_descriptors[NUM_CONFIGS] ={
                                .bLength =
                                        sizeof(struct usb_endpoint_descriptor),
                                .bDescriptorType =      USB_DT_ENDPOINT,
-                               .bEndpointAddress =     0x03 | USB_DIR_IN,
+                               .bEndpointAddress =     UDC_INT_ENDPOINT | USB_DIR_IN,
                                .bmAttributes =         USB_ENDPOINT_XFER_INT,
                                .wMaxPacketSize =
                                        cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
@@ -393,7 +389,7 @@ static void str2wide (char *str, u16 * wide)
  * Test whether a character is in the RX buffer
  */
 
-int usbtty_tstc (void)
+int usbtty_tstc(struct stdio_dev *dev)
 {
        struct usb_endpoint_instance *endpoint =
                &endpoint_instance[rx_endpoint];
@@ -413,7 +409,7 @@ int usbtty_tstc (void)
  * written into its argument c.
  */
 
-int usbtty_getc (void)
+int usbtty_getc(struct stdio_dev *dev)
 {
        char c;
        struct usb_endpoint_instance *endpoint =
@@ -433,8 +429,11 @@ int usbtty_getc (void)
 /*
  * Output a single byte to the usb client port.
  */
-void usbtty_putc (const char c)
+void usbtty_putc(struct stdio_dev *dev, const char c)
 {
+       if (!usbtty_configured ())
+               return;
+
        buf_push (&usbtty_output, &c, 1);
        /* If \n, also do \r */
        if (c == '\n')
@@ -476,7 +475,7 @@ static void __usbtty_puts (const char *str, int len)
                if (space) {
                        write_buffer (&usbtty_output);
 
-                       n = MIN (space, MIN (len, maxlen));
+                       n = min(space, min(len, maxlen));
                        buf_push (&usbtty_output, str, n);
 
                        str += n;
@@ -485,11 +484,15 @@ static void __usbtty_puts (const char *str, int len)
        }
 }
 
-void usbtty_puts (const char *str)
+void usbtty_puts(struct stdio_dev *dev, const char *str)
 {
        int n;
-       int len = strlen (str);
+       int len;
+
+       if (!usbtty_configured ())
+               return;
 
+       len = strlen (str);
        /* add '\r' for each '\n' */
        while (len > 0) {
                n = next_nl_pos (str);
@@ -552,11 +555,11 @@ int drv_usbtty_init (void)
        usbtty_init_strings ();
        usbtty_init_instances ();
 
+       usbtty_init_endpoints ();
+
        udc_startup_events (device_instance);/* Enable dev, init udc pointers */
        udc_connect ();         /* Enable pullup for host detection */
 
-       usbtty_init_endpoints ();
-
        /* Device initialization */
        memset (&usbttydev, 0, sizeof (usbttydev));
 
@@ -568,7 +571,7 @@ int drv_usbtty_init (void)
        usbttydev.putc = usbtty_putc;   /* 'putc' function */
        usbttydev.puts = usbtty_puts;   /* 'puts' function */
 
-       rc = device_register (&usbttydev);
+       rc = stdio_register (&usbttydev);
 
        return (rc == 0) ? 1 : rc;
 }
@@ -624,6 +627,9 @@ static void usbtty_init_strings (void)
        usb_strings = usbtty_string_table;
 }
 
+#define init_wMaxPacketSize(x) le16_to_cpu(get_unaligned(\
+                       &ep_descriptor_ptrs[(x) - 1]->wMaxPacketSize));
+
 static void usbtty_init_instances (void)
 {
        int i;
@@ -632,6 +638,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;
@@ -686,14 +695,12 @@ static void usbtty_init_instances (void)
                endpoint_instance[i].rcv_attributes =
                        ep_descriptor_ptrs[i - 1]->bmAttributes;
 
-               endpoint_instance[i].rcv_packetSize =
-                       le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+               endpoint_instance[i].rcv_packetSize = init_wMaxPacketSize(i);
 
                endpoint_instance[i].tx_attributes =
                        ep_descriptor_ptrs[i - 1]->bmAttributes;
 
-               endpoint_instance[i].tx_packetSize =
-                       le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize);
+               endpoint_instance[i].tx_packetSize = init_wMaxPacketSize(i);
 
                endpoint_instance[i].tx_attributes =
                        ep_descriptor_ptrs[i - 1]->bmAttributes;
@@ -747,6 +754,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;
@@ -775,7 +786,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;
@@ -869,7 +882,7 @@ static int write_buffer (circbuf_t * buf)
                        space_avail =
                                current_urb->buffer_length -
                                current_urb->actual_length;
-                       popnum = MIN (space_avail, buf->size);
+                       popnum = min(space_avail, (int)buf->size);
                        if (popnum == 0)
                                break;
 
@@ -928,6 +941,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:
@@ -938,6 +954,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: