diff options
author | Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 2008-06-27 12:09:58 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-22 00:16:35 +0200 |
commit | 397f519a0d771a6bddbcd71a31da6880e81c2e6b (patch) | |
tree | d4bc7f296b2d9296fe917ffadcfe6a698a296616 /drivers/usb/host | |
parent | usb: r8a66597-hcd: fix interrupt trigger (diff) | |
download | linux-397f519a0d771a6bddbcd71a31da6880e81c2e6b.tar.xz linux-397f519a0d771a6bddbcd71a31da6880e81c2e6b.zip |
usb: r8a66597-hcd: fix iinterval for Full/Low speed device
fix interrupt transfer interval for Full/Low speed device.
Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 4db0107f3178..d5f02dddb120 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -863,6 +863,32 @@ static void disable_r8a66597_pipe_all(struct r8a66597 *r8a66597, dev->dma_map = 0; } +static u16 get_interval(struct urb *urb, __u8 interval) +{ + u16 time = 1; + int i; + + if (urb->dev->speed == USB_SPEED_HIGH) { + if (interval > IITV) + time = IITV; + else + time = interval ? interval - 1 : 0; + } else { + if (interval > 128) { + time = IITV; + } else { + /* calculate the nearest value for PIPEPERI */ + for (i = 0; i < 7; i++) { + if ((1 << i) < interval && + (1 << (i + 1) > interval)) + time = 1 << i; + } + } + } + + return time; +} + static unsigned long get_timer_interval(struct urb *urb, __u8 interval) { __u8 i; @@ -901,10 +927,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, info.interval = 0; info.timer_interval = 0; } else { - if (ep->bInterval > IITV) - info.interval = IITV; - else - info.interval = ep->bInterval ? ep->bInterval - 1 : 0; + info.interval = get_interval(urb, ep->bInterval); info.timer_interval = get_timer_interval(urb, ep->bInterval); } if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |