// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2020 Wind River Systems, Inc.
 *
 * Author:
 *   Bin Meng <bin.meng@windriver.com>
 *
 * A command interface to access misc devices with MISC uclass driver APIs.
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <errno.h>
#include <misc.h>

enum misc_op {
	MISC_OP_READ,
	MISC_OP_WRITE
};

static char *misc_op_str[] = {
	"read",
	"write"
};

static int do_misc_list(struct cmd_tbl *cmdtp, int flag,
			int argc, char *const argv[])
{
	struct udevice *dev;

	printf("Device               Index     Driver\n");
	printf("-------------------------------------\n");
	for (uclass_first_device(UCLASS_MISC, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		printf("%-20s %5d %10s\n", dev->name, dev->seq,
		       dev->driver->name);
	}

	return 0;
}

static int do_misc_op(struct cmd_tbl *cmdtp, int flag,
		      int argc, char *const argv[], enum misc_op op)
{
	int (*misc_op)(struct udevice *, int, void *, int);
	struct udevice *dev;
	int offset;
	void *buf;
	int size;
	int ret;

	ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev);
	if (ret) {
		printf("Unable to find device %s\n", argv[0]);
		return ret;
	}

	offset = simple_strtoul(argv[1], NULL, 16);
	buf = (void *)simple_strtoul(argv[2], NULL, 16);
	size = simple_strtoul(argv[3], NULL, 16);

	if (op == MISC_OP_READ)
		misc_op = misc_read;
	else
		misc_op = misc_write;

	ret = misc_op(dev, offset, buf, size);
	if (ret < 0) {
		if (ret == -ENOSYS) {
			printf("The device does not support %s\n",
			       misc_op_str[op]);
			ret = 0;
		}
	} else {
		if (ret == size)
			ret = 0;
		else
			printf("Partially %s %d bytes\n", misc_op_str[op], ret);
	}

	return ret;
}

static int do_misc_read(struct cmd_tbl *cmdtp, int flag,
			int argc, char *const argv[])
{
	return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ);
}

static int do_misc_write(struct cmd_tbl *cmdtp, int flag,
			 int argc, char *const argv[])
{
	return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE);
}

static struct cmd_tbl misc_commands[] = {
	U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""),
	U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""),
	U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""),
};

static int do_misc(struct cmd_tbl *cmdtp, int flag,
		   int argc, char *const argv[])
{
	struct cmd_tbl *misc_cmd;
	int ret;

	if (argc < 2)
		return CMD_RET_USAGE;
	misc_cmd = find_cmd_tbl(argv[1], misc_commands,
				ARRAY_SIZE(misc_commands));
	argc -= 2;
	argv += 2;
	if (!misc_cmd || argc != misc_cmd->maxargs)
		return CMD_RET_USAGE;

	ret = misc_cmd->cmd(misc_cmd, flag, argc, argv);

	return cmd_process_error(misc_cmd, ret);
}

U_BOOT_CMD(
	misc,	6,	1,	do_misc,
	"Access miscellaneous devices with MISC uclass driver APIs",
	"list                       - list all miscellaneous devices\n"
	"misc read  name offset addr len - read `len' bytes starting at\n"
	"				  `offset' of device `name'\n"
	"				  to memory at `addr'\n"
	"misc write name offset addr len - write `len' bytes starting at\n"
	"				  `offset' of device `name'\n"
	"				  from memory at `addr'"
);
