diff options
author | Keith Short <keithshort@chromium.org> | 2021-09-13 11:11:06 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-14 21:08:15 +0000 |
commit | dfbeff4b5f6d8e078c7f69b1fe5050a4288a1d66 (patch) | |
tree | d288fc2e3a83d2e7918793584d7040918a37174e | |
parent | 17b10f589a23ab208222742f9864201a85512e00 (diff) | |
download | chrome-ec-dfbeff4b5f6d8e078c7f69b1fe5050a4288a1d66.tar.gz |
zephyr: Automatically detect shared I2C ports
Delete the "physical-port" node from named-i2c-ports, and automatically
detected when multiple children point to the same I2C bus.
This ensures that the I2C bus locking always blocks all matching I2C
nodes, without the user needing to specify this relationship manually
in the devicetree.
BUG=none
BRANCH=none
TEST=Dump out i2c_physical_ports[] on herobrine.
Signed-off-by: Keith Short <keithshort@chromium.org>
Change-Id: I3d254684483a95af12e7940446f4cd8743684708
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3154694
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-by: Yuval Peress <peress@google.com>
-rw-r--r-- | zephyr/Kconfig | 9 | ||||
-rw-r--r-- | zephyr/boards/riscv/asurada/asurada.dts | 12 | ||||
-rw-r--r-- | zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml | 8 | ||||
-rw-r--r-- | zephyr/shim/src/i2c.c | 46 |
4 files changed, 51 insertions, 24 deletions
diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 563fddd737..3d4a5a62b5 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -454,6 +454,15 @@ config PLATFORM_EC_I2C should make shimming other platform/ec modules which rely on i2c communication "just work" without requiring any further code changes. +config PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP + bool "Console command: i2c_portmap" + default y + depends on PLATFORM_EC_I2C + help + Enable the 'i2c_portmap' console command. This comamnd is used to + display the mapping of the I2C ports defined by the named-i2c-ports + node to the physical port and remote port indexes. + config PLATFORM_EC_SMBUS_PEC bool "Packet error checking support for SMBus" help diff --git a/zephyr/boards/riscv/asurada/asurada.dts b/zephyr/boards/riscv/asurada/asurada.dts index 2ad8fbbc14..7b4519c0e1 100644 --- a/zephyr/boards/riscv/asurada/asurada.dts +++ b/zephyr/boards/riscv/asurada/asurada.dts @@ -90,74 +90,62 @@ i2c-port = <&i2c0>; enum-name = "I2C_PORT_POWER"; label = "POWER"; - physical-port = <0>; }; battery { i2c-port = <&i2c0>; remote-port = <0>; enum-name = "I2C_PORT_BATTERY"; label = "BATTERY"; - physical-port = <0>; }; eeprom { i2c-port = <&i2c0>; enum-name = "I2C_PORT_EEPROM"; label = "EEPROM"; - physical-port = <0>; }; charger { i2c-port = <&i2c0>; enum-name = "I2C_PORT_CHARGER"; label = "CHARGER"; - physical-port = <0>; }; i2c_sensor: sensor { i2c-port = <&i2c1>; enum-name = "I2C_PORT_SENSOR"; label = "SENSOR"; - physical-port = <1>; }; i2c-accel { i2c-port = <&i2c1>; enum-name = "I2C_PORT_ACCEL"; label = "ACCEL"; - physical-port = <1>; }; ppc0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_PPC0"; label = "PPC0"; - physical-port = <2>; }; ppc1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_PPC1"; label = "PPC1"; - physical-port = <4>; }; usb-c0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_USB_C0"; label = "USB_C0"; - physical-port = <2>; }; usb-c1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_USB_C1"; label = "USB_C1"; - physical-port = <4>; }; usb-mux0 { i2c-port = <&i2c2>; enum-name = "I2C_PORT_USB_MUX0"; label = "USB_MUX0"; - physical-port = <2>; }; usb-mux1 { i2c-port = <&i2c4>; enum-name = "I2C_PORT_USB_MUX1"; label = "USB_MUX1"; - physical-port = <4>; }; }; diff --git a/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml b/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml index b1b7916f85..ba2cc7b172 100644 --- a/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml +++ b/zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml @@ -54,11 +54,3 @@ properties: description: Human readable string describing the device (used as device_get_binding() argument). - physical-port: - type: int - # TODO: Change the field to true once all boards' named-i2c-ports support - # this property. - required: false - description: - In the named-i2c-ports, it's a number indicated an i2c device - (eg. battery, charger, etc.) connected to which soc's i2c port. diff --git a/zephyr/shim/src/i2c.c b/zephyr/shim/src/i2c.c index e67ea78be9..68dd212b1d 100644 --- a/zephyr/shim/src/i2c.c +++ b/zephyr/shim/src/i2c.c @@ -5,6 +5,7 @@ #include <sys/util.h> +#include "console.h" #include "i2c.h" #include "i2c/i2c.h" @@ -25,9 +26,6 @@ #define INIT_REMOTE_PORTS(id) \ [I2C_PORT(id)] = DT_PROP_OR(id, remote_port, -1), -#define INIT_PHYSICAL_PORTS(id) \ - i2c_physical_ports[I2C_PORT(id)] = DT_PROP_OR(id, physical_port, -1); - #define I2C_PORT_INIT(id) \ { \ .name = DT_LABEL(id), \ @@ -57,7 +55,27 @@ static const struct device *i2c_devices[I2C_PORT_COUNT] = { static int init_device_bindings(const struct device *device) { ARG_UNUSED(device); - DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_PHYSICAL_PORTS) + + /* + * The EC application may lock the I2C bus for more than a single + * I2C transaction. Initialize the i2c_physical_ports[] array to map + * each named-i2c-ports child to the physical bus assignment. + * + * TODO(b/199918263): zephyr: Optimize I2C mutexes + * Modify the port_mutex[] array defined by i2c_controller.c + * so that only mutexes for unique physical ports are created to + * save space. + */ + i2c_physical_ports[0] = 0; + for (int child = 1; child < I2C_PORT_COUNT; child++) { + for (int phys_port = 0; phys_port < I2C_PORT_COUNT; + phys_port++) { + if (i2c_devices[child] == i2c_devices[phys_port]) { + i2c_physical_ports[child] = phys_port; + break; + } + } + } return 0; } SYS_INIT(init_device_bindings, POST_KERNEL, 51); @@ -91,3 +109,23 @@ int i2c_get_physical_port(int enum_port) */ return (i2c_port < I2C_PORT_COUNT) ? i2c_port : -1; } + +#ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP +static int command_i2c_portmap(int argc, char **argv) +{ + int i; + + ccprintf("Zephyr physical I2C ports (%d):\n", I2C_PORT_COUNT); + for (i = 0; i < I2C_PORT_COUNT; i++) { + ccprintf(" %d : %d\n", i, i2c_physical_ports[i]); + } + ccprintf("Zephyr remote I2C ports (%d):\n", I2C_PORT_COUNT); + for (i = 0; i < I2C_PORT_COUNT; i++) { + ccprintf(" %d : %d\n", i, i2c_remote_ports[i]); + } + + return EC_RES_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(i2c_portmap, command_i2c_portmap, NULL, + "Show I2C port mapping"); +#endif /* CONFIG_PLATFORM_EC_CONSOLE_CMD_I2C_PORTMAP */ |