summaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-02-28 10:29:32 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-03-20 10:07:16 +0100
commit891b0a02566c477e4b48cece3fbdae1fd3029a5c (patch)
tree030e7dfd001ec160a9b1091b16e3e4b5dfac1446 /drivers/usb/core
parent5b17d93e75795413bc66b0b20ee4f3960ddce316 (diff)
downloadbarebox-891b0a02566c477e4b48cece3fbdae1fd3029a5c.tar.gz
barebox-891b0a02566c477e4b48cece3fbdae1fd3029a5c.tar.xz
usb: hub: Parse and save TT details from device descriptor
Adoption of U-Boot commit 5624dfd5aa91c244519ec60b40b4a42b4d9a43ca: | commit 5624dfd5aa91c244519ec60b40b4a42b4d9a43ca | Author: Bin Meng <bmeng.cn@gmail.com> | Date: Wed Jul 19 21:51:16 2017 +0800 | | usb: hub: Parse and save TT details from device descriptor | | A high speed hub has a special responsibility to handle full speed/ | low speed devices connected on downstream ports. In this case, the | hub must isolate the high speed signaling environment from the full | speed/low speed signaling environment with the help of Transaction | Translator (TT). TT details are provided by hub descriptors and we | parse and save it to hub uclass_priv for later use. | | Signed-off-by: Bin Meng <bmeng.cn@gmail.com> | Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hub.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6d664e80bb..7c7a325291 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -388,7 +388,7 @@ static int usb_hub_configure(struct usb_device *dev)
unsigned char buffer[USB_BUFSIZ], *bitmap;
struct usb_hub_descriptor *descriptor;
struct usb_hub_status *hubsts;
- int i;
+ int i, ret;
struct usb_hub_device *hub;
hub = xzalloc(sizeof (*hub));
@@ -468,6 +468,56 @@ static int usb_hub_configure(struct usb_device *dev)
break;
}
+ switch (dev->descriptor->bDeviceProtocol) {
+ case USB_HUB_PR_FS:
+ break;
+ case USB_HUB_PR_HS_SINGLE_TT:
+ dev_dbg(&dev->dev, "Single TT\n");
+ break;
+ case USB_HUB_PR_HS_MULTI_TT:
+ ret = usb_set_interface(dev, 0, 1);
+ if (ret == 0) {
+ dev_dbg(&dev->dev, "TT per port\n");
+ hub->tt.multi = true;
+ } else {
+ dev_dbg(&dev->dev, "Using single TT (err %d)\n", ret);
+ }
+ break;
+ case USB_HUB_PR_SS:
+ /* USB 3.0 hubs don't have a TT */
+ break;
+ default:
+ dev_dbg(&dev->dev, "Unrecognized hub protocol %d\n",
+ dev->descriptor->bDeviceProtocol);
+ break;
+ }
+
+ /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
+ switch (hub->desc.wHubCharacteristics & HUB_CHAR_TTTT) {
+ case HUB_TTTT_8_BITS:
+ if (dev->descriptor->bDeviceProtocol != 0) {
+ hub->tt.think_time = 666;
+ dev_dbg(&dev->dev, "TT requires at most %d FS bit times (%d ns)\n",
+ 8, hub->tt.think_time);
+ }
+ break;
+ case HUB_TTTT_16_BITS:
+ hub->tt.think_time = 666 * 2;
+ dev_dbg(&dev->dev, "TT requires at most %d FS bit times (%d ns)\n",
+ 16, hub->tt.think_time);
+ break;
+ case HUB_TTTT_24_BITS:
+ hub->tt.think_time = 666 * 3;
+ dev_dbg(&dev->dev, "TT requires at most %d FS bit times (%d ns)\n",
+ 24, hub->tt.think_time);
+ break;
+ case HUB_TTTT_32_BITS:
+ hub->tt.think_time = 666 * 4;
+ dev_dbg(&dev->dev, "TT requires at most %d FS bit times (%d ns)\n",
+ 32, hub->tt.think_time);
+ break;
+ }
+
dev_dbg(&dev->dev, "power on to power good time: %dms\n",
descriptor->bPwrOn2PwrGood * 2);
dev_dbg(&dev->dev, "hub controller current requirement: %dmA\n",