mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 02:35:28 +00:00
samus: include a force source mode for dual-role ports
Include a force source mode for dual-role ports to allow us to force a dual-role port into being a source. BUG=chrome-os-partner:28782 BRANCH=none TEST=tested on plankton, verified using the pd 0 dualrole console command. Change-Id: Ic4c2a9e11984b34b1dec09d5c71e1fd15ed9198c Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/209071 Reviewed-by: Vic Yang <victoryang@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
3060d32ff9
commit
1faa6ee202
@@ -214,6 +214,11 @@ enum pd_states {
|
||||
PD_STATE_BIST,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/* Port dual-role state */
|
||||
enum pd_dual_role_states drp_state = PD_DRP_TOGGLE_OFF;
|
||||
#endif
|
||||
|
||||
static struct pd_protocol {
|
||||
/* current port role */
|
||||
uint8_t role;
|
||||
@@ -221,10 +226,6 @@ static struct pd_protocol {
|
||||
uint8_t msg_id;
|
||||
/* Port polarity : 0 => CC1 is CC line, 1 => CC2 is CC line */
|
||||
uint8_t polarity;
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/* Port dual role toggling flag */
|
||||
uint8_t dual_role_toggle;
|
||||
#endif
|
||||
/* PD state for port */
|
||||
enum pd_states task_state;
|
||||
} pd[PD_PORT_COUNT];
|
||||
@@ -813,22 +814,38 @@ static void execute_hard_reset(int port)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
void pd_set_dual_role(enum pd_dual_role_states dr_state)
|
||||
void pd_set_dual_role(enum pd_dual_role_states state)
|
||||
{
|
||||
int i;
|
||||
drp_state = state;
|
||||
|
||||
for (i = 0; i < PD_PORT_COUNT; i++) {
|
||||
pd[i].dual_role_toggle = (dr_state == PD_DRP_TOGGLE_ON);
|
||||
|
||||
/* Change to sink if in src disconnected state or force sink */
|
||||
/*
|
||||
* Change to sink if port is currently a source AND (new DRP
|
||||
* state is force sink OR new DRP state is toggle off and we
|
||||
* are in the source disconnected state).
|
||||
*/
|
||||
if (pd[i].role == PD_ROLE_SOURCE &&
|
||||
(pd[i].task_state == PD_STATE_SRC_DISCONNECTED ||
|
||||
dr_state == PD_DRP_FORCE_SINK)) {
|
||||
(drp_state == PD_DRP_FORCE_SINK ||
|
||||
(drp_state == PD_DRP_TOGGLE_OFF
|
||||
&& pd[i].task_state == PD_STATE_SRC_DISCONNECTED))) {
|
||||
pd[i].role = PD_ROLE_SINK;
|
||||
pd[i].task_state = PD_STATE_SNK_DISCONNECTED;
|
||||
pd_set_host_mode(i, 0);
|
||||
task_wake(PORT_TO_TASK_ID(i));
|
||||
}
|
||||
|
||||
/*
|
||||
* Change to source if port is currently a sink and the
|
||||
* new DRP state is force source.
|
||||
*/
|
||||
if (pd[i].role == PD_ROLE_SINK &&
|
||||
drp_state == PD_DRP_FORCE_SOURCE) {
|
||||
pd[i].role = PD_ROLE_SOURCE;
|
||||
pd[i].task_state = PD_STATE_SRC_DISCONNECTED;
|
||||
pd_set_host_mode(i, 1);
|
||||
task_wake(PORT_TO_TASK_ID(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -929,8 +946,9 @@ void pd_task(void)
|
||||
}
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/* Swap roles if time expired or VBUS is present */
|
||||
else if ((get_time().val >= next_role_swap ||
|
||||
pd_snk_is_vbus_provided(port))) {
|
||||
else if (drp_state != PD_DRP_FORCE_SOURCE &&
|
||||
(get_time().val >= next_role_swap ||
|
||||
pd_snk_is_vbus_provided(port))) {
|
||||
pd[port].role = PD_ROLE_SINK;
|
||||
pd[port].task_state = PD_STATE_SNK_DISCONNECTED;
|
||||
pd_set_host_mode(port, 0);
|
||||
@@ -1015,7 +1033,7 @@ void pd_task(void)
|
||||
pd[port].task_state =
|
||||
PD_STATE_SNK_DISCOVERY;
|
||||
}
|
||||
} else if (pd[port].dual_role_toggle &&
|
||||
} else if (drp_state == PD_DRP_TOGGLE_ON &&
|
||||
get_time().val >= next_role_swap) {
|
||||
/* Swap roles to source */
|
||||
pd[port].role = PD_ROLE_SOURCE;
|
||||
@@ -1182,19 +1200,33 @@ static int command_pd(int argc, char **argv)
|
||||
pd[port].task_state = PD_STATE_SRC_READY;
|
||||
task_wake(PORT_TO_TASK_ID(port));
|
||||
} else if (!strcasecmp(argv[2], "dualrole")) {
|
||||
int on;
|
||||
char *e;
|
||||
|
||||
if (argc < 4) {
|
||||
ccprintf("dual-role toggling: %d\n",
|
||||
pd[port].dual_role_toggle);
|
||||
ccprintf("dual-role toggling: ");
|
||||
switch (drp_state) {
|
||||
case PD_DRP_TOGGLE_ON:
|
||||
ccprintf("on\n");
|
||||
break;
|
||||
case PD_DRP_TOGGLE_OFF:
|
||||
ccprintf("off\n");
|
||||
break;
|
||||
case PD_DRP_FORCE_SINK:
|
||||
ccprintf("force sink\n");
|
||||
break;
|
||||
case PD_DRP_FORCE_SOURCE:
|
||||
ccprintf("force source\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
on = strtoi(argv[3], &e, 10);
|
||||
if (*e)
|
||||
if (!strcasecmp(argv[3], "on"))
|
||||
pd_set_dual_role(PD_DRP_TOGGLE_ON);
|
||||
else if (!strcasecmp(argv[3], "off"))
|
||||
pd_set_dual_role(PD_DRP_TOGGLE_OFF);
|
||||
else if (!strcasecmp(argv[3], "sink"))
|
||||
pd_set_dual_role(PD_DRP_FORCE_SINK);
|
||||
else if (!strcasecmp(argv[3], "source"))
|
||||
pd_set_dual_role(PD_DRP_FORCE_SOURCE);
|
||||
else
|
||||
return EC_ERROR_PARAM3;
|
||||
|
||||
pd_set_dual_role(on ? PD_DRP_TOGGLE_ON :
|
||||
PD_DRP_FORCE_SINK);
|
||||
}
|
||||
} else if (!strncasecmp(argv[2], "state", 5)) {
|
||||
const char * const state_names[] = {
|
||||
|
||||
@@ -138,15 +138,16 @@ enum pd_errors {
|
||||
enum pd_dual_role_states {
|
||||
PD_DRP_TOGGLE_ON,
|
||||
PD_DRP_TOGGLE_OFF,
|
||||
PD_DRP_FORCE_SINK
|
||||
PD_DRP_FORCE_SINK,
|
||||
PD_DRP_FORCE_SOURCE
|
||||
};
|
||||
/**
|
||||
* Set dual role state, from among enum pd_dual_role_states
|
||||
*
|
||||
* @param dr_state New state of dual-role port, selected from
|
||||
* enum pd_dual_role_states
|
||||
* @param state New state of dual-role port, selected from
|
||||
* enum pd_dual_role_states
|
||||
*/
|
||||
void pd_set_dual_role(enum pd_dual_role_states dr_state);
|
||||
void pd_set_dual_role(enum pd_dual_role_states state);
|
||||
#endif
|
||||
|
||||
/* --- Policy layer functions --- */
|
||||
|
||||
Reference in New Issue
Block a user