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        int (*misc_op)(struct udevice *, int, void *, int);
  48        struct udevice *dev;
  49        int offset;
  50        void *buf;
  51        int size;
  52        int ret;
  53
  54        ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev);
  55        if (ret) {
  56                printf("Unable to find device %s\n", argv[0]);
  57                return ret;
  58        }
  59
  60        offset = hextoul(argv[1], NULL);
  61        buf = (void *)hextoul(argv[2], NULL);
  62        size = hextoul(argv[3], NULL);
  63
  64        if (op == MISC_OP_READ)
  65                misc_op = misc_read;
  66        else
  67                misc_op = misc_write;
  68
  69        ret = misc_op(dev, offset, buf, size);
  70        if (ret < 0) {
  71                if (ret == -ENOSYS) {
  72                        printf("The device does not support %s\n",
  73                               misc_op_str[op]);
  74                        ret = 0;
  75                }
  76        } else {
  77                if (ret == size)
  78                        ret = 0;
  79                else
  80                        printf("Partially %s %d bytes\n", misc_op_str[op], ret);
  81        }
  82
  83        return ret;
  84}
  85
  86static int do_misc_read(struct cmd_tbl *cmdtp, int flag,
  87                        int argc, char *const argv[])
  88{
  89        return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ);
  90}
  91
  92static int do_misc_write(struct cmd_tbl *cmdtp, int flag,
  93                         int argc, char *const argv[])
  94{
  95        return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE);
  96}
  97
  98static struct cmd_tbl misc_commands[] = {
  99        U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""),
 100        U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""),
 101        U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""),
 102};
 103
 104static int do_misc(struct cmd_tbl *cmdtp, int flag,
 105                   int argc, char *const argv[])
 106{
 107        struct cmd_tbl *misc_cmd;
 108        int ret;
 109
 110        if (argc < 2)
 111                return CMD_RET_USAGE;
 112        misc_cmd = find_cmd_tbl(argv[1], misc_commands,
 113                                ARRAY_SIZE(misc_commands));
 114        argc -= 2;
 115        argv += 2;
 116        if (!misc_cmd || argc != misc_cmd->maxargs)
 117                return CMD_RET_USAGE;
 118
 119        ret = misc_cmd->cmd(misc_cmd, flag, argc, argv);
 120
 121        return cmd_process_error(misc_cmd, ret);
 122}
 123
 124U_BOOT_CMD(
 125        misc,   6,      1,      do_misc,
 126        "Access miscellaneous devices with MISC uclass driver APIs",
 127        "list                       - list all miscellaneous devices\n"
 128        "misc read  name offset addr len - read `len' bytes starting at\n"
 129        "                                 `offset' of device `name'\n"
 130        "                                 to memory at `addr'\n"
 131        "misc write name offset addr len - write `len' bytes starting at\n"
 132        "                                 `offset' of device `name'\n"
 133        "                                 from memory at `addr'"
 134);
 135