Commit d5a8313905f54ebdf128ac428c3cf58a2ebcbda2
Committed by
Tom Rini
1 parent
37b596ac5c
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
cmd: pinmux: Add pinmux command
pinmux command allows to : - list all pin-controllers available on platforms - select a pin-controller - display the muxing of all pins of the current pin-controller or all pin-controllers depending of given options Signed-off-by: Patrice Chotard <patrice.chotard@st.com> cmd: pinmux: Fix pinmux command if "pinmux status" command is used without having set dev using "pinmux dev", print pinmux usage Reviewed-by: Simon Glass <sjg@chromium.org>
Showing 4 changed files with 158 additions and 0 deletions Side-by-side Diff
cmd/Kconfig
... | ... | @@ -953,6 +953,14 @@ |
953 | 953 | about 1990. These devices are typically removable memory or network |
954 | 954 | cards using a standard 68-pin connector. |
955 | 955 | |
956 | +config CMD_PINMUX | |
957 | + bool "pinmux - show pins muxing" | |
958 | + default y if PINCTRL | |
959 | + help | |
960 | + Parse all available pin-controllers and show pins muxing. This | |
961 | + is useful for debug purpoer to check the pin muxing and to know if | |
962 | + a pin is configured as a GPIO or as an alternate function. | |
963 | + | |
956 | 964 | config CMD_POWEROFF |
957 | 965 | bool "poweroff" |
958 | 966 | help |
cmd/Makefile
cmd/pinmux.c
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 | +) |