1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 4 */ 5 6#include <common.h> 7#include <command.h> 8#include <dm.h> 9#include <errno.h> 10#include <dm/pinctrl.h> 11#include <dm/uclass-internal.h> 12 13#define LIMIT_DEVNAME 30 14 15static struct udevice *currdev; 16 17static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc, 18 char *const argv[]) 19{ 20 const char *name; 21 int ret; 22 23 switch (argc) { 24 case 2: 25 name = argv[1]; 26 ret = uclass_get_device_by_name(UCLASS_PINCTRL, name, &currdev); 27 if (ret) { 28 printf("Can't get the pin-controller: %s!\n", name); 29 return CMD_RET_FAILURE; 30 } 31 /* fall through */ 32 case 1: 33 if (!currdev) { 34 printf("Pin-controller device is not set!\n"); 35 return CMD_RET_USAGE; 36 } 37 38 printf("dev: %s\n", currdev->name); 39 } 40 41 return CMD_RET_SUCCESS; 42} 43 44/** 45 * Print the muxing information for one or all pins of one pinctrl device 46 * 47 * @param dev pinctrl device 48 * @param name NULL to display all the pins 49 * or name of the pin to display 50 * Return: 0 on success, non-0 on error 51 */ 52static int show_pinmux(struct udevice *dev, char *name) 53{ 54 char pin_name[PINNAME_SIZE]; 55 char pin_mux[PINMUX_SIZE]; 56 int pins_count; 57 int i; 58 int ret; 59 bool found = false; 60 61 pins_count = pinctrl_get_pins_count(dev); 62 63 if (pins_count == -ENOSYS) { 64 printf("Ops get_pins_count not supported by %s\n", dev->name); 65 return pins_count; 66 } 67 68 for (i = 0; i < pins_count; i++) { 69 ret = pinctrl_get_pin_name(dev, i, pin_name, PINNAME_SIZE); 70 if (ret) { 71 printf("Ops get_pin_name error (%d) by %s\n", ret, dev->name); 72 return ret; 73 } 74 if (name && strcmp(name, pin_name)) 75 continue; 76 found = true; 77 ret = pinctrl_get_pin_muxing(dev, i, pin_mux, PINMUX_SIZE); 78 if (ret) { 79 printf("Ops get_pin_muxing error (%d) by %s in %s\n", 80 ret, pin_name, dev->name); 81 return ret; 82 } 83 84 printf("%-*s: %-*s\n", PINNAME_SIZE, pin_name, 85 PINMUX_SIZE, pin_mux); 86 } 87 88 if (!found) 89 return -ENOENT; 90 91 return 0; 92} 93 94static int do_status(struct cmd_tbl *cmdtp, int flag, int argc, 95 char *const argv[]) 96{ 97 struct udevice *dev; 98 char *name; 99 int ret; 100 101 if (argc < 2) { 102 if (!currdev) { 103 printf("pin-controller device not selected\n"); 104 return CMD_RET_FAILURE; 105 } 106 show_pinmux(currdev, NULL); 107 return CMD_RET_SUCCESS; 108 } 109 110 if (strcmp(argv[1], "-a")) 111 name = argv[1]; 112 else 113 name = NULL; 114 115 uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { 116 if (!name) { 117 /* insert a separator between each pin-controller display */ 118 printf("--------------------------\n"); 119 printf("%s:\n", dev->name); 120 } 121 ret = show_pinmux(dev, name); 122 /* stop when the status of requested pin is displayed */ 123 if (name && !ret) 124 return CMD_RET_SUCCESS; 125 } 126 127 if (name) { 128 printf("%s not found\n", name); 129 return CMD_RET_FAILURE; 130 } 131 132 return CMD_RET_SUCCESS; 133} 134 135static int do_list(struct cmd_tbl *cmdtp, int flag, int argc, 136 char *const argv[]) 137{ 138 struct udevice *dev; 139 140 printf("| %-*.*s| %-*.*s| %s\n", 141 LIMIT_DEVNAME, LIMIT_DEVNAME, "Device", 142 LIMIT_DEVNAME, LIMIT_DEVNAME, "Driver", 143 "Parent"); 144 145 uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { 146 printf("| %-*.*s| %-*.*s| %s\n", 147 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, 148 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->driver->name, 149 dev->parent->name); 150 } 151 152 return CMD_RET_SUCCESS; 153} 154 155static struct cmd_tbl pinmux_subcmd[] = { 156 U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""), 157 U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""), 158 U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""), 159}; 160 161static int do_pinmux(struct cmd_tbl *cmdtp, int flag, int argc, 162 char *const argv[]) 163{ 164 struct cmd_tbl *cmd; 165 166 argc--; 167 argv++; 168 169 cmd = find_cmd_tbl(argv[0], pinmux_subcmd, ARRAY_SIZE(pinmux_subcmd)); 170 if (!cmd || argc > cmd->maxargs) 171 return CMD_RET_USAGE; 172 173 return cmd->cmd(cmdtp, flag, argc, argv); 174} 175 176U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux, 177 "show pin-controller muxing", 178 "list - list UCLASS_PINCTRL devices\n" 179 "pinmux dev [pincontroller-name] - select pin-controller device\n" 180 "pinmux status [-a | pin-name] - print pin-controller muxing [for all | for pin-name]\n" 181); 182