diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-06-23 17:52:04 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-06-30 17:18:25 +0000 |
commit | 82ec2510a3acebbf47f2c366e2eabff80d87cc07 (patch) | |
tree | 1157130bccd541f2ac20036acf7e82372917afa0 | |
parent | 59576398dbc7676fd7a30c2f87700f3c585d6b7e (diff) | |
download | chrome-ec-82ec2510a3acebbf47f2c366e2eabff80d87cc07.tar.gz |
pd: refactor tcpm and move alert function to tcpm driver
Refactor the tcpm/tcpc split such that the tcpm driver implements
the alert functionality since it may be unique for different tcpc
chips.
BUG=chrome-os-partner:41842
BRANCH=none
TEST=make -j buildall. run on samus and glados.
Change-Id: I23f2d7f8627d5337b8d001a09bf27622be24fe33
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/281631
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | board/pdeval-stm32f072/PD_evaluation.md | 2 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 89 | ||||
-rw-r--r-- | common/usb_pd_tcpc.c | 15 | ||||
-rw-r--r-- | driver/tcpm/stub.c | 64 | ||||
-rw-r--r-- | driver/tcpm/tcpci.c | 61 | ||||
-rw-r--r-- | driver/tcpm/tcpci.h | 85 | ||||
-rw-r--r-- | include/usb_pd.h | 15 | ||||
-rw-r--r-- | include/usb_pd_tcpm.h | 126 |
8 files changed, 265 insertions, 192 deletions
diff --git a/board/pdeval-stm32f072/PD_evaluation.md b/board/pdeval-stm32f072/PD_evaluation.md index 6c38ee457a..4eac047ab8 100644 --- a/board/pdeval-stm32f072/PD_evaluation.md +++ b/board/pdeval-stm32f072/PD_evaluation.md @@ -37,7 +37,7 @@ You also need to create/delete the corresponding `PD_Cx` tasks in [board/pdeval- By default, the firmware is using I2C1 with SCL/SDA on pins PB6 and PB7, running with a 100kHz clock. To change the pins or speed, you need to edit `i2c_ports` in [board/pdeval-stm32f072/board.c](board.c), update `I2C_PORT_TCPC` in [board/pdeval-stm32f072/board.h](board.h) with the right controller number, and change the pin mux in [board/pdeval-stm32f072/gpio.inc](gpio.inc). -An interrupt line, PA1, is configured to be used for the TCPC to get the attention of the TCPM. The GPIO is configured to trigger an interrupt on the falling edge and will call `tcpc_alert()` which will determine the cause of the interrupt and take action. The GPIO can be changed in [board/pdeval-stm32f072/gpio.inc](gpio.inc). +An interrupt line, PA1, is configured to be used for the TCPC to get the attention of the TCPM. The GPIO is configured to trigger an interrupt on the falling edge and will call `tcpc_alert()`, which must be implemented in **driver/tcpm/<vendor>.c**, and should determine the cause of the interrupt and take action. The GPIO can be changed in [board/pdeval-stm32f072/gpio.inc](gpio.inc). Flashing and Running -------------------- diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index deeb683630..e22aa29d4e 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -302,9 +302,9 @@ static void inc_id(int port) pd[port].msg_id = (pd[port].msg_id + 1) & PD_MESSAGE_ID_COUNT; } -static void pd_transmit_complete(int port, int status) +void pd_transmit_complete(int port, int status) { - if (status & TCPC_REG_ALERT_TX_SUCCESS) + if (status == TCPC_TX_COMPLETE_SUCCESS) inc_id(port); pd[port].tx_status = status; @@ -329,7 +329,7 @@ static int pd_transmit(int port, enum tcpm_transmit_type type, return -1; /* TODO: give different error condition for failed vs discarded */ - return pd[port].tx_status & TCPC_REG_ALERT_TX_SUCCESS ? 1 : -1; + return pd[port].tx_status == TCPC_TX_COMPLETE_SUCCESS ? 1 : -1; } static void pd_update_roles(int port) @@ -344,7 +344,7 @@ static int send_control(int port, int type) uint16_t header = PD_HEADER(type, pd[port].power_role, pd[port].data_role, pd[port].msg_id, 0); - bit_len = pd_transmit(port, TRANSMIT_SOP, header, NULL); + bit_len = pd_transmit(port, TCPC_TX_SOP, header, NULL); if (debug_level >= 1) CPRINTF("CTRL[%d]>%d\n", type, bit_len); @@ -372,7 +372,7 @@ static int send_source_cap(int port) header = PD_HEADER(PD_DATA_SOURCE_CAP, pd[port].power_role, pd[port].data_role, pd[port].msg_id, src_pdo_cnt); - bit_len = pd_transmit(port, TRANSMIT_SOP, header, src_pdo); + bit_len = pd_transmit(port, TCPC_TX_SOP, header, src_pdo); if (debug_level >= 1) CPRINTF("srcCAP>%d\n", bit_len); @@ -386,7 +386,7 @@ static void send_sink_cap(int port) uint16_t header = PD_HEADER(PD_DATA_SINK_CAP, pd[port].power_role, pd[port].data_role, pd[port].msg_id, pd_snk_pdo_cnt); - bit_len = pd_transmit(port, TRANSMIT_SOP, header, pd_snk_pdo); + bit_len = pd_transmit(port, TCPC_TX_SOP, header, pd_snk_pdo); if (debug_level >= 1) CPRINTF("snkCAP>%d\n", bit_len); } @@ -397,7 +397,7 @@ static int send_request(int port, uint32_t rdo) uint16_t header = PD_HEADER(PD_DATA_REQUEST, pd[port].power_role, pd[port].data_role, pd[port].msg_id, 1); - bit_len = pd_transmit(port, TRANSMIT_SOP, header, &rdo); + bit_len = pd_transmit(port, TCPC_TX_SOP, header, &rdo); if (debug_level >= 1) CPRINTF("REQ%d>\n", bit_len); @@ -414,7 +414,7 @@ static int send_bist_cmd(int port) uint16_t header = PD_HEADER(PD_DATA_BIST, pd[port].power_role, pd[port].data_role, pd[port].msg_id, 1); - bit_len = pd_transmit(port, TRANSMIT_SOP, header, &bdo); + bit_len = pd_transmit(port, TCPC_TX_SOP, header, &bdo); CPRINTF("BIST>%d\n", bit_len); return bit_len; @@ -464,7 +464,7 @@ static void handle_vdm_request(int port, int cnt, uint32_t *payload) PD_VDO_VID(payload[0]), payload[0] & 0xFFFF); } -static void execute_hard_reset(int port) +void pd_execute_hard_reset(int port) { if (pd[port].last_state == PD_STATE_HARD_RESET_SEND) CPRINTF("C%d HARD RST TX\n", port); @@ -731,7 +731,7 @@ static void handle_data_request(int port, uint16_t head, /* currently only support sending bist carrier mode 2 */ if ((payload[0] >> 28) == 5) { /* bist data object mode is 2 */ - pd_transmit(port, TRANSMIT_BIST_MODE_2, 0, + pd_transmit(port, TCPC_TX_BIST_MODE_2, 0, NULL); /* Set to appropriate port disconnected state */ set_state(port, DUAL_ROLE_IF_ELSE(port, @@ -1084,7 +1084,7 @@ static void pd_vdm_send_state_machine(int port) header = PD_HEADER(PD_DATA_VENDOR_DEF, pd[port].power_role, pd[port].data_role, pd[port].msg_id, (int)pd[port].vdo_count); - res = pd_transmit(port, TRANSMIT_SOP, header, + res = pd_transmit(port, TCPC_TX_SOP, header, pd[port].vdo_data); if (res < 0) { pd[port].vdm_state = VDM_STATE_ERR_SEND; @@ -1299,25 +1299,6 @@ void pd_set_new_power_request(int port) #error "Backwards compatible DFP does not support USB" #endif -int tcpm_init_alert_mask(int port) -{ - uint16_t mask; - int rv; - - /* - * Create mask of alert events that will cause the TCPC to - * signal the TCPM via the Alert# gpio line. - */ - mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED | - TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS | - TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS; - /* Set the alert mask in TCPC */ - rv = tcpm_alert_mask_set(port, TCPC_REG_ALERT_MASK, mask); - - return rv; -} - - void pd_task(void) { int head; @@ -1349,9 +1330,6 @@ void pd_task(void) tcpm_init(port); CPRINTF("[%T TCPC p%d ready]\n", port); - /* Initialize TCPC alert mask register via the TCPM */ - tcpm_init_alert_mask(port); - /* Disable TCPC RX until connection is established */ tcpm_set_rx_enable(port, 0); @@ -1383,9 +1361,9 @@ void pd_task(void) res = pd_board_checks(); if (res != EC_SUCCESS) { /* cut the power */ - execute_hard_reset(port); + pd_execute_hard_reset(port); /* notify the other side of the issue */ - pd_transmit(port, TRANSMIT_HARD_RESET, 0, NULL); + pd_transmit(port, TCPC_TX_HARD_RESET, 0, NULL); } /* wait for next event/packet or timeout expiration */ @@ -2298,7 +2276,7 @@ void pd_task(void) /* try sending hard reset until it succeeds */ if (!hard_reset_sent) { - if (pd_transmit(port, TRANSMIT_HARD_RESET, + if (pd_transmit(port, TCPC_TX_HARD_RESET, 0, NULL) < 0) { timeout = 10*MSEC; break; @@ -2332,7 +2310,7 @@ void pd_task(void) #endif /* reset our own state machine */ - execute_hard_reset(port); + pd_execute_hard_reset(port); timeout = 10*MSEC; break; #ifdef CONFIG_COMMON_RUNTIME @@ -2346,7 +2324,7 @@ void pd_task(void) PD_STATE_SRC_DISCONNECTED)); break; case PD_STATE_BIST_TX: - pd_transmit(port, TRANSMIT_BIST_MODE_2, 0, NULL); + pd_transmit(port, TCPC_TX_BIST_MODE_2, 0, NULL); /* Delay at least enough to finish sending BIST */ timeout = PD_T_BIST_TRANSMIT + 20*MSEC; /* Set to appropriate port disconnected state */ @@ -2411,41 +2389,6 @@ void pd_task(void) } } -void tcpc_alert(int port) -{ - int status; - - /* Read the Alert register from the TCPC */ - tcpm_alert_status(port, TCPC_REG_ALERT, (uint16_t *)&status); - - if (status & TCPC_REG_ALERT_CC_STATUS) { - /* CC status changed, wake task */ - task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); - } - if (status & TCPC_REG_ALERT_RX_STATUS) { - /* message received */ - /* - * If TCPC is compiled in, then we will have already - * received PD_EVENT_RX from phy layer in - * pd_rx_event(), so we don't need to set another - * event. If TCPC is not running on this MCU, then - * this needs to wake the PD task. - */ -#ifndef CONFIG_USB_PD_TCPC - task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_RX, 0); -#endif - } - if (status & TCPC_REG_ALERT_RX_HARD_RST) { - /* hard reset received */ - execute_hard_reset(port); - task_wake(PD_PORT_TO_TASK_ID(port)); - } - if (status & TCPC_REG_ALERT_TX_COMPLETE) { - /* transmit complete */ - pd_transmit_complete(port, status); - } -} - #ifdef CONFIG_USB_PD_DUAL_ROLE static void dual_role_on(void) { diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c index 307f7c7c0e..1d12620969 100644 --- a/common/usb_pd_tcpc.c +++ b/common/usb_pd_tcpc.c @@ -13,6 +13,7 @@ #include "host_command.h" #include "registers.h" #include "task.h" +#include "tcpci.h" #include "timer.h" #include "util.h" #include "usb_pd.h" @@ -742,16 +743,16 @@ int tcpc_run(int port, int evt) /* outgoing packet ? */ if ((evt & PD_EVENT_TX) && pd[port].rx_enabled) { switch (pd[port].tx_type) { - case TRANSMIT_SOP: + case TCPC_TX_SOP: res = send_validate_message(port, pd[port].tx_head, pd[port].tx_data); break; - case TRANSMIT_BIST_MODE_2: + case TCPC_TX_BIST_MODE_2: bist_mode_2_tx(port); res = 0; break; - case TRANSMIT_HARD_RESET: + case TCPC_TX_HARD_RESET: res = send_hard_reset(port); break; default: @@ -822,7 +823,7 @@ void pd_rx_event(int port) task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_RX, 0); } -int tcpc_alert_status(int port, uint16_t *alert) +int tcpc_alert_status(int port, int *alert) { /* return the value of the TCPC Alert register */ uint16_t ret = pd[port].alert; @@ -842,7 +843,7 @@ int tcpc_alert_status_clear(int port, uint16_t mask) return EC_SUCCESS; } -int tcpc_alert_mask_update(int port, uint16_t mask) +int tcpc_alert_mask_set(int port, uint16_t mask) { /* Update the alert mask as specificied by the TCPM */ pd[port].alert_mask = mask; @@ -971,7 +972,7 @@ static void tcpc_i2c_write(int port, int reg, int len, uint8_t *payload) case TCPC_REG_ALERT_MASK: alert = payload[1]; alert |= (payload[2] << 8); - tcpc_alert_mask_update(port, alert); + tcpc_alert_mask_set(port, alert); break; case TCPC_REG_RX_DETECT: tcpc_set_rx_enable(port, payload[1] & @@ -993,7 +994,7 @@ static void tcpc_i2c_write(int port, int reg, int len, uint8_t *payload) static int tcpc_i2c_read(int port, int reg, uint8_t *payload) { int cc1, cc2; - uint16_t alert; + int alert; switch (reg) { case TCPC_REG_VENDOR_ID: diff --git a/driver/tcpm/stub.c b/driver/tcpm/stub.c index 60651670a5..5fbde334d8 100644 --- a/driver/tcpm/stub.c +++ b/driver/tcpm/stub.c @@ -5,14 +5,14 @@ /* TCPM for MCU also running TCPC */ +#include "task.h" +#include "tcpci.h" #include "usb_pd.h" #include "usb_pd_tcpm.h" -#include "console.h" - -extern int tcpc_alert_status(int port, uint16_t *alert); +extern int tcpc_alert_status(int port, int *alert); extern int tcpc_alert_status_clear(int port, uint16_t mask); -extern int tcpc_alert_mask_update(int port, uint16_t mask); +extern int tcpc_alert_mask_set(int port, uint16_t mask); extern int tcpc_get_cc(int port, int *cc1, int *cc2); extern int tcpc_set_cc(int port, int pull); extern int tcpc_set_polarity(int port, int polarity); @@ -24,10 +24,28 @@ extern int tcpc_get_message(int port, uint32_t *payload, int *head); extern int tcpc_transmit(int port, enum tcpm_transmit_type type, uint16_t header, const uint32_t *data); +static int init_alert_mask(int port) +{ + uint16_t mask; + int rv; + + /* + * Create mask of alert events that will cause the TCPC to + * signal the TCPM via the Alert# gpio line. + */ + mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED | + TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS | + TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS; + /* Set the alert mask in TCPC */ + rv = tcpm_alert_mask_set(port, mask); + + return rv; +} + int tcpm_init(int port) { tcpc_init(port); - return EC_SUCCESS; + return init_alert_mask(port); } int tcpm_get_cc(int port, int *cc1, int *cc2) @@ -55,7 +73,7 @@ int tcpm_set_msg_header(int port, int power_role, int data_role) return tcpc_set_msg_header(port, power_role, data_role); } -int tcpm_alert_status(int port, int alert_reg, uint16_t *alert) +int tcpm_alert_status(int port, int *alert) { int rv; @@ -71,9 +89,9 @@ int tcpm_set_rx_enable(int port, int enable) return tcpc_set_rx_enable(port, enable); } -int tcpm_alert_mask_set(int port, int reg, uint16_t mask) +int tcpm_alert_mask_set(int port, uint16_t mask) { - return tcpc_alert_mask_update(port, mask); + return tcpc_alert_mask_set(port, mask); } int tcpm_get_message(int port, uint32_t *payload, int *head) @@ -86,3 +104,33 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header, { return tcpc_transmit(port, type, header, data); } + +void tcpc_alert(int port) +{ + int status; + + /* Read the Alert register from the TCPC */ + tcpm_alert_status(port, &status); + + if (status & TCPC_REG_ALERT_CC_STATUS) { + /* CC status changed, wake task */ + task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); + } + if (status & TCPC_REG_ALERT_RX_STATUS) { + /* + * message received. since TCPC is compiled in, we + * already received PD_EVENT_RX from phy layer in + * pd_rx_event(), so we don't need to set another + * event. + */ + } + if (status & TCPC_REG_ALERT_RX_HARD_RST) { + /* hard reset received */ + pd_execute_hard_reset(port); + task_wake(PD_PORT_TO_TASK_ID(port)); + } + if (status & TCPC_REG_ALERT_TX_COMPLETE) { + /* transmit complete */ + pd_transmit_complete(port, status & TCPC_REG_ALERT_TX_COMPLETE); + } +} diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 7d2c38774b..727b41186a 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -6,20 +6,37 @@ /* Type-C port manager */ #include "i2c.h" +#include "task.h" +#include "tcpci.h" #include "timer.h" #include "usb_pd.h" #include "usb_pd_tcpc.h" #include "usb_pd_tcpm.h" #include "util.h" -#include "console.h" - - /* Convert port number to tcpc i2c address */ #define I2C_ADDR_TCPC(p) (CONFIG_TCPC_I2C_BASE_ADDR + 2*(p)) static int tcpc_polarity, tcpc_vconn; +static int init_alert_mask(int port) +{ + uint16_t mask; + int rv; + + /* + * Create mask of alert events that will cause the TCPC to + * signal the TCPM via the Alert# gpio line. + */ + mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED | + TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS | + TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS; + /* Set the alert mask in TCPC */ + rv = tcpm_alert_mask_set(port, mask); + + return rv; +} + int tcpm_init(int port) { int rv, vid = 0; @@ -32,7 +49,7 @@ int tcpm_init(int port) * is complete */ if (rv == EC_SUCCESS && vid) - return rv; + return init_alert_mask(port); msleep(10); } } @@ -92,19 +109,19 @@ int tcpm_set_msg_header(int port, int power_role, int data_role) TCPC_REG_MSG_HDR_INFO_SET(data_role, power_role)); } -int tcpm_alert_status(int port, int alert_reg, uint16_t *alert) +int tcpm_alert_status(int port, int *alert) { int rv; /* Read TCPC Alert register */ rv = i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - alert_reg, (int *)alert); + TCPC_REG_ALERT, alert); /* * The PD protocol layer will process all alert bits * returned by this function. Therefore, these bits * can now be cleared from the TCPC register. */ i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - alert_reg, *alert); + TCPC_REG_ALERT, *alert); return rv; } @@ -116,12 +133,12 @@ int tcpm_set_rx_enable(int port, int enable) enable ? TCPC_REG_RX_DETECT_SOP_HRST_MASK : 0); } -int tcpm_alert_mask_set(int port, int reg, uint16_t mask) +int tcpm_alert_mask_set(int port, uint16_t mask) { int rv; /* write to the Alert Mask register */ rv = i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - reg, mask); + TCPC_REG_ALERT_MASK, mask); if (rv) return rv; @@ -192,3 +209,29 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header, return rv; } + +void tcpc_alert(int port) +{ + int status; + + /* Read the Alert register from the TCPC */ + tcpm_alert_status(port, &status); + + if (status & TCPC_REG_ALERT_CC_STATUS) { + /* CC status changed, wake task */ + task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); + } + if (status & TCPC_REG_ALERT_RX_STATUS) { + /* message received */ + task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_RX, 0); + } + if (status & TCPC_REG_ALERT_RX_HARD_RST) { + /* hard reset received */ + pd_execute_hard_reset(port); + task_wake(PD_PORT_TO_TASK_ID(port)); + } + if (status & TCPC_REG_ALERT_TX_COMPLETE) { + /* transmit complete */ + pd_transmit_complete(port, status & TCPC_REG_ALERT_TX_COMPLETE); + } +} diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h new file mode 100644 index 0000000000..7ede3fe6d7 --- /dev/null +++ b/driver/tcpm/tcpci.h @@ -0,0 +1,85 @@ +/* Copyright 2015 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_USB_PD_TCPM_TCPCI_H +#define __CROS_EC_USB_PD_TCPM_TCPCI_H + +#define TCPC_REG_VENDOR_ID 0x0 +#define TCPC_REG_PRODUCT_ID 0x2 +#define TCPC_REG_BCD_DEV 0x4 +#define TCPC_REG_TC_REV 0x6 +#define TCPC_REG_PD_REV 0x8 +#define TCPC_REG_PD_INT_REV 0xa +#define TCPC_REG_DEV_CAP_1 0xc +#define TCPC_REG_DEV_CAP_2 0xd +#define TCPC_REG_DEV_CAP_3 0xe +#define TCPC_REG_DEV_CAP_4 0xf +#define TCPC_REG_ALERT 0x10 +#define TCPC_REG_ALERT_GPIO_CHANGE (1<<10) +#define TCPC_REG_ALERT_V_ALARM_LO (1<<9) +#define TCPC_REG_ALERT_V_ALARM_HI (1<<8) +#define TCPC_REG_ALERT_SLEEP_EXITED (1<<7) +#define TCPC_REG_ALERT_POWER_STATUS (1<<6) +#define TCPC_REG_ALERT_CC_STATUS (1<<5) +#define TCPC_REG_ALERT_RX_STATUS (1<<4) +#define TCPC_REG_ALERT_RX_HARD_RST (1<<3) +#define TCPC_REG_ALERT_TX_SUCCESS (1<<2) +#define TCPC_REG_ALERT_TX_DISCARDED (1<<1) +#define TCPC_REG_ALERT_TX_FAILED (1<<0) +#define TCPC_REG_ALERT_TX_COMPLETE (TCPC_REG_ALERT_TX_SUCCESS | \ + TCPC_REG_ALERT_TX_DISCARDED | \ + TCPC_REG_ALERT_TX_FAILED) + +#define TCPC_REG_ALERT_MASK 0x12 +#define TCPC_REG_POWER_STATUS_MASK 0x14 +#define TCPC_REG_CC1_STATUS 0x16 +#define TCPC_REG_CC2_STATUS 0x17 +#define TCPC_REG_CC_STATUS_SET(term, volt) \ + ((term) << 3 | volt) +#define TCPC_REG_CC_STATUS_TERM(reg) (((reg) & 0x38) >> 3) +#define TCPC_REG_CC_STATUS_VOLT(reg) ((reg) & 0x7) + +#define TCPC_REG_POWER_STATUS 0x1a +#define TCPC_REG_ROLE_CTRL 0x1b +#define TCPC_REG_ROLE_CTRL_SET(drp, rp, cc2, cc1) \ + ((drp) << 6 | (rp) << 4 | (cc2) << 2 | (cc1)) +#define TCPC_REG_ROLE_CTRL_CC2(reg) (((reg) & 0xc) >> 2) +#define TCPC_REG_ROLE_CTRL_CC1(reg) ((reg) & 0x3) + +#define TCPC_REG_POWER_PATH_CTRL 0x1c +#define TCPC_REG_POWER_CTRL 0x1d +#define TCPC_REG_POWER_CTRL_SET(polarity, vconn) \ + ((polarity) << 4 | (vconn)) +#define TCPC_REG_POWER_CTRL_POLARITY(reg) (((reg) & 0x10) >> 4) +#define TCPC_REG_POWER_CTRL_VCONN(reg) ((reg) & 0x1) + +#define TCPC_REG_COMMAND 0x23 +#define TCPC_REG_MSG_HDR_INFO 0x2e +#define TCPC_REG_MSG_HDR_INFO_SET(drole, prole) \ + ((drole) << 3 | (PD_REV20 << 1) | (prole)) +#define TCPC_REG_MSG_HDR_INFO_DROLE(reg) (((reg) & 0x8) >> 3) +#define TCPC_REG_MSG_HDR_INFO_PROLE(reg) ((reg) & 0x1) + +#define TCPC_REG_RX_BYTE_CNT 0x2f +#define TCPC_REG_RX_STATUS 0x30 +#define TCPC_REG_RX_DETECT 0x31 +#define TCPC_REG_RX_DETECT_SOP_HRST_MASK 0x21 + +#define TCPC_REG_RX_HDR 0x32 +#define TCPC_REG_RX_DATA 0x34 /* through 0x4f */ + +#define TCPC_REG_TRANSMIT 0x50 +#define TCPC_REG_TRANSMIT_SET(type) \ + (PD_RETRY_COUNT << 4 | (type)) +#define TCPC_REG_TRANSMIT_RETRY(reg) (((reg) & 0x30) >> 4) +#define TCPC_REG_TRANSMIT_TYPE(reg) ((reg) & 0x7) + +#define TCPC_REG_TX_BYTE_CNT 0x51 +#define TCPC_REG_TX_HDR 0x52 +#define TCPC_REG_TX_DATA 0x54 /* through 0x6f */ + +#endif /* __CROS_EC_USB_PD_TCPM_TCPCI_H */ diff --git a/include/usb_pd.h b/include/usb_pd.h index 640c650a74..8b915a14c4 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -1479,6 +1479,21 @@ int pd_analyze_rx(int port, uint32_t *payload); int pd_is_connected(int port); /** + * Execute a hard reset + * + * @param port USB-C port number + */ +void pd_execute_hard_reset(int port); + +/** + * Signal to protocol layer that PD transmit is complete + * + * @param port USB-C port number + * @param status status of the transmission + */ +void pd_transmit_complete(int port, int status); + +/** * Get port polarity. * * @param port USB-C port number diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h index 71f0610ece..71357e0ac1 100644 --- a/include/usb_pd_tcpm.h +++ b/include/usb_pd_tcpm.h @@ -14,40 +14,6 @@ /* Time to wait for TCPC to complete transmit */ #define PD_T_TCPC_TX_TIMEOUT (100*MSEC) -#define TCPC_REG_VENDOR_ID 0x0 -#define TCPC_REG_PRODUCT_ID 0x2 -#define TCPC_REG_BCD_DEV 0x4 -#define TCPC_REG_TC_REV 0x6 -#define TCPC_REG_PD_REV 0x8 -#define TCPC_REG_PD_INT_REV 0xa -#define TCPC_REG_DEV_CAP_1 0xc -#define TCPC_REG_DEV_CAP_2 0xd -#define TCPC_REG_DEV_CAP_3 0xe -#define TCPC_REG_DEV_CAP_4 0xf -#define TCPC_REG_ALERT 0x10 -#define TCPC_REG_ALERT_GPIO_CHANGE (1<<10) -#define TCPC_REG_ALERT_V_ALARM_LO (1<<9) -#define TCPC_REG_ALERT_V_ALARM_HI (1<<8) -#define TCPC_REG_ALERT_SLEEP_EXITED (1<<7) -#define TCPC_REG_ALERT_POWER_STATUS (1<<6) -#define TCPC_REG_ALERT_CC_STATUS (1<<5) -#define TCPC_REG_ALERT_RX_STATUS (1<<4) -#define TCPC_REG_ALERT_RX_HARD_RST (1<<3) -#define TCPC_REG_ALERT_TX_SUCCESS (1<<2) -#define TCPC_REG_ALERT_TX_DISCARDED (1<<1) -#define TCPC_REG_ALERT_TX_FAILED (1<<0) -#define TCPC_REG_ALERT_TX_COMPLETE (TCPC_REG_ALERT_TX_SUCCESS | \ - TCPC_REG_ALERT_TX_DISCARDED | \ - TCPC_REG_ALERT_TX_FAILED) - -#define TCPC_REG_ALERT_MASK 0x12 -#define TCPC_REG_POWER_STATUS_MASK 0x14 -#define TCPC_REG_CC1_STATUS 0x16 -#define TCPC_REG_CC2_STATUS 0x17 -#define TCPC_REG_CC_STATUS_SET(term, volt) \ - ((term) << 3 | volt) -#define TCPC_REG_CC_STATUS_TERM(reg) (((reg) & 0x38) >> 3) -#define TCPC_REG_CC_STATUS_VOLT(reg) ((reg) & 0x7) enum tcpc_cc_termination_status { TYPEC_CC_TERM_RA = 0, TYPEC_CC_TERM_RP_DEF = 1, @@ -67,16 +33,11 @@ enum tcpc_cc_voltage_status { TYPEC_CC_VOLT_SRC_3_0 = 6, TYPEC_CC_VOLT_OPEN = 7 }; + /* Check if CC voltage is within Rd */ #define TYPEC_CC_IS_RD(cc) ((cc) >= TYPEC_CC_VOLT_SNK_DEF && \ (cc) <= TYPEC_CC_VOLT_SNK_3_0) -#define TCPC_REG_POWER_STATUS 0x1a -#define TCPC_REG_ROLE_CTRL 0x1b -#define TCPC_REG_ROLE_CTRL_SET(drp, rp, cc2, cc1) \ - ((drp) << 6 | (rp) << 4 | (cc2) << 2 | (cc1)) -#define TCPC_REG_ROLE_CTRL_CC2(reg) (((reg) & 0xc) >> 2) -#define TCPC_REG_ROLE_CTRL_CC1(reg) ((reg) & 0x3) enum tcpc_cc_pull { TYPEC_CC_RA = 0, TYPEC_CC_RP = 1, @@ -84,53 +45,32 @@ enum tcpc_cc_pull { TYPEC_CC_OPEN = 3, }; -#define TCPC_REG_POWER_PATH_CTRL 0x1c -#define TCPC_REG_POWER_CTRL 0x1d -#define TCPC_REG_POWER_CTRL_SET(polarity, vconn) \ - ((polarity) << 4 | (vconn)) -#define TCPC_REG_POWER_CTRL_POLARITY(reg) (((reg) & 0x10) >> 4) -#define TCPC_REG_POWER_CTRL_VCONN(reg) ((reg) & 0x1) - -#define TCPC_REG_COMMAND 0x23 -#define TCPC_REG_MSG_HDR_INFO 0x2e -#define TCPC_REG_MSG_HDR_INFO_SET(drole, prole) \ - ((drole) << 3 | (PD_REV20 << 1) | (prole)) -#define TCPC_REG_MSG_HDR_INFO_DROLE(reg) (((reg) & 0x8) >> 3) -#define TCPC_REG_MSG_HDR_INFO_PROLE(reg) ((reg) & 0x1) - -#define TCPC_REG_RX_BYTE_CNT 0x2f -#define TCPC_REG_RX_STATUS 0x30 -#define TCPC_REG_RX_DETECT 0x31 -#define TCPC_REG_RX_DETECT_SOP_HRST_MASK 0x21 - -#define TCPC_REG_RX_HDR 0x32 -#define TCPC_REG_RX_DATA 0x34 /* through 0x4f */ - -#define TCPC_REG_TRANSMIT 0x50 -#define TCPC_REG_TRANSMIT_SET(type) \ - (PD_RETRY_COUNT << 4 | (type)) -#define TCPC_REG_TRANSMIT_RETRY(reg) (((reg) & 0x30) >> 4) -#define TCPC_REG_TRANSMIT_TYPE(reg) ((reg) & 0x7) enum tcpm_transmit_type { - TRANSMIT_SOP = 0, - TRANSMIT_SOP_PRIME = 1, - TRANSMIT_SOP_PRIME_PRIME = 2, - TRANSMIT_SOP_DEBUG_PRIME = 3, - TRANSMIT_SOP_DEBUG_PRIME_PRIME = 4, - TRANSMIT_HARD_RESET = 5, - TRANSMIT_CABLE_RESET = 6, - TRANSMIT_BIST_MODE_2 = 7 + TCPC_TX_SOP = 0, + TCPC_TX_SOP_PRIME = 1, + TCPC_TX_SOP_PRIME_PRIME = 2, + TCPC_TX_SOP_DEBUG_PRIME = 3, + TCPC_TX_SOP_DEBUG_PRIME_PRIME = 4, + TCPC_TX_HARD_RESET = 5, + TCPC_TX_CABLE_RESET = 6, + TCPC_TX_BIST_MODE_2 = 7 }; -#define TCPC_REG_TX_BYTE_CNT 0x51 -#define TCPC_REG_TX_HDR 0x52 -#define TCPC_REG_TX_DATA 0x54 /* through 0x6f */ +enum tcpc_transmit_complete { + TCPC_TX_COMPLETE_SUCCESS = (1 << 2), + TCPC_TX_COMPLETE_DISCARDED = (1 << 1), + TCPC_TX_COMPLETE_FAILED = (1 << 0), +}; /** - * TCPC is asserting alert + * Initialize TCPM driver and wait for TCPC readiness. + * + * @param port Type-C port number + * + * @return EC_SUCCESS or error */ -void tcpc_alert(int port); -void tcpc_alert_clear(int port); +int tcpm_init(int port); + /** * Initialize TCPC. * @@ -139,6 +79,14 @@ void tcpc_alert_clear(int port); void tcpc_init(int port); /** + * TCPC is asserting alert + * + * @param port Type-C port number + */ +void tcpc_alert(int port); +void tcpc_alert_clear(int port); + +/** * Run TCPC task once. This checks for incoming messages, processes * any outgoing messages, and reads CC lines. * @@ -147,36 +95,26 @@ void tcpc_init(int port); */ int tcpc_run(int port, int evt); + /** * Read TCPC alert status * * @param port Type-C port number - * @param reg TCPC register address * @param alert Pointer to location to store alert status * @return EC_SUCCESS or error */ -int tcpm_alert_status(int port, int reg, uint16_t *alert); +int tcpm_alert_status(int port, int *alert); /** * Write TCPC Alert Mask register * * @param port Type-C port number - * @param reg TCPC register address * @param mask bits to be set in Alert Mask register * @return EC_SUCCESS or error */ -int tcpm_alert_mask_set(int port, int reg, uint16_t mask); - -/** - * Initialize TCPM driver and wait for TCPC readiness. - * - * @param port Type-C port number - * - * @return EC_SUCCESS or error - */ -int tcpm_init(int port); +int tcpm_alert_mask_set(int port, uint16_t mask); /** * Read the CC line status. |