]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_usb.c
karo: tx51: remove duplicate CONFIG_SYS_SDRAM_CLK definition
[karo-tx-uboot.git] / common / cmd_usb.c
index dacdc2d5b1c2da32437cb40715c98740e8eda061..2519497dad8cf1a821cbf4c8889a7e38d74aca43 100644 (file)
@@ -5,24 +5,7 @@
  * Most of this source has been derived from the Linux USB
  * project.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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>
@@ -269,14 +252,42 @@ static void usb_display_config(struct usb_device *dev)
        printf("\n");
 }
 
+static struct usb_device *usb_find_device(int devnum)
+{
+       struct usb_device *dev;
+       int d;
+
+       for (d = 0; d < USB_MAX_DEVICE; d++) {
+               dev = usb_get_dev_index(d);
+               if (dev == NULL)
+                       return NULL;
+               if (dev->devnum == devnum)
+                       return dev;
+       }
+
+       return NULL;
+}
+
 static inline char *portspeed(int speed)
 {
-       if (speed == USB_SPEED_HIGH)
-               return "480 Mb/s";
-       else if (speed == USB_SPEED_LOW)
-               return "1.5 Mb/s";
-       else
-               return "12 Mb/s";
+       char *speed_str;
+
+       switch (speed) {
+       case USB_SPEED_SUPER:
+               speed_str = "5 Gb/s";
+               break;
+       case USB_SPEED_HIGH:
+               speed_str = "480 Mb/s";
+               break;
+       case USB_SPEED_LOW:
+               speed_str = "1.5 Mb/s";
+               break;
+       default:
+               speed_str = "12 Mb/s";
+               break;
+       }
+
+       return speed_str;
 }
 
 /* shows the device tree recursively */
@@ -348,6 +359,66 @@ static void usb_show_tree(struct usb_device *dev)
        usb_show_tree_graph(dev, &preamble[0]);
 }
 
+static int usb_test(struct usb_device *dev, int port, char* arg)
+{
+       int mode;
+
+       if (port > dev->maxchild) {
+               printf("Device is no hub or does not have %d ports.\n", port);
+               return 1;
+       }
+
+       switch (arg[0]) {
+       case 'J':
+       case 'j':
+               printf("Setting Test_J mode");
+               mode = USB_TEST_MODE_J;
+               break;
+       case 'K':
+       case 'k':
+               printf("Setting Test_K mode");
+               mode = USB_TEST_MODE_K;
+               break;
+       case 'S':
+       case 's':
+               printf("Setting Test_SE0_NAK mode");
+               mode = USB_TEST_MODE_SE0_NAK;
+               break;
+       case 'P':
+       case 'p':
+               printf("Setting Test_Packet mode");
+               mode = USB_TEST_MODE_PACKET;
+               break;
+       case 'F':
+       case 'f':
+               printf("Setting Test_Force_Enable mode");
+               mode = USB_TEST_MODE_FORCE_ENABLE;
+               break;
+       default:
+               printf("Unrecognized test mode: %s\nAvailable modes: "
+                      "J, K, S[E0_NAK], P[acket], F[orce_Enable]\n", arg);
+               return 1;
+       }
+
+       if (port)
+               printf(" on downstream facing port %d...\n", port);
+       else
+               printf(" on upstream facing port...\n");
+
+       if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE,
+                           port ? USB_RT_PORT : USB_RECIP_DEVICE,
+                           port ? USB_PORT_FEAT_TEST : USB_FEAT_TEST,
+                           (mode << 8) | port,
+                           NULL, 0, USB_CNTL_TIMEOUT) == -1) {
+               printf("Error during SET_FEATURE.\n");
+               return 1;
+       } else {
+               printf("Test mode successfully set. Use 'usb start' "
+                      "to return to normal operation.\n");
+               return 0;
+       }
+}
+
 
 /******************************************************************************
  * usb boot command intepreter. Derived from diskboot
@@ -441,17 +512,9 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        }
                        return 0;
                } else {
-                       int d;
-
-                       i = simple_strtoul(argv[2], NULL, 16);
+                       i = simple_strtoul(argv[2], NULL, 10);
                        printf("config for device %d\n", i);
-                       for (d = 0; d < USB_MAX_DEVICE; d++) {
-                               dev = usb_get_dev_index(d);
-                               if (dev == NULL)
-                                       break;
-                               if (dev->devnum == i)
-                                       break;
-                       }
+                       dev = usb_find_device(i);
                        if (dev == NULL) {
                                printf("*** No device available ***\n");
                                return 0;
@@ -462,6 +525,18 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                }
                return 0;
        }
+       if (strncmp(argv[1], "test", 4) == 0) {
+               if (argc < 5)
+                       return CMD_RET_USAGE;
+               i = simple_strtoul(argv[2], NULL, 10);
+               dev = usb_find_device(i);
+               if (dev == NULL) {
+                       printf("Device %d does not exist.\n", i);
+                       return 1;
+               }
+               i = simple_strtoul(argv[3], NULL, 10);
+               return usb_test(dev, i, argv[4]);
+       }
 #ifdef CONFIG_USB_STORAGE
        if (strncmp(argv[1], "stor", 4) == 0)
                return usb_stor_info();
@@ -571,7 +646,6 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        return CMD_RET_USAGE;
 }
 
-#ifdef CONFIG_USB_STORAGE
 U_BOOT_CMD(
        usb,    5,      1,      do_usb,
        "USB sub-system",
@@ -580,30 +654,26 @@ U_BOOT_CMD(
        "usb stop [f] - stop USB [f]=force stop\n"
        "usb tree - show USB device tree\n"
        "usb info [dev] - show available USB devices\n"
+       "usb test [dev] [port] [mode] - set USB 2.0 test mode\n"
+       "    (specify port 0 to indicate the device's upstream port)\n"
+       "    Available modes: J, K, S[E0_NAK], P[acket], F[orce_Enable]\n"
+#ifdef CONFIG_USB_STORAGE
        "usb storage - show details of USB storage devices\n"
        "usb dev [dev] - show or set current USB storage device\n"
        "usb part [dev] - print partition table of one or all USB storage"
-       " devices\n"
+       "    devices\n"
        "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
        "    to memory address `addr'\n"
        "usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"
        "    from memory address `addr'"
+#endif /* CONFIG_USB_STORAGE */
 );
 
 
+#ifdef CONFIG_USB_STORAGE
 U_BOOT_CMD(
        usbboot,        3,      1,      do_usbboot,
        "boot from USB device",
        "loadAddr dev:part"
 );
-
-#else
-U_BOOT_CMD(
-       usb,    5,      1,      do_usb,
-       "USB sub-system",
-       "start - start (scan) USB controller\n"
-       "usb reset - reset (rescan) USB controller\n"
-       "usb tree - show USB device tree\n"
-       "usb info [dev] - show available USB devices"
-);
-#endif
+#endif /* CONFIG_USB_STORAGE */