summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2017-07-25 16:22:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-31 21:39:39 -0700
commit00ea73ab166ebc8a2c4b5693b7fa776c76c7fe45 (patch)
treec99009ec5bce12c97a85a32695bd7f0f435c1e2c /board
parentddbfe690e294e595c6ed3511dcf417410d9b2804 (diff)
downloadchrome-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.c2
-rw-r--r--board/cr50/usb_i2c.c40
-rw-r--r--board/hammer/board.c1
-rw-r--r--board/mn50/board.c5
-rw-r--r--board/servo_micro/board.c2
-rw-r--r--board/servo_v4/board.c1
-rw-r--r--board/tigertail/board.c2
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.