summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2024-10-16 21:45:21 -0600
committerTom Rini <[email protected]>2024-10-16 21:45:21 -0600
commit9e1cd2f2cb86865bbc002ed961a095c7a8bcc989 (patch)
tree276fd4061b5e58a4bfc692c2ac6412efc4c891fa /cmd
parent98a36deb9ab7aaea70b0b0db47718100e08cf3e8 (diff)
parent6852a2c82e695c418c744b0fcb4298bc0e759842 (diff)
Merge https://source.denx.de/u-boot/custodians/u-boot-usb
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig7
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/tcpm.c136
3 files changed, 144 insertions, 0 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 8c677b1e486..bff22b94de2 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -221,6 +221,13 @@ config CMD_REGINFO
help
Register dump
+config CMD_TCPM
+ bool "tcpm"
+ depends on TYPEC_TCPM
+ help
+ Show voltage and current negotiated via USB PD as well as the
+ current state of the Type C Port Manager (TCPM) state machine.
+
config CMD_TLV_EEPROM
bool "tlv_eeprom"
depends on I2C_EEPROM
diff --git a/cmd/Makefile b/cmd/Makefile
index f3091405372..3c5bd56e912 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -179,6 +179,7 @@ obj-$(CONFIG_CMD_SMBIOS) += smbios.o
obj-$(CONFIG_CMD_SMC) += smccc.o
obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o
obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o
+obj-$(CONFIG_CMD_TCPM) += tcpm.o
obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o
obj-$(CONFIG_CMD_TERMINAL) += terminal.o
obj-$(CONFIG_CMD_TIME) += time.o
diff --git a/cmd/tcpm.c b/cmd/tcpm.c
new file mode 100644
index 00000000000..39578f6ccc0
--- /dev/null
+++ b/cmd/tcpm.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2024 Collabora
+ */
+
+#include <command.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <usb/tcpm.h>
+
+#define LIMIT_DEV 32
+#define LIMIT_PARENT 20
+
+static struct udevice *currdev;
+
+static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ int devnum, ret;
+
+ switch (argc) {
+ case 2:
+ devnum = (int)dectoul(argv[1], NULL);
+ ret = tcpm_get(devnum, &currdev);
+ if (ret) {
+ log_err("Can't get TCPM %d: %d (%s)!\n", devnum, ret, errno_str(ret));
+ return CMD_RET_FAILURE;
+ }
+ case 1:
+ if (!currdev) {
+ log_err("TCPM device is not set!\n\n");
+ return CMD_RET_USAGE;
+ }
+
+ printf("dev: %d @ %s\n", dev_seq(currdev), currdev->name);
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_list(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ int ret, err = 0;
+
+ printf("| ID | %-*.*s| %-*.*s| %s @ %s\n",
+ LIMIT_DEV, LIMIT_DEV, "Name",
+ LIMIT_PARENT, LIMIT_PARENT, "Parent name",
+ "Parent uclass", "seq");
+
+ for (ret = uclass_first_device_check(UCLASS_TCPM, &dev); dev;
+ ret = uclass_next_device_check(&dev)) {
+ if (ret)
+ err = ret;
+
+ printf("| %2d | %-*.*s| %-*.*s| %s @ %d | status: %i\n",
+ dev_seq(dev),
+ LIMIT_DEV, LIMIT_DEV, dev->name,
+ LIMIT_PARENT, LIMIT_PARENT, dev->parent->name,
+ dev_get_uclass_name(dev->parent), dev_seq(dev->parent),
+ ret);
+ }
+
+ if (err)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
+
+int do_print_info(struct udevice *dev)
+{
+ enum typec_orientation orientation = tcpm_get_orientation(dev);
+ const char *state = tcpm_get_state(dev);
+ int pd_rev = tcpm_get_pd_rev(dev);
+ int mv = tcpm_get_voltage(dev);
+ int ma = tcpm_get_current(dev);
+ enum typec_role pwr_role = tcpm_get_pwr_role(dev);
+ enum typec_data_role data_role = tcpm_get_data_role(dev);
+ bool connected = tcpm_is_connected(dev);
+
+ if (!connected) {
+ printf("TCPM State: %s\n", state);
+ return 0;
+ }
+
+ printf("Orientation: %s\n", typec_orientation_name[orientation]);
+ printf("PD Revision: %s\n", typec_pd_rev_name[pd_rev]);
+ printf("Power Role: %s\n", typec_role_name[pwr_role]);
+ printf("Data Role: %s\n", typec_data_role_name[data_role]);
+ printf("Voltage: %2d.%03d V\n", mv / 1000, mv % 1000);
+ printf("Current: %2d.%03d A\n", ma / 1000, ma % 1000);
+
+ return 0;
+}
+
+static int do_info(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (!currdev) {
+ printf("First, set the TCPM device!\n");
+ return CMD_RET_USAGE;
+ }
+
+ return do_print_info(currdev);
+}
+
+static struct cmd_tbl subcmd[] = {
+ U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
+ U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
+ U_BOOT_CMD_MKENT(info, 1, 1, do_info, "", ""),
+};
+
+static int do_tcpm(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct cmd_tbl *cmd;
+
+ argc--;
+ argv++;
+
+ cmd = find_cmd_tbl(argv[0], subcmd, ARRAY_SIZE(subcmd));
+ if (!cmd || argc > cmd->maxargs)
+ return CMD_RET_USAGE;
+
+ return cmd->cmd(cmdtp, flag, argc, argv);
+}
+
+ /**************************************************/
+
+U_BOOT_CMD(tcpm, CONFIG_SYS_MAXARGS, 1, do_tcpm,
+ "TCPM sub-system",
+ "list - list TCPM devices\n"
+ "tcpm dev [ID] - show or [set] operating TCPM device\n"
+ "tcpm info - dump information\n"
+);