summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig147
-rw-r--r--cmd/Makefile10
-rw-r--r--cmd/bdinfo.c5
-rw-r--r--cmd/elf.c2
-rw-r--r--cmd/net-common.c109
-rw-r--r--cmd/net-lwip.c45
-rw-r--r--cmd/net.c115
-rw-r--r--cmd/tcpm.c136
8 files changed, 389 insertions, 180 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 37894eb80d6..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
@@ -1653,6 +1660,7 @@ config CMD_USB
config CMD_USB_SDP
bool "sdp"
+ depends on USB_GADGET_DOWNLOAD
select USB_FUNCTION_SDP
help
Enables the command "sdp" which is used to have U-Boot emulating the
@@ -1788,12 +1796,16 @@ config CMD_AB_SELECT
endmenu
-if NET
+if NET || NET_LWIP
menuconfig CMD_NET
bool "Network commands"
default y
+endif
+
+if NET
+
if CMD_NET
config CMD_BOOTP
@@ -1802,12 +1814,6 @@ config CMD_BOOTP
help
bootp - boot image via network using BOOTP/TFTP protocol
-config CMD_DHCP
- bool "dhcp"
- depends on CMD_BOOTP
- help
- Boot image via network using DHCP/TFTP protocol
-
config CMD_DHCP6
bool "dhcp6"
depends on IPV6
@@ -1951,12 +1957,6 @@ config BOOTP_VCI_STRING
default "U-Boot.arm" if ARM
default "U-Boot"
-config CMD_TFTPBOOT
- bool "tftpboot"
- default y
- help
- tftpboot - load file via network using TFTP protocol
-
config CMD_TFTPPUT
bool "tftp put"
depends on CMD_TFTPBOOT
@@ -2008,42 +2008,6 @@ config SYS_DISABLE_AUTOLOAD
is complete. Enable this option to disable this behavior and instead
require files to be loaded over the network by subsequent commands.
-config CMD_WGET
- bool "wget"
- select PROT_TCP
- default y if SANDBOX
- help
- wget is a simple command to download kernel, or other files,
- from a http server over TCP.
-
-config CMD_MII
- bool "mii"
- imply CMD_MDIO
- help
- If set, allows 802.3(clause 22) MII Management functions interface access
- The management interface specified in Clause 22 provides
- a simple, two signal, serial interface to connect a
- Station Management entity and a managed PHY for providing access
- to management parameters and services.
- The interface is referred to as the MII management interface.
-
-config MII_INIT
- bool "Call mii_init() in the mii command"
- depends on CMD_MII && (MPC8XX_FEC || FSLDMAFE || MCFFEC)
-
-config CMD_MDIO
- bool "mdio"
- depends on PHYLIB
- help
- If set, allows Enable 802.3(clause 45) MDIO interface registers access
- The MDIO interface is orthogonal to the MII interface and extends
- it by adding access to more registers through indirect addressing.
-
-config CMD_PING
- bool "ping"
- help
- Send ICMP ECHO_REQUEST to network host
-
config CMD_PING6
bool "ping6"
depends on IPV6
@@ -2062,11 +2026,6 @@ config CMD_SNTP
help
Synchronize RTC via network
-config CMD_DNS
- bool "dns"
- help
- Lookup the IP of a hostname
-
config CMD_LINK_LOCAL
bool "linklocal"
select LIB_RAND
@@ -2087,7 +2046,7 @@ config IPV6_ROUTER_DISCOVERY
help
Will automatically perform router solicitation on first IPv6
network operation
-endif
+endif # if CMD_NET
config CMD_ETHSW
bool "ethsw"
@@ -2097,6 +2056,77 @@ config CMD_ETHSW
operations such as enabling / disabling a port and
viewing/maintaining the filtering database (FDB)
+config CMD_WOL
+ bool "wol"
+ help
+ Wait for wake-on-lan Magic Packet
+
+endif # if NET
+
+if NET || NET_LWIP
+
+if CMD_NET
+
+config CMD_DHCP
+ bool "dhcp"
+ select PROT_DHCP_LWIP if NET_LWIP
+ help
+ Boot image via network using DHCP/TFTP protocol
+
+config CMD_DNS
+ bool "dns"
+ select PROT_DNS_LWIP if NET_LWIP
+ help
+ Lookup the IP of a hostname
+
+config CMD_MII
+ bool "mii"
+ imply CMD_MDIO
+ help
+ If set, allows 802.3(clause 22) MII Management functions interface access
+ The management interface specified in Clause 22 provides
+ a simple, two signal, serial interface to connect a
+ Station Management entity and a managed PHY for providing access
+ to management parameters and services.
+ The interface is referred to as the MII management interface.
+
+config MII_INIT
+ bool "Call mii_init() in the mii command"
+ depends on CMD_MII && (MPC8XX_FEC || FSLDMAFE || MCFFEC)
+
+config CMD_MDIO
+ bool "mdio"
+ depends on PHYLIB
+ help
+ If set, allows Enable 802.3(clause 45) MDIO interface registers access
+ The MDIO interface is orthogonal to the MII interface and extends
+ it by adding access to more registers through indirect addressing.
+
+config CMD_PING
+ bool "ping"
+ select PROT_RAW_LWIP if NET_LWIP
+ help
+ Send ICMP ECHO_REQUEST to network host
+
+config CMD_TFTPBOOT
+ bool "tftp"
+ select PROT_UDP_LWIP if NET_LWIP
+ default y
+ help
+ tftpboot - load file via network using TFTP protocol
+
+config CMD_WGET
+ bool "wget"
+ default y if SANDBOX
+ select PROT_TCP if NET
+ select PROT_TCP_LWIP if NET_LWIP
+ select PROT_DNS_LWIP if NET_LWIP
+ help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
+endif # if CMD_NET
+
config CMD_PXE
bool "pxe"
select PXE_UTILS
@@ -2104,12 +2134,7 @@ config CMD_PXE
help
Boot image via network using PXE protocol
-config CMD_WOL
- bool "wol"
- help
- Wait for wake-on-lan Magic Packet
-
-endif
+endif # if NET || NET_LWIP
menu "Misc commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index 21d376309b9..3c5bd56e912 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -127,7 +127,14 @@ obj-y += legacy-mtd-utils.o
endif
obj-$(CONFIG_CMD_MUX) += mux.o
obj-$(CONFIG_CMD_NAND) += nand.o
-obj-$(CONFIG_CMD_NET) += net.o
+ifdef CONFIG_CMD_NET
+obj-$(CONFIG_NET) += net.o
+obj-$(CONFIG_NET_LWIP) += net-lwip.o
+obj-$(filter y,$(CONFIG_CMD_NET) $(CONFIG_CMD_NET_LWIP)) += net-common.o
+lwip-includes := -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot
+CFLAGS_net-lwip.o := $(lwip-includes)
+CFLAGS_net-common.o := $(lwip-includes)
+endif
obj-$(CONFIG_ENV_SUPPORT) += nvedit.o
obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o
obj-$(CONFIG_CMD_ONENAND) += onenand.o
@@ -172,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/bdinfo.c b/cmd/bdinfo.c
index f6e534dd5bb..4c0e2adabc3 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -151,7 +151,7 @@ static int bdinfo_print_all(struct bd_info *bd)
bdinfo_print_num_l("relocaddr", gd->relocaddr);
bdinfo_print_num_l("reloc off", gd->reloc_off);
printf("%-12s= %u-bit\n", "Build", (uint)sizeof(void *) * 8);
- if (IS_ENABLED(CONFIG_CMD_NET))
+ if (IS_ENABLED(CONFIG_CMD_NET) || IS_ENABLED(CONFIG_CMD_NET_LWIP))
print_eth();
bdinfo_print_num_l("fdt_blob", (ulong)map_to_sysmem(gd->fdt_blob));
if (IS_ENABLED(CONFIG_VIDEO))
@@ -192,7 +192,8 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
case 'a':
return bdinfo_print_all(bd);
case 'e':
- if (!IS_ENABLED(CONFIG_CMD_NET))
+ if (!IS_ENABLED(CONFIG_CMD_NET) &&
+ !IS_ENABLED(CONFIG_CMD_NET_LWIP))
return CMD_RET_USAGE;
print_eth();
return CMD_RET_SUCCESS;
diff --git a/cmd/elf.c b/cmd/elf.c
index 114f2caf7fa..6b49c613703 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -133,7 +133,7 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
else
addr = hextoul(argv[1], NULL);
-#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_LWIP)
/*
* Check to see if we need to tftp the image ourselves
* before starting
diff --git a/cmd/net-common.c b/cmd/net-common.c
new file mode 100644
index 00000000000..1c9fb83b896
--- /dev/null
+++ b/cmd/net-common.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <command.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <net.h>
+#include <linux/compat.h>
+#include <linux/ethtool.h>
+
+static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ const struct udevice *current = eth_get_dev();
+ unsigned char env_enetaddr[ARP_HLEN];
+ const struct udevice *dev;
+ struct uclass *uc;
+
+ uclass_id_foreach_dev(UCLASS_ETH, dev, uc) {
+ eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
+ printf("eth%d : %s %pM %s\n", dev_seq(dev), dev->name, env_enetaddr,
+ current == dev ? "active" : "");
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int do_net_stats(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ int nstats, err, i, off;
+ struct udevice *dev;
+ u64 *values;
+ u8 *strings;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ err = uclass_get_device_by_name(UCLASS_ETH, argv[1], &dev);
+ if (err) {
+ printf("Could not find device %s\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+
+ if (!eth_get_ops(dev)->get_sset_count ||
+ !eth_get_ops(dev)->get_strings ||
+ !eth_get_ops(dev)->get_stats) {
+ printf("Driver does not implement stats dump!\n");
+ return CMD_RET_FAILURE;
+ }
+
+ nstats = eth_get_ops(dev)->get_sset_count(dev);
+ strings = kcalloc(nstats, ETH_GSTRING_LEN, GFP_KERNEL);
+ if (!strings)
+ return CMD_RET_FAILURE;
+
+ values = kcalloc(nstats, sizeof(u64), GFP_KERNEL);
+ if (!values)
+ goto err_free_strings;
+
+ eth_get_ops(dev)->get_strings(dev, strings);
+ eth_get_ops(dev)->get_stats(dev, values);
+
+ off = 0;
+ for (i = 0; i < nstats; i++) {
+ printf(" %s: %llu\n", &strings[off], values[i]);
+ off += ETH_GSTRING_LEN;
+ };
+
+ kfree(strings);
+ kfree(values);
+
+ return CMD_RET_SUCCESS;
+
+err_free_strings:
+ kfree(strings);
+
+ return CMD_RET_FAILURE;
+}
+
+static struct cmd_tbl cmd_net[] = {
+ U_BOOT_CMD_MKENT(list, 1, 0, do_net_list, "", ""),
+ U_BOOT_CMD_MKENT(stats, 2, 0, do_net_stats, "", ""),
+};
+
+static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ struct cmd_tbl *cp;
+
+ cp = find_cmd_tbl(argv[1], cmd_net, ARRAY_SIZE(cmd_net));
+
+ /* Drop the net command */
+ argc--;
+ argv++;
+
+ if (!cp || argc > cp->maxargs)
+ return CMD_RET_USAGE;
+ if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
+ return CMD_RET_SUCCESS;
+
+ return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+ net, 3, 1, do_net,
+ "NET sub-system",
+ "list - list available devices\n"
+ "stats <device> - dump statistics for specified device\n"
+);
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c
new file mode 100644
index 00000000000..42f8bd6b259
--- /dev/null
+++ b/cmd/net-lwip.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2024 Linaro Ltd. */
+
+#include <command.h>
+#include <net.h>
+
+#if defined(CONFIG_CMD_DHCP)
+U_BOOT_CMD(
+ dhcp, 3, 1, do_dhcp,
+ "boot image via network using DHCP/TFTP protocol",
+ "[loadAddress] [[hostIPaddr:]bootfilename]"
+);
+#endif
+
+#if defined(CONFIG_CMD_PING)
+U_BOOT_CMD(
+ ping, 2, 1, do_ping,
+ "send ICMP ECHO_REQUEST to network host",
+ "pingAddress"
+);
+#endif
+
+#if defined(CONFIG_CMD_TFTPBOOT)
+U_BOOT_CMD(
+ tftpboot, 3, 0, do_tftpb,
+ "boot image via network using TFTP protocol\n",
+ "[loadAddress] [[hostIPaddr:]bootfilename]"
+);
+#endif
+
+#if defined(CONFIG_CMD_DNS)
+U_BOOT_CMD(
+ dns, 3, 1, do_dns,
+ "lookup the IP of a hostname",
+ "hostname [envvar]"
+);
+#endif
+
+#if defined(CONFIG_CMD_WGET)
+U_BOOT_CMD(
+ wget, 3, 1, do_wget,
+ "boot image via network using HTTP protocol",
+ "[loadAddress] URL"
+);
+#endif
diff --git a/cmd/net.c b/cmd/net.c
index 53ce2bc5d0c..c90578e1b9f 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -674,118 +674,3 @@ U_BOOT_CMD(
);
#endif /* CONFIG_CMD_LINK_LOCAL */
-
-static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- const struct udevice *current = eth_get_dev();
- unsigned char env_enetaddr[ARP_HLEN];
- const struct udevice *dev;
- struct uclass *uc;
-
- uclass_id_foreach_dev(UCLASS_ETH, dev, uc) {
- eth_env_get_enetaddr_by_index("eth", dev_seq(dev), env_enetaddr);
- printf("eth%d : %s %pM %s\n", dev_seq(dev), dev->name, env_enetaddr,
- current == dev ? "active" : "");
- }
- return CMD_RET_SUCCESS;
-}
-
-static int do_net_stats(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- int nstats, err, i, off;
- struct udevice *dev;
- u64 *values;
- u8 *strings;
-
- if (argc < 2)
- return CMD_RET_USAGE;
-
- err = uclass_get_device_by_name(UCLASS_ETH, argv[1], &dev);
- if (err) {
- printf("Could not find device %s\n", argv[1]);
- return CMD_RET_FAILURE;
- }
-
- if (!eth_get_ops(dev)->get_sset_count ||
- !eth_get_ops(dev)->get_strings ||
- !eth_get_ops(dev)->get_stats) {
- printf("Driver does not implement stats dump!\n");
- return CMD_RET_FAILURE;
- }
-
- nstats = eth_get_ops(dev)->get_sset_count(dev);
- strings = kcalloc(nstats, ETH_GSTRING_LEN, GFP_KERNEL);
- if (!strings)
- return CMD_RET_FAILURE;
-
- values = kcalloc(nstats, sizeof(u64), GFP_KERNEL);
- if (!values)
- goto err_free_strings;
-
- eth_get_ops(dev)->get_strings(dev, strings);
- eth_get_ops(dev)->get_stats(dev, values);
-
- off = 0;
- for (i = 0; i < nstats; i++) {
- printf(" %s: %llu\n", &strings[off], values[i]);
- off += ETH_GSTRING_LEN;
- };
-
- return CMD_RET_SUCCESS;
-
-err_free_strings:
- kfree(strings);
-
- return CMD_RET_FAILURE;
-}
-
-static struct cmd_tbl cmd_net[] = {
- U_BOOT_CMD_MKENT(list, 1, 0, do_net_list, "", ""),
- U_BOOT_CMD_MKENT(stats, 2, 0, do_net_stats, "", ""),
-};
-
-static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- struct cmd_tbl *cp;
-
- cp = find_cmd_tbl(argv[1], cmd_net, ARRAY_SIZE(cmd_net));
-
- /* Drop the net command */
- argc--;
- argv++;
-
- if (!cp || argc > cp->maxargs)
- return CMD_RET_USAGE;
- if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
- return CMD_RET_SUCCESS;
-
- return cp->cmd(cmdtp, flag, argc, argv);
-}
-
-U_BOOT_CMD(
- net, 3, 1, do_net,
- "NET sub-system",
- "list - list available devices\n"
- "stats <device> - dump statistics for specified device\n"
-);
-
-#if defined(CONFIG_CMD_NCSI)
-static int do_ncsi(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
-{
- if (!phy_interface_is_ncsi() || !ncsi_active()) {
- printf("Device not configured for NC-SI\n");
- return CMD_RET_FAILURE;
- }
-
- if (net_loop(NCSI) < 0)
- return CMD_RET_FAILURE;
-
- return CMD_RET_SUCCESS;
-}
-
-U_BOOT_CMD(
- ncsi, 1, 1, do_ncsi,
- "Configure attached NIC via NC-SI",
- ""
-);
-#endif /* CONFIG_CMD_NCSI */
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"
+);