"Das U-Boot" Source Tree
at master 183 lines 4.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * List, select, and deselect mux controllers on the fly. 4 * 5 * Copyright (c) 2020 Texas Instruments Inc. 6 * Author: Pratyush Yadav <p.yadav@ti.com> 7 */ 8 9#include <command.h> 10#include <errno.h> 11#include <dm.h> 12#include <dm/device_compat.h> 13#include <mux.h> 14#include <mux-internal.h> 15#include <linux/err.h> 16#include <dt-bindings/mux/mux.h> 17 18#define COLUMN_SIZE 16 19 20/* 21 * Print a member of a column. The total size of the text printed, including 22 * trailing whitespace, will always be COLUMN_SIZE. 23 */ 24#define PRINT_COLUMN(fmt, args...) do { \ 25 char buf[COLUMN_SIZE + 1]; \ 26 snprintf(buf, COLUMN_SIZE + 1, fmt, ##args); \ 27 printf("%-*s", COLUMN_SIZE, buf); \ 28} while (0) 29 30/* 31 * Find a mux based on its device name in argv[1] and index in the chip in 32 * argv[2]. 33 */ 34static struct mux_control *cmd_mux_find(char *const argv[]) 35{ 36 struct udevice *dev; 37 struct mux_chip *chip; 38 int ret; 39 unsigned long id; 40 41 ret = strict_strtoul(argv[2], 10, &id); 42 if (ret) 43 return ERR_PTR(ret); 44 45 ret = uclass_get_device_by_name(UCLASS_MUX, argv[1], &dev); 46 if (ret) 47 return ERR_PTR(ret); 48 49 chip = dev_get_uclass_priv(dev); 50 if (!chip) 51 return ERR_PTR(-EINVAL); 52 53 if (id >= chip->controllers) 54 return ERR_PTR(-EINVAL); 55 56 return &chip->mux[id]; 57} 58 59/* 60 * Print the details of a mux. The columns printed correspond to: "Selected", 61 * "Current State", "Idle State", and "Num States". 62 */ 63static void print_mux(struct mux_control *mux) 64{ 65 PRINT_COLUMN("%s", mux->in_use ? "yes" : "no"); 66 67 if (mux->cached_state == MUX_IDLE_AS_IS) 68 PRINT_COLUMN("%s", "unknown"); 69 else 70 PRINT_COLUMN("0x%x", mux->cached_state); 71 72 if (mux->idle_state == MUX_IDLE_AS_IS) 73 PRINT_COLUMN("%s", "as-is"); 74 else if (mux->idle_state == MUX_IDLE_DISCONNECT) 75 PRINT_COLUMN("%s", "disconnect"); 76 else 77 PRINT_COLUMN("0x%x", mux->idle_state); 78 79 PRINT_COLUMN("0x%x", mux->states); 80 81 printf("\n"); 82} 83 84static int do_mux_list(struct cmd_tbl *cmdtp, int flag, int argc, 85 char *const argv[]) 86{ 87 struct udevice *dev; 88 struct mux_chip *chip; 89 int j; 90 91 for (uclass_first_device(UCLASS_MUX, &dev); 92 dev; 93 uclass_next_device(&dev)) { 94 chip = dev_get_uclass_priv(dev); 95 if (!chip) { 96 dev_err(dev, "can't find mux chip\n"); 97 continue; 98 } 99 100 printf("%s:\n", dev->name); 101 102 printf(" "); 103 PRINT_COLUMN("ID"); 104 PRINT_COLUMN("Selected"); 105 PRINT_COLUMN("Current State"); 106 PRINT_COLUMN("Idle State"); 107 PRINT_COLUMN("Num States"); 108 printf("\n"); 109 for (j = 0; j < chip->controllers; j++) { 110 printf(" "); 111 PRINT_COLUMN("%d", j); 112 print_mux(&chip->mux[j]); 113 } 114 printf("\n"); 115 } 116 117 return 0; 118} 119 120static int do_mux_select(struct cmd_tbl *cmdtp, int flag, int argc, 121 char *const argv[]) 122{ 123 struct mux_control *mux; 124 int ret; 125 unsigned long state; 126 127 if (argc != 4) 128 return CMD_RET_USAGE; 129 130 mux = cmd_mux_find(argv); 131 if (IS_ERR_OR_NULL(mux)) { 132 printf("Failed to find the specified mux\n"); 133 return CMD_RET_FAILURE; 134 } 135 136 ret = strict_strtoul(argv[3], 16, &state); 137 if (ret) { 138 printf("Invalid state\n"); 139 return CMD_RET_FAILURE; 140 } 141 142 ret = mux_control_select(mux, state); 143 if (ret) { 144 printf("Failed to select requested state\n"); 145 return CMD_RET_FAILURE; 146 } 147 148 return CMD_RET_SUCCESS; 149} 150 151static int do_mux_deselect(struct cmd_tbl *cmdtp, int flag, int argc, 152 char *const argv[]) 153{ 154 struct mux_control *mux; 155 int ret; 156 157 if (argc != 3) 158 return CMD_RET_USAGE; 159 160 mux = cmd_mux_find(argv); 161 if (IS_ERR_OR_NULL(mux)) { 162 printf("Failed to find the specified mux\n"); 163 return CMD_RET_FAILURE; 164 } 165 166 ret = mux_control_deselect(mux); 167 if (ret) { 168 printf("Failed to deselect mux\n"); 169 return CMD_RET_FAILURE; 170 } 171 172 return CMD_RET_SUCCESS; 173} 174 175U_BOOT_LONGHELP(mux, 176 "list - List all Muxes and their states\n" 177 "select <chip> <id> <state> - Select the given mux state\n" 178 "deselect <chip> <id> - Deselect the given mux and reset it to its idle state"); 179 180U_BOOT_CMD_WITH_SUBCMDS(mux, "List, select, and deselect muxes", mux_help_text, 181 U_BOOT_SUBCMD_MKENT(list, 1, 1, do_mux_list), 182 U_BOOT_SUBCMD_MKENT(select, 4, 0, do_mux_select), 183 U_BOOT_SUBCMD_MKENT(deselect, 3, 0, do_mux_deselect));