From c8f98e80fdbe85fc0bc0f892d4b22dad19186aef Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Fri, 5 Dec 2014 16:23:11 -0800 Subject: [PATCH] samus_pd: Open USB data switches in UFP mode Samus USB ports can't actually act as UFPs, so open switches when in UFP mode. BUG=chrome-os-partner:32003 TEST=Manual on Samus. Connect two Samus units, run `pd 1 swap data`, verify that switches are opened on switch to UFP. Unplug samus and connect a USB 2.0 device instead, verify that ports are again closed. BRANCH=samus Change-Id: I9e1ca58089caf29e419698c8426bf8b72500833a Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/233711 Reviewed-by: Alec Berg --- board/samus_pd/usb_pd_policy.c | 4 +++- common/usb_pd_protocol.c | 15 ++++++++++----- driver/pi3usb9281.h | 5 ++++- driver/usb_switch_pi3usb9281.c | 11 +++++++++++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index 8646433734..95af500e69 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -10,6 +10,7 @@ #include "gpio.h" #include "hooks.h" #include "host_command.h" +#include "pi3usb9281.h" #include "registers.h" #include "task.h" #include "timer.h" @@ -226,7 +227,8 @@ int pd_check_data_swap(int port, int data_role) void pd_execute_data_swap(int port, int data_role) { - /* TODO: when switching to UFP need to open D+/D- switches */ + /* Open USB switches when taking UFP role */ + pi3usb9281_set_switches(port, (data_role == PD_ROLE_UFP)); } void pd_new_contract(int port, int pr_role, int dr_role, diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 88ef00719d..9c45062377 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -939,10 +939,15 @@ void pd_request_data_swap(int port) task_wake(PORT_TO_TASK_ID(port)); } +static void pd_set_data_role(int port, int role) +{ + pd[port].data_role = role; + pd_execute_data_swap(port, role); +} + static void pd_dr_swap(int port) { - pd[port].data_role = !pd[port].data_role; - pd_execute_data_swap(port, pd[port].data_role); + pd_set_data_role(port, !pd[port].data_role); pd[port].flags |= PD_FLAGS_DATA_SWAPPED; } @@ -1511,7 +1516,7 @@ void pd_task(void) /* Initialize PD protocol state variables for each port. */ pd[port].power_role = PD_ROLE_DEFAULT; - pd[port].data_role = PD_ROLE_DEFAULT; + pd_set_data_role(port, PD_ROLE_DEFAULT); pd[port].vdm_state = VDM_STATE_DONE; pd[port].flags = 0; set_state(port, PD_DEFAULT_STATE); @@ -1573,7 +1578,7 @@ void pd_task(void) GET_POLARITY(cc1_volt, cc2_volt); pd_select_polarity(port, pd[port].polarity); /* initial data role for source is DFP */ - pd[port].data_role = PD_ROLE_DFP; + pd_set_data_role(port, PD_ROLE_DFP); /* Set to USB SS initially */ #ifdef CONFIG_USBC_SS_MUX board_set_usb_mux(port, TYPEC_MUX_USB, @@ -1869,7 +1874,7 @@ void pd_task(void) /* reset message ID on connection */ pd[port].msg_id = 0; /* initial data role for sink is UFP */ - pd[port].data_role = PD_ROLE_UFP; + pd_set_data_role(port, PD_ROLE_UFP); #ifdef CONFIG_CHARGE_MANAGER initialized[port] = 1; typec_curr = get_typec_current_limit( diff --git a/driver/pi3usb9281.h b/driver/pi3usb9281.h index 392c02ae52..38f1125535 100644 --- a/driver/pi3usb9281.h +++ b/driver/pi3usb9281.h @@ -82,9 +82,12 @@ int pi3usb9281_get_ilim(int device_type, int charger_status); /* Set switch configuration to manual. */ int pi3usb9281_set_switch_manual(uint8_t chip_idx, int val); -/* Set bits to enable pins in manual switch register */ +/* Set bits to enable pins in manual switch register. */ int pi3usb9281_set_pins(uint8_t chip_idx, uint8_t mask); +/* Set D+/D-/Vbus switches to open or closed/auto-control. */ +int pi3usb9281_set_switches(uint8_t chip_idx, int open); + /* Reset PI3USB9281. */ int pi3usb9281_reset(uint8_t chip_idx); diff --git a/driver/usb_switch_pi3usb9281.c b/driver/usb_switch_pi3usb9281.c index 78580fc7a8..329c476708 100644 --- a/driver/usb_switch_pi3usb9281.c +++ b/driver/usb_switch_pi3usb9281.c @@ -185,6 +185,17 @@ int pi3usb9281_set_pins(uint8_t chip_idx, uint8_t val) return pi3usb9281_write(chip_idx, PI3USB9281_REG_MANUAL, val); } +int pi3usb9281_set_switches(uint8_t chip_idx, int open) +{ + uint8_t ctrl = pi3usb9281_read(chip_idx, PI3USB9281_REG_CONTROL) & 0x15; + if (open) + ctrl &= ~PI3USB9281_CTRL_SWITCH_AUTO; + else + ctrl |= PI3USB9281_CTRL_SWITCH_AUTO; + + return pi3usb9281_write(chip_idx, PI3USB9281_REG_CONTROL, ctrl); +} + static void pi3usb9281_init(void) { uint8_t dev_id;