mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 00:51:29 +00:00
Host command for USB PD role and mux control
This allows us to control PD role and type-C mux through ectool.
BUG=None
TEST=Change role/mux on samus using ectool:
$ ./ectool --interface=lpc --dev 1 usbpd 0 usb
-> In EC console, 'typec 0' shows 'Superspeed USB1'
$ ./ectool --interface=lpc --dev 1 usbpd 0 sink
-> In EC console, 'pd 0 state' shows 'force sink'
BRANCH=None
Change-Id: I5b90fb53ea1c30e3bc269c12d61e4398c5dcee6c
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/209956
Reviewed-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
9797f654d9
commit
139a9c6880
@@ -8,8 +8,10 @@
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "crc.h"
|
||||
#include "ec_commands.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "host_command.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
@@ -1333,4 +1335,59 @@ DECLARE_CONSOLE_COMMAND(typec, command_typec,
|
||||
NULL);
|
||||
#endif /* CONFIG_USBC_SS_MUX */
|
||||
|
||||
static int hc_usb_pd_control(struct host_cmd_handler_args *args)
|
||||
{
|
||||
const struct ec_params_usb_pd_control *p = args->params;
|
||||
|
||||
if (p->role != USB_PD_CTRL_ROLE_NO_CHANGE) {
|
||||
enum pd_dual_role_states role;
|
||||
switch (p->role) {
|
||||
case USB_PD_CTRL_ROLE_TOGGLE_ON:
|
||||
role = PD_DRP_TOGGLE_ON;
|
||||
break;
|
||||
case USB_PD_CTRL_ROLE_TOGGLE_OFF:
|
||||
role = PD_DRP_TOGGLE_OFF;
|
||||
break;
|
||||
case USB_PD_CTRL_ROLE_FORCE_SINK:
|
||||
role = PD_DRP_FORCE_SINK;
|
||||
break;
|
||||
case USB_PD_CTRL_ROLE_FORCE_SOURCE:
|
||||
role = PD_DRP_FORCE_SOURCE;
|
||||
break;
|
||||
default:
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
pd_set_dual_role(role);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBC_SS_MUX
|
||||
if (p->mux != USB_PD_CTRL_MUX_NO_CHANGE) {
|
||||
enum typec_mux mux;
|
||||
switch (p->mux) {
|
||||
case USB_PD_CTRL_MUX_NONE:
|
||||
mux = TYPEC_MUX_NONE;
|
||||
break;
|
||||
case USB_PD_CTRL_MUX_USB:
|
||||
mux = TYPEC_MUX_USB;
|
||||
break;
|
||||
case USB_PD_CTRL_MUX_AUTO:
|
||||
case USB_PD_CTRL_MUX_DP:
|
||||
mux = TYPEC_MUX_DP;
|
||||
break;
|
||||
case USB_PD_CTRL_MUX_DOCK:
|
||||
mux = TYPEC_MUX_DOCK;
|
||||
break;
|
||||
default:
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
board_set_usb_mux(p->port, mux, pd_get_polarity(p->port));
|
||||
}
|
||||
#endif /* CONFIG_USBC_SS_MUX */
|
||||
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_USB_PD_CONTROL,
|
||||
hc_usb_pd_control,
|
||||
EC_VER_MASK(0));
|
||||
|
||||
#endif /* CONFIG_COMMON_RUNTIME */
|
||||
|
||||
@@ -2500,6 +2500,32 @@ struct ec_response_pd_status {
|
||||
int8_t status; /* currently empty */
|
||||
} __packed;
|
||||
|
||||
/* Set USB type-C port role and muxes */
|
||||
#define EC_CMD_USB_PD_CONTROL 0x101
|
||||
|
||||
enum usb_pd_control_role {
|
||||
USB_PD_CTRL_ROLE_NO_CHANGE = 0,
|
||||
USB_PD_CTRL_ROLE_TOGGLE_ON = 1, /* == AUTO */
|
||||
USB_PD_CTRL_ROLE_TOGGLE_OFF = 2,
|
||||
USB_PD_CTRL_ROLE_FORCE_SINK = 3,
|
||||
USB_PD_CTRL_ROLE_FORCE_SOURCE = 4,
|
||||
};
|
||||
|
||||
enum usb_pd_control_mux {
|
||||
USB_PD_CTRL_MUX_NO_CHANGE = 0,
|
||||
USB_PD_CTRL_MUX_NONE = 1,
|
||||
USB_PD_CTRL_MUX_USB = 2,
|
||||
USB_PD_CTRL_MUX_DP = 3,
|
||||
USB_PD_CTRL_MUX_DOCK = 4,
|
||||
USB_PD_CTRL_MUX_AUTO = 5,
|
||||
};
|
||||
|
||||
struct ec_params_usb_pd_control {
|
||||
uint8_t port;
|
||||
uint8_t role;
|
||||
uint8_t mux;
|
||||
} __packed;
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Passthru commands
|
||||
|
||||
@@ -177,6 +177,9 @@ const char help_str[] =
|
||||
" Set USB charging mode\n"
|
||||
" usbmux <mux>\n"
|
||||
" Set USB mux switch state\n"
|
||||
" usbpd <port> <auto | "
|
||||
"[toggle|toggle-off|sink|source] [none|usb|dp|dock]>\n"
|
||||
" Control USB PD/type-C\n"
|
||||
" version\n"
|
||||
" Prints EC version\n"
|
||||
" wireless <flags> [<mask> [<suspend_flags> <suspend_mask>]]\n"
|
||||
@@ -2413,6 +2416,81 @@ int cmd_usb_mux(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_usb_pd(int argc, char *argv[])
|
||||
{
|
||||
const char *role_str[] = {"", "toggle", "toggle-off", "sink", "source"};
|
||||
const char *mux_str[] = {"", "none", "usb", "dp", "dock"};
|
||||
struct ec_params_usb_pd_control p;
|
||||
int rv, i, j;
|
||||
int option_ok;
|
||||
char *e;
|
||||
|
||||
p.role = USB_PD_CTRL_ROLE_NO_CHANGE;
|
||||
p.mux = USB_PD_CTRL_MUX_NO_CHANGE;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "No option specified.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p.port = strtol(argv[1], &e, 0);
|
||||
if (e && *e) {
|
||||
fprintf(stderr, "Invalid param (port)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 2; i < argc; ++i) {
|
||||
option_ok = 0;
|
||||
if (!strcmp(argv[i], "auto")) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "\"auto\" may not be used "
|
||||
"with other options.\n");
|
||||
return -1;
|
||||
}
|
||||
p.role = USB_PD_CTRL_ROLE_TOGGLE_ON;
|
||||
p.mux = USB_PD_CTRL_MUX_AUTO;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(role_str); ++j) {
|
||||
if (!strcmp(argv[i], role_str[j])) {
|
||||
if (p.role != USB_PD_CTRL_ROLE_NO_CHANGE) {
|
||||
fprintf(stderr,
|
||||
"Only one role allowed.\n");
|
||||
return -1;
|
||||
}
|
||||
p.role = j;
|
||||
option_ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (option_ok)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(mux_str); ++j) {
|
||||
if (!strcmp(argv[i], mux_str[j])) {
|
||||
if (p.mux != USB_PD_CTRL_MUX_NO_CHANGE) {
|
||||
fprintf(stderr,
|
||||
"Only one mux type allowed.\n");
|
||||
return -1;
|
||||
}
|
||||
p.mux = j;
|
||||
option_ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!option_ok) {
|
||||
fprintf(stderr, "Unknown option: %s\n", argv[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
rv = ec_command(EC_CMD_USB_PD_CONTROL, 0, &p, sizeof(p), NULL, 0);
|
||||
return (rv < 0 ? rv : 0);
|
||||
}
|
||||
|
||||
|
||||
int cmd_kbpress(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_mkbp_simulate_key p;
|
||||
@@ -4533,6 +4611,7 @@ const struct command commands[] = {
|
||||
{"tmp006raw", cmd_tmp006raw},
|
||||
{"usbchargemode", cmd_usb_charge_set_mode},
|
||||
{"usbmux", cmd_usb_mux},
|
||||
{"usbpd", cmd_usb_pd},
|
||||
{"version", cmd_version},
|
||||
{"wireless", cmd_wireless},
|
||||
{NULL, NULL}
|
||||
|
||||
Reference in New Issue
Block a user