diff options
author | Dino Li <dino.li@ite.com.tw> | 2016-04-18 15:41:27 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-18 17:32:41 -0700 |
commit | 69668a04436700071bc2a26400f5f52f0e499020 (patch) | |
tree | 163d7ff68d473b703471e3639692041508ad0d93 /driver | |
parent | 068cd0850684ee28a5a514e5a270edce2edb3979 (diff) | |
download | chrome-ec-69668a04436700071bc2a26400f5f52f0e499020.tar.gz |
chip: it83xx: add USBPD module
Add USBPD module for it8320 emulation board
BRANCH=none
BUG=none
TEST=manual
plug zinger adapter, connect uart console and type commands:
pd 1 dev [20|12|5]
pd 1 charger
pd 1 swap power
and check PD states
Change-Id: I9ca1822deeb4b4dce1279a09490ed4175890cf3a
Signed-off-by: Leon-Lee <leon.lee@ite.com.tw>
Signed-off-by: Dino Li <dino.li@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/326230
Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/tcpm/it83xx.c | 456 | ||||
-rw-r--r-- | driver/tcpm/it83xx_pd.h | 112 |
3 files changed, 569 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk index 19e108eb89..999cc52032 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -77,6 +77,7 @@ driver-$(CONFIG_THERMISTOR_NCP15WB)+=temp_sensor/thermistor_ncp15wb.o driver-$(CONFIG_USB_PD_TCPM_STUB)+=tcpm/stub.o driver-$(CONFIG_USB_PD_TCPM_TCPCI)+=tcpm/tcpci.o driver-$(CONFIG_USB_PD_TCPM_FUSB302)+=tcpm/fusb302.o +driver-$(CONFIG_USB_PD_TCPM_ITE83XX)+=tcpm/it83xx.o # USB switches driver-$(CONFIG_USB_SWITCH_PI3USB9281)+=usb_switch_pi3usb9281.o diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c new file mode 100644 index 0000000000..4a1257514b --- /dev/null +++ b/driver/tcpm/it83xx.c @@ -0,0 +1,456 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* TCPM for MCU also running TCPC */ + +#include "common.h" +#include "config.h" +#include "console.h" +#include "it83xx_pd.h" +#include "registers.h" +#include "system.h" +#include "task.h" +#include "timer.h" +#include "util.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" + +const struct usbpd_ctrl_t usbpd_ctrl_regs[] = { + {&IT83XX_GPIO_GPCRF4, &IT83XX_GPIO_GPCRF5, IT83XX_IRQ_USBPD0}, + {&IT83XX_GPIO_GPCRH1, &IT83XX_GPIO_GPCRH2, IT83XX_IRQ_USBPD1}, +}; +BUILD_ASSERT(ARRAY_SIZE(usbpd_ctrl_regs) == USBPD_PORT_COUNT); + +static enum tcpc_cc_voltage_status it83xx_get_cc( + enum usbpd_port port, + enum usbpd_cc_pin cc_pin) +{ + enum usbpd_ufp_volt_status ufp_volt; + enum usbpd_dfp_volt_status dfp_volt; + enum tcpc_cc_voltage_status cc_state = TYPEC_CC_VOLT_OPEN; + int pull; + + pull = (cc_pin == USBPD_CC_PIN_1) ? + USBPD_GET_CC1_PULL_REGISTER_SELECTION(port) : + USBPD_GET_CC2_PULL_REGISTER_SELECTION(port); + + /* select Rp */ + if (pull) + CLEAR_MASK(cc_state, (1 << 2)); + /* select Rd */ + else + SET_MASK(cc_state, (1 << 2)); + + /* sink */ + if (USBPD_GET_POWER_ROLE(port) == USBPD_POWER_ROLE_CONSUMER) { + if (cc_pin == USBPD_CC_PIN_1) + ufp_volt = IT83XX_USBPD_UFPVDR(port) & 0xf; + else + ufp_volt = (IT83XX_USBPD_UFPVDR(port) >> 4) & 0xf; + + switch (ufp_volt) { + case USBPD_UFP_STATE_SNK_DEF: + cc_state |= (TYPEC_CC_VOLT_SNK_DEF & 3); + break; + case USBPD_UFP_STATE_SNK_1_5: + cc_state |= (TYPEC_CC_VOLT_SNK_1_5 & 3); + break; + case USBPD_UFP_STATE_SNK_3_0: + cc_state |= (TYPEC_CC_VOLT_SNK_3_0 & 3); + break; + case USBPD_UFP_STATE_SNK_OPEN: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + default: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + } + /* source */ + } else { + if (cc_pin == USBPD_CC_PIN_1) + dfp_volt = IT83XX_USBPD_DFPVDR(port) & 0xf; + else + dfp_volt = (IT83XX_USBPD_DFPVDR(port) >> 4) & 0xf; + + switch (dfp_volt) { + case USBPD_DFP_STATE_SRC_RA: + cc_state |= TYPEC_CC_VOLT_RA; + break; + case USBPD_DFP_STATE_SRC_RD: + cc_state |= TYPEC_CC_VOLT_RD; + break; + case USBPD_DFP_STATE_SRC_OPEN: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + default: + cc_state = TYPEC_CC_VOLT_OPEN; + break; + } + } + + return cc_state; +} + +static void it83xx_rx_data(enum usbpd_port port, int *head, uint32_t *buf) +{ + struct usbpd_header *p_head = (struct usbpd_header *)head; + *head = 0; + + if (!USBPD_IS_RX_DONE(port)) + return; + + /* store header */ + *p_head = *((struct usbpd_header *)IT83XX_USBPD_RMH_BASE(port)); + /* check data message */ + if (p_head->data_obj_num) + memcpy(buf, + (uint8_t *)IT83XX_USBPD_RDO_BASE(port), + p_head->data_obj_num * 4); + /* + * Note: clear RX done interrupt after get the data. + * If clear this bit, USBPD receives next packet + */ + IT83XX_USBPD_MRSR(port) = USBPD_REG_MASK_RX_MSG_VALID; +} + +static enum tcpc_transmit_complete it83xx_tx_data( + enum usbpd_port port, + enum tcpm_transmit_type type, + uint8_t msg_type, + uint8_t length, + const uint32_t *buf) +{ + int r; + uint32_t evt; + + /* set message type */ + IT83XX_USBPD_MTSR0(port) = + (IT83XX_USBPD_MTSR0(port) & ~0x1f) | (msg_type & 0xf); + /* SOP type: bit[5:4] 00 SOP, 01 SOP', 10 SOP" */ + IT83XX_USBPD_MTSR1(port) = + (IT83XX_USBPD_MTSR1(port) & ~0x30) | ((type & 0x3) << 4); + /* bit7: transmit message is send to cable or not */ + if (TCPC_TX_SOP == type) + IT83XX_USBPD_MTSR0(port) &= ~USBPD_REG_MASK_CABLE_ENABLE; + else + IT83XX_USBPD_MTSR0(port) |= USBPD_REG_MASK_CABLE_ENABLE; + /* clear msg length */ + IT83XX_USBPD_MTSR1(port) &= (~0x7); + /* Limited by PD_HEADER_CNT() */ + ASSERT(length <= 0x7); + + if (length) { + /* set data bit */ + IT83XX_USBPD_MTSR0(port) |= (1 << 4); + /* set data length setting */ + IT83XX_USBPD_MTSR1(port) |= length; + /* set data */ + memcpy((uint8_t *)IT83XX_USBPD_TDO_BASE(port), buf, length * 4); + } + + for (r = 0; r <= PD_RETRY_COUNT; r++) { + /* Start TX */ + USBPD_KICK_TX_START(port); + evt = task_wait_event_mask(TASK_EVENT_PHY_TX_DONE, + PD_T_TCPC_TX_TIMEOUT); + /* check TX status */ + if (USBPD_IS_TX_ERR(port) || (evt & TASK_EVENT_TIMER)) { + /* + * If discard, means HW doesn't send the msg and resend. + */ + if (USBPD_IS_TX_DISCARD(port)) + continue; + else + return TCPC_TX_COMPLETE_FAILED; + } else { + break; + } + } + + if (r > PD_RETRY_COUNT) + return TCPC_TX_COMPLETE_DISCARDED; + + return TCPC_TX_COMPLETE_SUCCESS; +} + +static enum tcpc_transmit_complete it83xx_send_hw_reset(enum usbpd_port port, + enum tcpm_transmit_type reset_type) +{ + if (reset_type == TCPC_TX_CABLE_RESET) + IT83XX_USBPD_MTSR0(port) |= USBPD_REG_MASK_CABLE_ENABLE; + else + IT83XX_USBPD_MTSR0(port) &= ~USBPD_REG_MASK_CABLE_ENABLE; + + /* send hard reset */ + USBPD_SEND_HARD_RESET(port); + usleep(MSEC); + + if (IT83XX_USBPD_MTSR0(port) & USBPD_REG_MASK_SEND_HW_RESET) + return TCPC_TX_COMPLETE_FAILED; + + return TCPC_TX_COMPLETE_SUCCESS; +} + +static void it83xx_send_bist_mode2_pattern(enum usbpd_port port) +{ + USBPD_ENABLE_SEND_BIST_MODE_2(port); + usleep(PD_T_BIST_TRANSMIT); + USBPD_DISABLE_SEND_BIST_MODE_2(port); +} + +static void it83xx_enable_vconn(enum usbpd_port port, int enabled) +{ + enum usbpd_cc_pin cc_pin; + + if (USBPD_GET_PULL_CC_SELECTION(port)) + cc_pin = USBPD_CC_PIN_1; + else + cc_pin = USBPD_CC_PIN_2; + + if (enabled) { + /* Disable unused CC to become VCONN */ + if (cc_pin == USBPD_CC_PIN_1) { + IT83XX_USBPD_CCCSR(port) = + (IT83XX_USBPD_CCCSR(port) | 0xa0) & ~0xa; + IT83XX_USBPD_CCPSR(port) = (IT83XX_USBPD_CCPSR(port) + & ~USBPD_REG_MASK_DISCONNECT_POWER_CC2) + | USBPD_REG_MASK_DISCONNECT_POWER_CC1; + } else { + IT83XX_USBPD_CCCSR(port) = + (IT83XX_USBPD_CCCSR(port) | 0xa) & ~0xa0; + IT83XX_USBPD_CCPSR(port) = (IT83XX_USBPD_CCPSR(port) + & ~USBPD_REG_MASK_DISCONNECT_POWER_CC1) + | USBPD_REG_MASK_DISCONNECT_POWER_CC2; + } + } else { + /* Enable cc1 and cc2 */ + IT83XX_USBPD_CCCSR(port) &= ~0xaa; + IT83XX_USBPD_CCPSR(port) |= + (USBPD_REG_MASK_DISCONNECT_POWER_CC1 | + USBPD_REG_MASK_DISCONNECT_POWER_CC2); + } +} + +static void it83xx_set_power_role(enum usbpd_port port, int power_role) +{ + /* PD_ROLE_SINK 0, PD_ROLE_SOURCE 1 */ + if (power_role == PD_ROLE_SOURCE) { + /* bit0: source */ + SET_MASK(IT83XX_USBPD_PDMSR(port), (1 << 0)); + /* bit1: CC1 select Rp */ + SET_MASK(IT83XX_USBPD_CCGCR(port), (1 << 1)); + /* bit3: CC2 select Rp */ + SET_MASK(IT83XX_USBPD_BMCSR(port), (1 << 3)); + } else { + /* bit0: sink */ + CLEAR_MASK(IT83XX_USBPD_PDMSR(port), (1 << 0)); + /* bit1: CC1 select Rd */ + CLEAR_MASK(IT83XX_USBPD_CCGCR(port), (1 << 1)); + /* bit3: CC2 select Rd */ + CLEAR_MASK(IT83XX_USBPD_BMCSR(port), (1 << 3)); + } +} + +static void it83xx_set_data_role(enum usbpd_port port, int pd_role) +{ + /* 0: PD_ROLE_UFP 1: PD_ROLE_DFP */ + IT83XX_USBPD_PDMSR(port) = + (IT83XX_USBPD_PDMSR(port) & ~0xc) | ((pd_role & 0x1) << 2); +} + +static void it83xx_init(enum usbpd_port port, int role) +{ + /* defalut PD Clock = PLL 48 / 6 = 8M. */ + IT83XX_ECPM_SCDCR4 = (IT83XX_ECPM_SCDCR4 & 0xf0) | 5; + /* reset */ + IT83XX_USBPD_GCR(port) = 0; + USBPD_SW_RESET(port); + /* set SOP: receive SOP message only. + * bit[7]: SOP" support enable. + * bit[6]: SOP' support enable. + * bit[5]: SOP support enable. + */ + IT83XX_USBPD_PDMSR(port) = USBPD_REG_MASK_SOP_ENABLE; + /* W/C status */ + IT83XX_USBPD_ISR(port) = 0xff; + /* enable cc, select cc1 and Rd (80uA output when Rp selected) */ + IT83XX_USBPD_CCGCR(port) = 0xd; + /* change data role as the same power role */ + it83xx_set_data_role(port, role); + /* set power role */ + it83xx_set_power_role(port, role); + /* disable all interrupts */ + IT83XX_USBPD_IMR(port) = 0xff; + /* enable tx done and reset detect interrupt */ + IT83XX_USBPD_IMR(port) &= ~(USBPD_REG_MASK_MSG_TX_DONE | + USBPD_REG_MASK_HARD_RESET_DETECT); + IT83XX_USBPD_CCPSR(port) = 0xff; + /* cc connect */ + IT83XX_USBPD_CCCSR(port) = 0; + /* disable vconn */ + it83xx_enable_vconn(port, 0); + /* TX start from high */ + IT83XX_USBPD_CCADCR(port) |= (1 << 6); + /* enable cc1/cc2 */ + *usbpd_ctrl_regs[port].cc1 = 0x86; + *usbpd_ctrl_regs[port].cc2 = 0x86; + task_clear_pending_irq(usbpd_ctrl_regs[port].irq); + task_enable_irq(usbpd_ctrl_regs[port].irq); + USBPD_START(port); +} + +static void it83xx_select_polarity(enum usbpd_port port, + enum usbpd_cc_pin cc_pin) +{ + /* cc1/cc2 selection */ + if (cc_pin == USBPD_CC_PIN_1) + SET_MASK(IT83XX_USBPD_CCGCR(port), (1 << 0)); + else + CLEAR_MASK(IT83XX_USBPD_CCGCR(port), (1 << 0)); +} + +static void it83xx_set_cc(enum usbpd_port port, int pull) +{ + if (pull == TYPEC_CC_RD) + it83xx_set_power_role(port, PD_ROLE_SINK); + else if (pull == TYPEC_CC_RP) + it83xx_set_power_role(port, PD_ROLE_SOURCE); +} + +static int it83xx_tcpm_init(int port) +{ + /* Initialize physical layer */ + it83xx_init(port, PD_ROLE_DEFAULT); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_get_cc(int port, int *cc1, int *cc2) +{ + *cc2 = it83xx_get_cc(port, USBPD_CC_PIN_2); + *cc1 = it83xx_get_cc(port, USBPD_CC_PIN_1); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_cc(int port, int pull) +{ + it83xx_set_cc(port, pull); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_polarity(int port, int polarity) +{ + it83xx_select_polarity(port, polarity); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_vconn(int port, int enable) +{ +#ifdef CONFIG_USBC_VCONN + it83xx_enable_vconn(port, enable); + /* vconn switch */ + board_pd_vconn_ctrl(port, + USBPD_GET_PULL_CC_SELECTION(port) ? + USBPD_CC_PIN_2 : + USBPD_CC_PIN_1, enable); +#endif + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_msg_header(int port, int power_role, int data_role) +{ + it83xx_set_power_role(port, power_role); + it83xx_set_data_role(port, data_role); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_set_rx_enable(int port, int enable) +{ + int i; + + if (enable) { + IT83XX_USBPD_IMR(port) &= ~USBPD_REG_MASK_MSG_RX_DONE; + USBPD_ENABLE_BMC_PHY(port); + } else { + IT83XX_USBPD_IMR(port) |= USBPD_REG_MASK_MSG_RX_DONE; + USBPD_DISABLE_BMC_PHY(port); + } + + /* If any PD port is connected, then disable deep sleep */ + for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; ++i) + if (IT83XX_USBPD_GCR(port) | USBPD_REG_MASK_BMC_PHY) + break; + + if (i == CONFIG_USB_PD_PORT_COUNT) + enable_sleep(SLEEP_MASK_USB_PD); + else + disable_sleep(SLEEP_MASK_USB_PD); + + return EC_SUCCESS; +} + +static int it83xx_tcpm_get_message(int port, uint32_t *payload, int *head) +{ + it83xx_rx_data(port, head, payload); + /* un-mask RX done interrupt */ + IT83XX_USBPD_IMR(port) &= ~USBPD_REG_MASK_MSG_RX_DONE; + + return EC_SUCCESS; +} + +static int it83xx_tcpm_transmit(int port, + enum tcpm_transmit_type type, + uint16_t header, + const uint32_t *data) +{ + int status = TCPC_TX_COMPLETE_FAILED; + + switch (type) { + case TCPC_TX_SOP: + case TCPC_TX_SOP_PRIME: + case TCPC_TX_SOP_PRIME_PRIME: + status = it83xx_tx_data(port, + type, + PD_HEADER_TYPE(header), + PD_HEADER_CNT(header), + data); + break; + case TCPC_TX_BIST_MODE_2: + it83xx_send_bist_mode2_pattern(port); + status = TCPC_TX_COMPLETE_SUCCESS; + break; + case TCPC_TX_HARD_RESET: + case TCPC_TX_CABLE_RESET: + status = it83xx_send_hw_reset(port, type); + break; + default: + status = TCPC_TX_COMPLETE_FAILED; + break; + } + pd_transmit_complete(port, status); + + return EC_SUCCESS; +} + +const struct tcpm_drv it83xx_tcpm_drv = { + .init = &it83xx_tcpm_init, + .get_cc = &it83xx_tcpm_get_cc, +#ifdef CONFIG_USB_PD_TCPM_VBUS + .get_vbus_level = NULL, +#endif + .set_cc = &it83xx_tcpm_set_cc, + .set_polarity = &it83xx_tcpm_set_polarity, + .set_vconn = &it83xx_tcpm_set_vconn, + .set_msg_header = &it83xx_tcpm_set_msg_header, + .set_rx_enable = &it83xx_tcpm_set_rx_enable, + .get_message = &it83xx_tcpm_get_message, + .transmit = &it83xx_tcpm_transmit, + .tcpc_alert = NULL, +}; diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h new file mode 100644 index 0000000000..0702b24b84 --- /dev/null +++ b/driver/tcpm/it83xx_pd.h @@ -0,0 +1,112 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* USB Power delivery port management */ +#ifndef __CROS_EC_DRIVER_TCPM_IT83XX_H +#define __CROS_EC_DRIVER_TCPM_IT83XX_H + +#define TASK_EVENT_PHY_TX_DONE TASK_EVENT_CUSTOM((1 << 17)) + +#define SET_MASK(reg, bit_mask) ((reg) |= (bit_mask)) +#define CLEAR_MASK(reg, bit_mask) ((reg) &= (~(bit_mask))) +#define IS_MASK_SET(reg, bit_mask) (((reg) & (bit_mask)) != 0) +#define IS_MASK_CLEAR(reg, bit_mask) (((reg) & (bit_mask)) == 0) + +/* macros for set */ +#define USBPD_KICK_TX_START(port) \ + SET_MASK(IT83XX_USBPD_MTCR(port), \ + USBPD_REG_MASK_TX_START) +#define USBPD_SEND_HARD_RESET(port) \ + SET_MASK(IT83XX_USBPD_MTSR0(port), \ + USBPD_REG_MASK_SEND_HW_RESET) +#define USBPD_SW_RESET(port) \ + SET_MASK(IT83XX_USBPD_GCR(port), \ + USBPD_REG_MASK_SW_RESET_BIT) +#define USBPD_ENABLE_BMC_PHY(port) \ + SET_MASK(IT83XX_USBPD_GCR(port), \ + USBPD_REG_MASK_BMC_PHY) +#define USBPD_DISABLE_BMC_PHY(port) \ + CLEAR_MASK(IT83XX_USBPD_GCR(port), \ + USBPD_REG_MASK_BMC_PHY) +#define USBPD_START(port) \ + CLEAR_MASK(IT83XX_USBPD_CCGCR(port), \ + USBPD_REG_MASK_DISABLE_CC) +#define USBPD_ENABLE_SEND_BIST_MODE_2(port) \ + SET_MASK(IT83XX_USBPD_MTSR0(port), \ + USBPD_REG_MASK_SEND_BIST_MODE_2) +#define USBPD_DISABLE_SEND_BIST_MODE_2(port) \ + CLEAR_MASK(IT83XX_USBPD_MTSR0(port), \ + USBPD_REG_MASK_SEND_BIST_MODE_2) + +/* macros for get */ +#define USBPD_GET_POWER_ROLE(port) \ + (IT83XX_USBPD_PDMSR(port) & 1) +#define USBPD_GET_CC1_PULL_REGISTER_SELECTION(port) \ + (IT83XX_USBPD_CCGCR(port) & (1 << 1)) +#define USBPD_GET_CC2_PULL_REGISTER_SELECTION(port) \ + (IT83XX_USBPD_BMCSR(port) & (1 << 3)) +#define USBPD_GET_PULL_CC_SELECTION(port) \ + (IT83XX_USBPD_CCGCR(port) & 1) + +/* macros for check */ +#define USBPD_IS_TX_ERR(port) \ + IS_MASK_SET(IT83XX_USBPD_MTCR(port), USBPD_REG_MASK_TX_ERR_STAT) +#define USBPD_IS_TX_DISCARD(port) \ + IS_MASK_SET(IT83XX_USBPD_MTCR(port), USBPD_REG_MASK_TX_DISCARD_STAT) + +/* macros for PD ISR */ +#define USBPD_IS_HARD_RESET_DETECT(port) \ + IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_HARD_RESET_DETECT) +#define USBPD_IS_TX_DONE(port) \ + IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_TX_DONE) +#define USBPD_IS_RX_DONE(port) \ + IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_RX_DONE) + +enum usbpd_cc_pin { + USBPD_CC_PIN_1, + USBPD_CC_PIN_2, +}; + +enum usbpd_ufp_volt_status { + USBPD_UFP_STATE_SNK_OPEN = 0, + USBPD_UFP_STATE_SNK_DEF = 1, + USBPD_UFP_STATE_SNK_1_5 = 3, + USBPD_UFP_STATE_SNK_3_0 = 7, +}; + +enum usbpd_dfp_volt_status { + USBPD_DFP_STATE_SRC_RA = 0, + USBPD_DFP_STATE_SRC_RD = 1, + USBPD_DFP_STATE_SRC_OPEN = 3, +}; + +enum usbpd_power_role { + USBPD_POWER_ROLE_CONSUMER, + USBPD_POWER_ROLE_PROVIDER, + USBPD_POWER_ROLE_CONSUMER_PROVIDER, + USBPD_POWER_ROLE_PROVIDER_CONSUMER, +}; + +struct usbpd_header { + uint8_t msg_type : 4; + uint8_t reserved : 1; + uint8_t port_role : 1; + uint8_t spec_ver : 2; + uint8_t power_role : 1; + uint8_t msg_id : 3; + uint8_t data_obj_num : 3; + uint8_t reserved2 : 1; +}; + +struct usbpd_ctrl_t { + volatile uint8_t *cc1; + volatile uint8_t *cc2; + uint8_t irq; +}; + +extern const struct usbpd_ctrl_t usbpd_ctrl_regs[]; +extern const struct tcpm_drv it83xx_tcpm_drv; + +#endif /* __CROS_EC_DRIVER_TCPM_IT83XX_H */ |