uboot/cmd/misc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2020 Wind River Systems, Inc.
   4 *
   5 * Author:
   6 *   Bin Meng <bin.meng@windriver.com>
   7 *
   8 * A command interface to access misc devices with MISC uclass driver APIs.
   9 */
  10
  11#include <common.h>
  12#include <command.h>
  13#include <dm.h>
  14#include <errno.h>
  15#include <misc.h>
  16
  17enum misc_op {
  18        MISC_OP_READ,
  19        MISC_OP_WRITE
  20};
  21
  22static char *misc_op_str[] = {
  23        "read",
  24        "write"
  25};
  26
  27static int do_misc_list(struct cmd_tbl *cmdtp, int flag,
  28                        int argc, char *const argv[])
  29{
  30        struct udevice *dev;
  31
  32        printf("Device               Index     Driver\n");
  33        printf("-------------------------------------\n");
  34        for (uclass_first_device(UCLASS_MISC, &dev);
  35             dev;
  36             uclass_next_device(&dev)) {
  37                printf("%-20s %5d %10s\n", dev->name, dev_seq(dev),
  38                       dev->driver->name);
  39        }
  40
  41        return 0;
  42}
  43
  44static int do_misc_op(struct cmd_tbl *cmdtp, int flag,
  45                      int argc, char *const argv[], enum misc_op op)
  46{
  47        struct udevice *dev;
  48        int offset;
  49        void *buf;
  50        int size;
  51        int ret;
  52
  53        ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev);
  54        if (ret) {
  55                printf("Unable to find device %s\n", argv[0]);
  56                return ret;
  57        }
  58
  59        offset = hextoul(argv[1], NULL);
  60        buf = (void *)hextoul(argv[2], NULL);
  61        size = hextoul(argv[3], NULL);
  62
  63        if (op == MISC_OP_READ)
  64                ret = misc_read(dev, offset, buf, size);
  65        else
  66                ret = misc_write(dev, offset, buf, size);
  67
  68        if (ret < 0) {
  69                if (ret == -ENOSYS) {
  70                        printf("The device does not support %s\n",
  71                               misc_op_str[op]);
  72                        ret = 0;
  73                }
  74        } else {
  75                if (ret == size)
  76                        ret = 0;
  77                else
  78                        printf("Partially %s %d bytes\n", misc_op_str[op], ret);
  79        }
  80
  81        return ret;
  82}
  83
  84static int do_misc_read(struct cmd_tbl *cmdtp, int flag,
  85                        int argc, char *const argv[])
  86{
  87        return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ);
  88}
  89
  90static int do_misc_write(struct cmd_tbl *cmdtp, int flag,
  91                         int argc, char *const argv[])
  92{
  93        return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE);
  94}
  95
  96static struct cmd_tbl misc_commands[] = {
  97        U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""),
  98        U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""),
  99        U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""),
 100};
 101
 102static int do_misc(struct cmd_tbl *cmdtp, int flag,
 103                   int argc, char *const argv[])
 104{
 105        struct cmd_tbl *misc_cmd;
 106        int ret;
 107
 108        if (argc < 2)
 109                return CMD_RET_USAGE;
 110        misc_cmd = find_cmd_tbl(argv[1], misc_commands,
 111                                ARRAY_SIZE(misc_commands));
 112        argc -= 2;
 113        argv += 2;
 114        if (!misc_cmd || argc != misc_cmd->maxargs)
 115                return CMD_RET_USAGE;
 116
 117        ret = misc_cmd->cmd(misc_cmd, flag, argc, argv);
 118
 119        return cmd_process_error(misc_cmd, ret);
 120}
 121
 122U_BOOT_CMD(
 123        misc,   6,      1,      do_misc,
 124        "Access miscellaneous devices with MISC uclass driver APIs",
 125        "list                       - list all miscellaneous devices\n"
 126        "misc read  name offset addr len - read `len' bytes starting at\n"
 127        "                                 `offset' of device `name'\n"
 128        "                                 to memory at `addr'\n"
 129        "misc write name offset addr len - write `len' bytes starting at\n"
 130        "                                 `offset' of device `name'\n"
 131        "                                 from memory at `addr'"
 132);
 133