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