summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-11-04 12:43:07 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-11-08 17:31:12 -0800
commit92a65427d3881f3d2ec64b1ab540fb5a4aa0ce93 (patch)
tree6f99c785998cc784755ed1317724a236ffd656ab
parent6f4595ff7ac0821c9e4a4097444e6838e33b52c1 (diff)
downloadchrome-ec-92a65427d3881f3d2ec64b1ab540fb5a4aa0ce93.tar.gz
tcpm: Add configuration struct for tcpc i2c params
Add a new configuration struct tcpc_config_t that initially defines the i2c host port and i2c slave address of all TCPCs present on the board. This will allow us to create boards with multiple TCPCs on different i2c ports, with arbitrary i2c slave addresses. BUG=chromium:551078 TEST=Manual on glados. Verify PD communication / charging is still functional on both PD ports. BRANCH=None Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I9b2bde85d7f1642e8727c052e064371be7967619 Reviewed-on: https://chromium-review.googlesource.com/311000 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--board/chell/board.c5
-rw-r--r--board/glados/board.c5
-rw-r--r--board/kunimitsu/board.c5
-rw-r--r--board/lars/board.c7
-rw-r--r--board/oak/board.c5
-rw-r--r--board/pdeval-stm32f072/PD_evaluation.md4
-rw-r--r--board/pdeval-stm32f072/board.c8
-rw-r--r--board/pdeval-stm32f072/board.h4
-rw-r--r--board/strago/board.c4
-rw-r--r--board/wheatley/board.c5
-rw-r--r--driver/tcpm/fusb302.c184
-rw-r--r--driver/tcpm/fusb302.h4
-rw-r--r--driver/tcpm/tcpci.c97
-rw-r--r--driver/tcpm/tcpm.h62
-rw-r--r--include/config.h2
-rw-r--r--include/usb_pd_tcpc.h4
-rw-r--r--include/usb_pd_tcpm.h9
17 files changed, 242 insertions, 172 deletions
diff --git a/board/chell/board.c b/board/chell/board.c
index d6a78a1018..4706474487 100644
--- a/board/chell/board.c
+++ b/board/chell/board.c
@@ -110,6 +110,11 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR + 2},
+};
+
/* SPI devices */
const struct spi_device_t spi_devices[] = {
{ CONFIG_SPI_FLASH_PORT, 0, GPIO_PVT_CS0},
diff --git a/board/glados/board.c b/board/glados/board.c
index f26b1ff156..299e04fbae 100644
--- a/board/glados/board.c
+++ b/board/glados/board.c
@@ -130,6 +130,11 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR + 2},
+};
+
/* SPI devices */
const struct spi_device_t spi_devices[] = {
{ CONFIG_SPI_FLASH_PORT, 0, GPIO_PVT_CS0},
diff --git a/board/kunimitsu/board.c b/board/kunimitsu/board.c
index cebbadb83b..7344656908 100644
--- a/board/kunimitsu/board.c
+++ b/board/kunimitsu/board.c
@@ -123,6 +123,11 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR + 2},
+};
+
#ifndef BOARD_KUNIMITSU_V3
/* Physical fans. These are logically separate from pwm_channels. */
const struct fan_t fans[] = {
diff --git a/board/lars/board.c b/board/lars/board.c
index 0a9b5ea0ed..67342480ea 100644
--- a/board/lars/board.c
+++ b/board/lars/board.c
@@ -116,6 +116,13 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+#if CONFIG_USB_PD_PORT_COUNT >= 2
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR + 2},
+#endif
+};
+
/* Physical fans. These are logically separate from pwm_channels. */
const struct fan_t fans[] = {
{.flags = FAN_USE_RPM_MODE,
diff --git a/board/oak/board.c b/board/oak/board.c
index 7e204a33b5..687ad628dc 100644
--- a/board/oak/board.c
+++ b/board/oak/board.c
@@ -104,6 +104,11 @@ const struct i2c_port_t i2c_ports[] = {
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR + 2},
+};
+
struct mutex pericom_mux_lock;
struct pi3usb9281_config pi3usb9281_chips[] = {
{
diff --git a/board/pdeval-stm32f072/PD_evaluation.md b/board/pdeval-stm32f072/PD_evaluation.md
index b7fec09f35..395466f477 100644
--- a/board/pdeval-stm32f072/PD_evaluation.md
+++ b/board/pdeval-stm32f072/PD_evaluation.md
@@ -38,8 +38,8 @@ then document the new `CONFIG_USB_PD_TCPM_` variable in the [include/config.h](.
In [board/pdeval-stm32f072/board.h](board.h), you can update `CONFIG_USB_PD_PORT_COUNT` to the actual number of ports on your board.
You also need to create/delete the corresponding `PD_Cx` tasks in [board/pdeval-stm32f072/ec.tasklist](ec.tasklist).
-By default, the firmware is using I2C1 with SCL/SDA on pins PB6 and PB7, running with a 100kHz clock.
-To change the pins or speed, you need to edit `i2c_ports` in [board/pdeval-stm32f072/board.c](board.c), update `I2C_PORT_TCPC` in [board/pdeval-stm32f072/board.h](board.h) with the right controller number, and change the pin mux in [board/pdeval-stm32f072/gpio.inc](gpio.inc).
+By default, the firmware is using I2C1 with SCL/SDA on pins PB6 and PB7, running with a 100kHz clock, and tries to talk to TCPCs at i2c slave addresses 0x9c and 0x9e.
+To change the pins or speed, you need to edit `i2c_ports` in [board/pdeval-stm32f072/board.c](board.c), update `I2C_PORT_TCPC` in [board/pdeval-stm32f072/board.h](board.h) with the right controller number, and change the pin mux in [board/pdeval-stm32f072/gpio.inc](gpio.inc). To change TCPC i2c slave addresses, update `TCPC1_I2C_ADDR` and `TCPC2_I2C_ADDR` in [board/pdeval-stm32f072/board.h](board.h).
The I2C bus needs pull-up resistors on SCL/SDA. If your setup doesn't have external pull-ups on those lines, you can activate the chip internal pull-ups (but they are a bit weak for I2C) by editing [board/pdeval-stm32f072/gpio.inc](gpio.inc) and updating the alternate mode configuration flags with `GPIO_PULL_UP` e.g. :
`ALTERNATE(PIN_MASK(B, 0x00c0), 1, MODULE_I2C, GPIO_PULL_UP) /* I2C MASTER:PB6/7 */`
diff --git a/board/pdeval-stm32f072/board.c b/board/pdeval-stm32f072/board.c
index 3daedb5ae1..6fd472eee5 100644
--- a/board/pdeval-stm32f072/board.c
+++ b/board/pdeval-stm32f072/board.c
@@ -14,6 +14,7 @@
#include "task.h"
#include "usb_descriptor.h"
#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
#include "util.h"
void button_event(enum gpio_signal signal);
@@ -53,3 +54,10 @@ const struct i2c_port_t i2c_ports[] = {
{"tcpc", I2C_PORT_TCPC, 100 /* kHz */, GPIO_I2C0_SCL, GPIO_I2C0_SDA}
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, TCPC1_I2C_ADDR},
+#if CONFIG_USB_PD_PORT_COUNT >= 2
+ {I2C_PORT_TCPC, TCPC2_I2C_ADDR},
+#endif
+};
diff --git a/board/pdeval-stm32f072/board.h b/board/pdeval-stm32f072/board.h
index 8358420b93..2d2b4edc29 100644
--- a/board/pdeval-stm32f072/board.h
+++ b/board/pdeval-stm32f072/board.h
@@ -46,6 +46,10 @@
#define I2C_PORT_TCPC 0
#define I2C_PORT_PD_MCU 0
+/* TCPC I2C slave addresses */
+#define TCPC1_I2C_ADDR 0x9c
+#define TCPC2_I2C_ADDR 0x9e
+
/* Timer selection */
/* USB Configuration */
diff --git a/board/strago/board.c b/board/strago/board.c
index 79e99b83ee..441835b0ea 100644
--- a/board/strago/board.c
+++ b/board/strago/board.c
@@ -108,6 +108,10 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+};
+
/* SPI master ports */
const struct spi_device_t spi_devices[] = {
{ CONFIG_SPI_FLASH_PORT, 0, GPIO_PVT_CS0},
diff --git a/board/wheatley/board.c b/board/wheatley/board.c
index 85ebedb53c..247edea7d0 100644
--- a/board/wheatley/board.c
+++ b/board/wheatley/board.c
@@ -123,6 +123,11 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = {
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR},
+ {I2C_PORT_TCPC, CONFIG_TCPC_I2C_BASE_ADDR + 2},
+};
+
const enum gpio_signal hibernate_wake_pins[] = {
GPIO_AC_PRESENT,
GPIO_LID_OPEN,
diff --git a/driver/tcpm/fusb302.c b/driver/tcpm/fusb302.c
index 1b5d26f233..2bddaff7fb 100644
--- a/driver/tcpm/fusb302.c
+++ b/driver/tcpm/fusb302.c
@@ -9,18 +9,14 @@
#include "console.h"
#include "fusb302.h"
-#include "i2c.h"
#include "task.h"
#include "hooks.h"
+#include "tcpm.h"
#include "timer.h"
#include "usb_pd.h"
#include "usb_pd_tcpc.h"
-#include "usb_pd_tcpm.h"
#include "util.h"
-/* Convert port number to tcpc i2c address */
-#define I2C_ADDR_TCPC(p) (CONFIG_TCPC_I2C_BASE_ADDR + 2*(p))
-
static struct fusb302_chip_state {
int cc_polarity;
int vconn_enabled;
@@ -34,20 +30,10 @@ static struct fusb302_chip_state {
int tx_hard_reset_req;
} state[CONFIG_USB_PD_PORT_COUNT];
-static int fusb302_i2c_write8(int port, int reg, int val)
-{
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), reg, val);
-}
-
-static int fusb302_i2c_read8(int port, int reg, int *val)
-{
- return i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), reg, val);
-}
-
/* bring the FUSB302 out of reset after Hard Reset signaling */
static void fusb302_pd_reset(int port)
{
- fusb302_i2c_write8(port, TCPC_REG_RESET, TCPC_REG_RESET_PD_RESET);
+ tcpc_write(port, TCPC_REG_RESET, TCPC_REG_RESET_PD_RESET);
}
static void fusb302_flush_rx_fifo(int port)
@@ -58,30 +44,30 @@ static void fusb302_flush_rx_fifo(int port)
* then we'll have to keep a shadow of what this register
* value should be so we don't clobber it here!
*/
- fusb302_i2c_write8(port, TCPC_REG_CONTROL1, TCPC_REG_CONTROL1_RX_FLUSH);
+ tcpc_write(port, TCPC_REG_CONTROL1, TCPC_REG_CONTROL1_RX_FLUSH);
}
static void fusb302_flush_tx_fifo(int port)
{
int reg;
- fusb302_i2c_read8(port, TCPC_REG_CONTROL0, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL0, &reg);
reg |= TCPC_REG_CONTROL0_TX_FLUSH;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL0, reg);
+ tcpc_write(port, TCPC_REG_CONTROL0, reg);
}
static void fusb302_auto_goodcrc_enable(int port, int enable)
{
int reg;
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES1, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES1, &reg);
if (enable)
reg |= TCPC_REG_SWITCHES1_AUTO_GCRC;
else
reg &= ~TCPC_REG_SWITCHES1_AUTO_GCRC;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES1, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES1, reg);
}
/* Convert BC LVL values (in FUSB302) to Type-C CC Voltage Status */
@@ -119,12 +105,12 @@ static void detect_cc_pin_source(int port, int *cc1_lvl, int *cc2_lvl)
/* Measure CC1 */
/* Enable CC1 measurement switch and pullup */
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0,
- TCPC_REG_SWITCHES0_CC1_PU_EN |
- TCPC_REG_SWITCHES0_MEAS_CC1);
+ tcpc_write(port, TCPC_REG_SWITCHES0,
+ TCPC_REG_SWITCHES0_CC1_PU_EN |
+ TCPC_REG_SWITCHES0_MEAS_CC1);
/* Set MDAC Value to High. MDAC Reg is 7:2 */
- fusb302_i2c_write8(port, TCPC_REG_MEASURE, 0x26 << 2);
+ tcpc_write(port, TCPC_REG_MEASURE, 0x26 << 2);
/* CC1 is now being measured by FUSB302. */
@@ -132,20 +118,20 @@ static void detect_cc_pin_source(int port, int *cc1_lvl, int *cc2_lvl)
usleep(250);
/* Read status register */
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &reg);
+ tcpc_read(port, TCPC_REG_STATUS0, &reg);
if (reg & TCPC_REG_STATUS0_COMP) {
*cc1_lvl = TYPEC_CC_VOLT_OPEN;
} else {
/* Set MDAC Value to Low. MDAC Reg is 7:2 */
- fusb302_i2c_write8(port, TCPC_REG_MEASURE, 0x05 << 2);
+ tcpc_write(port, TCPC_REG_MEASURE, 0x05 << 2);
/* Wait on measurement */
usleep(250);
/* Read status register */
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &reg);
+ tcpc_read(port, TCPC_REG_STATUS0, &reg);
if (reg & TCPC_REG_STATUS0_COMP)
*cc1_lvl = TYPEC_CC_VOLT_RA;
@@ -156,12 +142,12 @@ static void detect_cc_pin_source(int port, int *cc1_lvl, int *cc2_lvl)
/* Measure CC2 */
/* Enable CC2 measurement switch and pullup */
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0,
- TCPC_REG_SWITCHES0_CC2_PU_EN |
- TCPC_REG_SWITCHES0_MEAS_CC2);
+ tcpc_write(port, TCPC_REG_SWITCHES0,
+ TCPC_REG_SWITCHES0_CC2_PU_EN |
+ TCPC_REG_SWITCHES0_MEAS_CC2);
/* Set MDAC Value to High. MDAC Reg is 7:2 */
- fusb302_i2c_write8(port, TCPC_REG_MEASURE, 0x26 << 2);
+ tcpc_write(port, TCPC_REG_MEASURE, 0x26 << 2);
/* CC2 is now being measured by FUSB302. */
@@ -169,20 +155,20 @@ static void detect_cc_pin_source(int port, int *cc1_lvl, int *cc2_lvl)
usleep(250);
/* Read status register */
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &reg);
+ tcpc_read(port, TCPC_REG_STATUS0, &reg);
if (reg & TCPC_REG_STATUS0_COMP) {
*cc2_lvl = TYPEC_CC_VOLT_OPEN;
} else {
/* Set MDAC Value to Low. MDAC Reg is 7:2 */
- fusb302_i2c_write8(port, TCPC_REG_MEASURE, 0x05 << 2);
+ tcpc_write(port, TCPC_REG_MEASURE, 0x05 << 2);
/* Wait on measurement */
usleep(250);
/* Read status register */
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &reg);
+ tcpc_read(port, TCPC_REG_STATUS0, &reg);
if (reg & TCPC_REG_STATUS0_COMP)
*cc2_lvl = TYPEC_CC_VOLT_RA;
@@ -204,7 +190,7 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2)
/*
* Measure CC1 first.
*/
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
/* save original state to be returned to later... */
if (reg & TCPC_REG_SWITCHES0_MEAS_CC1)
@@ -222,12 +208,12 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2)
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2;
reg |= TCPC_REG_SWITCHES0_MEAS_CC1;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
/*
* CC1 is now being measured by FUSB302.
*/
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &bc_lvl_cc1);
+ tcpc_read(port, TCPC_REG_STATUS0, &bc_lvl_cc1);
/* mask away unwanted bits */
bc_lvl_cc1 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1);
@@ -236,18 +222,18 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2)
* Measure CC2 next.
*/
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
/* Disable CC1 measurement switch, enable CC2 measurement switch */
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1;
reg |= TCPC_REG_SWITCHES0_MEAS_CC2;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
/*
* CC2 is now being measured by FUSB302.
*/
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &bc_lvl_cc2);
+ tcpc_read(port, TCPC_REG_STATUS0, &bc_lvl_cc2);
/* mask away unwanted bits */
bc_lvl_cc2 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1);
@@ -256,7 +242,7 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2)
*cc2 = convert_bc_lvl(port, bc_lvl_cc2);
/* return MEAS_CC1/2 switches to original state */
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
if (orig_meas_cc1)
reg |= TCPC_REG_SWITCHES0_MEAS_CC1;
else
@@ -266,7 +252,7 @@ static void detect_cc_pin_sink(int port, int *cc1, int *cc2)
else
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
}
/* Parse header bytes for the size of packet */
@@ -333,10 +319,9 @@ static int fusb302_send_message(int port, uint16_t header, const uint32_t *data,
buf[buf_pos++] = FUSB302_TKN_TXON;
/* burst write for speed! */
- i2c_lock(I2C_PORT_TCPC, 1);
- rv = i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- buf, buf_pos, 0, 0, I2C_XFER_SINGLE);
- i2c_lock(I2C_PORT_TCPC, 0);
+ tcpc_lock(port, 1);
+ rv = tcpc_xfer(port, buf, buf_pos, 0, 0, I2C_XFER_SINGLE);
+ tcpc_lock(port, 0);
return rv;
}
@@ -362,14 +347,14 @@ int tcpm_init(int port)
/* all other variables assumed to default to 0 */
/* Restore default settings */
- fusb302_i2c_write8(port, TCPC_REG_RESET, TCPC_REG_RESET_SW_RESET);
+ tcpc_write(port, TCPC_REG_RESET, TCPC_REG_RESET_SW_RESET);
/* Turn on retries and set number of retries */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL3, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL3, &reg);
reg |= TCPC_REG_CONTROL3_AUTO_RETRY;
reg |= (PD_RETRY_COUNT & 0x3) <<
TCPC_REG_CONTROL3_N_RETRIES_POS;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL3, reg);
+ tcpc_write(port, TCPC_REG_CONTROL3, reg);
/* Create interrupt masks */
reg = 0xFF;
@@ -379,7 +364,7 @@ int tcpm_init(int port)
reg &= ~TCPC_REG_MASK_COLLISION;
/* misc alert */
reg &= ~TCPC_REG_MASK_ALERT;
- fusb302_i2c_write8(port, TCPC_REG_MASK, reg);
+ tcpc_write(port, TCPC_REG_MASK, reg);
reg = 0xFF;
/* informs of attaches */
@@ -392,17 +377,17 @@ int tcpm_init(int port)
reg &= ~TCPC_REG_MASKA_TX_SUCCESS;
/* when fusb302 receives a hard reset */
reg &= ~TCPC_REG_MASKA_HARDRESET;
- fusb302_i2c_write8(port, TCPC_REG_MASKA, reg);
+ tcpc_write(port, TCPC_REG_MASKA, reg);
reg = 0xFF;
/* when fusb302 sends GoodCRC to ack a pd message */
reg &= ~TCPC_REG_MASKB_GCRCSENT;
- fusb302_i2c_write8(port, TCPC_REG_MASKB, reg);
+ tcpc_write(port, TCPC_REG_MASKB, reg);
/* Interrupt Enable */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL0, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL0, &reg);
reg &= ~TCPC_REG_CONTROL0_INT_MASK;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL0, reg);
+ tcpc_write(port, TCPC_REG_CONTROL0, reg);
/* Set VCONN switch defaults */
tcpm_set_polarity(port, 0);
@@ -410,7 +395,7 @@ int tcpm_init(int port)
/* Turn on the power! */
/* TODO: Reduce power consumption */
- fusb302_i2c_write8(port, TCPC_REG_POWER, TCPC_REG_POWER_PWR_ALL);
+ tcpc_write(port, TCPC_REG_POWER, TCPC_REG_POWER_PWR_ALL);
return 0;
}
@@ -457,20 +442,20 @@ int tcpm_set_cc(int port, int pull)
!state[port].togdone_pullup_cc2) {
/* Enable DFP Toggle Mode */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL2, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL2, &reg);
/* turn on toggle */
reg |= (TCPC_REG_CONTROL2_MODE_DFP <<
TCPC_REG_CONTROL2_MODE_POS);
reg |= TCPC_REG_CONTROL2_TOGGLE;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL2, reg);
+ tcpc_write(port, TCPC_REG_CONTROL2, reg);
state[port].pulling_up = 1;
state[port].dfp_toggling_on = 1;
} else {
/* enable the pull-up we know to be necessary */
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN);
reg &= ~(TCPC_REG_SWITCHES0_CC1_PU_EN);
@@ -482,7 +467,7 @@ int tcpm_set_cc(int port, int pull)
else
reg |= TCPC_REG_SWITCHES0_CC2_PU_EN;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
state[port].pulling_up = 1;
state[port].dfp_toggling_on = 0;
@@ -493,35 +478,35 @@ int tcpm_set_cc(int port, int pull)
/* Enable UFP Mode */
/* turn off toggle */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL2, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL2, &reg);
reg &= ~TCPC_REG_CONTROL2_TOGGLE;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL2, reg);
+ tcpc_write(port, TCPC_REG_CONTROL2, reg);
/* enable pull-downs, disable pullups */
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN);
reg &= ~(TCPC_REG_SWITCHES0_CC1_PU_EN);
reg |= (TCPC_REG_SWITCHES0_CC1_PD_EN);
reg |= (TCPC_REG_SWITCHES0_CC2_PD_EN);
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
state[port].pulling_up = 0;
state[port].dfp_toggling_on = 0;
break;
case TYPEC_CC_OPEN:
/* Disable toggling */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL2, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL2, &reg);
reg &= ~TCPC_REG_CONTROL2_TOGGLE;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL2, reg);
+ tcpc_write(port, TCPC_REG_CONTROL2, reg);
/* Ensure manual switches are opened */
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
reg &= ~TCPC_REG_SWITCHES0_CC1_PU_EN;
reg &= ~TCPC_REG_SWITCHES0_CC2_PU_EN;
reg &= ~TCPC_REG_SWITCHES0_CC1_PD_EN;
reg &= ~TCPC_REG_SWITCHES0_CC2_PD_EN;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
state[port].pulling_up = 0;
state[port].dfp_toggling_on = 0;
@@ -538,7 +523,7 @@ int tcpm_set_polarity(int port, int polarity)
/* Port polarity : 0 => CC1 is CC line, 1 => CC2 is CC line */
int reg;
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
/* clear VCONN switch bits */
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1;
@@ -562,9 +547,9 @@ int tcpm_set_polarity(int port, int polarity)
else
reg |= TCPC_REG_SWITCHES0_MEAS_CC1;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES1, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES1, &reg);
/* clear tx_cc bits */
reg &= ~TCPC_REG_SWITCHES1_TXCC1_EN;
@@ -576,7 +561,7 @@ int tcpm_set_polarity(int port, int polarity)
else
reg |= TCPC_REG_SWITCHES1_TXCC1_EN;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES1, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES1, reg);
/* Save the polarity for later */
state[port].cc_polarity = polarity;
@@ -601,13 +586,13 @@ int tcpm_set_vconn(int port, int enable)
tcpm_set_polarity(port, state[port].cc_polarity);
} else {
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
/* clear VCONN switch bits */
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1;
reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
}
/* save enable state for later use */
@@ -619,7 +604,7 @@ int tcpm_set_msg_header(int port, int power_role, int data_role)
{
int reg;
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES1, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES1, &reg);
reg &= ~TCPC_REG_SWITCHES1_POWERROLE;
reg &= ~TCPC_REG_SWITCHES1_DATAROLE;
@@ -629,7 +614,7 @@ int tcpm_set_msg_header(int port, int power_role, int data_role)
if (data_role)
reg |= TCPC_REG_SWITCHES1_DATAROLE;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES1, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES1, reg);
return 0;
}
@@ -641,7 +626,7 @@ int tcpm_set_rx_enable(int port, int enable)
state[port].rx_enable = enable;
/* Get current switch state */
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
/* Clear CC1/CC2 measure bits */
reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1;
@@ -662,7 +647,7 @@ int tcpm_set_rx_enable(int port, int enable)
/* "shouldn't get here" */
return EC_ERROR_UNKNOWN;
}
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
/* flush rx fifo in case messages have been coming our way */
fusb302_flush_rx_fifo(port);
@@ -681,7 +666,7 @@ int tcpm_set_rx_enable(int port, int enable)
tcpm_set_cc(port, state[port].previous_pull);
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
}
fusb302_auto_goodcrc_enable(port, enable);
@@ -709,10 +694,9 @@ int tcpm_get_message(int port, uint32_t *payload, int *head)
* PART 1 OF BURST READ: Write in register address.
* Issue a START, no STOP.
*/
- i2c_lock(I2C_PORT_TCPC, 1);
+ tcpc_lock(port, 1);
buf[0] = TCPC_REG_FIFOS;
- rv |= i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- buf, 1, 0, 0, I2C_XFER_START);
+ rv |= tcpc_xfer(port, buf, 1, 0, 0, I2C_XFER_START);
/*
* PART 2 OF BURST READ: Read up to the header.
@@ -720,8 +704,7 @@ int tcpm_get_message(int port, uint32_t *payload, int *head)
* only grab three bytes so we can get the header
* and determine how many more bytes we need to read.
*/
- rv |= i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- 0, 0, buf, 3, I2C_XFER_START);
+ rv |= tcpc_xfer(port, 0, 0, buf, 3, I2C_XFER_START);
/* Grab the header */
*head = (buf[1] & 0xFF);
@@ -735,10 +718,9 @@ int tcpm_get_message(int port, uint32_t *payload, int *head)
* No START, but do issue a STOP at the end.
* add 4 to len to read CRC out
*/
- rv |= i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- 0, 0, buf, len+4, I2C_XFER_STOP);
+ rv |= tcpc_xfer(port, 0, 0, buf, len+4, I2C_XFER_STOP);
- i2c_lock(I2C_PORT_TCPC, 0);
+ tcpc_lock(port, 0);
/* return the data */
memcpy(payload, buf, len);
@@ -774,7 +756,7 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header,
switch (type) {
case TCPC_TX_SOP:
- /* put register address first for of burst i2c write */
+ /* put register address first for of burst tcpc write */
buf[buf_pos++] = TCPC_REG_FIFOS;
/* Write the SOP Ordered Set into TX FIFO */
@@ -788,16 +770,16 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header,
state[port].tx_hard_reset_req = 1;
/* Simply hit the SEND_HARD_RESET bit */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL3, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL3, &reg);
reg |= TCPC_REG_CONTROL3_SEND_HARDRESET;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL3, reg);
+ tcpc_write(port, TCPC_REG_CONTROL3, reg);
break;
case TCPC_TX_BIST_MODE_2:
/* Simply hit the BIST_MODE2 bit */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL1, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL1, &reg);
reg |= TCPC_REG_CONTROL1_BIST_MODE2;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL1, reg);
+ tcpc_write(port, TCPC_REG_CONTROL1, reg);
break;
default:
return EC_ERROR_UNIMPLEMENTED;
@@ -811,7 +793,7 @@ int tcpm_get_vbus_level(int port)
int reg;
/* Read status register */
- fusb302_i2c_read8(port, TCPC_REG_STATUS0, &reg);
+ tcpc_read(port, TCPC_REG_STATUS0, &reg);
return (reg & TCPC_REG_STATUS0_VBUSOK) ? 1 : 0;
}
@@ -827,9 +809,9 @@ void tcpc_alert(int port)
/* reading interrupt registers clears them */
- fusb302_i2c_read8(port, TCPC_REG_INTERRUPT, &interrupt);
- fusb302_i2c_read8(port, TCPC_REG_INTERRUPTA, &interrupta);
- fusb302_i2c_read8(port, TCPC_REG_INTERRUPTB, &interruptb);
+ tcpc_read(port, TCPC_REG_INTERRUPT, &interrupt);
+ tcpc_read(port, TCPC_REG_INTERRUPTA, &interrupta);
+ tcpc_read(port, TCPC_REG_INTERRUPTB, &interruptb);
if (interrupt & TCPC_REG_INTERRUPT_BC_LVL) {
/* CC Status change */
@@ -856,16 +838,16 @@ void tcpc_alert(int port)
state[port].dfp_toggling_on = 0;
/* read what 302 settled on for an answer...*/
- fusb302_i2c_read8(port, TCPC_REG_STATUS1A, &reg);
+ tcpc_read(port, TCPC_REG_STATUS1A, &reg);
reg = reg >> TCPC_REG_STATUS1A_TOGSS_POS;
reg = reg & TCPC_REG_STATUS1A_TOGSS_MASK;
toggle_answer = reg;
/* Turn off toggle so we can take over the switches again */
- fusb302_i2c_read8(port, TCPC_REG_CONTROL2, &reg);
+ tcpc_read(port, TCPC_REG_CONTROL2, &reg);
reg &= ~TCPC_REG_CONTROL2_TOGGLE;
- fusb302_i2c_write8(port, TCPC_REG_CONTROL2, reg);
+ tcpc_write(port, TCPC_REG_CONTROL2, reg);
switch (toggle_answer) {
case TCPC_REG_STATUS1A_TOGSS_SRC1:
@@ -894,7 +876,7 @@ void tcpc_alert(int port)
}
/* enable the pull-up we know to be necessary */
- fusb302_i2c_read8(port, TCPC_REG_SWITCHES0, &reg);
+ tcpc_read(port, TCPC_REG_SWITCHES0, &reg);
reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN);
reg &= ~(TCPC_REG_SWITCHES0_CC1_PU_EN);
@@ -906,7 +888,7 @@ void tcpc_alert(int port)
else
reg |= TCPC_REG_SWITCHES0_CC2_PU_EN;
- fusb302_i2c_write8(port, TCPC_REG_SWITCHES0, reg);
+ tcpc_write(port, TCPC_REG_SWITCHES0, reg);
}
if (interrupta & TCPC_REG_INTERRUPTA_RETRYFAIL) {
diff --git a/driver/tcpm/fusb302.h b/driver/tcpm/fusb302.h
index ce8bd20af9..45fa0f3362 100644
--- a/driver/tcpm/fusb302.h
+++ b/driver/tcpm/fusb302.h
@@ -10,9 +10,6 @@
#ifndef __CROS_EC_DRIVER_TCPM_FUSB302_H
#define __CROS_EC_DRIVER_TCPM_FUSB302_H
-/* FUSB302 I2C Address */
-#define CONFIG_TCPC_I2C_BASE_ADDR 0x44
-
/* Default retry count for transmitting */
#define PD_RETRY_COUNT 3
@@ -193,6 +190,5 @@ enum fusb302_txfifo_tokens {
FUSB302_TKN_TXOFF = 0xFE,
};
-
#endif /* __CROS_EC_DRIVER_TCPM_FUSB302_H */
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index b01b7d806e..acc61e70c4 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -5,19 +5,15 @@
/* Type-C port manager */
-#include "i2c.h"
#include "task.h"
#include "tcpci.h"
+#include "tcpm.h"
#include "timer.h"
#include "usb_charge.h"
#include "usb_pd.h"
#include "usb_pd_tcpc.h"
-#include "usb_pd_tcpm.h"
#include "util.h"
-/* Convert port number to tcpc i2c address */
-#define I2C_ADDR_TCPC(p) (CONFIG_TCPC_I2C_BASE_ADDR + 2*(p))
-
static int tcpc_vbus[CONFIG_USB_PD_PORT_COUNT];
static int init_alert_mask(int port)
@@ -62,10 +58,9 @@ int tcpm_get_cc(int port, int *cc1, int *cc2)
int status;
int rv;
- rv = i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_CC_STATUS, &status);
+ rv = tcpc_read(port, TCPC_REG_CC_STATUS, &status);
- /* If i2c read fails, return error */
+ /* If tcpc read fails, return error */
if (rv)
return rv;
@@ -86,8 +81,7 @@ int tcpm_get_cc(int port, int *cc1, int *cc2)
int tcpm_get_power_status(int port, int *status)
{
- return i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_POWER_STATUS, status);
+ return tcpc_read(port, TCPC_REG_POWER_STATUS, status);
}
int tcpm_set_cc(int port, int pull)
@@ -97,59 +91,51 @@ int tcpm_set_cc(int port, int pull)
* pull.
*/
/* TODO: set desired Rp strength */
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_ROLE_CTRL,
+ return tcpc_write(port, TCPC_REG_ROLE_CTRL,
TCPC_REG_ROLE_CTRL_SET(0, 0, pull, pull));
}
int tcpm_set_polarity(int port, int polarity)
{
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_TCPC_CTRL,
+ return tcpc_write(port, TCPC_REG_TCPC_CTRL,
TCPC_REG_TCPC_CTRL_SET(polarity));
}
int tcpm_set_vconn(int port, int enable)
{
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_POWER_CTRL,
+ return tcpc_write(port, TCPC_REG_POWER_CTRL,
TCPC_REG_POWER_CTRL_SET(enable));
}
int tcpm_set_msg_header(int port, int power_role, int data_role)
{
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_MSG_HDR_INFO,
+ return tcpc_write(port, TCPC_REG_MSG_HDR_INFO,
TCPC_REG_MSG_HDR_INFO_SET(data_role, power_role));
}
int tcpm_alert_status(int port, int *alert)
{
/* Read TCPC Alert register */
- return i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_ALERT, alert);
+ return tcpc_read16(port, TCPC_REG_ALERT, alert);
}
int tcpm_set_rx_enable(int port, int enable)
{
/* If enable, then set RX detect for SOP and HRST */
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_RX_DETECT,
+ return tcpc_write(port, TCPC_REG_RX_DETECT,
enable ? TCPC_REG_RX_DETECT_SOP_HRST_MASK : 0);
}
int tcpm_set_power_status_mask(int port, uint8_t mask)
{
/* write to the Alert Mask register */
- return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_POWER_STATUS_MASK , mask);
+ return tcpc_write(port, TCPC_REG_POWER_STATUS_MASK , mask);
}
int tcpm_alert_mask_set(int port, uint16_t mask)
{
/* write to the Alert Mask register */
- return i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_ALERT_MASK, mask);
+ return tcpc_write16(port, TCPC_REG_ALERT_MASK, mask);
}
#ifdef CONFIG_USB_PD_TCPM_VBUS
@@ -163,23 +149,20 @@ int tcpm_get_message(int port, uint32_t *payload, int *head)
{
int rv, cnt, reg = TCPC_REG_RX_DATA;
- rv = i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_RX_BYTE_CNT, &cnt);
+ rv = tcpc_read(port, TCPC_REG_RX_BYTE_CNT, &cnt);
- rv |= i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_RX_HDR, (int *)head);
+ rv |= tcpc_read16(port, TCPC_REG_RX_HDR, (int *)head);
if (rv == EC_SUCCESS && cnt > 0) {
- i2c_lock(I2C_PORT_TCPC, 1);
- rv = i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- (uint8_t *)&reg, 1, (uint8_t *)payload,
- cnt, I2C_XFER_SINGLE);
- i2c_lock(I2C_PORT_TCPC, 0);
+ tcpc_lock(port, 1);
+ rv = tcpc_xfer(port,
+ (uint8_t *)&reg, 1, (uint8_t *)payload,
+ cnt, I2C_XFER_SINGLE);
+ tcpc_lock(port, 0);
}
/* Read complete, clear RX status alert bit */
- i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS);
+ tcpc_write16(port, TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS);
return rv;
}
@@ -190,31 +173,28 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header,
int reg = TCPC_REG_TX_DATA;
int rv, cnt = 4*PD_HEADER_CNT(header);
- rv = i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_TX_BYTE_CNT, cnt);
+ rv = tcpc_write(port, TCPC_REG_TX_BYTE_CNT, cnt);
- rv |= i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_TX_HDR, header);
+ rv |= tcpc_write16(port, TCPC_REG_TX_HDR, header);
- /* If i2c read fails, return error */
+ /* If tcpc read fails, return error */
if (rv)
return rv;
if (cnt > 0) {
- i2c_lock(I2C_PORT_TCPC, 1);
- rv = i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- (uint8_t *)&reg, 1, NULL, 0, I2C_XFER_START);
- rv |= i2c_xfer(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- (uint8_t *)data, cnt, NULL, 0, I2C_XFER_STOP);
- i2c_lock(I2C_PORT_TCPC, 0);
+ tcpc_lock(port, 1);
+ rv = tcpc_xfer(port,
+ (uint8_t *)&reg, 1, NULL, 0, I2C_XFER_START);
+ rv |= tcpc_xfer(port,
+ (uint8_t *)data, cnt, NULL, 0, I2C_XFER_STOP);
+ tcpc_lock(port, 0);
}
- /* If i2c read fails, return error */
+ /* If tcpc read fails, return error */
if (rv)
return rv;
- rv = i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_TRANSMIT, TCPC_REG_TRANSMIT_SET(type));
+ rv = tcpc_write(port, TCPC_REG_TRANSMIT, TCPC_REG_TRANSMIT_SET(type));
return rv;
}
@@ -231,8 +211,8 @@ void tcpc_alert(int port)
* be cleared until we have successfully retrieved message.
*/
if (status & ~TCPC_REG_ALERT_RX_STATUS)
- i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_ALERT, status & ~TCPC_REG_ALERT_RX_STATUS);
+ tcpc_write16(port, TCPC_REG_ALERT,
+ status & ~TCPC_REG_ALERT_RX_STATUS);
if (status & TCPC_REG_ALERT_CC_STATUS) {
/* CC status changed, wake task */
@@ -241,8 +221,7 @@ void tcpc_alert(int port)
if (status & TCPC_REG_ALERT_POWER_STATUS) {
int reg = 0;
- i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_POWER_STATUS_MASK, &reg);
+ tcpc_read(port, TCPC_REG_POWER_STATUS_MASK, &reg);
if (reg == TCPC_REG_POWER_STATUS_MASK_ALL) {
/*
@@ -287,17 +266,15 @@ int tcpm_init(int port)
int power_status;
while (1) {
- rv = i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_POWER_STATUS, &power_status);
+ rv = tcpc_read(port, TCPC_REG_POWER_STATUS, &power_status);
/*
- * If i2c succeeds and the uninitialized bit is clear, then
+ * If read succeeds and the uninitialized bit is clear, then
* initalization is complete, clear all alert bits and write
* the initial alert mask.
*/
if (rv == EC_SUCCESS &&
!(power_status & TCPC_REG_POWER_STATUS_UNINIT)) {
- i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port),
- TCPC_REG_ALERT, 0xffff);
+ tcpc_write16(port, TCPC_REG_ALERT, 0xffff);
/* Initialize power_status_mask */
init_power_status_mask(port);
/* Update VBUS status */
diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h
new file mode 100644
index 0000000000..4c4ff6c9a2
--- /dev/null
+++ b/driver/tcpm/tcpm.h
@@ -0,0 +1,62 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* USB Power delivery port management - common header for TCPM drivers */
+
+#ifndef __CROS_EC_USB_PD_TCPM_TCPM_H
+#define __CROS_EC_USB_PD_TCPM_TCPM_H
+
+#include "i2c.h"
+#include "usb_pd_tcpm.h"
+
+extern const struct tcpc_config_t tcpc_config[];
+
+/* I2C wrapper functions - get I2C port / slave addr from config struct. */
+static inline int tcpc_write(int port, int reg, int val)
+{
+ return i2c_write8(tcpc_config[port].i2c_host_port,
+ tcpc_config[port].i2c_slave_addr,
+ reg, val);
+}
+
+static inline int tcpc_write16(int port, int reg, int val)
+{
+ return i2c_write16(tcpc_config[port].i2c_host_port,
+ tcpc_config[port].i2c_slave_addr,
+ reg, val);
+}
+
+static inline int tcpc_read(int port, int reg, int *val)
+{
+ return i2c_read8(tcpc_config[port].i2c_host_port,
+ tcpc_config[port].i2c_slave_addr,
+ reg, val);
+}
+
+static inline int tcpc_read16(int port, int reg, int *val)
+{
+ return i2c_read16(tcpc_config[port].i2c_host_port,
+ tcpc_config[port].i2c_slave_addr,
+ reg, val);
+}
+
+static inline int tcpc_xfer(int port,
+ const uint8_t *out, int out_size,
+ uint8_t *in, int in_size,
+ int flags)
+{
+ return i2c_xfer(tcpc_config[port].i2c_host_port,
+ tcpc_config[port].i2c_slave_addr,
+ out, out_size,
+ in, in_size,
+ flags);
+}
+
+static inline void tcpc_lock(int port, int lock)
+{
+ i2c_lock(tcpc_config[port].i2c_host_port, lock);
+}
+
+#endif
diff --git a/include/config.h b/include/config.h
index a1e1d8e78c..1e8618ca7d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1783,7 +1783,7 @@
#undef CONFIG_USB_PD_TCPM_VBUS
/* Define the type-c port controller I2C base address. */
-#undef CONFIG_TCPC_I2C_BASE_ADDR
+#define CONFIG_TCPC_I2C_BASE_ADDR 0x9c
/* Use this option to enable Try.SRC mode for Dual Role devices */
#undef CONFIG_USB_PD_TRY_SRC
diff --git a/include/usb_pd_tcpc.h b/include/usb_pd_tcpc.h
index a640714c4f..371e6666a4 100644
--- a/include/usb_pd_tcpc.h
+++ b/include/usb_pd_tcpc.h
@@ -8,10 +8,6 @@
#ifndef __CROS_EC_USB_PD_TCPC_H
#define __CROS_EC_USB_PD_TCPC_H
-#ifndef CONFIG_TCPC_I2C_BASE_ADDR
-#define CONFIG_TCPC_I2C_BASE_ADDR 0x9c
-#endif
-
/* If we are a TCPC but do not a TCPM, then we implement the slave TCPCI */
#if defined(CONFIG_USB_PD_TCPC) && !defined(CONFIG_USB_PD_TCPM_STUB)
#define TCPCI_I2C_SLAVE
diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h
index 8d446bcae8..6b1180cafd 100644
--- a/include/usb_pd_tcpm.h
+++ b/include/usb_pd_tcpm.h
@@ -47,6 +47,15 @@ enum tcpc_transmit_complete {
TCPC_TX_COMPLETE_FAILED = 2,
};
+struct tcpc_config_t {
+ int i2c_host_port;
+ int i2c_slave_addr;
+ /*
+ * TODO: Consider adding driver struct / function pointers to support
+ * different TCPM drivers on the same board.
+ */
+};
+
/**
* Initialize TCPM driver and wait for TCPC readiness.
*