summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2021-09-13 11:11:06 -0600
committerCommit Bot <commit-bot@chromium.org>2021-09-14 21:08:15 +0000
commitdfbeff4b5f6d8e078c7f69b1fe5050a4288a1d66 (patch)
treed288fc2e3a83d2e7918793584d7040918a37174e
parent17b10f589a23ab208222742f9864201a85512e00 (diff)
downloadchrome-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/Kconfig9
-rw-r--r--zephyr/boards/riscv/asurada/asurada.dts12
-rw-r--r--zephyr/dts/bindings/i2c/cros-ec-i2c-port-base.yaml8
-rw-r--r--zephyr/shim/src/i2c.c46
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 */