u-boot/cmd/mux.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

184 lines
4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* List, select, and deselect mux controllers on the fly.
*
* Copyright (c) 2020 Texas Instruments Inc.
* Author: Pratyush Yadav <p.yadav@ti.com>
*/
#include <common.h>
#include <command.h>
#include <errno.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <mux.h>
#include <mux-internal.h>
#include <linux/err.h>
#include <dt-bindings/mux/mux.h>
#define COLUMN_SIZE 16
/*
* Print a member of a column. The total size of the text printed, including
* trailing whitespace, will always be COLUMN_SIZE.
*/
#define PRINT_COLUMN(fmt, args...) do { \
char buf[COLUMN_SIZE + 1]; \
snprintf(buf, COLUMN_SIZE + 1, fmt, ##args); \
printf("%-*s", COLUMN_SIZE, buf); \
} while (0)
/*
* Find a mux based on its device name in argv[1] and index in the chip in
* argv[2].
*/
static struct mux_control *cmd_mux_find(char *const argv[])
{
struct udevice *dev;
struct mux_chip *chip;
int ret;
unsigned long id;
ret = strict_strtoul(argv[2], 10, &id);
if (ret)
return ERR_PTR(ret);
ret = uclass_get_device_by_name(UCLASS_MUX, argv[1], &dev);
if (ret)
return ERR_PTR(ret);
chip = dev_get_uclass_priv(dev);
if (!chip)
return ERR_PTR(-EINVAL);
if (id >= chip->controllers)
return ERR_PTR(-EINVAL);
return &chip->mux[id];
}
/*
* Print the details of a mux. The columns printed correspond to: "Selected",
* "Current State", "Idle State", and "Num States".
*/
static void print_mux(struct mux_control *mux)
{
PRINT_COLUMN("%s", mux->in_use ? "yes" : "no");
if (mux->cached_state == MUX_IDLE_AS_IS)
PRINT_COLUMN("%s", "unknown");
else
PRINT_COLUMN("0x%x", mux->cached_state);
if (mux->idle_state == MUX_IDLE_AS_IS)
PRINT_COLUMN("%s", "as-is");
else if (mux->idle_state == MUX_IDLE_DISCONNECT)
PRINT_COLUMN("%s", "disconnect");
else
PRINT_COLUMN("0x%x", mux->idle_state);
PRINT_COLUMN("0x%x", mux->states);
printf("\n");
}
static int do_mux_list(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
struct udevice *dev;
struct mux_chip *chip;
int j;
for (uclass_first_device(UCLASS_MUX, &dev);
dev;
uclass_next_device(&dev)) {
chip = dev_get_uclass_priv(dev);
if (!chip) {
dev_err(dev, "can't find mux chip\n");
continue;
}
printf("%s:\n", dev->name);
printf(" ");
PRINT_COLUMN("ID");
PRINT_COLUMN("Selected");
PRINT_COLUMN("Current State");
PRINT_COLUMN("Idle State");
PRINT_COLUMN("Num States");
printf("\n");
for (j = 0; j < chip->controllers; j++) {
printf(" ");
PRINT_COLUMN("%d", j);
print_mux(&chip->mux[j]);
}
printf("\n");
}
return 0;
}
static int do_mux_select(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
struct mux_control *mux;
int ret;
unsigned long state;
if (argc != 4)
return CMD_RET_USAGE;
mux = cmd_mux_find(argv);
if (IS_ERR_OR_NULL(mux)) {
printf("Failed to find the specified mux\n");
return CMD_RET_FAILURE;
}
ret = strict_strtoul(argv[3], 16, &state);
if (ret) {
printf("Invalid state\n");
return CMD_RET_FAILURE;
}
ret = mux_control_select(mux, state);
if (ret) {
printf("Failed to select requested state\n");
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
static int do_mux_deselect(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
struct mux_control *mux;
int ret;
if (argc != 3)
return CMD_RET_USAGE;
mux = cmd_mux_find(argv);
if (IS_ERR_OR_NULL(mux)) {
printf("Failed to find the specified mux\n");
return CMD_RET_FAILURE;
}
ret = mux_control_deselect(mux);
if (ret) {
printf("Failed to deselect mux\n");
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
U_BOOT_LONGHELP(mux,
"list - List all Muxes and their states\n"
"select <chip> <id> <state> - Select the given mux state\n"
"deselect <chip> <id> - Deselect the given mux and reset it to its idle state");
U_BOOT_CMD_WITH_SUBCMDS(mux, "List, select, and deselect muxes", mux_help_text,
U_BOOT_SUBCMD_MKENT(list, 1, 1, do_mux_list),
U_BOOT_SUBCMD_MKENT(select, 4, 0, do_mux_select),
U_BOOT_SUBCMD_MKENT(deselect, 3, 0, do_mux_deselect));