mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 10:31:02 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
ff4f39d906
commit
3898267abb
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user