Files
OpenCellular/include/usb_api.h
Vincent Palatin 096ea20ed1 g: restore DATA PID after USB suspend/resume
In USB FS on a bulk/interrupt endpoint, the transactions normally toggles
between DATA0 and DATA1 PIDs.
After a USB suspend/resume cycle, we need to restart from the PID we
were at before suspend.
In our current code, when going to deep-sleep during USB suspend, we are
re-initializing everything when the MCU restarts at each resume. So we set
implicitly the PID to DATA0. The USB Hardware IP just silently discards the
packet when the PID of an incoming OUT packet is not matching the
expectation in the endpoint register.

In order to preserve DATA PIDS, record the state of the PID toggling on
each endpoint when going to deep-sleep and restore it during the USB
initialization.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>

BRANCH=none
BUG=b:38160821
TEST=manual, plug a HG proto2 on a Linux host machine and enable
'auto-suspend' for this USB device. Let it go to sleep and wake-it up by
sending a U2FHID request. Repeat the process several times and see that
the key answers every time (while it was failing after the second cycle
before).

Change-Id: I75e2cfc39f22483d9e9b32c5f8b887dbafc37108
Reviewed-on: https://chromium-review.googlesource.com/655238
Commit-Ready: Marius Schilder <mschilder@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
2017-09-07 15:01:04 -07:00

86 lines
2.4 KiB
C

/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* USB API definitions.
*
* This file includes definitions needed by common code that wants to control
* the state of the USB peripheral, but doesn't need to know about the specific
* implementation.
*/
#ifndef __CROS_EC_USB_API_H
#define __CROS_EC_USB_API_H
/*
* Initialize the USB peripheral, enabling its clock and configuring the DP/DN
* GPIOs correctly. This function is called via an init hook (unless the board
* defined CONFIG_USB_INHIBIT_INIT), but may need to be called again if
* usb_release is called. This function will call usb_connect by default
* unless CONFIG_USB_INHIBIT_CONNECT is defined.
*/
void usb_init(void);
/* Check if USB peripheral is enabled. */
int usb_is_enabled(void);
/*
* Enable the pullup on the DP line to signal that this device exists to the
* host and to start the enumeration process.
*/
void usb_connect(void);
/*
* Disable the pullup on the DP line. This causes the device to be disconnected
* from the host.
*/
void usb_disconnect(void);
/*
* Disconnect from the host by calling usb_disconnect and then turn off the USB
* peripheral, releasing its GPIOs and disabling its clock.
*/
void usb_release(void);
/*
* Returns true if USB device is currently suspended.
* Requires CONFIG_USB_SUSPEND to be defined.
*/
int usb_is_suspended(void);
/*
* Preserve in non-volatile memory the state of the USB hardware registers
* which cannot be simply re-initialized when powered up again.
*/
void usb_save_suspended_state(void);
/*
* Restore from non-volatile memory the state of the USB hardware registers
* which was lost by powering them down.
*/
void usb_restore_suspended_state(void);
/*
* Tell the host to wake up. Does nothing if CONFIG_USB_REMOTE_WAKEUP is not
* defined.
*
* Returns immediately, suspend status can be checked using usb_is_suspended.
*/
#ifdef CONFIG_USB_REMOTE_WAKEUP
void usb_wake(void);
#else
static inline void usb_wake(void) {}
#endif
/* Board-specific USB wake, for side-band wake, called by usb_wake above. */
void board_usb_wake(void);
#ifdef CONFIG_USB_SELECT_PHY
/* Select which PHY to use. */
void usb_select_phy(uint32_t phy);
/* Get the current PHY */
uint32_t usb_get_phy(void);
#endif
#endif /* __CROS_EC_USB_API_H */