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 <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/233711
Reviewed-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
Shawn Nematbakhsh
2014-12-05 16:23:11 -08:00
committed by chrome-internal-fetch
parent 4b8be2f778
commit c8f98e80fd
4 changed files with 28 additions and 7 deletions

View File

@@ -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,

View File

@@ -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(

View File

@@ -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);

View File

@@ -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;