// 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 <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));
