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 15 static struct udevice *currdev; 16 17 static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 18 { 19 const char *name; 20 int ret; 21 22 switch (argc) { 23 case 2: 24 name = argv[1]; 25 ret = uclass_get_device_by_name(UCLASS_PINCTRL, name, &currdev); 26 if (ret) { 27 printf("Can't get the pin-controller: %s!\n", name); 28 return CMD_RET_FAILURE; 29 } 30 /* fall through */ 31 case 1: 32 if (!currdev) { 33 printf("Pin-controller device is not set!\n"); 34 return CMD_RET_USAGE; 35 } 36 37 printf("dev: %s\n", currdev->name); 38 } 39 40 return CMD_RET_SUCCESS; 41 } 42 43 static int show_pinmux(struct udevice *dev) 44 { 45 char pin_name[PINNAME_SIZE]; 46 char pin_mux[PINMUX_SIZE]; 47 int pins_count; 48 int i; 49 int ret; 50 51 pins_count = pinctrl_get_pins_count(dev); 52 53 if (pins_count == -ENOSYS) { 54 printf("Ops get_pins_count not supported\n"); 55 return pins_count; 56 } 57 58 for (i = 0; i < pins_count; i++) { 59 ret = pinctrl_get_pin_name(dev, i, pin_name, PINNAME_SIZE); 60 if (ret == -ENOSYS) { 61 printf("Ops get_pin_name not supported\n"); 62 return ret; 63 } 64 65 ret = pinctrl_get_pin_muxing(dev, i, pin_mux, PINMUX_SIZE); 66 if (ret) { 67 printf("Ops get_pin_muxing error (%d)\n", ret); 68 return ret; 69 } 70 71 printf("%-*s: %-*s\n", PINNAME_SIZE, pin_name, 72 PINMUX_SIZE, pin_mux); 73 } 74 75 return 0; 76 } 77 78 static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 79 { 80 struct udevice *dev; 81 int ret = CMD_RET_USAGE; 82 83 if (currdev && (argc < 2 || strcmp(argv[1], "-a"))) 84 return show_pinmux(currdev); 85 86 if (argc < 2 || strcmp(argv[1], "-a")) 87 return ret; 88 89 uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { 90 /* insert a separator between each pin-controller display */ 91 printf("--------------------------\n"); 92 printf("%s:\n", dev->name); 93 ret = show_pinmux(dev); 94 if (ret < 0) 95 printf("Can't display pin muxing for %s\n", 96 dev->name); 97 } 98 99 return ret; 100 } 101 102 static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 103 { 104 struct udevice *dev; 105 106 printf("| %-*.*s| %-*.*s| %s\n", 107 LIMIT_DEVNAME, LIMIT_DEVNAME, "Device", 108 LIMIT_DEVNAME, LIMIT_DEVNAME, "Driver", 109 "Parent"); 110 111 uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { 112 printf("| %-*.*s| %-*.*s| %s\n", 113 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, 114 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->driver->name, 115 dev->parent->name); 116 } 117 118 return CMD_RET_SUCCESS; 119 } 120 121 static cmd_tbl_t pinmux_subcmd[] = { 122 U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""), 123 U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""), 124 U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""), 125 }; 126 127 static int do_pinmux(cmd_tbl_t *cmdtp, int flag, int argc, 128 char * const argv[]) 129 { 130 cmd_tbl_t *cmd; 131 132 argc--; 133 argv++; 134 135 cmd = find_cmd_tbl(argv[0], pinmux_subcmd, ARRAY_SIZE(pinmux_subcmd)); 136 if (!cmd || argc > cmd->maxargs) 137 return CMD_RET_USAGE; 138 139 return cmd->cmd(cmdtp, flag, argc, argv); 140 } 141 142 U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux, 143 "show pin-controller muxing", 144 "list - list UCLASS_PINCTRL devices\n" 145 "pinmux dev [pincontroller-name] - select pin-controller device\n" 146 "pinmux status [-a] - print pin-controller muxing [for all]\n" 147 ) 148