diff options
author | Randall Spangler <rspangler@chromium.org> | 2017-07-25 16:22:27 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-07-31 21:39:39 -0700 |
commit | 00ea73ab166ebc8a2c4b5693b7fa776c76c7fe45 (patch) | |
tree | c99009ec5bce12c97a85a32695bd7f0f435c1e2c /board | |
parent | ddbfe690e294e595c6ed3511dcf417410d9b2804 (diff) | |
download | chrome-ec-00ea73ab166ebc8a2c4b5693b7fa776c76c7fe45.tar.gz |
usb_i2c: Fail if board I2C bridge is disabled
Add usb_i2c_board_is_enabled().
On Cr50, this is now also connected to the I2C CCD capability. The
USB-I2C bridge can only be used when the capability is available.
On other platforms (Servo V4, etc.) where usb_i2c_board_enable() is
a no-op, add a dummy implementation which always returns true.
See go/cr50-ccd-wp for more information.
BUG=b:62537474
BRANCH=cr50
TEST=manual with CR50_DEV=1
Connect host PC to dev board USB port
On host PC:
sudo servod -c ccd_cr50.xml -c reef_r1_inas.xml
dut-control pp3300_ec_shv_reg --> fail, error 0x8001
ccdoops --> reset I2C config
ccd i2c disable --> I2C disabled
On host PC:
sudo servod -c ccd_cr50.xml -c reef_r1_inas.xml
dut-control pp3300_ec_shv_reg --> fail, error 0x0006
ccd i2c enable --> I2C enabled
ccdunlock --> I2C disabled
ccdoops --> I2C enabled
ccdset i2c unlesslocked
ccdlock --> I2C disabled
ccdunlock --> I2C enabled
Change-Id: Ia3df32e239a5f7c5915bc6c7e408ce0dc8b26c89
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/590577
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/cr50/rdd.c | 2 | ||||
-rw-r--r-- | board/cr50/usb_i2c.c | 40 | ||||
-rw-r--r-- | board/hammer/board.c | 1 | ||||
-rw-r--r-- | board/mn50/board.c | 5 | ||||
-rw-r--r-- | board/servo_micro/board.c | 2 | ||||
-rw-r--r-- | board/servo_v4/board.c | 1 | ||||
-rw-r--r-- | board/tigertail/board.c | 2 |
7 files changed, 49 insertions, 4 deletions
diff --git a/board/cr50/rdd.c b/board/cr50/rdd.c index 622bd8f986..bf5a3ed8f0 100644 --- a/board/cr50/rdd.c +++ b/board/cr50/rdd.c @@ -289,6 +289,8 @@ static int command_ccd(int argc, char **argv) ccprintf("AP UART: %s\nEC UART: %s\n", uart_tx_is_connected(UART_AP) ? " enabled" : "disabled", uart_tx_is_connected(UART_EC) ? " enabled" : "disabled"); + ccprintf("I2C: %s\n", + usb_i2c_board_is_enabled() ? " enabled" : "disabled"); return EC_SUCCESS; } diff --git a/board/cr50/usb_i2c.c b/board/cr50/usb_i2c.c index 24a6fbdea6..0bc5b3f215 100644 --- a/board/cr50/usb_i2c.c +++ b/board/cr50/usb_i2c.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include "case_closed_debug.h" #include "console.h" #include "device_state.h" #include "gpio.h" @@ -16,7 +17,7 @@ #define CPRINTS(format, args...) cprints(CC_USB, format, ## args) -static int i2c_enabled(void) +int usb_i2c_board_is_enabled(void) { return !gpio_get_level(GPIO_EN_PP3300_INA_L); } @@ -64,7 +65,7 @@ static void ina_connect(void) void usb_i2c_board_disable(void) { - if (!i2c_enabled()) + if (!usb_i2c_board_is_enabled()) return; ina_disconnect(); @@ -78,8 +79,41 @@ int usb_i2c_board_enable(void) return EC_ERROR_BUSY; } - if (!i2c_enabled()) + if (ccd_get_mode() != CCD_MODE_ENABLED) + return EC_ERROR_BUSY; + + if (!ccd_is_cap_enabled(CCD_CAP_I2C)) + return EC_ERROR_ACCESS_DENIED; + + if (!usb_i2c_board_is_enabled()) ina_connect(); return EC_SUCCESS; } + +/** + * CCD config change hook + */ +static void ccd_change_i2c(void) +{ + /* + * If the capability state doesn't match the current I2C enable state, + * try to make them match. + */ + if (usb_i2c_board_is_enabled() && !ccd_is_cap_enabled(CCD_CAP_I2C)) { + /* I2C bridge is enabled, but it's no longer allowed to be */ + usb_i2c_board_disable(); + } else if (!usb_i2c_board_is_enabled() && + ccd_is_cap_enabled(CCD_CAP_I2C)) { + /* + * I2C bridge is disabled, but is allowed to be enabled. Try + * enabling it. Note that this could fail for several reasons, + * such as CCD not connected, or servo attached. That's ok; + * those things will also attempt usb_i2c_board_enable() if + * their state changes later. + */ + usb_i2c_board_enable(); + } +} + +DECLARE_HOOK(HOOK_CCD_CHANGE, ccd_change_i2c, HOOK_PRIO_DEFAULT); diff --git a/board/hammer/board.c b/board/hammer/board.c index dcab35ca20..a3e90dc14b 100644 --- a/board/hammer/board.c +++ b/board/hammer/board.c @@ -80,6 +80,7 @@ BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); int usb_i2c_board_enable(void) { return EC_SUCCESS; } void usb_i2c_board_disable(void) {} +int usb_i2c_board_is_enabled(void) { return 1; } #ifdef CONFIG_KEYBOARD_BOARD_CONFIG struct keyboard_scan_config keyscan_config = { diff --git a/board/mn50/board.c b/board/mn50/board.c index 992fceb93c..39746a1745 100644 --- a/board/mn50/board.c +++ b/board/mn50/board.c @@ -103,6 +103,11 @@ int usb_i2c_board_enable(void) return EC_SUCCESS; } +int usb_i2c_board_is_enabled(void) +{ + return 1; +} + /* Initialize board. */ static void board_init(void) { diff --git a/board/servo_micro/board.c b/board/servo_micro/board.c index 505a6d628a..71b780917d 100644 --- a/board/servo_micro/board.c +++ b/board/servo_micro/board.c @@ -244,6 +244,8 @@ const struct i2c_port_t i2c_ports[] = { }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); +int usb_i2c_board_is_enabled(void) { return 1; } + /****************************************************************************** * Initialize board. */ diff --git a/board/servo_v4/board.c b/board/servo_v4/board.c index eb9c068520..f7bd390129 100644 --- a/board/servo_v4/board.c +++ b/board/servo_v4/board.c @@ -238,6 +238,7 @@ const struct i2c_port_t i2c_ports[] = { }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); +int usb_i2c_board_is_enabled(void) { return 1; } /****************************************************************************** * Initialize board. diff --git a/board/tigertail/board.c b/board/tigertail/board.c index 86d3a79d47..d2908fa394 100644 --- a/board/tigertail/board.c +++ b/board/tigertail/board.c @@ -111,7 +111,7 @@ const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); int usb_i2c_board_enable(void) {return EC_SUCCESS; } void usb_i2c_board_disable(void) {} - +int usb_i2c_board_is_enabled(void) { return 1; } /****************************************************************************** * Console commands. |