1
0
forked from me/IronOS

Culling until fits in code

Does _not_ negotiate correctly :(
This commit is contained in:
Ben V. Brown
2020-06-12 22:13:40 +10:00
parent 34ae57ee58
commit 2c0b14edd4
13 changed files with 1377 additions and 1779 deletions

View File

@@ -9,7 +9,6 @@ void power_probe() {
// If TS100 - noop // If TS100 - noop
#ifdef MODEL_TS80 #ifdef MODEL_TS80
startQC(systemSettings.voltageDiv); startQC(systemSettings.voltageDiv);
seekQC((systemSettings.cutoutSetting) ? 120 : 90, seekQC((systemSettings.cutoutSetting) ? 120 : 90,
@@ -21,11 +20,26 @@ void power_probe() {
void power_check() { void power_check() {
#ifdef MODEL_TS80 #ifdef MODEL_TS80
QC_resync(); QC_resync();
if (FUSB302_present) {
pd_run_state_machine();
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9) == GPIO_PIN_RESET) {
tcpc_alert();
}
}
#endif #endif
} }
uint8_t usb_pd_detect(){ uint8_t usb_pd_detect() {
#ifdef MODEL_TS80 #ifdef MODEL_TS80
FUSB302_present=fusb302_detect(); FUSB302_present = fusb302_detect();
if (FUSB302_present) {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
return FUSB302_present; return FUSB302_present;
#endif #endif
return false; return false;

View File

@@ -291,7 +291,7 @@ typedef struct
/** @defgroup RCC_Flag Flags /** @defgroup RCC_Flag Flags
* Elements values convention: XXXYYYYYb * Elements values convention: XXXYYYYYb
* - YYYYY : Flag position in the register * - YYYYY : Flag position in the register
* - XXX : Register index * - X XX : Register index
* - 001: CR register * - 001: CR register
* - 010: BDCR register * - 010: BDCR register
* - 011: CSR register * - 011: CSR register

View File

@@ -8,7 +8,14 @@
#include "stdlib.h" #include "stdlib.h"
#include "task.h" #include "task.h"
#include "I2C_Wrapper.hpp" #include "I2C_Wrapper.hpp"
#include "USBC_TCPM/tcpm.h"
void postRToSInit() { void postRToSInit() {
// Any after RTos setup // Any after RTos setup
FRToSI2C::FRToSInit(); FRToSI2C::FRToSInit();
#ifdef MODEL_TS80
tcpm_init();
osDelay(50);
pd_init();
osDelay(50);
#endif
} }

View File

@@ -14,8 +14,8 @@
#include "I2C_Wrapper.hpp" #include "I2C_Wrapper.hpp"
#define PACKET_IS_GOOD_CRC(head) (PD_HEADER_TYPE(head) == PD_CTRL_GOOD_CRC && \ #define PACKET_IS_GOOD_CRC(head) (PD_HEADER_TYPE(head) == PD_CTRL_GOOD_CRC && \
PD_HEADER_CNT(head) == 0) PD_HEADER_CNT(head) == 0)
const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { { 0, const struct tcpc_config_t tcpc_config = {
fusb302_I2C_SLAVE_ADDR, &fusb302_tcpm_drv, TCPC_ALERT_ACTIVE_LOW }, }; fusb302_I2C_SLAVE_ADDR, &fusb302_tcpm_drv };
static struct fusb302_chip_state { static struct fusb302_chip_state {
int cc_polarity; int cc_polarity;
int vconn_enabled; int vconn_enabled;
@@ -24,15 +24,15 @@ static struct fusb302_chip_state {
int rx_enable; int rx_enable;
uint8_t mdac_vnc; uint8_t mdac_vnc;
uint8_t mdac_rd; uint8_t mdac_rd;
} state[CONFIG_USB_PD_PORT_COUNT]; } state;
/* /*
* Bring the FUSB302 out of reset after Hard Reset signaling. This will * Bring the FUSB302 out of reset after Hard Reset signaling. This will
* automatically flush both the Rx and Tx FIFOs. * automatically flush both the Rx and Tx FIFOs.
*/ */
static void fusb302_pd_reset(int port) { static void fusb302_pd_reset() {
tcpc_write(port, TCPC_REG_RESET, TCPC_REG_RESET_PD_RESET); tcpc_write( TCPC_REG_RESET, TCPC_REG_RESET_PD_RESET);
} }
@@ -40,7 +40,7 @@ static void fusb302_pd_reset(int port) {
* Flush our Rx FIFO. To prevent packet framing issues, this function should * Flush our Rx FIFO. To prevent packet framing issues, this function should
* only be called when Rx is disabled. * only be called when Rx is disabled.
*/ */
static void fusb302_flush_rx_fifo(int port) { static void fusb302_flush_rx_fifo() {
/* /*
* other bits in the register _should_ be 0 * other bits in the register _should_ be 0
* until the day we support other SOP* types... * until the day we support other SOP* types...
@@ -48,39 +48,39 @@ static void fusb302_flush_rx_fifo(int port) {
* value should be so we don't clobber it here! * value should be so we don't clobber it here!
*/ */
tcpc_write(port, TCPC_REG_CONTROL1, TCPC_REG_CONTROL1_RX_FLUSH); tcpc_write( TCPC_REG_CONTROL1, TCPC_REG_CONTROL1_RX_FLUSH);
} }
static void fusb302_flush_tx_fifo(int port) { static void fusb302_flush_tx_fifo() {
int reg; int reg;
tcpc_read(port, TCPC_REG_CONTROL0, &reg); tcpc_read( TCPC_REG_CONTROL0, &reg);
reg |= TCPC_REG_CONTROL0_TX_FLUSH; reg |= TCPC_REG_CONTROL0_TX_FLUSH;
tcpc_write(port, TCPC_REG_CONTROL0, reg); tcpc_write( TCPC_REG_CONTROL0, reg);
} }
static void fusb302_auto_goodcrc_enable(int port, int enable) { static void fusb302_auto_goodcrc_enable(int enable) {
int reg; int reg;
tcpc_read(port, TCPC_REG_SWITCHES1, &reg); tcpc_read( TCPC_REG_SWITCHES1, &reg);
if (enable) if (enable)
reg |= TCPC_REG_SWITCHES1_AUTO_GCRC; reg |= TCPC_REG_SWITCHES1_AUTO_GCRC;
else else
reg &= ~TCPC_REG_SWITCHES1_AUTO_GCRC; reg &= ~TCPC_REG_SWITCHES1_AUTO_GCRC;
tcpc_write(port, TCPC_REG_SWITCHES1, reg); tcpc_write( TCPC_REG_SWITCHES1, reg);
} }
/* Convert BC LVL values (in FUSB302) to Type-C CC Voltage Status */ /* Convert BC LVL values (in FUSB302) to Type-C CC Voltage Status */
static int convert_bc_lvl(int port, int bc_lvl) { static int convert_bc_lvl(int bc_lvl) {
/* assume OPEN unless one of the following conditions is true... */ /* assume OPEN unless one of the following conditions is true... */
int ret = TYPEC_CC_VOLT_OPEN; int ret = TYPEC_CC_VOLT_OPEN;
if (state[port].pulling_up) { if (state.pulling_up) {
if (bc_lvl == 0x00) if (bc_lvl == 0x00)
ret = TYPEC_CC_VOLT_RA; ret = TYPEC_CC_VOLT_RA;
else if (bc_lvl < 0x3) else if (bc_lvl < 0x3)
@@ -97,13 +97,13 @@ static int convert_bc_lvl(int port, int bc_lvl) {
return ret; return ret;
} }
static int measure_cc_pin_source(int port, int cc_measure) { static int measure_cc_pin_source(int cc_measure) {
int switches0_reg; int switches0_reg;
int reg; int reg;
int cc_lvl; int cc_lvl;
/* Read status register */ /* Read status register */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
/* Save current value */ /* Save current value */
switches0_reg = reg; switches0_reg = reg;
/* Clear pull-up register settings and measure bits */ /* Clear pull-up register settings and measure bits */
@@ -117,16 +117,16 @@ static int measure_cc_pin_source(int port, int cc_measure) {
reg |= cc_measure; reg |= cc_measure;
/* Set measurement switch */ /* Set measurement switch */
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
/* Set MDAC for Open vs Rd/Ra comparison */ /* Set MDAC for Open vs Rd/Ra comparison */
tcpc_write(port, TCPC_REG_MEASURE, state[port].mdac_vnc); tcpc_write( TCPC_REG_MEASURE, state.mdac_vnc);
/* Wait on measurement */ /* Wait on measurement */
usleep(250); usleep(250);
/* Read status register */ /* Read status register */
tcpc_read(port, TCPC_REG_STATUS0, &reg); tcpc_read( TCPC_REG_STATUS0, &reg);
/* Assume open */ /* Assume open */
cc_lvl = TYPEC_CC_VOLT_OPEN; cc_lvl = TYPEC_CC_VOLT_OPEN;
@@ -134,13 +134,13 @@ static int measure_cc_pin_source(int port, int cc_measure) {
/* CC level is below the 'no connect' threshold (vOpen) */ /* CC level is below the 'no connect' threshold (vOpen) */
if ((reg & TCPC_REG_STATUS0_COMP) == 0) { if ((reg & TCPC_REG_STATUS0_COMP) == 0) {
/* Set MDAC for Rd vs Ra comparison */ /* Set MDAC for Rd vs Ra comparison */
tcpc_write(port, TCPC_REG_MEASURE, state[port].mdac_rd); tcpc_write( TCPC_REG_MEASURE, state.mdac_rd);
/* Wait on measurement */ /* Wait on measurement */
usleep(250); usleep(250);
/* Read status register */ /* Read status register */
tcpc_read(port, TCPC_REG_STATUS0, &reg); tcpc_read( TCPC_REG_STATUS0, &reg);
cc_lvl = cc_lvl =
(reg & TCPC_REG_STATUS0_COMP) ? (reg & TCPC_REG_STATUS0_COMP) ?
@@ -148,32 +148,32 @@ static int measure_cc_pin_source(int port, int cc_measure) {
} }
/* Restore SWITCHES0 register to its value prior */ /* Restore SWITCHES0 register to its value prior */
tcpc_write(port, TCPC_REG_SWITCHES0, switches0_reg); tcpc_write( TCPC_REG_SWITCHES0, switches0_reg);
return cc_lvl; return cc_lvl;
} }
/* Determine cc pin state for source when in manual detect mode */ /* Determine cc pin state for source when in manual detect mode */
static void detect_cc_pin_source_manual(int port, int *cc1_lvl, int *cc2_lvl) { static void detect_cc_pin_source_manual(int *cc1_lvl, int *cc2_lvl) {
int cc1_measure = TCPC_REG_SWITCHES0_MEAS_CC1; int cc1_measure = TCPC_REG_SWITCHES0_MEAS_CC1;
int cc2_measure = TCPC_REG_SWITCHES0_MEAS_CC2; int cc2_measure = TCPC_REG_SWITCHES0_MEAS_CC2;
if (state[port].vconn_enabled) { if (state.vconn_enabled) {
/* If VCONN enabled, measure cc_pin that matches polarity */ /* If VCONN enabled, measure cc_pin that matches polarity */
if (state[port].cc_polarity) if (state.cc_polarity)
*cc2_lvl = measure_cc_pin_source(port, cc2_measure); *cc2_lvl = measure_cc_pin_source(cc2_measure);
else else
*cc1_lvl = measure_cc_pin_source(port, cc1_measure); *cc1_lvl = measure_cc_pin_source(cc1_measure);
} else { } else {
/* If VCONN not enabled, measure both cc1 and cc2 */ /* If VCONN not enabled, measure both cc1 and cc2 */
*cc1_lvl = measure_cc_pin_source(port, cc1_measure); *cc1_lvl = measure_cc_pin_source(cc1_measure);
*cc2_lvl = measure_cc_pin_source(port, cc2_measure); *cc2_lvl = measure_cc_pin_source(cc2_measure);
} }
} }
/* Determine cc pin state for sink */ /* Determine cc pin state for sink */
static void detect_cc_pin_sink(int port, int *cc1, int *cc2) { static void detect_cc_pin_sink(int *cc1, int *cc2) {
int reg; int reg;
int orig_meas_cc1; int orig_meas_cc1;
int orig_meas_cc2; int orig_meas_cc2;
@@ -183,7 +183,7 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2) {
/* /*
* Measure CC1 first. * Measure CC1 first.
*/ */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
/* save original state to be returned to later... */ /* save original state to be returned to later... */
if (reg & TCPC_REG_SWITCHES0_MEAS_CC1) if (reg & TCPC_REG_SWITCHES0_MEAS_CC1)
@@ -200,14 +200,14 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2) {
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2;
reg |= TCPC_REG_SWITCHES0_MEAS_CC1; reg |= TCPC_REG_SWITCHES0_MEAS_CC1;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
/* CC1 is now being measured by FUSB302. */ /* CC1 is now being measured by FUSB302. */
/* Wait on measurement */ /* Wait on measurement */
usleep(250); usleep(250);
tcpc_read(port, TCPC_REG_STATUS0, &bc_lvl_cc1); tcpc_read( TCPC_REG_STATUS0, &bc_lvl_cc1);
/* mask away unwanted bits */ /* mask away unwanted bits */
bc_lvl_cc1 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1); bc_lvl_cc1 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1);
@@ -216,29 +216,29 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2) {
* Measure CC2 next. * Measure CC2 next.
*/ */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
/* Disable CC1 measurement switch, enable CC2 measurement switch */ /* Disable CC1 measurement switch, enable CC2 measurement switch */
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1;
reg |= TCPC_REG_SWITCHES0_MEAS_CC2; reg |= TCPC_REG_SWITCHES0_MEAS_CC2;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
/* CC2 is now being measured by FUSB302. */ /* CC2 is now being measured by FUSB302. */
/* Wait on measurement */ /* Wait on measurement */
usleep(250); usleep(250);
tcpc_read(port, TCPC_REG_STATUS0, &bc_lvl_cc2); tcpc_read( TCPC_REG_STATUS0, &bc_lvl_cc2);
/* mask away unwanted bits */ /* mask away unwanted bits */
bc_lvl_cc2 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1); bc_lvl_cc2 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1);
*cc1 = convert_bc_lvl(port, bc_lvl_cc1); *cc1 = convert_bc_lvl(bc_lvl_cc1);
*cc2 = convert_bc_lvl(port, bc_lvl_cc2); *cc2 = convert_bc_lvl(bc_lvl_cc2);
/* return MEAS_CC1/2 switches to original state */ /* return MEAS_CC1/2 switches to original state */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
if (orig_meas_cc1) if (orig_meas_cc1)
reg |= TCPC_REG_SWITCHES0_MEAS_CC1; reg |= TCPC_REG_SWITCHES0_MEAS_CC1;
else else
@@ -248,7 +248,7 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2) {
else else
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
} }
@@ -268,7 +268,7 @@ static int get_num_bytes(uint16_t header) {
return rv; return rv;
} }
static int fusb302_send_message(int port, uint16_t header, const uint32_t *data, static int fusb302_send_message(uint16_t header, const uint32_t *data,
uint8_t *buf, int buf_pos) { uint8_t *buf, int buf_pos) {
int rv; int rv;
int reg; int reg;
@@ -315,17 +315,17 @@ static int fusb302_send_message(int port, uint16_t header, const uint32_t *data,
/* burst write for speed! */ /* burst write for speed! */
rv = tcpc_xfer(port, buf, buf_pos, 0, 0, I2C_XFER_SINGLE); rv = tcpc_xfer(buf, buf_pos, 0, 0, I2C_XFER_SINGLE);
return rv; return rv;
} }
static int fusb302_tcpm_select_rp_value(int port, int rp) { static int fusb302_tcpm_select_rp_value(int rp) {
int reg; int reg;
int rv; int rv;
uint8_t vnc, rd; uint8_t vnc, rd;
rv = tcpc_read(port, TCPC_REG_CONTROL0, &reg); rv = tcpc_read( TCPC_REG_CONTROL0, &reg);
if (rv) if (rv)
return rv; return rv;
@@ -348,35 +348,35 @@ static int fusb302_tcpm_select_rp_value(int port, int rp) {
vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_VNC_MV); vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_VNC_MV);
rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_RD_THRESH_MV); rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_RD_THRESH_MV);
} }
state[port].mdac_vnc = vnc; state.mdac_vnc = vnc;
state[port].mdac_rd = rd; state.mdac_rd = rd;
rv = tcpc_write(port, TCPC_REG_CONTROL0, reg); rv = tcpc_write( TCPC_REG_CONTROL0, reg);
return rv; return rv;
} }
static int fusb302_tcpm_init(int port) { static int fusb302_tcpm_init() {
int reg; int reg;
/* set default */ /* set default */
state[port].cc_polarity = -1; state.cc_polarity = -1;
/* set the voltage threshold for no connect detection (vOpen) */ /* set the voltage threshold for no connect detection (vOpen) */
state[port].mdac_vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_VNC_MV); state.mdac_vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_VNC_MV);
/* set the voltage threshold for Rd vs Ra detection */ /* set the voltage threshold for Rd vs Ra detection */
state[port].mdac_rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_RD_THRESH_MV); state.mdac_rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_RD_THRESH_MV);
/* all other variables assumed to default to 0 */ /* all other variables assumed to default to 0 */
/* Restore default settings */ /* Restore default settings */
tcpc_write(port, TCPC_REG_RESET, TCPC_REG_RESET_SW_RESET); tcpc_write( TCPC_REG_RESET, TCPC_REG_RESET_SW_RESET);
/* Turn on retries and set number of retries */ /* Turn on retries and set number of retries */
tcpc_read(port, TCPC_REG_CONTROL3, &reg); tcpc_read( TCPC_REG_CONTROL3, &reg);
reg |= TCPC_REG_CONTROL3_AUTO_RETRY; reg |= TCPC_REG_CONTROL3_AUTO_RETRY;
reg |= (PD_RETRY_COUNT & 0x3) << reg |= (PD_RETRY_COUNT & 0x3) <<
TCPC_REG_CONTROL3_N_RETRIES_POS; TCPC_REG_CONTROL3_N_RETRIES_POS;
tcpc_write(port, TCPC_REG_CONTROL3, reg); tcpc_write( TCPC_REG_CONTROL3, reg);
/* Create interrupt masks */ /* Create interrupt masks */
reg = 0xFF; reg = 0xFF;
@@ -388,7 +388,7 @@ static int fusb302_tcpm_init(int port) {
reg &= ~TCPC_REG_MASK_ALERT; reg &= ~TCPC_REG_MASK_ALERT;
/* packet received with correct CRC */ /* packet received with correct CRC */
reg &= ~TCPC_REG_MASK_CRC_CHK; reg &= ~TCPC_REG_MASK_CRC_CHK;
tcpc_write(port, TCPC_REG_MASK, reg); tcpc_write( TCPC_REG_MASK, reg);
reg = 0xFF; reg = 0xFF;
/* when all pd message retries fail... */ /* when all pd message retries fail... */
@@ -399,46 +399,46 @@ static int fusb302_tcpm_init(int port) {
reg &= ~TCPC_REG_MASKA_TX_SUCCESS; reg &= ~TCPC_REG_MASKA_TX_SUCCESS;
/* when fusb302 receives a hard reset */ /* when fusb302 receives a hard reset */
reg &= ~TCPC_REG_MASKA_HARDRESET; reg &= ~TCPC_REG_MASKA_HARDRESET;
tcpc_write(port, TCPC_REG_MASKA, reg); tcpc_write( TCPC_REG_MASKA, reg);
reg = 0xFF; reg = 0xFF;
/* when fusb302 sends GoodCRC to ack a pd message */ /* when fusb302 sends GoodCRC to ack a pd message */
reg &= ~TCPC_REG_MASKB_GCRCSENT; reg &= ~TCPC_REG_MASKB_GCRCSENT;
tcpc_write(port, TCPC_REG_MASKB, reg); tcpc_write( TCPC_REG_MASKB, reg);
/* Interrupt Enable */ /* Interrupt Enable */
tcpc_read(port, TCPC_REG_CONTROL0, &reg); tcpc_read( TCPC_REG_CONTROL0, &reg);
reg &= ~TCPC_REG_CONTROL0_INT_MASK; reg &= ~TCPC_REG_CONTROL0_INT_MASK;
tcpc_write(port, TCPC_REG_CONTROL0, reg); tcpc_write( TCPC_REG_CONTROL0, reg);
/* Set VCONN switch defaults */ /* Set VCONN switch defaults */
tcpm_set_polarity(port, 0); tcpm_set_polarity(0);
tcpm_set_vconn(port, 0); tcpm_set_vconn(0);
/* Turn on the power! */ /* Turn on the power! */
/* TODO: Reduce power consumption */ /* TODO: Reduce power consumption */
tcpc_write(port, TCPC_REG_POWER, TCPC_REG_POWER_PWR_ALL); tcpc_write( TCPC_REG_POWER, TCPC_REG_POWER_PWR_ALL);
return 0; return 0;
} }
static int fusb302_tcpm_release(int port) { static int fusb302_tcpm_release() {
return EC_ERROR_UNIMPLEMENTED; return EC_ERROR_UNIMPLEMENTED;
} }
static int fusb302_tcpm_get_cc(int port, int *cc1, int *cc2) { static int fusb302_tcpm_get_cc(int *cc1, int *cc2) {
if (state[port].pulling_up) { if (state.pulling_up) {
/* Source mode? */ /* Source mode? */
detect_cc_pin_source_manual(port, cc1, cc2); detect_cc_pin_source_manual(cc1, cc2);
} else { } else {
/* Sink mode? */ /* Sink mode? */
detect_cc_pin_sink(port, cc1, cc2); detect_cc_pin_sink(cc1, cc2);
} }
return 0; return 0;
} }
static int fusb302_tcpm_set_cc(int port, int pull) { static int fusb302_tcpm_set_cc(int pull) {
int reg; int reg;
/* NOTE: FUSB302 toggles a single pull-up between CC1 and CC2 */ /* NOTE: FUSB302 toggles a single pull-up between CC1 and CC2 */
@@ -446,7 +446,7 @@ static int fusb302_tcpm_set_cc(int port, int pull) {
switch (pull) { switch (pull) {
case TYPEC_CC_RP: case TYPEC_CC_RP:
/* enable the pull-up we know to be necessary */ /* enable the pull-up we know to be necessary */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN | reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN |
TCPC_REG_SWITCHES0_CC1_PU_EN | TCPC_REG_SWITCHES0_CC1_PU_EN |
@@ -458,49 +458,49 @@ static int fusb302_tcpm_set_cc(int port, int pull) {
reg |= TCPC_REG_SWITCHES0_CC1_PU_EN | reg |= TCPC_REG_SWITCHES0_CC1_PU_EN |
TCPC_REG_SWITCHES0_CC2_PU_EN; TCPC_REG_SWITCHES0_CC2_PU_EN;
if (state[port].vconn_enabled) if (state.vconn_enabled)
reg |= state[port].cc_polarity ? reg |= state.cc_polarity ?
TCPC_REG_SWITCHES0_VCONN_CC1 : TCPC_REG_SWITCHES0_VCONN_CC1 :
TCPC_REG_SWITCHES0_VCONN_CC2; TCPC_REG_SWITCHES0_VCONN_CC2;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
state[port].pulling_up = 1; state.pulling_up = 1;
break; break;
case TYPEC_CC_RD: case TYPEC_CC_RD:
/* Enable UFP Mode */ /* Enable UFP Mode */
/* turn off toggle */ /* turn off toggle */
tcpc_read(port, TCPC_REG_CONTROL2, &reg); tcpc_read( TCPC_REG_CONTROL2, &reg);
reg &= ~TCPC_REG_CONTROL2_TOGGLE; reg &= ~TCPC_REG_CONTROL2_TOGGLE;
tcpc_write(port, TCPC_REG_CONTROL2, reg); tcpc_write( TCPC_REG_CONTROL2, reg);
/* enable pull-downs, disable pullups */ /* enable pull-downs, disable pullups */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN); reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN);
reg &= ~(TCPC_REG_SWITCHES0_CC1_PU_EN); reg &= ~(TCPC_REG_SWITCHES0_CC1_PU_EN);
reg |= (TCPC_REG_SWITCHES0_CC1_PD_EN); reg |= (TCPC_REG_SWITCHES0_CC1_PD_EN);
reg |= (TCPC_REG_SWITCHES0_CC2_PD_EN); reg |= (TCPC_REG_SWITCHES0_CC2_PD_EN);
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
state[port].pulling_up = 0; state.pulling_up = 0;
break; break;
case TYPEC_CC_OPEN: case TYPEC_CC_OPEN:
/* Disable toggling */ /* Disable toggling */
tcpc_read(port, TCPC_REG_CONTROL2, &reg); tcpc_read( TCPC_REG_CONTROL2, &reg);
reg &= ~TCPC_REG_CONTROL2_TOGGLE; reg &= ~TCPC_REG_CONTROL2_TOGGLE;
tcpc_write(port, TCPC_REG_CONTROL2, reg); tcpc_write( TCPC_REG_CONTROL2, reg);
/* Ensure manual switches are opened */ /* Ensure manual switches are opened */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
reg &= ~TCPC_REG_SWITCHES0_CC1_PU_EN; reg &= ~TCPC_REG_SWITCHES0_CC1_PU_EN;
reg &= ~TCPC_REG_SWITCHES0_CC2_PU_EN; reg &= ~TCPC_REG_SWITCHES0_CC2_PU_EN;
reg &= ~TCPC_REG_SWITCHES0_CC1_PD_EN; reg &= ~TCPC_REG_SWITCHES0_CC1_PD_EN;
reg &= ~TCPC_REG_SWITCHES0_CC2_PD_EN; reg &= ~TCPC_REG_SWITCHES0_CC2_PD_EN;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
state[port].pulling_up = 0; state.pulling_up = 0;
break; break;
default: default:
/* Unsupported... */ /* Unsupported... */
@@ -510,17 +510,17 @@ static int fusb302_tcpm_set_cc(int port, int pull) {
return 0; return 0;
} }
static int fusb302_tcpm_set_polarity(int port, int polarity) { static int fusb302_tcpm_set_polarity(int polarity) {
/* Port polarity : 0 => CC1 is CC line, 1 => CC2 is CC line */ /* Port polarity : 0 => CC1 is CC line, 1 => CC2 is CC line */
int reg; int reg;
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
/* clear VCONN switch bits */ /* clear VCONN switch bits */
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1; reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1;
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2; reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2;
if (state[port].vconn_enabled) { if (state.vconn_enabled) {
/* set VCONN switch to be non-CC line */ /* set VCONN switch to be non-CC line */
if (polarity) if (polarity)
reg |= TCPC_REG_SWITCHES0_VCONN_CC1; reg |= TCPC_REG_SWITCHES0_VCONN_CC1;
@@ -538,9 +538,9 @@ static int fusb302_tcpm_set_polarity(int port, int polarity) {
else else
reg |= TCPC_REG_SWITCHES0_MEAS_CC1; reg |= TCPC_REG_SWITCHES0_MEAS_CC1;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
tcpc_read(port, TCPC_REG_SWITCHES1, &reg); tcpc_read( TCPC_REG_SWITCHES1, &reg);
/* clear tx_cc bits */ /* clear tx_cc bits */
reg &= ~TCPC_REG_SWITCHES1_TXCC1_EN; reg &= ~TCPC_REG_SWITCHES1_TXCC1_EN;
@@ -552,15 +552,15 @@ static int fusb302_tcpm_set_polarity(int port, int polarity) {
else else
reg |= TCPC_REG_SWITCHES1_TXCC1_EN; reg |= TCPC_REG_SWITCHES1_TXCC1_EN;
tcpc_write(port, TCPC_REG_SWITCHES1, reg); tcpc_write( TCPC_REG_SWITCHES1, reg);
/* Save the polarity for later */ /* Save the polarity for later */
state[port].cc_polarity = polarity; state.cc_polarity = polarity;
return 0; return 0;
} }
static int fusb302_tcpm_set_vconn(int port, int enable) { static int fusb302_tcpm_set_vconn(int enable) {
/* /*
* FUSB302 does not have dedicated VCONN Enable switch. * FUSB302 does not have dedicated VCONN Enable switch.
* We'll get through this by disabling both of the * We'll get through this by disabling both of the
@@ -572,31 +572,30 @@ static int fusb302_tcpm_set_vconn(int port, int enable) {
int reg; int reg;
/* save enable state for later use */ /* save enable state for later use */
state[port].vconn_enabled = enable; state.vconn_enabled = enable;
if (enable) { if (enable) {
/* set to saved polarity */ /* set to saved polarity */
tcpm_set_polarity(port, state[port].cc_polarity); tcpm_set_polarity(state.cc_polarity);
} else { } else {
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
/* clear VCONN switch bits */ /* clear VCONN switch bits */
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1; reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1;
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2; reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2;
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
} }
return 0; return 0;
} }
static int fusb302_tcpm_set_msg_header(int port, int power_role, static int fusb302_tcpm_set_msg_header(int power_role, int data_role) {
int data_role) {
int reg; int reg;
tcpc_read(port, TCPC_REG_SWITCHES1, &reg); tcpc_read( TCPC_REG_SWITCHES1, &reg);
reg &= ~TCPC_REG_SWITCHES1_POWERROLE; reg &= ~TCPC_REG_SWITCHES1_POWERROLE;
reg &= ~TCPC_REG_SWITCHES1_DATAROLE; reg &= ~TCPC_REG_SWITCHES1_DATAROLE;
@@ -606,25 +605,25 @@ static int fusb302_tcpm_set_msg_header(int port, int power_role,
if (data_role) if (data_role)
reg |= TCPC_REG_SWITCHES1_DATAROLE; reg |= TCPC_REG_SWITCHES1_DATAROLE;
tcpc_write(port, TCPC_REG_SWITCHES1, reg); tcpc_write( TCPC_REG_SWITCHES1, reg);
return 0; return 0;
} }
static int fusb302_tcpm_set_rx_enable(int port, int enable) { static int fusb302_tcpm_set_rx_enable(int enable) {
int reg; int reg;
state[port].rx_enable = enable; state.rx_enable = enable;
/* Get current switch state */ /* Get current switch state */
tcpc_read(port, TCPC_REG_SWITCHES0, &reg); tcpc_read( TCPC_REG_SWITCHES0, &reg);
/* Clear CC1/CC2 measure bits */ /* Clear CC1/CC2 measure bits */
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1;
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2;
if (enable) { if (enable) {
switch (state[port].cc_polarity) { switch (state.cc_polarity) {
/* if CC polarity hasnt been determined, can't enable */ /* if CC polarity hasnt been determined, can't enable */
case -1: case -1:
return EC_ERROR_UNKNOWN; return EC_ERROR_UNKNOWN;
@@ -638,39 +637,39 @@ static int fusb302_tcpm_set_rx_enable(int port, int enable) {
/* "shouldn't get here" */ /* "shouldn't get here" */
return EC_ERROR_UNKNOWN; return EC_ERROR_UNKNOWN;
} }
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
/* Disable BC_LVL interrupt when enabling PD comm */ /* Disable BC_LVL interrupt when enabling PD comm */
if (!tcpc_read(port, TCPC_REG_MASK, &reg)) if (!tcpc_read( TCPC_REG_MASK, &reg))
tcpc_write(port, TCPC_REG_MASK, reg | TCPC_REG_MASK_BC_LVL); tcpc_write( TCPC_REG_MASK, reg | TCPC_REG_MASK_BC_LVL);
/* flush rx fifo in case messages have been coming our way */ /* flush rx fifo in case messages have been coming our way */
fusb302_flush_rx_fifo(port); fusb302_flush_rx_fifo();
} else { } else {
tcpc_write(port, TCPC_REG_SWITCHES0, reg); tcpc_write( TCPC_REG_SWITCHES0, reg);
/* Enable BC_LVL interrupt when disabling PD comm */ /* Enable BC_LVL interrupt when disabling PD comm */
if (!tcpc_read(port, TCPC_REG_MASK, &reg)) if (!tcpc_read( TCPC_REG_MASK, &reg))
tcpc_write(port, TCPC_REG_MASK, reg & ~TCPC_REG_MASK_BC_LVL); tcpc_write( TCPC_REG_MASK, reg & ~TCPC_REG_MASK_BC_LVL);
} }
fusb302_auto_goodcrc_enable(port, enable); fusb302_auto_goodcrc_enable(enable);
return 0; return 0;
} }
/* Return true if our Rx FIFO is empty */ /* Return true if our Rx FIFO is empty */
static int fusb302_rx_fifo_is_empty(int port) { static int fusb302_rx_fifo_is_empty() {
int reg, ret; int reg, ret;
ret = (!tcpc_read(port, TCPC_REG_STATUS1, &reg)) ret = (!tcpc_read( TCPC_REG_STATUS1, &reg))
&& (reg & TCPC_REG_STATUS1_RX_EMPTY); && (reg & TCPC_REG_STATUS1_RX_EMPTY);
return ret; return ret;
} }
static int fusb302_tcpm_get_message(int port, uint32_t *payload, int *head) { static int fusb302_tcpm_get_message(uint32_t *payload, int *head) {
/* /*
* This is the buffer that will get the burst-read data * This is the buffer that will get the burst-read data
* from the fusb302. * from the fusb302.
@@ -683,7 +682,7 @@ static int fusb302_tcpm_get_message(int port, uint32_t *payload, int *head) {
int rv, len; int rv, len;
/* If our FIFO is empty then we have no packet */ /* If our FIFO is empty then we have no packet */
if (fusb302_rx_fifo_is_empty(port)) if (fusb302_rx_fifo_is_empty())
return EC_ERROR_UNKNOWN; return EC_ERROR_UNKNOWN;
/* Read until we have a non-GoodCRC packet or an empty FIFO */ /* Read until we have a non-GoodCRC packet or an empty FIFO */
@@ -694,7 +693,7 @@ static int fusb302_tcpm_get_message(int port, uint32_t *payload, int *head) {
* PART 1 OF BURST READ: Write in register address. * PART 1 OF BURST READ: Write in register address.
* Issue a START, no STOP. * Issue a START, no STOP.
*/ */
rv = tcpc_xfer(port, buf, 1, 0, 0, I2C_XFER_START); rv = tcpc_xfer(buf, 1, 0, 0, I2C_XFER_START);
/* /*
* PART 2 OF BURST READ: Read up to the header. * PART 2 OF BURST READ: Read up to the header.
@@ -703,7 +702,7 @@ static int fusb302_tcpm_get_message(int port, uint32_t *payload, int *head) {
* and determine how many more bytes we need to read. * and determine how many more bytes we need to read.
* TODO: Check token to ensure valid packet. * TODO: Check token to ensure valid packet.
*/ */
rv |= tcpc_xfer(port, 0, 0, buf, 3, I2C_XFER_START); rv |= tcpc_xfer(0, 0, buf, 3, I2C_XFER_START);
/* Grab the header */ /* Grab the header */
*head = (buf[1] & 0xFF); *head = (buf[1] & 0xFF);
@@ -717,9 +716,9 @@ static int fusb302_tcpm_get_message(int port, uint32_t *payload, int *head) {
* No START, but do issue a STOP at the end. * No START, but do issue a STOP at the end.
* add 4 to len to read CRC out * add 4 to len to read CRC out
*/ */
rv |= tcpc_xfer(port, 0, 0, buf, len + 4, I2C_XFER_STOP); rv |= tcpc_xfer(0, 0, buf, len + 4, I2C_XFER_STOP);
} while (!rv && PACKET_IS_GOOD_CRC(*head) && !fusb302_rx_fifo_is_empty(port)); } while (!rv && PACKET_IS_GOOD_CRC(*head) && !fusb302_rx_fifo_is_empty());
if (!rv) { if (!rv) {
/* Discard GoodCRC packets */ /* Discard GoodCRC packets */
@@ -738,8 +737,8 @@ static int fusb302_tcpm_get_message(int port, uint32_t *payload, int *head) {
return rv; return rv;
} }
static int fusb302_tcpm_transmit(int port, enum tcpm_transmit_type type, static int fusb302_tcpm_transmit(enum tcpm_transmit_type type, uint16_t header,
uint16_t header, const uint32_t *data) { const uint32_t *data) {
/* /*
* this is the buffer that will be burst-written into the fusb302 * this is the buffer that will be burst-written into the fusb302
* maximum size necessary = * maximum size necessary =
@@ -760,7 +759,7 @@ static int fusb302_tcpm_transmit(int port, enum tcpm_transmit_type type,
int reg; int reg;
/* Flush the TXFIFO */ /* Flush the TXFIFO */
fusb302_flush_tx_fifo(port); fusb302_flush_tx_fifo ();
switch (type) { switch (type) {
case TCPC_TX_SOP: case TCPC_TX_SOP:
@@ -774,37 +773,37 @@ static int fusb302_tcpm_transmit(int port, enum tcpm_transmit_type type,
buf[buf_pos++] = fusb302_TKN_SYNC1; buf[buf_pos++] = fusb302_TKN_SYNC1;
buf[buf_pos++] = fusb302_TKN_SYNC2; buf[buf_pos++] = fusb302_TKN_SYNC2;
fusb302_send_message(port, header, data, buf, buf_pos); fusb302_send_message(header, data, buf, buf_pos);
// wait for the GoodCRC to come back before we let the rest // wait for the GoodCRC to come back before we let the rest
// of the code do stuff like change polarity and miss it // of the code do stuff like change polarity and miss it
// delay_us(600); // delay_us(600);
osDelay(1); osDelay(1);
break; break;
case TCPC_TX_HARD_RESET: case TCPC_TX_HARD_RESET:
/* Simply hit the SEND_HARD_RESET bit */ /* Simply hit the SEND_HARD_RESET bit */
tcpc_read(port, TCPC_REG_CONTROL3, &reg); tcpc_read( TCPC_REG_CONTROL3, &reg);
reg |= TCPC_REG_CONTROL3_SEND_HARDRESET; reg |= TCPC_REG_CONTROL3_SEND_HARDRESET;
tcpc_write(port, TCPC_REG_CONTROL3, reg); tcpc_write( TCPC_REG_CONTROL3, reg);
break; break;
case TCPC_TX_BIST_MODE_2: case TCPC_TX_BIST_MODE_2:
/* Hit the BIST_MODE2 bit and start TX */ /* Hit the BIST_MODE2 bit and start TX */
tcpc_read(port, TCPC_REG_CONTROL1, &reg); tcpc_read( TCPC_REG_CONTROL1, &reg);
reg |= TCPC_REG_CONTROL1_BIST_MODE2; reg |= TCPC_REG_CONTROL1_BIST_MODE2;
tcpc_write(port, TCPC_REG_CONTROL1, reg); tcpc_write( TCPC_REG_CONTROL1, reg);
tcpc_read(port, TCPC_REG_CONTROL0, &reg); tcpc_read( TCPC_REG_CONTROL0, &reg);
reg |= TCPC_REG_CONTROL0_TX_START; reg |= TCPC_REG_CONTROL0_TX_START;
tcpc_write(port, TCPC_REG_CONTROL0, reg); tcpc_write( TCPC_REG_CONTROL0, reg);
//task_wait_event(PD_T_BIST_TRANSMIT); //task_wait_event(PD_T_BIST_TRANSMIT);
/* Clear BIST mode bit, TX_START is self-clearing */ /* Clear BIST mode bit, TX_START is self-clearing */
tcpc_read(port, TCPC_REG_CONTROL1, &reg); tcpc_read( TCPC_REG_CONTROL1, &reg);
reg &= ~TCPC_REG_CONTROL1_BIST_MODE2; reg &= ~TCPC_REG_CONTROL1_BIST_MODE2;
tcpc_write(port, TCPC_REG_CONTROL1, reg); tcpc_write( TCPC_REG_CONTROL1, reg);
break; break;
default: default:
@@ -815,20 +814,19 @@ static int fusb302_tcpm_transmit(int port, enum tcpm_transmit_type type,
} }
#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC #ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
static int fusb302_tcpm_get_vbus_level(int port) static int fusb302_tcpm_get_vbus_level()
{ {
int reg; int reg;
/* Read status register */ /* Read status register */
tcpc_read(port, TCPC_REG_STATUS0, &reg); tcpc_read( TCPC_REG_STATUS0, &reg);
return (reg & TCPC_REG_STATUS0_VBUSOK) ? 1 : 0; return (reg & TCPC_REG_STATUS0_VBUSOK) ? 1 : 0;
} }
#endif #endif
void fusb302_tcpc_alert(int port) { void fusb302_tcpc_alert() {
/* interrupt has been received */ /* interrupt has been received */
int interrupt; int interrupt;
int interrupta; int interrupta;
@@ -836,85 +834,85 @@ void fusb302_tcpc_alert(int port) {
/* reading interrupt registers clears them */ /* reading interrupt registers clears them */
tcpc_read(port, TCPC_REG_INTERRUPT, &interrupt); tcpc_read( TCPC_REG_INTERRUPT, &interrupt);
tcpc_read(port, TCPC_REG_INTERRUPTA, &interrupta); tcpc_read( TCPC_REG_INTERRUPTA, &interrupta);
tcpc_read(port, TCPC_REG_INTERRUPTB, &interruptb); tcpc_read( TCPC_REG_INTERRUPTB, &interruptb);
/* /*
* Ignore BC_LVL changes when transmitting / receiving PD, * Ignore BC_LVL changes when transmitting / receiving PD,
* since CC level will constantly change. * since CC level will constantly change.
*/ */
if (state[port].rx_enable) if (state.rx_enable)
interrupt &= ~TCPC_REG_INTERRUPT_BC_LVL; interrupt &= ~TCPC_REG_INTERRUPT_BC_LVL;
if (interrupt & TCPC_REG_INTERRUPT_BC_LVL) { if (interrupt & TCPC_REG_INTERRUPT_BC_LVL) {
/* CC Status change */ /* CC Status change */
//task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); //task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0);
} }
if (interrupt & TCPC_REG_INTERRUPT_COLLISION) { if (interrupt & TCPC_REG_INTERRUPT_COLLISION) {
/* packet sending collided */ /* packet sending collided */
pd_transmit_complete(port, TCPC_TX_COMPLETE_FAILED); pd_transmit_complete(TCPC_TX_COMPLETE_FAILED);
} }
/* GoodCRC was received, our FIFO is now non-empty */ /* GoodCRC was received, our FIFO is now non-empty */
if (interrupta & TCPC_REG_INTERRUPTA_TX_SUCCESS) { if (interrupta & TCPC_REG_INTERRUPTA_TX_SUCCESS) {
//task_set_event(PD_PORT_TO_TASK_ID(port), //task_set_event(PD_PORT_TO_TASK_ID(port),
// PD_EVENT_RX, 0); // PD_EVENT_RX, 0);
pd_transmit_complete(port, TCPC_TX_COMPLETE_SUCCESS); pd_transmit_complete(TCPC_TX_COMPLETE_SUCCESS);
} }
if (interrupta & TCPC_REG_INTERRUPTA_RETRYFAIL) { if (interrupta & TCPC_REG_INTERRUPTA_RETRYFAIL) {
/* all retries have failed to get a GoodCRC */ /* all retries have failed to get a GoodCRC */
pd_transmit_complete(port, TCPC_TX_COMPLETE_FAILED); pd_transmit_complete(TCPC_TX_COMPLETE_FAILED);
} }
if (interrupta & TCPC_REG_INTERRUPTA_HARDSENT) { if (interrupta & TCPC_REG_INTERRUPTA_HARDSENT) {
/* hard reset has been sent */ /* hard reset has been sent */
/* bring FUSB302 out of reset */ /* bring FUSB302 out of reset */
fusb302_pd_reset(port); fusb302_pd_reset();
pd_transmit_complete(port, TCPC_TX_COMPLETE_SUCCESS); pd_transmit_complete(TCPC_TX_COMPLETE_SUCCESS);
} }
if (interrupta & TCPC_REG_INTERRUPTA_HARDRESET) { if (interrupta & TCPC_REG_INTERRUPTA_HARDRESET) {
/* hard reset has been received */ /* hard reset has been received */
/* bring FUSB302 out of reset */ /* bring FUSB302 out of reset */
fusb302_pd_reset(port); fusb302_pd_reset();
pd_execute_hard_reset(port); pd_execute_hard_reset ();
//task_wake(PD_PORT_TO_TASK_ID(port)); //task_wake(PD_PORT_TO_TASK_ID(port));
} }
if (interruptb & TCPC_REG_INTERRUPTB_GCRCSENT) { if (interruptb & TCPC_REG_INTERRUPTB_GCRCSENT) {
/* Packet received and GoodCRC sent */ /* Packet received and GoodCRC sent */
/* (this interrupt fires after the GoodCRC finishes) */ /* (this interrupt fires after the GoodCRC finishes) */
if (state[port].rx_enable) { if (state.rx_enable) {
//task_set_event(PD_PORT_TO_TASK_ID(port), //task_set_event(PD_PORT_TO_TASK_ID(port),
// PD_EVENT_RX, 0); // PD_EVENT_RX, 0);
} else { } else {
/* flush rx fifo if rx isn't enabled */ /* flush rx fifo if rx isn't enabled */
fusb302_flush_rx_fifo(port); fusb302_flush_rx_fifo();
} }
} }
} }
/* For BIST receiving */ /* For BIST receiving */
void tcpm_set_bist_test_data(int port) { void tcpm_set_bist_test_data() {
int reg; int reg;
/* Read control3 register */ /* Read control3 register */
tcpc_read(port, TCPC_REG_CONTROL3, &reg); tcpc_read( TCPC_REG_CONTROL3, &reg);
/* Set the BIST_TMODE bit (Clears on Hard Reset) */ /* Set the BIST_TMODE bit (Clears on Hard Reset) */
reg |= TCPC_REG_CONTROL3_BIST_TMODE; reg |= TCPC_REG_CONTROL3_BIST_TMODE;
/* Write the updated value */ /* Write the updated value */
tcpc_write(port, TCPC_REG_CONTROL3, reg); tcpc_write( TCPC_REG_CONTROL3, reg);
} }

View File

@@ -192,17 +192,17 @@ enum pd_rx_errors {
/* function table for entered mode */ /* function table for entered mode */
struct amode_fx { struct amode_fx {
int (*status)(int port, uint32_t *payload); int (*status)( uint32_t *payload);
int (*config)(int port, uint32_t *payload); int (*config)( uint32_t *payload);
}; };
/* function table for alternate mode capable responders */ /* function table for alternate mode capable responders */
struct svdm_response { struct svdm_response {
int (*identity)(int port, uint32_t *payload); int (*identity)( uint32_t *payload);
int (*svids)(int port, uint32_t *payload); int (*svids)( uint32_t *payload);
int (*modes)(int port, uint32_t *payload); int (*modes)( uint32_t *payload);
int (*enter_mode)(int port, uint32_t *payload); int (*enter_mode)( uint32_t *payload);
int (*exit_mode)(int port, uint32_t *payload); int (*exit_mode)( uint32_t *payload);
struct amode_fx *amode; struct amode_fx *amode;
}; };
@@ -214,12 +214,12 @@ struct svdm_svid_data {
struct svdm_amode_fx { struct svdm_amode_fx {
uint16_t svid; uint16_t svid;
int (*enter)(int port, uint32_t mode_caps); int (*enter)( uint32_t mode_caps);
int (*status)(int port, uint32_t *payload); int (*status)( uint32_t *payload);
int (*config)(int port, uint32_t *payload); int (*config)( uint32_t *payload);
void (*post_config)(int port); void (*post_config)();
int (*attention)(int port, uint32_t *payload); int (*attention)( uint32_t *payload);
void (*exit)(int port); void (*exit)();
}; };
/* defined in <board>/usb_pd_policy.c */ /* defined in <board>/usb_pd_policy.c */
@@ -251,8 +251,6 @@ enum hpd_event {
/* supported alternate modes */ /* supported alternate modes */
enum pd_alternate_modes { enum pd_alternate_modes {
PD_AMODE_GOOGLE,
PD_AMODE_DISPLAYPORT,
/* not a real mode */ /* not a real mode */
PD_AMODE_COUNT, PD_AMODE_COUNT,
}; };
@@ -787,7 +785,7 @@ void pd_set_dual_role(enum pd_dual_role_states state);
* *
* @param port Port number from which to get role * @param port Port number from which to get role
*/ */
int pd_get_role(int port); int pd_get_role();
#endif #endif
@@ -973,7 +971,7 @@ enum pd_request_type {
* @param port USB-C port number * @param port USB-C port number
* @return 0 for PD_REV1.0, 1 for PD_REV2.0, 2 for PD_REV3.0 * @return 0 for PD_REV1.0, 1 for PD_REV2.0, 2 for PD_REV3.0
*/ */
int pd_get_rev(int port); int pd_get_rev();
/** /**
* Get current PD VDO Version * Get current PD VDO Version
@@ -981,7 +979,7 @@ int pd_get_rev(int port);
* @param port USB-C port number * @param port USB-C port number
* @return 0 for PD_REV1.0, 1 for PD_REV2.0 * @return 0 for PD_REV1.0, 1 for PD_REV2.0
*/ */
int pd_get_vdo_ver(int port); int pd_get_vdo_ver();
#else #else
#define pd_get_rev(n) PD_REV20 #define pd_get_rev(n) PD_REV20
#define pd_get_vdo_ver(n) VDM_VER10 #define pd_get_vdo_ver(n) VDM_VER10
@@ -996,7 +994,7 @@ int pd_get_vdo_ver(int port);
* @param req_type request type * @param req_type request type
* @return <0 if invalid, else EC_SUCCESS * @return <0 if invalid, else EC_SUCCESS
*/ */
int pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv, int pd_build_request( uint32_t *rdo, uint32_t *ma, uint32_t *mv,
enum pd_request_type req_type); enum pd_request_type req_type);
/** /**
@@ -1014,7 +1012,7 @@ int pd_is_max_request_allowed(void);
* @param cnt the number of Power Data Objects. * @param cnt the number of Power Data Objects.
* @param src_caps Power Data Objects representing the source capabilities. * @param src_caps Power Data Objects representing the source capabilities.
*/ */
void pd_process_source_cap_callback(int port, int cnt, uint32_t *src_caps); void pd_process_source_cap_callback( int cnt, uint32_t *src_caps);
/** /**
* Process source capabilities packet * Process source capabilities packet
@@ -1023,7 +1021,7 @@ void pd_process_source_cap_callback(int port, int cnt, uint32_t *src_caps);
* @param cnt the number of Power Data Objects. * @param cnt the number of Power Data Objects.
* @param src_caps Power Data Objects representing the source capabilities. * @param src_caps Power Data Objects representing the source capabilities.
*/ */
void pd_process_source_cap(int port, int cnt, uint32_t *src_caps); void pd_process_source_cap( int cnt, uint32_t *src_caps);
/** /**
* Find PDO index that offers the most amount of power and stays within * Find PDO index that offers the most amount of power and stays within
@@ -1034,7 +1032,7 @@ void pd_process_source_cap(int port, int cnt, uint32_t *src_caps);
* @param pdo raw pdo corresponding to index, or index 0 on error (output) * @param pdo raw pdo corresponding to index, or index 0 on error (output)
* @return index of PDO within source cap packet * @return index of PDO within source cap packet
*/ */
int pd_find_pdo_index(int port, int max_mv, uint32_t *pdo); int pd_find_pdo_index( int max_mv, uint32_t *pdo);
/** /**
* Extract power information out of a Power Data Object (PDO) * Extract power information out of a Power Data Object (PDO)
@@ -1052,7 +1050,7 @@ void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv);
* @param ma reduce current to minimum value. * @param ma reduce current to minimum value.
* @param mv reduce voltage to minimum value. * @param mv reduce voltage to minimum value.
*/ */
void pd_snk_give_back(int port, uint32_t * const ma, uint32_t * const mv); void pd_snk_give_back( uint32_t * const ma, uint32_t * const mv);
/** /**
* Put a cap on the max voltage requested as a sink. * Put a cap on the max voltage requested as a sink.
@@ -1104,7 +1102,7 @@ void pd_transition_voltage(int idx);
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_power_supply_reset(int port); void pd_power_supply_reset();
/** /**
* Enable or disable VBUS discharge for a given port. * Enable or disable VBUS discharge for a given port.
@@ -1112,7 +1110,7 @@ void pd_power_supply_reset(int port);
* @param port USB-C port number * @param port USB-C port number
* @enable 1 if enabling discharge, 0 if disabling * @enable 1 if enabling discharge, 0 if disabling
*/ */
void pd_set_vbus_discharge(int port, int enable); void pd_set_vbus_discharge( int enable);
/** /**
* Enable the power supply output after the ready delay. * Enable the power supply output after the ready delay.
@@ -1120,7 +1118,7 @@ void pd_set_vbus_discharge(int port, int enable);
* @param port USB-C port number * @param port USB-C port number
* @return EC_SUCCESS if the power supply is ready, <0 else. * @return EC_SUCCESS if the power supply is ready, <0 else.
*/ */
int pd_set_power_supply_ready(int port); int pd_set_power_supply_ready();
/** /**
* Ask the specified voltage from the PD source. * Ask the specified voltage from the PD source.
@@ -1129,7 +1127,7 @@ int pd_set_power_supply_ready(int port);
* @param port USB-C port number * @param port USB-C port number
* @param mv request voltage in millivolts. * @param mv request voltage in millivolts.
*/ */
void pd_request_source_voltage(int port, int mv); void pd_request_source_voltage( int mv);
/** /**
* Set a voltage limit from the PD source. * Set a voltage limit from the PD source.
@@ -1138,7 +1136,7 @@ void pd_request_source_voltage(int port, int mv);
* @param port USB-C port number * @param port USB-C port number
* @param mv limit voltage in millivolts. * @param mv limit voltage in millivolts.
*/ */
void pd_set_external_voltage_limit(int port, int mv); void pd_set_external_voltage_limit( int mv);
/** /**
* Set the PD input current limit. * Set the PD input current limit.
@@ -1147,7 +1145,7 @@ void pd_set_external_voltage_limit(int port, int mv);
* @param max_ma Maximum current limit * @param max_ma Maximum current limit
* @param supply_voltage Voltage at which current limit is applied * @param supply_voltage Voltage at which current limit is applied
*/ */
void pd_set_input_current_limit(int port, uint32_t max_ma, void pd_set_input_current_limit( uint32_t max_ma,
uint32_t supply_voltage); uint32_t supply_voltage);
@@ -1156,7 +1154,7 @@ void pd_set_input_current_limit(int port, uint32_t max_ma,
* *
* @param port USB-C port number. * @param port USB-C port number.
*/ */
void pd_update_contract(int port); void pd_update_contract();
/* Encode DTS status of port partner in current limit parameter */ /* Encode DTS status of port partner in current limit parameter */
typedef uint32_t typec_current_t; typedef uint32_t typec_current_t;
@@ -1170,7 +1168,7 @@ typedef uint32_t typec_current_t;
* @param max_ma Maximum current limit * @param max_ma Maximum current limit
* @param supply_voltage Voltage at which current limit is applied * @param supply_voltage Voltage at which current limit is applied
*/ */
void typec_set_input_current_limit(int port, typec_current_t max_ma, void typec_set_input_current_limit( typec_current_t max_ma,
uint32_t supply_voltage); uint32_t supply_voltage);
/** /**
@@ -1179,7 +1177,7 @@ void typec_set_input_current_limit(int port, typec_current_t max_ma,
* @param port USB-C port number * @param port USB-C port number
* @param rp One of enum tcpc_rp_value (eg TYPEC_RP_3A0) defining the limit. * @param rp One of enum tcpc_rp_value (eg TYPEC_RP_3A0) defining the limit.
*/ */
void typec_set_source_current_limit(int port, int rp); void typec_set_source_current_limit( int rp);
/** /**
* Verify board specific health status : current, voltages... * Verify board specific health status : current, voltages...
@@ -1194,14 +1192,14 @@ int pd_board_checks(void);
* @param port USB-C port number * @param port USB-C port number
* @return VBUS is detected * @return VBUS is detected
*/ */
int pd_snk_is_vbus_provided(int port); int pd_snk_is_vbus_provided();
/** /**
* Notify PD protocol that VBUS has gone low * Notify PD protocol that VBUS has gone low
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_vbus_low(int port); void pd_vbus_low();
/** /**
* Check if power swap is allowed. * Check if power swap is allowed.
@@ -1209,7 +1207,7 @@ void pd_vbus_low(int port);
* @param port USB-C port number * @param port USB-C port number
* @return True if power swap is allowed, False otherwise * @return True if power swap is allowed, False otherwise
*/ */
int pd_check_power_swap(int port); int pd_check_power_swap();
/** /**
* Check if data swap is allowed. * Check if data swap is allowed.
@@ -1218,7 +1216,7 @@ int pd_check_power_swap(int port);
* @param data_role current data role * @param data_role current data role
* @return True if data swap is allowed, False otherwise * @return True if data swap is allowed, False otherwise
*/ */
int pd_check_data_swap(int port, int data_role); int pd_check_data_swap( int data_role);
/** /**
* Check if vconn swap is allowed. * Check if vconn swap is allowed.
@@ -1227,7 +1225,7 @@ int pd_check_data_swap(int port, int data_role);
* @return True if vconn swap is allowed, False otherwise * @return True if vconn swap is allowed, False otherwise
*/ */
int pd_check_vconn_swap(int port); int pd_check_vconn_swap();
/** /**
* Check current power role for potential power swap * Check current power role for potential power swap
@@ -1236,7 +1234,7 @@ int pd_check_vconn_swap(int port);
* @param pr_role Our power role * @param pr_role Our power role
* @param flags PD flags * @param flags PD flags
*/ */
void pd_check_pr_role(int port, int pr_role, int flags); void pd_check_pr_role( int pr_role, int flags);
/** /**
* Check current data role for potential data swap * Check current data role for potential data swap
@@ -1245,7 +1243,7 @@ void pd_check_pr_role(int port, int pr_role, int flags);
* @param dr_role Our data role * @param dr_role Our data role
* @param flags PD flags * @param flags PD flags
*/ */
void pd_check_dr_role(int port, int dr_role, int flags); void pd_check_dr_role( int dr_role, int flags);
/** /**
* Check if we should charge from this device. This is * Check if we should charge from this device. This is
@@ -1264,7 +1262,7 @@ int pd_charge_from_device(uint16_t vid, uint16_t pid);
* @param port USB-C port number * @param port USB-C port number
* @param data_role new data role * @param data_role new data role
*/ */
void pd_execute_data_swap(int port, int data_role); void pd_execute_data_swap( int data_role);
/** /**
* Get PD device info used for VDO_CMD_SEND_INFO / VDO_CMD_READ_INFO * Get PD device info used for VDO_CMD_SEND_INFO / VDO_CMD_READ_INFO
@@ -1282,7 +1280,7 @@ void pd_get_info(uint32_t *info_data);
* @param rpayload pointer to the data to send back. * @param rpayload pointer to the data to send back.
* @return if >0, number of VDOs to send back. * @return if >0, number of VDOs to send back.
*/ */
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload); int pd_custom_vdm( int cnt, uint32_t *payload, uint32_t **rpayload);
/** /**
* Handle Structured Vendor Defined Messages * Handle Structured Vendor Defined Messages
@@ -1293,7 +1291,7 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload);
* @param rpayload pointer to the data to send back. * @param rpayload pointer to the data to send back.
* @return if >0, number of VDOs to send back. * @return if >0, number of VDOs to send back.
*/ */
int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload); int pd_svdm( int cnt, uint32_t *payload, uint32_t **rpayload);
/** /**
* Handle Custom VDMs for flashing. * Handle Custom VDMs for flashing.
@@ -1303,7 +1301,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload);
* @param payload payload data. * @param payload payload data.
* @return if >0, number of VDOs to send back. * @return if >0, number of VDOs to send back.
*/ */
int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload); int pd_custom_flash_vdm( int cnt, uint32_t *payload);
/** /**
* Enter alternate mode on DFP * Enter alternate mode on DFP
@@ -1313,7 +1311,7 @@ int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload);
* @param opos object position of mode to exit. * @param opos object position of mode to exit.
* @return vdm for UFP to be sent to enter mode or zero if not. * @return vdm for UFP to be sent to enter mode or zero if not.
*/ */
uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos); uint32_t pd_dfp_enter_mode( uint16_t svid, int opos);
/** /**
* Get DisplayPort pin mode for DFP to request from UFP's capabilities. * Get DisplayPort pin mode for DFP to request from UFP's capabilities.
@@ -1322,7 +1320,7 @@ uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos);
* @param status DisplayPort Status VDO. * @param status DisplayPort Status VDO.
* @return one-hot PIN config to request. * @return one-hot PIN config to request.
*/ */
int pd_dfp_dp_get_pin_mode(int port, uint32_t status); int pd_dfp_dp_get_pin_mode( uint32_t status);
/** /**
* Exit alternate mode on DFP * Exit alternate mode on DFP
@@ -1332,14 +1330,14 @@ int pd_dfp_dp_get_pin_mode(int port, uint32_t status);
* @param opos object position of mode to exit. * @param opos object position of mode to exit.
* @return 1 if UFP should be sent exit mode VDM. * @return 1 if UFP should be sent exit mode VDM.
*/ */
int pd_dfp_exit_mode(int port, uint16_t svid, int opos); int pd_dfp_exit_mode( uint16_t svid, int opos);
/** /**
* Initialize policy engine for DFP * Initialize policy engine for DFP
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_dfp_pe_init(int port); void pd_dfp_pe_init();
/** /**
* Return the VID of the USB PD accessory connected to a specified port * Return the VID of the USB PD accessory connected to a specified port
@@ -1347,7 +1345,7 @@ void pd_dfp_pe_init(int port);
* @param port USB-C port number * @param port USB-C port number
* @return the USB Vendor Identifier or 0 if it doesn't exist * @return the USB Vendor Identifier or 0 if it doesn't exist
*/ */
uint16_t pd_get_identity_vid(int port); uint16_t pd_get_identity_vid();
/** /**
* Return the PID of the USB PD accessory connected to a specified port * Return the PID of the USB PD accessory connected to a specified port
@@ -1355,7 +1353,7 @@ uint16_t pd_get_identity_vid(int port);
* @param port USB-C port number * @param port USB-C port number
* @return the USB Product Identifier or 0 if it doesn't exist * @return the USB Product Identifier or 0 if it doesn't exist
*/ */
uint16_t pd_get_identity_pid(int port); uint16_t pd_get_identity_pid();
/** /**
* Store Device ID & RW hash of device * Store Device ID & RW hash of device
@@ -1367,7 +1365,7 @@ uint16_t pd_get_identity_pid(int port);
* @return true if the dev / hash match an existing hash * @return true if the dev / hash match an existing hash
* in our table, false otherwise * in our table, false otherwise
*/ */
int pd_dev_store_rw_hash(int port, uint16_t dev_id, uint32_t *rw_hash, int pd_dev_store_rw_hash( uint16_t dev_id, uint32_t *rw_hash,
uint32_t ec_current_image); uint32_t ec_current_image);
/** /**
@@ -1376,7 +1374,7 @@ int pd_dev_store_rw_hash(int port, uint16_t dev_id, uint32_t *rw_hash,
* @param port USB-C accessory port number * @param port USB-C accessory port number
* @return EC_RES_SUCCESS if the VDM was sent properly else error code * @return EC_RES_SUCCESS if the VDM was sent properly else error code
*/ */
int pd_fetch_acc_log_entry(int port); int pd_fetch_acc_log_entry();
/** /**
* Analyze the log entry received as the VDO_CMD_GET_LOG payload. * Analyze the log entry received as the VDO_CMD_GET_LOG payload.
@@ -1385,7 +1383,7 @@ int pd_fetch_acc_log_entry(int port);
* @param cnt number of data objects in payload * @param cnt number of data objects in payload
* @param payload payload data * @param payload payload data
*/ */
void pd_log_recv_vdm(int port, int cnt, uint32_t *payload); void pd_log_recv_vdm( int cnt, uint32_t *payload);
/** /**
* Send Vendor Defined Message * Send Vendor Defined Message
@@ -1396,7 +1394,7 @@ void pd_log_recv_vdm(int port, int cnt, uint32_t *payload);
* @param data Pointer to payload to send * @param data Pointer to payload to send
* @param count number of data objects in payload * @param count number of data objects in payload
*/ */
void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data, void pd_send_vdm( uint32_t vid, int cmd, const uint32_t *data,
int count); int count);
/* Power Data Objects for the source and the sink */ /* Power Data Objects for the source and the sink */
@@ -1425,7 +1423,7 @@ static inline void pd_send_host_event(int mask) { }
* @param svid USB standard or vendor id * @param svid USB standard or vendor id
* @return object position of mode chosen in alternate mode otherwise zero. * @return object position of mode chosen in alternate mode otherwise zero.
*/ */
int pd_alt_mode(int port, uint16_t svid); int pd_alt_mode( uint16_t svid);
/** /**
* Send hpd over USB PD. * Send hpd over USB PD.
@@ -1433,7 +1431,7 @@ int pd_alt_mode(int port, uint16_t svid);
* @param port port number. * @param port port number.
* @param hpd hotplug detect type. * @param hpd hotplug detect type.
*/ */
void pd_send_hpd(int port, enum hpd_event hpd); void pd_send_hpd( enum hpd_event hpd);
/** /**
* Enable USB Billboard Device. * Enable USB Billboard Device.
@@ -1448,7 +1446,7 @@ extern const struct deferred_data pd_usb_billboard_deferred_data;
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_init_dequeue(int port); void pd_init_dequeue();
/** /**
* Prepare packet reading state machine. * Prepare packet reading state machine.
@@ -1459,7 +1457,7 @@ void pd_init_dequeue(int port);
* @param val the read bits. * @param val the read bits.
* @return new position in the packet buffer. * @return new position in the packet buffer.
*/ */
int pd_dequeue_bits(int port, int off, int len, uint32_t *val); int pd_dequeue_bits( int off, int len, uint32_t *val);
/** /**
* Advance until the end of the preamble. * Advance until the end of the preamble.
@@ -1467,7 +1465,7 @@ int pd_dequeue_bits(int port, int off, int len, uint32_t *val);
* @param port USB-C port number * @param port USB-C port number
* @return new position in the packet buffer. * @return new position in the packet buffer.
*/ */
int pd_find_preamble(int port); int pd_find_preamble();
/** /**
* Write the preamble in the TX buffer. * Write the preamble in the TX buffer.
@@ -1475,7 +1473,7 @@ int pd_find_preamble(int port);
* @param port USB-C port number * @param port USB-C port number
* @return new position in the packet buffer. * @return new position in the packet buffer.
*/ */
int pd_write_preamble(int port); int pd_write_preamble();
/** /**
* Write one 10-period symbol in the TX packet. * Write one 10-period symbol in the TX packet.
@@ -1487,7 +1485,7 @@ int pd_write_preamble(int port);
* @param val10 the 10-bit integer. * @param val10 the 10-bit integer.
* @return new position in the packet buffer. * @return new position in the packet buffer.
*/ */
int pd_write_sym(int port, int bit_off, uint32_t val10); int pd_write_sym( int bit_off, uint32_t val10);
/** /**
@@ -1498,7 +1496,7 @@ int pd_write_sym(int port, int bit_off, uint32_t val10);
* @param bit_off current position in the packet buffer. * @param bit_off current position in the packet buffer.
* @return new position in the packet buffer. * @return new position in the packet buffer.
*/ */
int pd_write_last_edge(int port, int bit_off); int pd_write_last_edge( int bit_off);
/** /**
* Do 4B5B encoding on a 32-bit word. * Do 4B5B encoding on a 32-bit word.
@@ -1508,7 +1506,7 @@ int pd_write_last_edge(int port, int bit_off);
* @param val32 32-bit word value to encode * @param val32 32-bit word value to encode
* @return new offset in the message in bits. * @return new offset in the message in bits.
*/ */
int encode_word(int port, int off, uint32_t val32); int encode_word( int off, uint32_t val32);
/** /**
* Ensure that we have an edge after EOP and we end up at level 0, * Ensure that we have an edge after EOP and we end up at level 0,
@@ -1520,7 +1518,7 @@ int encode_word(int port, int off, uint32_t val32);
* @param data payload content * @param data payload content
* @return length of the message in bits. * @return length of the message in bits.
*/ */
int prepare_message(int port, uint16_t header, uint8_t cnt, int prepare_message( uint16_t header, uint8_t cnt,
const uint32_t *data); const uint32_t *data);
/** /**
@@ -1529,7 +1527,7 @@ int prepare_message(int port, uint16_t header, uint8_t cnt,
* @param port USB-C port number * @param port USB-C port number
* @param msg context string. * @param msg context string.
*/ */
void pd_dump_packet(int port, const char *msg); void pd_dump_packet( const char *msg);
/** /**
* Change the TX data clock frequency. * Change the TX data clock frequency.
@@ -1537,7 +1535,7 @@ void pd_dump_packet(int port, const char *msg);
* @param port USB-C port number * @param port USB-C port number
* @param freq frequency in hertz. * @param freq frequency in hertz.
*/ */
void pd_set_clock(int port, int freq); void pd_set_clock( int freq);
/* TX/RX callbacks */ /* TX/RX callbacks */
@@ -1549,7 +1547,7 @@ void pd_set_clock(int port, int freq);
* @param bit_len size of the packet in bits. * @param bit_len size of the packet in bits.
* @return length transmitted or negative if error * @return length transmitted or negative if error
*/ */
int pd_start_tx(int port, int polarity, int bit_len); int pd_start_tx( int polarity, int bit_len);
/** /**
* Set PD TX DMA to use circular mode. Call this before pd_start_tx() to * Set PD TX DMA to use circular mode. Call this before pd_start_tx() to
@@ -1557,14 +1555,14 @@ int pd_start_tx(int port, int polarity, int bit_len);
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_tx_set_circular_mode(int port); void pd_tx_set_circular_mode();
/** /**
* Stop PD TX DMA circular mode transaction already in progress. * Stop PD TX DMA circular mode transaction already in progress.
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_tx_clear_circular_mode(int port); void pd_tx_clear_circular_mode();
/** /**
* Call when we are done sending a packet. * Call when we are done sending a packet.
@@ -1572,7 +1570,7 @@ void pd_tx_clear_circular_mode(int port);
* @param port USB-C port number * @param port USB-C port number
* @param polarity plug polarity (0=CC1, 1=CC2). * @param polarity plug polarity (0=CC1, 1=CC2).
*/ */
void pd_tx_done(int port, int polarity); void pd_tx_done( int polarity);
/** /**
* Check whether the PD reception is started. * Check whether the PD reception is started.
@@ -1580,14 +1578,14 @@ void pd_tx_done(int port, int polarity);
* @param port USB-C port number * @param port USB-C port number
* @return true if the reception is on-going. * @return true if the reception is on-going.
*/ */
int pd_rx_started(int port); int pd_rx_started();
/** /**
* Suspend the PD task. * Suspend the PD task.
* @param port USB-C port number * @param port USB-C port number
* @param enable pass 0 to resume, anything else to suspend * @param enable pass 0 to resume, anything else to suspend
*/ */
void pd_set_suspend(int port, int enable); void pd_set_suspend( int enable);
/** /**
* Check if the port has been initialized and PD task has not been * Check if the port has been initialized and PD task has not been
@@ -1596,29 +1594,29 @@ void pd_set_suspend(int port, int enable);
* @param port USB-C port number * @param port USB-C port number
* @return true if the PD task is not suspended. * @return true if the PD task is not suspended.
*/ */
int pd_is_port_enabled(int port); int pd_is_port_enabled();
/* Callback when the hardware has detected an incoming packet */ /* Callback when the hardware has detected an incoming packet */
void pd_rx_event(int port); void pd_rx_event();
/* Start sampling the CC line for reception */ /* Start sampling the CC line for reception */
void pd_rx_start(int port); void pd_rx_start();
/* Call when we are done reading a packet */ /* Call when we are done reading a packet */
void pd_rx_complete(int port); void pd_rx_complete();
/* restart listening to the CC wire */ /* restart listening to the CC wire */
void pd_rx_enable_monitoring(int port); void pd_rx_enable_monitoring();
/* stop listening to the CC wire during transmissions */ /* stop listening to the CC wire during transmissions */
void pd_rx_disable_monitoring(int port); void pd_rx_disable_monitoring();
/* get time since last RX edge interrupt */ /* get time since last RX edge interrupt */
uint64_t get_time_since_last_edge(int port); uint64_t get_time_since_last_edge();
/** /**
* Deinitialize the hardware used for PD. * Deinitialize the hardware used for PD.
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_hw_release(int port); void pd_hw_release();
/** /**
* Initialize the hardware used for PD RX/TX. * Initialize the hardware used for PD RX/TX.
@@ -1626,7 +1624,7 @@ void pd_hw_release(int port);
* @param port USB-C port number * @param port USB-C port number
* @param role Role to initialize pins in * @param role Role to initialize pins in
*/ */
void pd_hw_init(int port, int role); void pd_hw_init( int role);
/** /**
* Initialize the reception side of hardware used for PD. * Initialize the reception side of hardware used for PD.
@@ -1636,19 +1634,19 @@ void pd_hw_init(int port, int role);
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_hw_init_rx(int port); void pd_hw_init_rx();
/** /**
* Initialize the Power Delivery state machine * Initialize the Power Delivery state machine
*/ */
void pd_init(int port); void pd_init();
/** /**
* Run the state machine. This function must be called regularly * Run the state machine. This function must be called regularly
* to iterate through the state machine. It uses get_time() to * to iterate through the state machine. It uses get_time() to
* determine what actions to take each call. * determine what actions to take each call.
*/ */
void pd_run_state_machine(int port); void pd_run_state_machine();
/* --- Protocol layer functions --- */ /* --- Protocol layer functions --- */
@@ -1659,14 +1657,14 @@ void pd_run_state_machine(int port);
* @param payload buffer to store the packet payload (must be 7x 32-bit) * @param payload buffer to store the packet payload (must be 7x 32-bit)
* @return the packet header or <0 in case of error * @return the packet header or <0 in case of error
*/ */
int pd_analyze_rx(int port, uint32_t *payload); int pd_analyze_rx( uint32_t *payload);
/** /**
* Check if PD communication is enabled * Check if PD communication is enabled
* *
* @return true if it's enabled or false otherwise * @return true if it's enabled or false otherwise
*/ */
int pd_comm_is_enabled(int port); int pd_comm_is_enabled();
/** /**
* Get connected state * Get connected state
@@ -1674,14 +1672,14 @@ int pd_comm_is_enabled(int port);
* @param port USB-C port number * @param port USB-C port number
* @return True if port is in connected state * @return True if port is in connected state
*/ */
int pd_is_connected(int port); int pd_is_connected();
/** /**
* Execute a hard reset * Execute a hard reset
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_execute_hard_reset(int port); void pd_execute_hard_reset();
/** /**
* Signal to protocol layer that PD transmit is complete * Signal to protocol layer that PD transmit is complete
@@ -1689,28 +1687,28 @@ void pd_execute_hard_reset(int port);
* @param port USB-C port number * @param port USB-C port number
* @param status status of the transmission * @param status status of the transmission
*/ */
void pd_transmit_complete(int port, int status); void pd_transmit_complete( int status);
/** /**
* Get port polarity. * Get port polarity.
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
int pd_get_polarity(int port); int pd_get_polarity();
/** /**
* Get port partner data swap capable status * Get port partner data swap capable status
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
int pd_get_partner_data_swap_capable(int port); int pd_get_partner_data_swap_capable();
/** /**
* Request power swap command to be issued * Request power swap command to be issued
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_request_power_swap(int port); void pd_request_power_swap();
/** /**
* Try to become the VCONN source, if we are not already the source and the * Try to become the VCONN source, if we are not already the source and the
@@ -1718,14 +1716,14 @@ void pd_request_power_swap(int port);
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_try_vconn_src(int port); void pd_try_vconn_src();
/** /**
* Request data swap command to be issued * Request data swap command to be issued
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_request_data_swap(int port); void pd_request_data_swap();
/** /**
* Set the PD communication enabled flag. When communication is disabled, * Set the PD communication enabled flag. When communication is disabled,
@@ -1735,7 +1733,7 @@ void pd_request_data_swap(int port);
* @param port USB-C port number * @param port USB-C port number
* @param enable Enable flag to set * @param enable Enable flag to set
*/ */
void pd_comm_enable(int port, int enable); void pd_comm_enable( int enable);
/** /**
* Set the PD pings enabled flag. When source has negotiated power over * Set the PD pings enabled flag. When source has negotiated power over
@@ -1745,7 +1743,7 @@ void pd_comm_enable(int port, int enable);
* @param port USB-C port number * @param port USB-C port number
* @param enable Enable flag to set * @param enable Enable flag to set
*/ */
void pd_ping_enable(int port, int enable); void pd_ping_enable( int enable);
/* Issue PD soft reset */ /* Issue PD soft reset */
void pd_soft_reset(void); void pd_soft_reset(void);
@@ -1758,7 +1756,7 @@ void pd_prepare_reset(void);
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
void pd_set_new_power_request(int port); void pd_set_new_power_request();
/** /**
* Return true if partner port is a DTS or TS capable of entering debug * Return true if partner port is a DTS or TS capable of entering debug
@@ -1766,7 +1764,7 @@ void pd_set_new_power_request(int port);
* *
* @param port USB-C port number * @param port USB-C port number
*/ */
int pd_ts_dts_plugged(int port); int pd_ts_dts_plugged();
/* ----- Logging ----- */ /* ----- Logging ----- */
#ifdef CONFIG_USB_PD_LOGGING #ifdef CONFIG_USB_PD_LOGGING

View File

@@ -17,69 +17,31 @@
static int rw_flash_changed = 1; static int rw_flash_changed = 1;
int pd_check_requested_voltage(uint32_t rdo, const int port) { int pd_check_requested_voltage(uint32_t rdo, const int port) {
int max_ma = rdo & 0x3FF; //No source
int op_ma = (rdo >> 10) & 0x3FF;
int idx = RDO_POS(rdo);
uint32_t pdo;
uint32_t pdo_ma;
#if defined(CONFIG_USB_PD_DYNAMIC_SRC_CAP) || \
defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT)
const uint32_t *src_pdo;
const int pdo_cnt = charge_manager_get_source_pdo(&src_pdo, port);
#else
const uint32_t *src_pdo = pd_src_pdo;
const int pdo_cnt = pd_src_pdo_cnt;
#endif
/* Board specific check for this request */
if (pd_board_check_request(rdo, pdo_cnt))
return EC_ERROR_INVAL; return EC_ERROR_INVAL;
/* check current ... */
pdo = src_pdo[idx - 1];
pdo_ma = (pdo & 0x3ff);
if (op_ma > pdo_ma)
return EC_ERROR_INVAL; /* too much op current */
if (max_ma > pdo_ma && !(rdo & RDO_CAP_MISMATCH))
return EC_ERROR_INVAL; /* too much max current */
CPRINTF("Requested %d V %d mA (for %d/%d mA)\n",
((pdo >> 10) & 0x3ff) * 50, (pdo & 0x3ff) * 10,
op_ma * 10, max_ma * 10);
/* Accept the requested voltage */
return EC_SUCCESS;
} }
static int stub_pd_board_check_request(uint32_t rdo, int pdo_cnt) {
int idx = RDO_POS(rdo);
/* Check for invalid index */
return (!idx || idx > pdo_cnt) ? EC_ERROR_INVAL : EC_SUCCESS;
}
int pd_board_check_request(uint32_t, int) __attribute__((weak, alias("stub_pd_board_check_request")));
#ifdef CONFIG_USB_PD_DUAL_ROLE #ifdef CONFIG_USB_PD_DUAL_ROLE
/* Last received source cap */ /* Last received source cap */
static uint32_t pd_src_caps[CONFIG_USB_PD_PORT_COUNT][PDO_MAX_OBJECTS]; static uint32_t pd_src_caps[PDO_MAX_OBJECTS];
static uint8_t pd_src_cap_cnt[CONFIG_USB_PD_PORT_COUNT]; static uint8_t pd_src_cap_cnt;
/* Cap on the max voltage requested as a sink (in millivolts) */ /* Cap on the max voltage requested as a sink (in millivolts) */
static unsigned max_request_mv = PD_MAX_VOLTAGE_MV; /* no cap */ static unsigned max_request_mv = PD_MAX_VOLTAGE_MV; /* no cap */
int pd_find_pdo_index(int port, int max_mv, uint32_t *selected_pdo) { int pd_find_pdo_index(int max_mv, uint32_t *selected_pdo) {
int i, uw, mv, ma; int i, uw, mv, ma;
int ret = 0; int ret = 0;
int __attribute__((unused)) cur_mv = 0; int __attribute__((unused)) cur_mv = 0;
int cur_uw = 0; int cur_uw = 0;
int prefer_cur; int prefer_cur;
const uint32_t *src_caps = pd_src_caps[port]; const uint32_t *src_caps = pd_src_caps;
/* max voltage is always limited by this boards max request */ /* max voltage is always limited by this boards max request */
max_mv = MIN(max_mv, PD_MAX_VOLTAGE_MV); max_mv = MIN(max_mv, PD_MAX_VOLTAGE_MV);
/* Get max power that is under our max voltage input */ /* Get max power that is under our max voltage input */
for (i = 0; i < pd_src_cap_cnt[port]; i++) { for (i = 0; i < pd_src_cap_cnt; i++) {
/* its an unsupported Augmented PDO (PD3.0) */ /* its an unsupported Augmented PDO (PD3.0) */
if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED) if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED)
continue; continue;
@@ -149,7 +111,7 @@ void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *mv) {
*ma = MIN(max_ma, PD_MAX_CURRENT_MA); *ma = MIN(max_ma, PD_MAX_CURRENT_MA);
} }
int pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv, int pd_build_request(uint32_t *rdo, uint32_t *ma, uint32_t *mv,
enum pd_request_type req_type) { enum pd_request_type req_type) {
uint32_t pdo; uint32_t pdo;
int pdo_index, flags = 0; int pdo_index, flags = 0;
@@ -160,10 +122,10 @@ int pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv,
if (req_type == PD_REQUEST_VSAFE5V) { if (req_type == PD_REQUEST_VSAFE5V) {
/* src cap 0 should be vSafe5V */ /* src cap 0 should be vSafe5V */
pdo_index = 0; pdo_index = 0;
pdo = pd_src_caps[port][0]; pdo = pd_src_caps[0];
} else { } else {
/* find pdo index for max voltage we can request */ /* find pdo index for max voltage we can request */
pdo_index = pd_find_pdo_index(port, max_request_mv, &pdo); pdo_index = pd_find_pdo_index(max_request_mv, &pdo);
} }
pd_extract_pdo_power(pdo, ma, mv); pd_extract_pdo_power(pdo, ma, mv);
@@ -205,29 +167,29 @@ int pd_build_request(int port, uint32_t *rdo, uint32_t *ma, uint32_t *mv,
return EC_SUCCESS; return EC_SUCCESS;
} }
void pd_process_source_cap(int port, int cnt, uint32_t *src_caps) { void pd_process_source_cap(int cnt, uint32_t *src_caps) {
#ifdef CONFIG_CHARGE_MANAGER #ifdef CONFIG_CHARGE_MANAGER
uint32_t ma, mv, pdo; uint32_t ma, mv, pdo;
#endif #endif
int i; int i;
pd_src_cap_cnt[port] = cnt; pd_src_cap_cnt = cnt;
for (i = 0; i < cnt; i++) for (i = 0; i < cnt; i++)
pd_src_caps[port][i] = *src_caps++; pd_src_caps[i] = *src_caps++;
#ifdef CONFIG_CHARGE_MANAGER #ifdef CONFIG_CHARGE_MANAGER
/* Get max power info that we could request */ /* Get max power info that we could request */
pd_find_pdo_index(port, PD_MAX_VOLTAGE_MV, &pdo); pd_find_pdo_index( PD_MAX_VOLTAGE_MV, &pdo);
pd_extract_pdo_power(pdo, &ma, &mv); pd_extract_pdo_power(pdo, &ma, &mv);
/* Set max. limit, but apply 500mA ceiling */ /* Set max. limit, but apply 500mA ceiling */
//charge_manager_set_ceil(port, CEIL_REQUESTOR_PD, PD_MIN_MA); //charge_manager_set_ceil( CEIL_REQUESTOR_PD, PD_MIN_MA);
pd_set_input_current_limit(port, ma, mv); pd_set_input_current_limit(ma, mv);
#endif #endif
} }
#pragma weak pd_process_source_cap_callback #pragma weak pd_process_source_cap_callback
void pd_process_source_cap_callback(int port, int cnt, uint32_t *src_caps) { void pd_process_source_cap_callback(int cnt, uint32_t *src_caps) {
} }
void pd_set_max_voltage(unsigned mv) { void pd_set_max_voltage(unsigned mv) {
@@ -257,16 +219,16 @@ static struct pd_policy pe[CONFIG_USB_PD_PORT_COUNT];
void pd_dfp_pe_init(int port) void pd_dfp_pe_init(int port)
{ {
memset(&pe[port], 0, sizeof(struct pd_policy)); memset(&pe, 0, sizeof(struct pd_policy));
} }
static void dfp_consume_identity(int port, int cnt, uint32_t *payload) static void dfp_consume_identity( int cnt, uint32_t *payload)
{ {
int ptype = PD_IDH_PTYPE(payload[VDO_I(IDH)]); int ptype = PD_IDH_PTYPE(payload[VDO_I(IDH)]);
size_t identity_size = MIN(sizeof(pe[port].identity), size_t identity_size = MIN(sizeof(pe.identity),
(cnt - 1) * sizeof(uint32_t)); (cnt - 1) * sizeof(uint32_t));
pd_dfp_pe_init(port); pd_dfp_pe_init(port);
memcpy(&pe[port].identity, payload + 1, identity_size); memcpy(&pe.identity, payload + 1, identity_size);
switch (ptype) { switch (ptype) {
case IDH_PTYPE_AMA: case IDH_PTYPE_AMA:
/* TODO(tbroch) do I disable VBUS here if power contract /* TODO(tbroch) do I disable VBUS here if power contract
@@ -286,19 +248,19 @@ static void dfp_consume_identity(int port, int cnt, uint32_t *payload)
} }
} }
static int dfp_discover_svids(int port, uint32_t *payload) static int dfp_discover_svids( uint32_t *payload)
{ {
payload[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID); payload[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID);
return 1; return 1;
} }
static void dfp_consume_svids(int port, uint32_t *payload) static void dfp_consume_svids( uint32_t *payload)
{ {
int i; int i;
uint32_t *ptr = payload + 1; uint32_t *ptr = payload + 1;
uint16_t svid0, svid1; uint16_t svid0, svid1;
for (i = pe[port].svid_cnt; i < pe[port].svid_cnt + 12; i += 2) { for (i = pe.svid_cnt; i < pe.svid_cnt + 12; i += 2) {
if (i == SVID_DISCOVERY_MAX) { if (i == SVID_DISCOVERY_MAX) {
CPRINTF("ERR:SVIDCNT\n"); CPRINTF("ERR:SVIDCNT\n");
break; break;
@@ -307,14 +269,14 @@ static void dfp_consume_svids(int port, uint32_t *payload)
svid0 = PD_VDO_SVID_SVID0(*ptr); svid0 = PD_VDO_SVID_SVID0(*ptr);
if (!svid0) if (!svid0)
break; break;
pe[port].svids[i].svid = svid0; pe.svids[i].svid = svid0;
pe[port].svid_cnt++; pe.svid_cnt++;
svid1 = PD_VDO_SVID_SVID1(*ptr); svid1 = PD_VDO_SVID_SVID1(*ptr);
if (!svid1) if (!svid1)
break; break;
pe[port].svids[i + 1].svid = svid1; pe.svids[i + 1].svid = svid1;
pe[port].svid_cnt++; pe.svid_cnt++;
ptr++; ptr++;
} }
/* TODO(tbroch) need to re-issue discover svids if > 12 */ /* TODO(tbroch) need to re-issue discover svids if > 12 */
@@ -322,65 +284,65 @@ static void dfp_consume_svids(int port, uint32_t *payload)
CPRINTF("ERR:SVID+12\n"); CPRINTF("ERR:SVID+12\n");
} }
static int dfp_discover_modes(int port, uint32_t *payload) static int dfp_discover_modes( uint32_t *payload)
{ {
uint16_t svid = pe[port].svids[pe[port].svid_idx].svid; uint16_t svid = pe.svids[pe.svid_idx].svid;
if (pe[port].svid_idx >= pe[port].svid_cnt) if (pe.svid_idx >= pe.svid_cnt)
return 0; return 0;
payload[0] = VDO(svid, 1, CMD_DISCOVER_MODES); payload[0] = VDO(svid, 1, CMD_DISCOVER_MODES);
return 1; return 1;
} }
static void dfp_consume_modes(int port, int cnt, uint32_t *payload) static void dfp_consume_modes( int cnt, uint32_t *payload)
{ {
int idx = pe[port].svid_idx; int idx = pe.svid_idx;
pe[port].svids[idx].mode_cnt = cnt - 1; pe.svids[idx].mode_cnt = cnt - 1;
if (pe[port].svids[idx].mode_cnt < 0) { if (pe.svids[idx].mode_cnt < 0) {
CPRINTF("ERR:NOMODE\n"); CPRINTF("ERR:NOMODE\n");
} else { } else {
memcpy(pe[port].svids[pe[port].svid_idx].mode_vdo, &payload[1], memcpy(pe.svids[pe.svid_idx].mode_vdo, &payload[1],
sizeof(uint32_t) * pe[port].svids[idx].mode_cnt); sizeof(uint32_t) * pe.svids[idx].mode_cnt);
} }
pe[port].svid_idx++; pe.svid_idx++;
} }
static int get_mode_idx(int port, uint16_t svid) static int get_mode_idx( uint16_t svid)
{ {
int i; int i;
for (i = 0; i < PD_AMODE_COUNT; i++) { for (i = 0; i < PD_AMODE_COUNT; i++) {
if (pe[port].amodes[i].fx->svid == svid) if (pe.amodes[i].fx->svid == svid)
return i; return i;
} }
return -1; return -1;
} }
static struct svdm_amode_data *get_modep(int port, uint16_t svid) static struct svdm_amode_data *get_modep( uint16_t svid)
{ {
int idx = get_mode_idx(port, svid); int idx = get_mode_idx( svid);
return (idx == -1) ? NULL : &pe[port].amodes[idx]; return (idx == -1) ? NULL : &pe.amodes[idx];
} }
int pd_alt_mode(int port, uint16_t svid) int pd_alt_mode( uint16_t svid)
{ {
struct svdm_amode_data *modep = get_modep(port, svid); struct svdm_amode_data *modep = get_modep( svid);
return (modep) ? modep->opos : -1; return (modep) ? modep->opos : -1;
} }
int allocate_mode(int port, uint16_t svid) int allocate_mode( uint16_t svid)
{ {
int i, j; int i, j;
struct svdm_amode_data *modep; struct svdm_amode_data *modep;
int mode_idx = get_mode_idx(port, svid); int mode_idx = get_mode_idx( svid);
if (mode_idx != -1) if (mode_idx != -1)
return mode_idx; return mode_idx;
/* There's no space to enter another mode */ /* There's no space to enter another mode */
if (pe[port].amode_idx == PD_AMODE_COUNT) { if (pe.amode_idx == PD_AMODE_COUNT) {
CPRINTF("ERR:NO AMODE SPACE\n"); CPRINTF("ERR:NO AMODE SPACE\n");
return -1; return -1;
} }
@@ -390,17 +352,17 @@ int allocate_mode(int port, uint16_t svid)
if (!&supported_modes[i]) if (!&supported_modes[i])
continue; continue;
for (j = 0; j < pe[port].svid_cnt; j++) { for (j = 0; j < pe.svid_cnt; j++) {
struct svdm_svid_data *svidp = &pe[port].svids[j]; struct svdm_svid_data *svidp = &pe.svids[j];
if ((svidp->svid != supported_modes[i].svid) || if ((svidp->svid != supported_modes[i].svid) ||
(svid && (svidp->svid != svid))) (svid && (svidp->svid != svid)))
continue; continue;
modep = &pe[port].amodes[pe[port].amode_idx]; modep = &pe.amodes[pe.amode_idx];
modep->fx = &supported_modes[i]; modep->fx = &supported_modes[i];
modep->data = &pe[port].svids[j]; modep->data = &pe.svids[j];
pe[port].amode_idx++; pe.amode_idx++;
return pe[port].amode_idx - 1; return pe.amode_idx - 1;
} }
} }
return -1; return -1;
@@ -410,15 +372,15 @@ int allocate_mode(int port, uint16_t svid)
* Enter default mode ( payload[0] == 0 ) or attempt to enter mode via svid & * Enter default mode ( payload[0] == 0 ) or attempt to enter mode via svid &
* opos * opos
*/ */
uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos) uint32_t pd_dfp_enter_mode( uint16_t svid, int opos)
{ {
int mode_idx = allocate_mode(port, svid); int mode_idx = allocate_mode( svid);
struct svdm_amode_data *modep; struct svdm_amode_data *modep;
uint32_t mode_caps; uint32_t mode_caps;
if (mode_idx == -1) if (mode_idx == -1)
return 0; return 0;
modep = &pe[port].amodes[mode_idx]; modep = &pe.amodes[mode_idx];
if (!opos) { if (!opos) {
/* choose the lowest as default */ /* choose the lowest as default */
@@ -431,7 +393,7 @@ uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos)
} }
mode_caps = modep->data->mode_vdo[modep->opos - 1]; mode_caps = modep->data->mode_vdo[modep->opos - 1];
if (modep->fx->enter(port, mode_caps) == -1) if (modep->fx->enter( mode_caps) == -1)
return 0; return 0;
/* SVDM to send to UFP for mode entry */ /* SVDM to send to UFP for mode entry */
@@ -459,17 +421,17 @@ static int validate_mode_request(struct svdm_amode_data *modep,
return 1; return 1;
} }
static void dfp_consume_attention(int port, uint32_t *payload) static void dfp_consume_attention( uint32_t *payload)
{ {
uint16_t svid = PD_VDO_VID(payload[0]); uint16_t svid = PD_VDO_VID(payload[0]);
int opos = PD_VDO_OPOS(payload[0]); int opos = PD_VDO_OPOS(payload[0]);
struct svdm_amode_data *modep = get_modep(port, svid); struct svdm_amode_data *modep = get_modep( svid);
if (!modep || !validate_mode_request(modep, svid, opos)) if (!modep || !validate_mode_request(modep, svid, opos))
return; return;
if (modep->fx->attention) if (modep->fx->attention)
modep->fx->attention(port, payload); modep->fx->attention( payload);
} }
/* /*
@@ -491,9 +453,9 @@ static void dfp_consume_attention(int port, uint32_t *payload)
* output. If UFP is a USB-C receptacle it may assert C/D/E/F. The DFP USB-C * output. If UFP is a USB-C receptacle it may assert C/D/E/F. The DFP USB-C
* receptacle must always choose C/D in those cases. * receptacle must always choose C/D in those cases.
*/ */
int pd_dfp_dp_get_pin_mode(int port, uint32_t status) int pd_dfp_dp_get_pin_mode( uint32_t status)
{ {
struct svdm_amode_data *modep = get_modep(port, USB_SID_DISPLAYPORT); struct svdm_amode_data *modep = get_modep( USB_SID_DISPLAYPORT);
uint32_t mode_caps; uint32_t mode_caps;
uint32_t pin_caps; uint32_t pin_caps;
if (!modep) if (!modep)
@@ -522,7 +484,7 @@ int pd_dfp_dp_get_pin_mode(int port, uint32_t status)
return 1 << get_next_bit(&pin_caps); return 1 << get_next_bit(&pin_caps);
} }
int pd_dfp_exit_mode(int port, uint16_t svid, int opos) int pd_dfp_exit_mode( uint16_t svid, int opos)
{ {
struct svdm_amode_data *modep; struct svdm_amode_data *modep;
int idx; int idx;
@@ -534,8 +496,8 @@ int pd_dfp_exit_mode(int port, uint16_t svid, int opos)
*/ */
if (!svid) { if (!svid) {
for (idx = 0; idx < PD_AMODE_COUNT; idx++) for (idx = 0; idx < PD_AMODE_COUNT; idx++)
if (pe[port].amodes[idx].fx) if (pe.amodes[idx].fx)
pe[port].amodes[idx].fx->exit(port); pe.amodes[idx].fx->exit(port);
pd_dfp_pe_init(port); pd_dfp_pe_init(port);
return 0; return 0;
@@ -547,7 +509,7 @@ int pd_dfp_exit_mode(int port, uint16_t svid, int opos)
* to exit all modes. We currently don't have any UFPs that support * to exit all modes. We currently don't have any UFPs that support
* multiple modes on one SVID. * multiple modes on one SVID.
*/ */
modep = get_modep(port, svid); modep = get_modep( svid);
if (!modep || !validate_mode_request(modep, svid, opos)) if (!modep || !validate_mode_request(modep, svid, opos))
return 0; return 0;
@@ -560,12 +522,12 @@ int pd_dfp_exit_mode(int port, uint16_t svid, int opos)
uint16_t pd_get_identity_vid(int port) uint16_t pd_get_identity_vid(int port)
{ {
return PD_IDH_VID(pe[port].identity[0]); return PD_IDH_VID(pe.identity[0]);
} }
uint16_t pd_get_identity_pid(int port) uint16_t pd_get_identity_pid(int port)
{ {
return PD_PRODUCT_PID(pe[port].identity[2]); return PD_PRODUCT_PID(pe.identity[2]);
} }
#ifdef CONFIG_CMD_USB_PD_PE #ifdef CONFIG_CMD_USB_PD_PE
@@ -579,34 +541,34 @@ static void dump_pe(int port)
struct svdm_amode_data *modep; struct svdm_amode_data *modep;
uint32_t mode_caps; uint32_t mode_caps;
if (pe[port].identity[0] == 0) { if (pe.identity[0] == 0) {
ccprintf("No identity discovered yet.\n"); ccprintf("No identity discovered yet.\n");
return; return;
} }
idh_ptype = PD_IDH_PTYPE(pe[port].identity[0]); idh_ptype = PD_IDH_PTYPE(pe.identity[0]);
ccprintf("IDENT:\n"); ccprintf("IDENT:\n");
ccprintf("\t[ID Header] %08x :: %s, VID:%04x\n", pe[port].identity[0], ccprintf("\t[ID Header] %08x :: %s, VID:%04x\n", pe.identity[0],
idh_ptype_names[idh_ptype], pd_get_identity_vid(port)); idh_ptype_names[idh_ptype], pd_get_identity_vid(port));
ccprintf("\t[Cert Stat] %08x\n", pe[port].identity[1]); ccprintf("\t[Cert Stat] %08x\n", pe.identity[1]);
for (i = 2; i < ARRAY_SIZE(pe[port].identity); i++) { for (i = 2; i < ARRAY_SIZE(pe.identity); i++) {
ccprintf("\t"); ccprintf("\t");
if (pe[port].identity[i]) if (pe.identity[i])
ccprintf("[%d] %08x ", i, pe[port].identity[i]); ccprintf("[%d] %08x ", i, pe.identity[i]);
} }
ccprintf("\n"); ccprintf("\n");
if (pe[port].svid_cnt < 1) { if (pe.svid_cnt < 1) {
ccprintf("No SVIDS discovered yet.\n"); ccprintf("No SVIDS discovered yet.\n");
return; return;
} }
for (i = 0; i < pe[port].svid_cnt; i++) { for (i = 0; i < pe.svid_cnt; i++) {
ccprintf("SVID[%d]: %04x MODES:", i, pe[port].svids[i].svid); ccprintf("SVID[%d]: %04x MODES:", i, pe.svids[i].svid);
for (j = 0; j < pe[port].svids[j].mode_cnt; j++) for (j = 0; j < pe.svids[j].mode_cnt; j++)
ccprintf(" [%d] %08x", j + 1, ccprintf(" [%d] %08x", j + 1,
pe[port].svids[i].mode_vdo[j]); pe.svids[i].mode_vdo[j]);
ccprintf("\n"); ccprintf("\n");
modep = get_modep(port, pe[port].svids[i].svid); modep = get_modep( pe.svids[i].svid);
if (modep) { if (modep) {
mode_caps = modep->data->mode_vdo[modep->opos - 1]; mode_caps = modep->data->mode_vdo[modep->opos - 1];
ccprintf("MODE[%d]: svid:%04x caps:%08x\n", modep->opos, ccprintf("MODE[%d]: svid:%04x caps:%08x\n", modep->opos,
@@ -638,10 +600,10 @@ DECLARE_CONSOLE_COMMAND(pe, command_pe,
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ #endif /* CONFIG_USB_PD_ALT_MODE_DFP */
int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int pd_svdm(int cnt, uint32_t *payload, uint32_t **rpayload) {
int cmd = PD_VDO_CMD(payload[0]); int cmd = PD_VDO_CMD(payload[0]);
int cmd_type = PD_VDO_CMDT(payload[0]); int cmd_type = PD_VDO_CMDT(payload[0]);
int (*func)(int port, uint32_t *payload) = NULL; int (*func)(uint32_t *payload) = NULL;
int rsize = 1; /* VDM header at a minimum */ int rsize = 1; /* VDM header at a minimum */
@@ -677,7 +639,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
* attention is only SVDM with no response * attention is only SVDM with no response
* (just goodCRC) return zero here. * (just goodCRC) return zero here.
*/ */
dfp_consume_attention(port, payload); dfp_consume_attention( payload);
return 0; return 0;
#endif #endif
default: default:
@@ -685,7 +647,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
rsize = 0; rsize = 0;
} }
if (func) if (func)
rsize = func(port, payload); rsize = func(payload);
else else
/* not supported : NACK it */ /* not supported : NACK it */
rsize = 0; rsize = 0;
@@ -703,30 +665,30 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
#ifdef CONFIG_USB_PD_ALT_MODE_DFP #ifdef CONFIG_USB_PD_ALT_MODE_DFP
struct svdm_amode_data *modep; struct svdm_amode_data *modep;
modep = get_modep(port, PD_VDO_VID(payload[0])); modep = get_modep( PD_VDO_VID(payload[0]));
#endif #endif
switch (cmd) { switch (cmd) {
#ifdef CONFIG_USB_PD_ALT_MODE_DFP #ifdef CONFIG_USB_PD_ALT_MODE_DFP
case CMD_DISCOVER_IDENT: case CMD_DISCOVER_IDENT:
dfp_consume_identity(port, cnt, payload); dfp_consume_identity( cnt, payload);
rsize = dfp_discover_svids(port, payload); rsize = dfp_discover_svids( payload);
#ifdef CONFIG_CHARGE_MANAGER #ifdef CONFIG_CHARGE_MANAGER
if (pd_charge_from_device(pd_get_identity_vid(port), if (pd_charge_from_device(pd_get_identity_vid(port),
pd_get_identity_pid(port))) pd_get_identity_pid(port)))
charge_manager_update_dualrole(port, charge_manager_update_dualrole(
CAP_DEDICATED); CAP_DEDICATED);
#endif #endif
break; break;
case CMD_DISCOVER_SVID: case CMD_DISCOVER_SVID:
dfp_consume_svids(port, payload); dfp_consume_svids( payload);
rsize = dfp_discover_modes(port, payload); rsize = dfp_discover_modes( payload);
break; break;
case CMD_DISCOVER_MODES: case CMD_DISCOVER_MODES:
dfp_consume_modes(port, cnt, payload); dfp_consume_modes( cnt, payload);
rsize = dfp_discover_modes(port, payload); rsize = dfp_discover_modes( payload);
/* enter the default mode for DFP */ /* enter the default mode for DFP */
if (!rsize) { if (!rsize) {
payload[0] = pd_dfp_enter_mode(port, 0, 0); payload[0] = pd_dfp_enter_mode( 0, 0);
if (payload[0]) if (payload[0])
rsize = 1; rsize = 1;
} }
@@ -736,10 +698,10 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
rsize = 0; rsize = 0;
} else { } else {
if (!modep->opos) if (!modep->opos)
pd_dfp_enter_mode(port, 0, 0); pd_dfp_enter_mode( 0, 0);
if (modep->opos) { if (modep->opos) {
rsize = modep->fx->status(port, rsize = modep->fx->status(
payload); payload);
payload[0] |= PD_VDO_OPOS(modep->opos); payload[0] |= PD_VDO_OPOS(modep->opos);
} }
@@ -748,9 +710,9 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
case CMD_DP_STATUS: case CMD_DP_STATUS:
/* DP status response & UFP's DP attention have same /* DP status response & UFP's DP attention have same
payload */ payload */
dfp_consume_attention(port, payload); dfp_consume_attention( payload);
if (modep && modep->opos) if (modep && modep->opos)
rsize = modep->fx->config(port, payload); rsize = modep->fx->config( payload);
else else
rsize = 0; rsize = 0;
break; break;
@@ -810,7 +772,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
#else #else
int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) int pd_svdm( int cnt, uint32_t *payload, uint32_t **rpayload)
{ {
return 0; return 0;
} }
@@ -818,7 +780,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
#endif /* CONFIG_USB_PD_ALT_MODE */ #endif /* CONFIG_USB_PD_ALT_MODE */
#ifndef CONFIG_USB_PD_CUSTOM_VDM #ifndef CONFIG_USB_PD_CUSTOM_VDM
int pd_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int pd_vdm(int cnt, uint32_t *payload, uint32_t **rpayload) {
return 0; return 0;
} }
#endif /* !CONFIG_USB_PD_CUSTOM_VDM */ #endif /* !CONFIG_USB_PD_CUSTOM_VDM */
@@ -837,7 +799,6 @@ static void pd_usb_billboard_deferred(void) {
#endif #endif
} }
DECLARE_DEFERRED( pd_usb_billboard_deferred);
#ifdef CONFIG_USB_PD_ALT_MODE_DFP #ifdef CONFIG_USB_PD_ALT_MODE_DFP
static int hc_remote_pd_discovery(struct host_cmd_handler_args *args) static int hc_remote_pd_discovery(struct host_cmd_handler_args *args)
@@ -897,110 +858,12 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_GET_AMODE,
#define FW_RW_END (CONFIG_EC_WRITABLE_STORAGE_OFF + \ #define FW_RW_END (CONFIG_EC_WRITABLE_STORAGE_OFF + \
CONFIG_RW_STORAGE_OFF + CONFIG_RW_SIZE) CONFIG_RW_STORAGE_OFF + CONFIG_RW_SIZE)
/*
uint8_t *flash_hash_rw(void)
{
static struct sha256_ctx ctx;
// re-calculate RW hash when changed as its time consuming
if (rw_flash_changed) {
rw_flash_changed = 0;
SHA256_init(&ctx);
SHA256_update(&ctx, (void *)CONFIG_PROGRAM_MEMORY_BASE +
CONFIG_RW_MEM_OFF,
CONFIG_RW_SIZE - RSANUMBYTES);
return SHA256_final(&ctx);
} else {
return ctx.buf;
}
}
void pd_get_info(uint32_t *info_data)
{
void *rw_hash = flash_hash_rw();
// copy first 20 bytes of RW hash
memcpy(info_data, rw_hash, 5 * sizeof(uint32_t));
// copy other info into data msg
#if defined(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR) && \
defined(CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR)
info_data[5] = VDO_INFO(CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR,
CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR,
ver_get_numcommits(),
(system_get_image_copy() != SYSTEM_IMAGE_RO));
#else
info_data[5] = 0;
#endif
}
int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload)
{
static int flash_offset;
int rsize = 1; // default is just VDM header returned
switch (PD_VDO_CMD(payload[0])) {
case VDO_CMD_VERSION:
memcpy(payload + 1, &current_image_data.version, 24);
rsize = 7;
break;
case VDO_CMD_REBOOT:
// ensure the power supply is in a safe state
pd_power_supply_reset(0);
system_reset(0);
break;
case VDO_CMD_READ_INFO:
// copy info into response
pd_get_info(payload + 1);
rsize = 7;
break;
case VDO_CMD_FLASH_ERASE:
// do not kill the code under our feet
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
break;
pd_log_event(PD_EVENT_ACC_RW_ERASE, 0, 0, NULL);
flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF;
flash_physical_erase(CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF, CONFIG_RW_SIZE);
rw_flash_changed = 1;
break;
case VDO_CMD_FLASH_WRITE:
// do not kill the code under our feet
if ((system_get_image_copy() != SYSTEM_IMAGE_RO) ||
(flash_offset < CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF))
break;
flash_physical_write(flash_offset, 4*(cnt - 1),
(const char *)(payload+1));
flash_offset += 4*(cnt - 1);
rw_flash_changed = 1;
break;
case VDO_CMD_ERASE_SIG:
// this is not touching the code area
{
uint32_t zero = 0;
int offset;
// zeroes the area containing the RSA signature
for (offset = FW_RW_END - RSANUMBYTES;
offset < FW_RW_END; offset += 4)
flash_physical_write(offset, 4,
(const char *)&zero);
}
break;
default:
// Unknown : do not answer
return 0;
}
return rsize;
}
*/
#ifdef CONFIG_USB_PD_DISCHARGE #ifdef CONFIG_USB_PD_DISCHARGE
void pd_set_vbus_discharge(int port, int enable) void pd_set_vbus_discharge( int enable)
{ {
static struct mutex discharge_lock[CONFIG_USB_PD_PORT_COUNT]; static struct mutex discharge_lock[CONFIG_USB_PD_PORT_COUNT];
mutex_lock(&discharge_lock[port]); mutex_lock(&discharge_lock);
enable &= !board_vbus_source_enabled(port); enable &= !board_vbus_source_enabled(port);
#ifdef CONFIG_USB_PD_DISCHARGE_GPIO #ifdef CONFIG_USB_PD_DISCHARGE_GPIO
if (!port) if (!port)
@@ -1010,10 +873,10 @@ void pd_set_vbus_discharge(int port, int enable)
gpio_set_level(GPIO_USB_C1_DISCHARGE, enable); gpio_set_level(GPIO_USB_C1_DISCHARGE, enable);
#endif /* CONFIG_USB_PD_PORT_COUNT */ #endif /* CONFIG_USB_PD_PORT_COUNT */
#elif defined(CONFIG_USB_PD_DISCHARGE_TCPC) #elif defined(CONFIG_USB_PD_DISCHARGE_TCPC)
tcpc_discharge_vbus(port, enable); tcpc_discharge_vbus( enable);
#else #else
#error "PD discharge implementation not defined" #error "PD discharge implementation not defined"
#endif #endif
mutex_unlock(&discharge_lock[port]); mutex_unlock(&discharge_lock);
} }
#endif /* CONFIG_USB_PD_DISCHARGE */ #endif /* CONFIG_USB_PD_DISCHARGE */

View File

@@ -18,110 +18,93 @@
#endif #endif
#ifndef CONFIG_USB_PD_TCPC #ifndef CONFIG_USB_PD_TCPC
extern const struct tcpc_config_t tcpc_config[]; extern const struct tcpc_config_t tcpc_config;
/* I2C wrapper functions - get I2C port / slave addr from config struct. */ /* I2C wrapper functions - get I2C port / slave addr from config struct. */
int tcpc_write(int port, int reg, int val); int tcpc_write(int reg, int val);
int tcpc_write16(int port, int reg, int val); int tcpc_write16(int reg, int val);
int tcpc_read(int port, int reg, int *val); int tcpc_read(int reg, int *val);
int tcpc_read16(int port, int reg, int *val); int tcpc_read16(int reg, int *val);
int tcpc_xfer(int port, int tcpc_xfer(const uint8_t *out, int out_size, uint8_t *in, int in_size,
const uint8_t *out, int out_size,
uint8_t *in, int in_size,
int flags); int flags);
/* TCPM driver wrapper function */ /* TCPM driver wrapper function */
static inline int tcpm_init(int port) static inline int tcpm_init() {
{
int rv; int rv;
rv = tcpc_config[port].drv->init(port); rv = tcpc_config.drv->init();
if (rv) if (rv)
return rv; return rv;
/* Board specific post TCPC init */ /* Board specific post TCPC init */
if (board_tcpc_post_init) if (board_tcpc_post_init)
rv = board_tcpc_post_init(port); rv = board_tcpc_post_init();
return rv; return rv;
} }
static inline int tcpm_release(int port) static inline int tcpm_release() {
{ return tcpc_config.drv->release();
return tcpc_config[port].drv->release(port);
} }
static inline int tcpm_get_cc(int port, int *cc1, int *cc2) static inline int tcpm_get_cc(int *cc1, int *cc2) {
{ return tcpc_config.drv->get_cc(cc1, cc2);
return tcpc_config[port].drv->get_cc(port, cc1, cc2);
} }
static inline int tcpm_get_vbus_level(int port) static inline int tcpm_get_vbus_level() {
{ return tcpc_config.drv->get_vbus_level();
return tcpc_config[port].drv->get_vbus_level(port);
} }
static inline int tcpm_select_rp_value(int port, int rp) static inline int tcpm_select_rp_value(int rp) {
{ return tcpc_config.drv->select_rp_value(rp);
return tcpc_config[port].drv->select_rp_value(port, rp);
} }
static inline int tcpm_set_cc(int port, int pull) static inline int tcpm_set_cc(int pull) {
{ return tcpc_config.drv->set_cc(pull);
return tcpc_config[port].drv->set_cc(port, pull);
} }
static inline int tcpm_set_polarity(int port, int polarity) static inline int tcpm_set_polarity(int polarity) {
{ return tcpc_config.drv->set_polarity(polarity);
return tcpc_config[port].drv->set_polarity(port, polarity);
} }
static inline int tcpm_set_vconn(int port, int enable) static inline int tcpm_set_vconn(int enable) {
{ return tcpc_config.drv->set_vconn(enable);
return tcpc_config[port].drv->set_vconn(port, enable);
} }
static inline int tcpm_set_msg_header(int port, int power_role, int data_role) static inline int tcpm_set_msg_header(int power_role, int data_role) {
{ return tcpc_config.drv->set_msg_header(power_role, data_role);
return tcpc_config[port].drv->set_msg_header(port, power_role,
data_role);
} }
static inline int tcpm_set_rx_enable(int port, int enable) static inline int tcpm_set_rx_enable(int enable) {
{ return tcpc_config.drv->set_rx_enable(enable);
return tcpc_config[port].drv->set_rx_enable(port, enable);
} }
static inline int tcpm_get_message(int port, uint32_t *payload, int *head) static inline int tcpm_get_message(uint32_t *payload, int *head) {
{ return tcpc_config.drv->get_message(payload, head);
return tcpc_config[port].drv->get_message(port, payload, head);
} }
static inline int tcpm_transmit(int port, enum tcpm_transmit_type type, static inline int tcpm_transmit(enum tcpm_transmit_type type, uint16_t header,
uint16_t header, const uint32_t *data) const uint32_t *data) {
{ return tcpc_config.drv->transmit(type, header, data);
return tcpc_config[port].drv->transmit(port, type, header, data);
} }
static inline void tcpc_alert(int port) static inline void tcpc_alert() {
{ tcpc_config.drv->tcpc_alert();
tcpc_config[port].drv->tcpc_alert(port);
} }
static inline void tcpc_discharge_vbus(int port, int enable) static inline void tcpc_discharge_vbus(int enable) {
{ tcpc_config.drv->tcpc_discharge_vbus(enable);
tcpc_config[port].drv->tcpc_discharge_vbus(port, enable);
} }
#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
static inline int tcpm_auto_toggle_supported(int port) static inline int tcpm_auto_toggle_supported()
{ {
return !!tcpc_config[port].drv->drp_toggle; return !!tcpc_config.drv->drp_toggle;
} }
static inline int tcpm_set_drp_toggle(int port, int enable) static inline int tcpm_set_drp_toggle( int enable)
{ {
return tcpc_config[port].drv->drp_toggle(port, enable); return tcpc_config.drv->drp_toggle( enable);
} }
#endif #endif
@@ -129,21 +112,20 @@ static inline int tcpm_set_drp_toggle(int port, int enable)
static inline int tcpc_i2c_read(const int port, const int addr, static inline int tcpc_i2c_read(const int port, const int addr,
const int reg, int *data) const int reg, int *data)
{ {
return tcpc_read(port, reg, data); return tcpc_read( reg, data);
} }
static inline int tcpc_i2c_write(const int port, const int addr, static inline int tcpc_i2c_write(const int port, const int addr,
const int reg, int data) const int reg, int data)
{ {
return tcpc_write(port, reg, data); return tcpc_write( reg, data);
} }
#endif #endif
static inline int tcpm_get_chip_info(int port, int renew, static inline int tcpm_get_chip_info(int renew,
struct ec_response_pd_chip_info **info) struct ec_response_pd_chip_info **info) {
{ if (tcpc_config.drv->get_chip_info)
if (tcpc_config[port].drv->get_chip_info) return tcpc_config.drv->get_chip_info(renew, info);
return tcpc_config[port].drv->get_chip_info(port, renew, info);
return EC_ERROR_UNIMPLEMENTED; return EC_ERROR_UNIMPLEMENTED;
} }
@@ -156,7 +138,7 @@ static inline int tcpm_get_chip_info(int port, int renew,
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_init(int port); int tcpm_init();
/** /**
* Read the CC line status. * Read the CC line status.
@@ -167,7 +149,7 @@ int tcpm_init(int port);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_get_cc(int port, int *cc1, int *cc2); int tcpm_get_cc( int *cc1, int *cc2);
/** /**
* Read VBUS * Read VBUS
@@ -176,7 +158,7 @@ int tcpm_get_cc(int port, int *cc1, int *cc2);
* *
* @return 0 => VBUS not detected, 1 => VBUS detected * @return 0 => VBUS not detected, 1 => VBUS detected
*/ */
int tcpm_get_vbus_level(int port); int tcpm_get_vbus_level();
/** /**
* Set the value of the CC pull-up used when we are a source. * Set the value of the CC pull-up used when we are a source.
@@ -186,7 +168,7 @@ int tcpm_get_vbus_level(int port);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_select_rp_value(int port, int rp); int tcpm_select_rp_value( int rp);
/** /**
* Set the CC pull resistor. This sets our role as either source or sink. * Set the CC pull resistor. This sets our role as either source or sink.
@@ -196,7 +178,7 @@ int tcpm_select_rp_value(int port, int rp);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_set_cc(int port, int pull); int tcpm_set_cc( int pull);
/** /**
* Set polarity * Set polarity
@@ -206,7 +188,7 @@ int tcpm_set_cc(int port, int pull);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_set_polarity(int port, int polarity); int tcpm_set_polarity( int polarity);
/** /**
* Set Vconn. * Set Vconn.
@@ -216,7 +198,7 @@ int tcpm_set_polarity(int port, int polarity);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_set_vconn(int port, int enable); int tcpm_set_vconn( int enable);
/** /**
* Set PD message header to use for goodCRC * Set PD message header to use for goodCRC
@@ -227,7 +209,7 @@ int tcpm_set_vconn(int port, int enable);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_set_msg_header(int port, int power_role, int data_role); int tcpm_set_msg_header( int power_role, int data_role);
/** /**
* Set RX enable flag * Set RX enable flag
@@ -237,7 +219,7 @@ int tcpm_set_msg_header(int port, int power_role, int data_role);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_set_rx_enable(int port, int enable); int tcpm_set_rx_enable( int enable);
/** /**
* Read last received PD message. * Read last received PD message.
@@ -248,7 +230,7 @@ int tcpm_set_rx_enable(int port, int enable);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_get_message(int port, uint32_t *payload, int *head); int tcpm_get_message( uint32_t *payload, int *head);
/** /**
* Transmit PD message * Transmit PD message
@@ -261,7 +243,7 @@ int tcpm_get_message(int port, uint32_t *payload, int *head);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header, int tcpm_transmit( enum tcpm_transmit_type type, uint16_t header,
const uint32_t *data); const uint32_t *data);
/** /**
@@ -269,7 +251,7 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header,
* *
* @param port Type-C port number * @param port Type-C port number
*/ */
void tcpc_alert(int port); void tcpc_alert();
#endif #endif

View File

@@ -95,17 +95,11 @@ enum tcpc_cc_voltage_status {
}; };
enum tcpc_cc_pull { enum tcpc_cc_pull {
TYPEC_CC_RA = 0, TYPEC_CC_RA = 0, TYPEC_CC_RP = 1, TYPEC_CC_RD = 2, TYPEC_CC_OPEN = 3,
TYPEC_CC_RP = 1,
TYPEC_CC_RD = 2,
TYPEC_CC_OPEN = 3,
}; };
enum tcpc_rp_value { enum tcpc_rp_value {
TYPEC_RP_USB = 0, TYPEC_RP_USB = 0, TYPEC_RP_1A5 = 1, TYPEC_RP_3A0 = 2, TYPEC_RP_RESERVED = 3,
TYPEC_RP_1A5 = 1,
TYPEC_RP_3A0 = 2,
TYPEC_RP_RESERVED = 3,
}; };
enum tcpm_transmit_type { enum tcpm_transmit_type {
@@ -133,7 +127,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*init)(int port); int (*init)();
/** /**
* Release the TCPM hardware and disconnect the driver. * Release the TCPM hardware and disconnect the driver.
@@ -143,7 +137,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*release)(int port); int (*release)();
/** /**
* Read the CC line status. * Read the CC line status.
@@ -154,7 +148,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*get_cc)(int port, int *cc1, int *cc2); int (*get_cc)(int *cc1, int *cc2);
/** /**
* Read VBUS * Read VBUS
@@ -163,7 +157,7 @@ struct tcpm_drv {
* *
* @return 0 => VBUS not detected, 1 => VBUS detected * @return 0 => VBUS not detected, 1 => VBUS detected
*/ */
int (*get_vbus_level)(int port); int (*get_vbus_level)();
/** /**
* Set the value of the CC pull-up used when we are a source. * Set the value of the CC pull-up used when we are a source.
@@ -173,7 +167,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*select_rp_value)(int port, int rp); int (*select_rp_value)(int rp);
/** /**
* Set the CC pull resistor. This sets our role as either source or sink. * Set the CC pull resistor. This sets our role as either source or sink.
@@ -183,7 +177,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*set_cc)(int port, int pull); int (*set_cc)(int pull);
/** /**
* Set polarity * Set polarity
@@ -193,7 +187,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*set_polarity)(int port, int polarity); int (*set_polarity)(int polarity);
/** /**
* Set Vconn. * Set Vconn.
@@ -203,7 +197,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*set_vconn)(int port, int enable); int (*set_vconn)(int enable);
/** /**
* Set PD message header to use for goodCRC * Set PD message header to use for goodCRC
@@ -214,7 +208,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*set_msg_header)(int port, int power_role, int data_role); int (*set_msg_header)(int power_role, int data_role);
/** /**
* Set RX enable flag * Set RX enable flag
@@ -224,7 +218,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*set_rx_enable)(int port, int enable); int (*set_rx_enable)(int enable);
/** /**
* Read last received PD message. * Read last received PD message.
@@ -235,7 +229,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*get_message)(int port, uint32_t *payload, int *head); int (*get_message)(uint32_t *payload, int *head);
/** /**
* Transmit PD message * Transmit PD message
@@ -248,7 +242,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*transmit)(int port, enum tcpm_transmit_type type, uint16_t header, int (*transmit)(enum tcpm_transmit_type type, uint16_t header,
const uint32_t *data); const uint32_t *data);
/** /**
@@ -256,7 +250,7 @@ struct tcpm_drv {
* *
* @param port Type-C port number * @param port Type-C port number
*/ */
void (*tcpc_alert)(int port); void (*tcpc_alert)();
/** /**
* Discharge PD VBUS on src/sink disconnect & power role swap * Discharge PD VBUS on src/sink disconnect & power role swap
@@ -264,7 +258,7 @@ struct tcpm_drv {
* @param port Type-C port number * @param port Type-C port number
* @param enable Discharge enable or disable * @param enable Discharge enable or disable
*/ */
void (*tcpc_discharge_vbus)(int port, int enable); void (*tcpc_discharge_vbus)(int enable);
#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
/** /**
@@ -275,7 +269,7 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*drp_toggle)(int port, int enable); int (*drp_toggle)( int enable);
#endif #endif
/** /**
@@ -287,20 +281,16 @@ struct tcpm_drv {
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int (*get_chip_info)(int port, int renew, int (*get_chip_info)(int renew, struct ec_response_pd_chip_info **info);
struct ec_response_pd_chip_info **info);
}; };
enum tcpc_alert_polarity { enum tcpc_alert_polarity {
TCPC_ALERT_ACTIVE_LOW, TCPC_ALERT_ACTIVE_LOW, TCPC_ALERT_ACTIVE_HIGH,
TCPC_ALERT_ACTIVE_HIGH,
}; };
struct tcpc_config_t { struct tcpc_config_t {
int i2c_host_port;
int i2c_slave_addr; int i2c_slave_addr;
const struct tcpm_drv *drv; const struct tcpm_drv *drv;
enum tcpc_alert_polarity pol;
}; };
/** /**
@@ -317,21 +307,21 @@ uint16_t tcpc_get_alert_status(void);
* @param port Type-C port number * @param port Type-C port number
* @param mode 0: off/sleep, 1: on/awake * @param mode 0: off/sleep, 1: on/awake
*/ */
void board_set_tcpc_power_mode(int port, int mode) __attribute__((weak)); void board_set_tcpc_power_mode(int mode) __attribute__((weak));
/** /**
* Initialize TCPC. * Initialize TCPC.
* *
* @param port Type-C port number * @param port Type-C port number
*/ */
void tcpc_init(int port); void tcpc_init();
/** /**
* TCPC is asserting alert * TCPC is asserting alert
* *
* @param port Type-C port number * @param port Type-C port number
*/ */
void tcpc_alert_clear(int port); void tcpc_alert_clear();
/** /**
* Run TCPC task once. This checks for incoming messages, processes * Run TCPC task once. This checks for incoming messages, processes
@@ -340,7 +330,7 @@ void tcpc_alert_clear(int port);
* @param port Type-C port number * @param port Type-C port number
* @param evt Event type that woke up this task * @param evt Event type that woke up this task
*/ */
int tcpc_run(int port, int evt); int tcpc_run(int evt);
/** /**
* Initialize board specific TCPC functions post TCPC initialization. * Initialize board specific TCPC functions post TCPC initialization.
@@ -349,6 +339,6 @@ int tcpc_run(int port, int evt);
* *
* @return EC_SUCCESS or error * @return EC_SUCCESS or error
*/ */
int board_tcpc_post_init(int port) __attribute__((weak)); int board_tcpc_post_init() __attribute__((weak));
#endif /* __CROS_EC_USB_PD_TCPM_H */ #endif /* __CROS_EC_USB_PD_TCPM_H */

View File

@@ -8,36 +8,36 @@
#include "tcpm_driver.h" #include "tcpm_driver.h"
#include "I2C_Wrapper.hpp" #include "I2C_Wrapper.hpp"
#include "I2CBB.hpp" #include "I2CBB.hpp"
extern const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT]; extern const struct tcpc_config_t tcpc_config;
#define STATUS_OK 0 #define STATUS_OK 0
/* I2C wrapper functions - get I2C port / slave addr from config struct. */ /* I2C wrapper functions - get I2C port / slave addr from config struct. */
int tcpc_write(int port, int reg, int val) { int tcpc_write(int reg, int val) {
I2CBB::Mem_Write(tcpc_config[port].i2c_slave_addr, reg, (uint8_t*) &val, 1); I2CBB::Mem_Write(tcpc_config.i2c_slave_addr, reg, (uint8_t*) &val, 1);
return STATUS_OK; return STATUS_OK;
} }
int tcpc_write16(int port, int reg, int val) { int tcpc_write16(int reg, int val) {
uint8_t data[2]; uint8_t data[2];
data[0] = (0xFF) & val; data[0] = (0xFF) & val;
data[1] = (0xFF) & (val >> 8); data[1] = (0xFF) & (val >> 8);
I2CBB::Mem_Write(tcpc_config[port].i2c_slave_addr, reg, (uint8_t*) data, 2); I2CBB::Mem_Write(tcpc_config.i2c_slave_addr, reg, (uint8_t*) data, 2);
return STATUS_OK; return STATUS_OK;
} }
int tcpc_read(int port, int reg, int *val) { int tcpc_read(int reg, int *val) {
uint8_t data[1]; uint8_t data[1];
I2CBB::Mem_Read(tcpc_config[port].i2c_slave_addr, reg, (uint8_t*) data, 1); I2CBB::Mem_Read(tcpc_config.i2c_slave_addr, reg, (uint8_t*) data, 1);
*val = data[0]; *val = data[0];
return STATUS_OK; return STATUS_OK;
} }
int tcpc_read16(int port, int reg, int *val) { int tcpc_read16(int reg, int *val) {
uint8_t data[2]; uint8_t data[2];
I2CBB::Mem_Write(tcpc_config[port].i2c_slave_addr, reg, (uint8_t*) data, 2); I2CBB::Mem_Write(tcpc_config.i2c_slave_addr, reg, (uint8_t*) data, 2);
*val = data[0]; *val = data[0];
*val |= (data[1] << 8); *val |= (data[1] << 8);
@@ -45,8 +45,8 @@ int tcpc_read16(int port, int reg, int *val) {
return STATUS_OK; return STATUS_OK;
} }
int tcpc_xfer(int port, const uint8_t *out, int out_size, uint8_t *in, int tcpc_xfer(const uint8_t *out, int out_size, uint8_t *in, int in_size,
int in_size, int flags) { int flags) {
// Write out the I2C port to the given slave address // Write out the I2C port to the given slave address
// Write out the out byte array to the device (sending a stop if the flag is set) // Write out the out byte array to the device (sending a stop if the flag is set)
// Then issue a read from the device // Then issue a read from the device
@@ -54,12 +54,12 @@ int tcpc_xfer(int port, const uint8_t *out, int out_size, uint8_t *in,
if (flags & I2C_XFER_STOP) { if (flags & I2C_XFER_STOP) {
//Issuing a stop between the requests //Issuing a stop between the requests
//Send as a Tx followed by a Rx //Send as a Tx followed by a Rx
I2CBB::Transmit(tcpc_config[port].i2c_slave_addr, (uint8_t*) out, I2CBB::Transmit(tcpc_config.i2c_slave_addr, (uint8_t*) out,
out_size); out_size);
I2CBB::Receive(tcpc_config[port].i2c_slave_addr, in, in_size); I2CBB::Receive(tcpc_config.i2c_slave_addr, in, in_size);
} else { } else {
//issue as a continious transmit & recieve //issue as a continious transmit & recieve
I2CBB::TransmitReceive(tcpc_config[port].i2c_slave_addr, (uint8_t*) out, I2CBB::TransmitReceive(tcpc_config.i2c_slave_addr, (uint8_t*) out,
out_size, in, in_size); out_size, in, in_size);
} }

View File

@@ -26,15 +26,15 @@ uint32_t pd_task_set_event(uint32_t event, int wait_for_reply) {
} }
const uint32_t pd_src_pdo[] = { PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), }; const uint32_t pd_src_pdo[] = { PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), };
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
const uint32_t pd_snk_pdo[] = { PDO_FIXED(5000, 500, PDO_FIXED_FLAGS), const uint32_t pd_snk_pdo[] = { PDO_FIXED(5000, 1000, PDO_FIXED_FLAGS),
PDO_FIXED(9000, 500, PDO_FIXED_FLAGS), PDO_FIXED(20000, 500, PDO_FIXED(9000, 1500, PDO_FIXED_FLAGS), PDO_FIXED(12000, 3500,
PDO_FIXED_FLAGS), }; PDO_FIXED_FLAGS), };
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo); const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
void pd_set_input_current_limit(int port, uint32_t max_ma, void pd_set_input_current_limit(uint32_t max_ma, uint32_t supply_voltage) {
uint32_t supply_voltage) {
} }
@@ -42,7 +42,7 @@ int pd_is_valid_input_voltage(int mv) {
return 1; return 1;
} }
int pd_snk_is_vbus_provided(int port) { int pd_snk_is_vbus_provided() {
return 1; return 1;
} }
@@ -58,20 +58,20 @@ timestamp_t get_time(void) {
return t; return t;
} }
void pd_power_supply_reset(int port) { void pd_power_supply_reset() {
return; return;
} }
void pd_execute_data_swap(int port, int data_role) { void pd_execute_data_swap(int data_role) {
/* Do nothing */ /* Do nothing */
} }
int pd_check_data_swap(int port, int data_role) { int pd_check_data_swap(int data_role) {
// Never allow data swap // Never allow data swap
return 0; return 0;
} }
int pd_check_power_swap(int port) { int pd_check_power_swap() {
/* Always refuse power swap */ /* Always refuse power swap */
return 0; return 0;
} }
@@ -80,17 +80,8 @@ int pd_board_checks(void) {
return EC_SUCCESS; return EC_SUCCESS;
} }
int pd_set_power_supply_ready(int port) { int pd_set_power_supply_ready() {
#if 0 //Tells other device if we can supply power
/* Disable charging */
gpio_set_level(GPIO_USB_C0_CHARGE_L, 1);
/* Enable VBUS source */
gpio_set_level(GPIO_USB_C0_5V_EN, 1);
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
#endif // if 0
return EC_SUCCESS; /* we are ready */ return EC_SUCCESS; /* we are ready */
} }
@@ -132,7 +123,7 @@ void pd_transition_voltage(int idx) {
} }
void pd_check_dr_role(int port, int dr_role, int flags) { void pd_check_dr_role(int dr_role, int flags) {
#if 0 #if 0
/* If UFP, try to switch to DFP */ /* If UFP, try to switch to DFP */
if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP)
@@ -140,7 +131,7 @@ void pd_check_dr_role(int port, int dr_role, int flags) {
#endif #endif
} }
void pd_check_pr_role(int port, int pr_role, int flags) { void pd_check_pr_role(int pr_role, int flags) {
#if 0 #if 0
/* /*
* If partner is dual-role power and dualrole toggling is on, consider * If partner is dual-role power and dualrole toggling is on, consider
@@ -162,40 +153,28 @@ void pd_check_pr_role(int port, int pr_role, int flags) {
#endif // if 0 #endif // if 0
} }
void pd_process_source_cap_callback(int port, int cnt, uint32_t *src_caps) { void pd_process_source_cap_callback(int cnt, uint32_t *src_caps) {
// char str[256]; char str[256];
// int i; int i;
// uint32_t ma, mv, pdo; uint32_t ma, mv, pdo;
// uint8_t old_display;
// for (i = 0; i < cnt; i++) {
// old_display = display_screen; pd_extract_pdo_power(src_caps[i], &ma, &mv);
// display_screen = SCREEN_POWER; //Charger can supply power at mv & mA
// memset(display_buffer[SCREEN_POWER], 0x00, DISP_MEM_SIZE); //TODO we want to ask for the charger to select the closest to our ideal (12V)
// //And fall back to 9V
// sprintf(str, "Has Power Delivery"); }
// UG_PutString(0, 8, str);
//
// for (i = 0; i < cnt; i++)
// {
// pd_extract_pdo_power(src_caps[i], &ma, &mv);
// sprintf(str, "%5.2f V, %5.2f A", (float)mv/1000, (float)ma/1000);
// UG_PutString(0, 8*(i+2), str);
// }
//
// display_screen = old_display;
// display_needs_update = 1;
//TODO Handle information on supported voltages? //TODO Handle information on supported voltages?
} }
/* ----------------- Vendor Defined Messages ------------------ */ /* ----------------- Vendor Defined Messages ------------------ */
/* Holds valid object position (opos) for entered mode */ /* Holds valid object position (opos) for entered mode */
static int alt_mode[PD_AMODE_COUNT];
const uint32_t vdo_idh = VDO_IDH(0, /* data caps as USB host */ const uint32_t vdo_idh = VDO_IDH(0, /* data caps as USB host */
1, /* data caps as USB device */ 1, /* data caps as USB device */
IDH_PTYPE_AMA, /* Alternate mode */ IDH_PTYPE_PERIPH, /* Alternate mode */
1, /* supports alt modes */ 0, /* Does not support alt modes */
USB_VID_GOOGLE); USB_VID_GOOGLE);
const uint32_t vdo_product = VDO_PRODUCT(CONFIG_USB_PID, CONFIG_USB_BCD_DEV); const uint32_t vdo_product = VDO_PRODUCT(CONFIG_USB_PID, CONFIG_USB_BCD_DEV);
@@ -205,21 +184,19 @@ const uint32_t vdo_ama = VDO_AMA(CONFIG_USB_PD_IDENTITY_HW_VERS,
0, /* Vconn power */ 0, /* Vconn power */
0, /* Vconn power required */ 0, /* Vconn power required */
1, /* Vbus power required */ 1, /* Vbus power required */
AMA_USBSS_BBONLY /* USB SS support */); AMA_USBSS_U2_ONLY /* USB 2.0 support */);
static int svdm_response_identity(int port, uint32_t *payload) { static int svdm_response_identity(uint32_t *payload) {
payload[VDO_I(IDH)] = vdo_idh; payload[VDO_I(IDH)] = vdo_idh;
/* TODO(tbroch): Do we plan to obtain TID (test ID) */
payload[VDO_I(CSTAT)] = VDO_CSTAT(0); payload[VDO_I(CSTAT)] = VDO_CSTAT(0);
payload[VDO_I(PRODUCT)] = vdo_product; payload[VDO_I(PRODUCT)] = vdo_product;
payload[VDO_I(AMA)] = vdo_ama; payload[VDO_I(AMA)] = vdo_ama;
return VDO_I(AMA) + 1; return VDO_I(AMA) + 1;
} }
//No custom svdm
static int svdm_response_svids(int port, uint32_t *payload) { static int svdm_response_svids(uint32_t *payload) {
payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, USB_VID_GOOGLE); payload[1] = 0;
payload[2] = 0; return 2;
return 3;
} }
#define OPOS_DP 1 #define OPOS_DP 1
@@ -233,21 +210,11 @@ MODE_DP_V13, /* DPv1.3 Support, no Gen2 */
MODE_DP_SNK) /* Its a sink only */ MODE_DP_SNK) /* Its a sink only */
}; };
const uint32_t vdo_goog_modes[1] = { VDO_MODE_GOOGLE(MODE_GOOGLE_FU) }; static int svdm_response_modes(uint32_t *payload) {
static int svdm_response_modes(int port, uint32_t *payload) {
if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) {
memcpy(payload + 1, vdo_dp_modes, sizeof(vdo_dp_modes));
return ARRAY_SIZE(vdo_dp_modes) + 1;
} else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) {
memcpy(payload + 1, vdo_goog_modes, sizeof(vdo_goog_modes));
return ARRAY_SIZE(vdo_goog_modes) + 1;
} else {
return 0; /* nak */ return 0; /* nak */
}
} }
static int dp_status(int port, uint32_t *payload) { static int dp_status(uint32_t *payload) {
int opos = PD_VDO_OPOS(payload[0]); int opos = PD_VDO_OPOS(payload[0]);
int hpd = 0; // gpio_get_level(GPIO_DP_HPD); int hpd = 0; // gpio_get_level(GPIO_DP_HPD);
if (opos != OPOS_DP) if (opos != OPOS_DP)
@@ -264,57 +231,22 @@ static int dp_status(int port, uint32_t *payload) {
return 2; return 2;
} }
static int dp_config(int port, uint32_t *payload) { static int dp_config(uint32_t *payload) {
if (PD_DP_CFG_DPON(payload[1]))
0; //gpio_set_level(GPIO_PD_SBU_ENABLE, 1);
return 1; return 1;
} }
static int svdm_enter_mode(int port, uint32_t *payload) { static int svdm_enter_mode(uint32_t *payload) {
int rv = 0; /* will generate a NAK */ int rv = 0; /* will generate a NAK */
char str[256];
uint8_t old_display;
/* SID & mode request is valid */
if ((PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT)
&& (PD_VDO_OPOS(payload[0]) == OPOS_DP)) {
alt_mode[PD_AMODE_DISPLAYPORT] = OPOS_DP;
rv = 1;
//pd_log_event(PD_EVENT_VIDEO_DP_MODE, 0, 1, NULL);
} else if ((PD_VDO_VID(payload[0]) == USB_VID_GOOGLE)
&& (PD_VDO_OPOS(payload[0]) == OPOS_GFU)) {
alt_mode[PD_AMODE_GOOGLE] = OPOS_GFU;
rv = 1;
}
// if (rv)
/*
* If we failed initial mode entry we'll have enumerated the USB
* Billboard class. If so we should disconnect.
*/
//usb_disconnect();
// old_display = display_screen;
// display_screen = SCREEN_ALTMODE;
// memset(display_buffer[SCREEN_ALTMODE], 0x00, DISP_MEM_SIZE);
//
// sprintf(str, "Requested Alt Mode");
// UG_PutString(0, 8, str);
//
// display_screen = old_display;
// display_needs_update = 1;
//TODO handle alt mode ?
return rv; return rv;
} }
int pd_alt_mode(int port, uint16_t svid) { int pd_alt_mode(uint16_t svid) {
if (svid == USB_SID_DISPLAYPORT)
return alt_mode[PD_AMODE_DISPLAYPORT];
else if (svid == USB_VID_GOOGLE)
return alt_mode[PD_AMODE_GOOGLE];
return 0; return 0;
} }
static int svdm_exit_mode(int port, uint32_t *payload) { static int svdm_exit_mode(uint32_t *payload) {
return 1; /* Must return ACK */ return 1; /* Must return ACK */
} }
@@ -324,91 +256,3 @@ const struct svdm_response svdm_rsp = { &svdm_response_identity,
&svdm_response_svids, &svdm_response_modes, &svdm_enter_mode, &svdm_response_svids, &svdm_response_modes, &svdm_enter_mode,
&svdm_exit_mode, &dp_fx, }; &svdm_exit_mode, &dp_fx, };
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) {
int rsize;
if (PD_VDO_VID(payload[0]) != USB_VID_GOOGLE || !alt_mode[PD_AMODE_GOOGLE])
return 0;
*rpayload = payload;
rsize = pd_custom_flash_vdm(port, cnt, payload);
if (!rsize) {
int cmd = PD_VDO_CMD(payload[0]);
switch (cmd) {
case VDO_CMD_GET_LOG:
rsize = pd_vdm_get_log_entry(payload);
break;
default:
/* Unknown : do not answer */
return 0;
}
}
/* respond (positively) to the request */
payload[0] |= VDO_SRC_RESPONDER;
return rsize;
}
int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload) {
static int flash_offset;
int rsize = 1; /* default is just VDM header returned */
switch (PD_VDO_CMD(payload[0])) {
#if 0
case VDO_CMD_VERSION:
memcpy(payload + 1, &current_image_data.version, 24);
rsize = 7;
break;
case VDO_CMD_REBOOT:
/* ensure the power supply is in a safe state */
pd_power_supply_reset(0);
system_reset(0);
break;
case VDO_CMD_READ_INFO:
/* copy info into response */
pd_get_info(payload + 1);
rsize = 7;
break;
case VDO_CMD_FLASH_ERASE:
/* do not kill the code under our feet */
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
break;
pd_log_event(PD_EVENT_ACC_RW_ERASE, 0, 0, NULL);
flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF;
flash_physical_erase(CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF, CONFIG_RW_SIZE);
rw_flash_changed = 1;
break;
case VDO_CMD_FLASH_WRITE:
/* do not kill the code under our feet */
if ((system_get_image_copy() != SYSTEM_IMAGE_RO) ||
(flash_offset < CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF))
break;
flash_physical_write(flash_offset, 4*(cnt - 1),
(const char *)(payload+1));
flash_offset += 4*(cnt - 1);
rw_flash_changed = 1;
break;
case VDO_CMD_ERASE_SIG:
/* this is not touching the code area */
{
uint32_t zero = 0;
int offset;
/* zeroes the area containing the RSA signature */
for (offset = FW_RW_END - RSANUMBYTES;
offset < FW_RW_END; offset += 4)
flash_physical_write(offset, 4,
(const char *)&zero);
}
break;
#endif // 0
default:
/* Unknown : do not answer */
return 0;
}
return rsize;
}

View File

@@ -17,9 +17,9 @@
#define CONFIG_CHARGE_MANAGER #define CONFIG_CHARGE_MANAGER
//#define CONFIG_USBC_BACKWARDS_COMPATIBLE_DFP //#define CONFIG_USBC_BACKWARDS_COMPATIBLE_DFP
//#define CONFIG_USBC_VCONN_SWAP //#define CONFIG_USBC_VCONN_SWAP
#define CONFIG_USB_PD_ALT_MODE //#define CONFIG_USB_PD_ALT_MODE
//#define CONFIG_USB_PD_CHROMEOS //#define CONFIG_USB_PD_CHROMEOS
#define CONFIG_USB_PD_DUAL_ROLE //#define CONFIG_USB_PD_DUAL_ROLE
//#define CONFIG_USB_PD_GIVE_BACK //#define CONFIG_USB_PD_GIVE_BACK
//#define CONFIG_USB_PD_SIMPLE_DFP //#define CONFIG_USB_PD_SIMPLE_DFP
//#define CONFIG_USB_PD_TCPM_TCPCI //#define CONFIG_USB_PD_TCPM_TCPCI

View File

@@ -353,8 +353,7 @@ static void settings_setInputPRange(void) {
static void settings_displayInputPRange(void) { static void settings_displayInputPRange(void) {
printShortDescription(0, 5); printShortDescription(0, 5);
//0 = 9V, 1=12V (Fixed Voltages, these imply 1.5A limits) //0 = 9V, 1=12V (Fixed Voltages, these imply 1.5A limits)
//2 = 18W, 2=24W (Auto Adjusting V, estimated from the tip resistance???) # TODO /// TODO TS80P
// Need to come back and look at these ^ as there were issues with voltage hunting
switch (systemSettings.cutoutSetting) { switch (systemSettings.cutoutSetting) {
case 0: case 0:
OLED::printNumber(9, 2); OLED::printNumber(9, 2);