diff options
author | Chunfeng Yun <chunfeng.yun@mediatek.com> | 2021-03-08 10:52:05 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-03-10 09:37:17 +0100 |
commit | fb95c7cf5600b7b74412f27dfb39a1e13fd8a90d (patch) | |
tree | a26adef0d2e1159293afa37941a1970bd206d2a5 /drivers/usb/common | |
parent | 14295a150050acfc3a1260ee3d2114b0b824199f (diff) |
usb: common: add function to get interval expressed in us unit
Add a new function to convert bInterval into the time expressed
in 1us unit.
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Link: https://lore.kernel.org/r/25c8a09b055f716c1e5bf11fea72c3418f844482.1615170625.git.chunfeng.yun@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/common')
-rw-r--r-- | drivers/usb/common/common.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index fc21cf2d36f6..675e8a4e683a 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -165,6 +165,47 @@ enum usb_dr_mode usb_get_dr_mode(struct device *dev) } EXPORT_SYMBOL_GPL(usb_get_dr_mode); +/** + * usb_decode_interval - Decode bInterval into the time expressed in 1us unit + * @epd: The descriptor of the endpoint + * @speed: The speed that the endpoint works as + * + * Function returns the interval expressed in 1us unit for servicing + * endpoint for data transfers. + */ +unsigned int usb_decode_interval(const struct usb_endpoint_descriptor *epd, + enum usb_device_speed speed) +{ + unsigned int interval = 0; + + switch (usb_endpoint_type(epd)) { + case USB_ENDPOINT_XFER_CONTROL: + /* uframes per NAK */ + if (speed == USB_SPEED_HIGH) + interval = epd->bInterval; + break; + case USB_ENDPOINT_XFER_ISOC: + interval = 1 << (epd->bInterval - 1); + break; + case USB_ENDPOINT_XFER_BULK: + /* uframes per NAK */ + if (speed == USB_SPEED_HIGH && usb_endpoint_dir_out(epd)) + interval = epd->bInterval; + break; + case USB_ENDPOINT_XFER_INT: + if (speed >= USB_SPEED_HIGH) + interval = 1 << (epd->bInterval - 1); + else + interval = epd->bInterval; + break; + } + + interval *= (speed >= USB_SPEED_HIGH) ? 125 : 1000; + + return interval; +} +EXPORT_SYMBOL_GPL(usb_decode_interval); + #ifdef CONFIG_OF /** * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device |