diff --git a/drivers/mdio/CMakeLists.txt b/drivers/mdio/CMakeLists.txt index e906cfb69a7..5e1718cc8f2 100644 --- a/drivers/mdio/CMakeLists.txt +++ b/drivers/mdio/CMakeLists.txt @@ -2,4 +2,5 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_MDIO_ATMEL_SAM mdio_sam.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_SHELL mdio_shell.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_ATMEL_SAM mdio_sam.c) diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig index 23c2e819b2c..b38ac8270d7 100644 --- a/drivers/mdio/Kconfig +++ b/drivers/mdio/Kconfig @@ -13,6 +13,16 @@ menuconfig MDIO if MDIO +config MDIO_SHELL + bool "Enable MDIO Shell" + default y + depends on SHELL + help + Enable MDIO Shell. + + The MDIO shell currently supports scanning and device + read/write. + # Include these first so that any properties (e.g. defaults) below can be # overridden (by defining symbols in multiple locations) source "drivers/mdio/Kconfig.sam" diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c new file mode 100644 index 00000000000..5dfb4fb12fe --- /dev/null +++ b/drivers/mdio/mdio_shell.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 IP-Logix Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mdio_shell, CONFIG_LOG_DEFAULT_LEVEL); + +#define MDIO_DEVICE "MDIO" + +/* + * Scan the entire 5-bit address space of the MDIO bus + * + * scan [] + */ +static int cmd_mdio_scan(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + int cnt; + uint16_t data; + uint16_t dev_addr; + + dev = device_get_binding(MDIO_DEVICE); + if (!dev) { + shell_error(sh, "MDIO: Device driver %s not found.", + MDIO_DEVICE); + + return -ENODEV; + } + + if (argc >= 2) { + dev_addr = strtol(argv[1], NULL, 16); + } else { + dev_addr = 0; + } + + shell_print(sh, + "Scanning bus for devices. Reading register 0x%x", + dev_addr); + cnt = 0; + + mdio_bus_enable(dev); + + for (int i = 0; i < 32; i++) { + data = 0; + if (mdio_read(dev, i, dev_addr, &data) >= 0 && + data != UINT16_MAX) { + cnt++; + shell_print(sh, "Found MDIO device @ 0x%x", i); + } + } + + mdio_bus_disable(dev); + + shell_print(sh, "%u devices found on %s", cnt, MDIO_DEVICE); + + return 0; +} + +/* mdio write */ +static int cmd_mdio_write(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + uint16_t data; + uint16_t dev_addr; + uint16_t port_addr; + + dev = device_get_binding(MDIO_DEVICE); + if (!dev) { + shell_error(sh, "MDIO: Device driver %s not found.", + MDIO_DEVICE); + + return -ENODEV; + } + + port_addr = strtol(argv[1], NULL, 16); + dev_addr = strtol(argv[2], NULL, 16); + data = strtol(argv[3], NULL, 16); + + mdio_bus_enable(dev); + + if (mdio_write(dev, port_addr, dev_addr, data) < 0) { + shell_error(sh, "Failed to write to device: %s", MDIO_DEVICE); + mdio_bus_disable(dev); + + return -EIO; + } + + mdio_bus_disable(dev); + + return 0; +} + +/* mdio read */ +static int cmd_mdio_read(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + uint16_t data; + uint16_t dev_addr; + uint16_t port_addr; + + dev = device_get_binding(MDIO_DEVICE); + if (!dev) { + shell_error(sh, "MDIO: Device driver %s not found.", + MDIO_DEVICE); + + return -ENODEV; + } + + port_addr = strtol(argv[1], NULL, 16); + dev_addr = strtol(argv[2], NULL, 16); + + mdio_bus_enable(dev); + + if (mdio_read(dev, port_addr, dev_addr, &data) < 0) { + shell_error(sh, "Failed to read from device: %s", MDIO_DEVICE); + mdio_bus_disable(dev); + + return -EIO; + } + + mdio_bus_disable(dev); + + shell_print(sh, "%x[%x]: 0x%x", port_addr, dev_addr, data); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_mdio_cmds, + SHELL_CMD_ARG(scan, NULL, + "Scan MDIO bus for devices: scan []", + cmd_mdio_scan, 0, 1), + SHELL_CMD_ARG(read, NULL, + "Read from MDIO device: read ", + cmd_mdio_read, 3, 0), + SHELL_CMD_ARG(write, NULL, + "Write to MDIO device: write ", + cmd_mdio_write, 4, 0), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); + +SHELL_CMD_REGISTER(mdio, &sub_mdio_cmds, "MDIO commands", NULL);