Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | // 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)); |