diff options
author | Nicolas Boichat <drinkcat@google.com> | 2017-03-07 09:23:39 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-03-08 03:13:19 -0800 |
commit | 3898267abbf1b200018daae8afee60b33f24bb3e (patch) | |
tree | fc24e79e620ed52f6afb9d2420f123bc45575986 | |
parent | ff4f39d90618557cf81bd324ddc9ec2477d379fe (diff) | |
download | chrome-ec-3898267abbf1b200018daae8afee60b33f24bb3e.tar.gz |
chip/stm32/usb: Add support for USB SET_FEATURE control requests
This is required so that the kernel can enable/disable remote wake-up
capabilities, and in particular for the kernel to enable autosuspend.
Also, properly implement GET_STATUS.
BRANCH=none
BUG=b:35579996
TEST=echo auto > /sys/bus/usb/drivers/usb/X-Y/power/control, device
autosuspends after 2 seconds, and wakes on keypress.
Note that this introduces other bugs, where keys are missing,
repeated, see b/35775048.
Change-Id: I7ddd257ac3877d27fb2da813f20583a614a0169b
Reviewed-on: https://chromium-review.googlesource.com/450826
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | chip/stm32/usb.c | 35 | ||||
-rw-r--r-- | include/usb_descriptor.h | 5 |
2 files changed, 35 insertions, 5 deletions
diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c index ad1e76d65b..fae1e26297 100644 --- a/chip/stm32/usb.c +++ b/chip/stm32/usb.c @@ -101,7 +101,10 @@ static int desc_left; static const uint8_t *desc_ptr; /* interface that should handle the next tx transaction */ static uint8_t iface_next = USB_IFACE_COUNT; - +#ifdef CONFIG_USB_REMOTE_WAKEUP +/* remote wake up feature enabled */ +static int remote_wakeup_enabled; +#endif void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet) { @@ -196,14 +199,35 @@ static void ep0_rx(void) desc_left ? 0 : EP_STATUS_OUT); /* send the null OUT transaction if the transfer is complete */ } else if (req == (USB_DIR_IN | (USB_REQ_GET_STATUS << 8))) { - uint16_t zero = 0; + uint16_t data = 0; /* Get status */ - memcpy_to_usbram(EP0_BUF_TX_SRAM_ADDR, (void *)&zero, 2); +#ifdef CONFIG_USB_SELF_POWERED + data |= USB_REQ_GET_STATUS_SELF_POWERED; +#endif +#ifdef CONFIG_USB_REMOTE_WAKEUP + if (remote_wakeup_enabled) + data |= USB_REQ_GET_STATUS_REMOTE_WAKEUP; +#endif + memcpy_to_usbram(EP0_BUF_TX_SRAM_ADDR, (void *)&data, 2); btable_ep[0].tx_count = 2; STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID, EP_STATUS_OUT /*null OUT transaction */); } else if ((req & 0xff) == USB_DIR_OUT) { switch (req >> 8) { + case USB_REQ_SET_FEATURE: + case USB_REQ_CLEAR_FEATURE: +#ifdef CONFIG_USB_REMOTE_WAKEUP + if (ep0_buf_rx[1] == + USB_REQ_FEATURE_DEVICE_REMOTE_WAKEUP) { + remote_wakeup_enabled = + ((req >> 8) == USB_REQ_SET_FEATURE); + btable_ep[0].tx_count = 0; + STM32_TOGGLE_EP(0, EP_TX_RX_MASK, + EP_TX_RX_VALID, 0); + break; + } +#endif + goto unknown_req; case USB_REQ_SET_ADDRESS: /* set the address after we got IN packet handshake */ set_addr = ep0_buf_rx[1] & 0xff; @@ -335,8 +359,9 @@ static void usb_resume(void) #ifdef CONFIG_USB_REMOTE_WAKEUP void usb_wake(void) { - if (!(STM32_USB_CNTR & STM32_USB_CNTR_FSUSP)) { - /* USB is already woken up, nothing to do. */ + if (!remote_wakeup_enabled || + !(STM32_USB_CNTR & STM32_USB_CNTR_FSUSP)) { + /* USB wake not enabled, or already woken up, nothing to do. */ return; } diff --git a/include/usb_descriptor.h b/include/usb_descriptor.h index 7cb64e35aa..c2df5f53f9 100644 --- a/include/usb_descriptor.h +++ b/include/usb_descriptor.h @@ -214,8 +214,13 @@ struct usb_endpoint_descriptor { /* Standard requests for bRequest field in a SETUP packet. */ #define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_GET_STATUS_SELF_POWERED (1 << 0) +#define USB_REQ_GET_STATUS_REMOTE_WAKEUP (1 << 1) #define USB_REQ_CLEAR_FEATURE 0x01 #define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_FEATURE_ENDPOINT_HALT 0x0000 +#define USB_REQ_FEATURE_DEVICE_REMOTE_WAKEUP 0x0001 +#define USB_REQ_FEATURE_TEST_MODE 0x0002 #define USB_REQ_SET_ADDRESS 0x05 #define USB_REQ_GET_DESCRIPTOR 0x06 #define USB_REQ_SET_DESCRIPTOR 0x07 |