pd: Enable alternate mode support for DP.

Change effects:
1. samus_pd: Acts as initiator of SVDM discovery once its reaches source
             ready and upon identifying UFP with display port
	     alternate mode enters that mode.
2. hoho: Acts as responder for SVDM discovery providing its identity,
         svids and svid capabilities which are display port only.  If
	 asked to enter display port alternate mode it does.
3. fruitpie: Acts a initiator with mock display port mode.

BRANCH=none
BUG=chrome-os-partner:30645
TEST=manual,
Plug hoho into samus_pd
- see dpout
- from console
  > typec 0
  Port C0: CC1 451 mV  CC2 111 mV (polarity:CC1)
  Superspeed DP1

Change-Id: I1a76767353a69baeceffa3e79c37dcea77b8337d
Signed-off-by: Todd Broch <tbroch@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/221354
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Todd Broch
2014-10-01 18:49:50 -07:00
committed by chrome-internal-fetch
parent 44e4f7cfe7
commit 8a6c72022f
7 changed files with 67 additions and 23 deletions

View File

@@ -21,9 +21,9 @@
#define CONFIG_USB_MS
#define CONFIG_USB_MS_BUFFER_SIZE SPI_FLASH_MAX_WRITE_SIZE
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_CUSTOM_VDM
#define CONFIG_USB_PD_ALT_MODE
#define CONFIG_USB_PD_ALT_MODE_DFP
#define CONFIG_USB_PD_CUSTOM_VDM
#define CONFIG_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_INTERNAL_COMP
#define CONFIG_USBC_SS_MUX

View File

@@ -186,20 +186,20 @@ int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
return pd_custom_vdm(port, cnt, payload, rpayload);
}
static void svdm_enter_dp_mode(uint32_t mode_caps)
static void svdm_enter_dp_mode(int port, uint32_t mode_caps)
{
ccprintf("Entering mode w/ vdo = %08x\n", mode_caps);
}
static void svdm_exit_dp_mode(void)
static void svdm_exit_dp_mode(int port)
{
ccprintf("Exiting mode\n");
/* return to safe config */
}
static struct svdm_amode_data supported_modes[] = {
const struct svdm_amode_fx supported_modes[] = {
{
.svid = 0xff01,
.svid = USB_SID_DISPLAYPORT,
.enter = &svdm_enter_dp_mode,
.exit = &svdm_exit_dp_mode,
},
@@ -208,20 +208,17 @@ static struct svdm_amode_data supported_modes[] = {
void pd_dfp_choose_modes(struct pd_policy *pe)
{
int i, j;
struct svdm_amode_data *modep;
pe->amode_cnt = sizeof(supported_modes) / sizeof(struct
svdm_amode_data);
pe->amodes = modep = supported_modes;
pe->amode_cnt = ARRAY_SIZE(supported_modes);
pe->amodes->fx = supported_modes;
for (i = 0; i < pe->amode_cnt; i++) {
for (j = 0; j < pe->svid_cnt; j++) {
if (pe->svids[j].svid == modep->svid) {
if (pe->svids[j].svid == pe->amodes->fx[i].svid) {
/* TODO(tbroch) need more elaborate mode
resolution */
modep->mode_caps = &pe->svids[j].mode_vdo[0];
modep->amode = dfp_amode1;
pe->amodes[i].mode_caps = pe->svids[j].mode_vdo;
pe->amodes[i].amode = dfp_amode1;
break;
}
}
modep++;
}
}

View File

@@ -188,9 +188,9 @@ static int pd_custom_vdm(int port, int cnt, uint32_t *payload,
rsize = 7;
break;
default:
/* Unknown : do not answer */
return 0;
rsize = 0;
}
ccprintf("%T] DONE\n");
/* respond (positively) to the request */
payload[0] |= VDO_SRC_RESPONDER;

View File

@@ -27,6 +27,8 @@
#define CONFIG_STM_HWTIMER32
#undef CONFIG_TASK_PROFILING
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_ALT_MODE
#define CONFIG_USB_PD_ALT_MODE_DFP
#undef CONFIG_USB_PD_COMM_ENABLED
#define CONFIG_USB_PD_COMM_ENABLED 0
#define CONFIG_USB_PD_CUSTOM_VDM

View File

@@ -158,6 +158,12 @@ static void pd_send_host_event(void)
}
/* ----------------- Vendor Defined Messages ------------------ */
const struct svdm_response svdm_rsp = {
.identity = NULL,
.svids = NULL,
.modes = NULL,
};
static int pd_custom_vdm(int port, int cnt, uint32_t *payload,
uint32_t **rpayload)
{
@@ -208,6 +214,41 @@ int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
return pd_custom_vdm(port, cnt, payload, rpayload);
}
static void svdm_enter_dp_mode(int port, uint32_t mode_caps)
{
board_set_usb_mux(port, TYPEC_MUX_DP, pd_get_polarity(port));
}
static void svdm_exit_dp_mode(int port)
{
board_set_usb_mux(port, TYPEC_MUX_NONE, pd_get_polarity(port));
}
const struct svdm_amode_fx supported_modes[] = {
{
.svid = USB_SID_DISPLAYPORT,
.enter = &svdm_enter_dp_mode,
.exit = &svdm_exit_dp_mode,
},
};
void pd_dfp_choose_modes(struct pd_policy *pe)
{
int i, j;
pe->amode_cnt = ARRAY_SIZE(supported_modes);
pe->amodes->fx = supported_modes;
for (i = 0; i < pe->amode_cnt; i++) {
for (j = 0; j < pe->svid_cnt; j++) {
if (pe->svids[j].svid == pe->amodes->fx[i].svid) {
/* TODO(tbroch) need more elaborate mode
resolution */
pe->amodes[i].mode_caps = pe->svids[j].mode_vdo;
pe->amodes[i].amode = dfp_amode1;
break;
}
}
}
}
/****************************************************************************/
/* Console commands */
static int command_ec_int(int argc, char **argv)

View File

@@ -106,8 +106,8 @@ static int dfp_enter_modes(int port, uint32_t *payload)
if (modep->amode == dfp_amode_none)
return 0;
modep->enter(*modep->mode_caps);
payload[0] = VDO(modep->svid, 1,
modep->fx->enter(port, *modep->mode_caps);
payload[0] = VDO(modep->fx->svid, 1,
CMD_ENTER_MODE |
VDO_OPOS(modep->amode));
pe[port].amode_idx++;
@@ -124,8 +124,8 @@ int pd_exit_modes(int port, uint32_t *payload)
if (modep->amode == dfp_amode_none)
return 1;
modep->exit();
payload[0] = VDO(modep->svid, 1,
modep->fx->exit(port);
payload[0] = VDO(modep->fx->svid, 1,
CMD_EXIT_MODE |
VDO_OPOS(modep->amode));
pe[port].amode_idx++;
@@ -146,7 +146,7 @@ static void dump_pe(int port)
}
for (i = 0; i < pe[port].amode_cnt; i++) {
ccprintf("MODE[%d]: svid:%04x mode:%d caps:%08x\n", i,
modep->svid, modep->amode, *modep->mode_caps);
modep->fx->svid, modep->amode, *modep->mode_caps);
modep++;
}
}

View File

@@ -134,12 +134,16 @@ struct svdm_svid_data {
uint32_t mode_vdo[PDO_MODES];
};
struct svdm_amode_data {
struct svdm_amode_fx {
uint16_t svid;
void (*enter)(int port, uint32_t mode_caps);
void (*exit)(int port);
};
struct svdm_amode_data {
const struct svdm_amode_fx *fx;
enum dfp_amode amode;
uint32_t *mode_caps;
void (*enter)(uint32_t mode_caps);
void (*exit)(void);
};
/* Policy structure for driving alternate mode */