summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlschyi <lschyi@google.com>2022-06-13 13:29:06 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-06-16 08:36:48 +0000
commit52427931f7afe3792fe71c4d82426fe2e6022ce3 (patch)
treedcb22987fdf1392d4506f1a43aab0b5824a81903
parent258e0d54b610969981f130f4afe98bb3f4c102ee (diff)
downloadchrome-ec-52427931f7afe3792fe71c4d82426fe2e6022ce3.tar.gz
ps8743: Fix mode to apply power optimization and value to write
Apply the power optimization if USB mode is on and DP mode is off. The check of these modes are achieved by checking the Misc register. Correct value to write to the mode register. As the optimization only applies when only USB2 devices are connected, and should not turn on USB mode if device is removed during S3, create enum and record status with internal variable, then restructure the logic for suspend and resume. BUG=b:229810117 TEST=Check the operation mode register (0x00) entering/leaving S3: (1) USB 3 device is connected, register value not changed with different type c side. (2) USB 2 device is connected, only the USB mode bit is unset at S3, and set in S0. (3) USB 2 device is connected in S0, and remove the device when in S3. USB mode bit is unset after back to S0. (4) Connect a A->C adapter in S0, then insert USB 2/3 device in S3. The USB mode bit is set after leaving S3. `lsusb` can identify the device under USB 2/3 bus. (5) USB mode bit is always unset if no device is connected. (6) type c display is connected, register value not changed. BRANCH=None Change-Id: Ic85ee805ffea26bfa3fc5004c3d319cefcf2e68e Signed-off-by: lschyi <lschyi@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3702073 Commit-Queue: Sung-Chi Li <lschyi@chromium.org> Reviewed-by: Eric Yilun Lin <yllin@google.com> Tested-by: Sung-Chi Li <lschyi@chromium.org>
-rw-r--r--driver/usb_mux/ps8743.c67
-rw-r--r--driver/usb_mux/ps8743.h5
2 files changed, 58 insertions, 14 deletions
diff --git a/driver/usb_mux/ps8743.c b/driver/usb_mux/ps8743.c
index 9a067f287a..28ad5e9546 100644
--- a/driver/usb_mux/ps8743.c
+++ b/driver/usb_mux/ps8743.c
@@ -14,6 +14,15 @@
#include "usb_pd.h"
#include "util.h"
+enum usb_conn_status {
+ NO_DEVICE,
+ USB2_CONNECTED,
+ USB3_CONNECTED,
+ UNKNOWN,
+};
+
+static enum usb_conn_status saved_usb_conn_status[CONFIG_USB_PD_PORT_MAX_COUNT];
+
int ps8743_read(const struct usb_mux *me, uint8_t reg, int *val)
{
return i2c_read8(me->i2c_port, me->i2c_addr_flags,
@@ -122,6 +131,9 @@ static int ps8743_set_mux(const struct usb_mux *me, mux_state_t mux_state,
if (mux_state & USB_PD_MUX_USB_ENABLED)
reg |= PS8743_MODE_USB_ENABLE;
+ else
+ saved_usb_conn_status[me->usb_port] = NO_DEVICE;
+
if (mux_state & USB_PD_MUX_DP_ENABLED)
reg |= PS8743_MODE_DP_ENABLE | PS8743_MODE_IN_HPD_ASSERT;
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
@@ -168,21 +180,38 @@ const struct usb_mux_driver ps8743_usb_mux_driver = {
.get = ps8743_get_mux,
};
-static bool ps8743_port_is_usb2_only(const struct usb_mux *me)
+static bool ps8743_port_is_usb_mode_only(const struct usb_mux *me)
{
int val;
- if (ps8743_read(me, PS8743_MISC_DCI_SS_MODES, &val))
+ if (ps8743_read(me, PS8743_MISC_HPD_DP_USB_FLIP, &val))
return false;
+ val &= (PS8743_USB_MODE_STATUS | PS8743_DP_MODE_STATUS);
+
+ return val == PS8743_USB_MODE_STATUS;
+}
+
+static enum usb_conn_status ps8743_get_usb_conn_status(const struct usb_mux *me)
+{
+ int val;
+
+ if (ps8743_read(me, PS8743_MISC_DCI_SS_MODES, &val))
+ return UNKNOWN;
+
+ if (val == 0)
+ return NO_DEVICE;
+
val &= (PS8743_SSTX_NORMAL_OPERATION_MODE |
PS8743_SSTX_POWER_SAVING_MODE | PS8743_SSTX_SUSPEND_MODE);
return (val != PS8743_SSTX_NORMAL_OPERATION_MODE &&
- val != PS8743_SSTX_POWER_SAVING_MODE);
+ val != PS8743_SSTX_POWER_SAVING_MODE) ?
+ USB2_CONNECTED :
+ USB3_CONNECTED;
}
-static void ps8743_update_usb_mode_all(bool is_resume)
+static void ps8743_suspend(void)
{
for (int i = 0; i < board_get_usb_pd_port_count(); i++) {
const struct usb_mux *mux = &usb_muxes[i];
@@ -190,24 +219,34 @@ static void ps8743_update_usb_mode_all(bool is_resume)
if (mux->driver != &ps8743_usb_mux_driver)
continue;
- if (is_resume) {
- ps8743_field_update(mux, PS8743_REG_MODE,
- PS8743_MODE_USB_ENABLE, 0xFF);
- } else if (ps8743_port_is_usb2_only(mux)) {
+ saved_usb_conn_status[i] = ps8743_get_usb_conn_status(mux);
+
+ if (ps8743_port_is_usb_mode_only(mux) &&
+ saved_usb_conn_status[i] == USB2_CONNECTED) {
ps8743_field_update(mux, PS8743_REG_MODE,
PS8743_MODE_USB_ENABLE, 0);
}
}
}
-
-static void ps8743_suspend(void)
-{
- ps8743_update_usb_mode_all(false);
-}
DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, ps8743_suspend, HOOK_PRIO_DEFAULT);
static void ps8743_resume(void)
{
- ps8743_update_usb_mode_all(true);
+ for (int i = 0; i < board_get_usb_pd_port_count(); i++) {
+ const struct usb_mux *mux = &usb_muxes[i];
+
+ if (mux->driver != &ps8743_usb_mux_driver)
+ continue;
+
+ if (saved_usb_conn_status[i] != NO_DEVICE) {
+ ps8743_field_update(mux, PS8743_REG_MODE,
+ PS8743_MODE_USB_ENABLE,
+ PS8743_MODE_USB_ENABLE);
+ }
+ }
}
+#ifdef CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK
+DECLARE_HOOK(HOOK_CHIPSET_RESUME_INIT, ps8743_resume, HOOK_PRIO_DEFAULT);
+#else
DECLARE_HOOK(HOOK_CHIPSET_RESUME, ps8743_resume, HOOK_PRIO_DEFAULT);
+#endif
diff --git a/driver/usb_mux/ps8743.h b/driver/usb_mux/ps8743.h
index 65ec8392ee..8e3a9d9b4c 100644
--- a/driver/usb_mux/ps8743.h
+++ b/driver/usb_mux/ps8743.h
@@ -35,4 +35,9 @@
#define PS8743_SSTX_POWER_SAVING_MODE BIT(5)
#define PS8743_SSTX_SUSPEND_MODE BIT(6)
+/* Misc resiger for checking HPD / DP / USB / FLIP mode status */
+#define PS8743_MISC_HPD_DP_USB_FLIP 0x09
+#define PS8743_USB_MODE_STATUS BIT(3)
+#define PS8743_DP_MODE_STATUS BIT(4)
+
#endif /* __CROS_EC_PS8743_H */