blob: 01f3e4af6cec3a4cdad6ed96357729949a788645 [file] [log] [blame]
Patrice Chotardd5a83132018-10-24 14:10:17 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4 */
5
Patrice Chotardd5a83132018-10-24 14:10:17 +02006#include <command.h>
7#include <dm.h>
8#include <errno.h>
9#include <dm/pinctrl.h>
10#include <dm/uclass-internal.h>
11
12#define LIMIT_DEVNAME 30
13
14static struct udevice *currdev;
15
Simon Glass09140112020-05-10 11:40:03 -060016static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc,
17 char *const argv[])
Patrice Chotardd5a83132018-10-24 14:10:17 +020018{
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 }
Patrick Delaunayd23aef12019-06-21 15:26:56 +020030 /* fall through */
Patrice Chotardd5a83132018-10-24 14:10:17 +020031 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
Patrick Delaunayfea03452021-05-21 09:47:32 +020043/**
44 * Print the muxing information for one or all pins of one pinctrl device
45 *
46 * @param dev pinctrl device
47 * @param name NULL to display all the pins
48 * or name of the pin to display
Heinrich Schuchardt185f8122022-01-19 18:05:50 +010049 * Return: 0 on success, non-0 on error
Patrick Delaunayfea03452021-05-21 09:47:32 +020050 */
51static int show_pinmux(struct udevice *dev, char *name)
Patrice Chotardd5a83132018-10-24 14:10:17 +020052{
53 char pin_name[PINNAME_SIZE];
54 char pin_mux[PINMUX_SIZE];
55 int pins_count;
56 int i;
57 int ret;
Patrick Delaunayfea03452021-05-21 09:47:32 +020058 bool found = false;
Patrice Chotardd5a83132018-10-24 14:10:17 +020059
60 pins_count = pinctrl_get_pins_count(dev);
61
62 if (pins_count == -ENOSYS) {
Patrick Delaunay4c60fd92021-05-21 09:47:31 +020063 printf("Ops get_pins_count not supported by %s\n", dev->name);
Patrice Chotardd5a83132018-10-24 14:10:17 +020064 return pins_count;
65 }
66
67 for (i = 0; i < pins_count; i++) {
68 ret = pinctrl_get_pin_name(dev, i, pin_name, PINNAME_SIZE);
Patrick Delaunay4c60fd92021-05-21 09:47:31 +020069 if (ret) {
70 printf("Ops get_pin_name error (%d) by %s\n", ret, dev->name);
Patrice Chotardd5a83132018-10-24 14:10:17 +020071 return ret;
72 }
Patrick Delaunayfea03452021-05-21 09:47:32 +020073 if (name && strcmp(name, pin_name))
74 continue;
75 found = true;
Patrice Chotardd5a83132018-10-24 14:10:17 +020076 ret = pinctrl_get_pin_muxing(dev, i, pin_mux, PINMUX_SIZE);
77 if (ret) {
Patrick Delaunay4c60fd92021-05-21 09:47:31 +020078 printf("Ops get_pin_muxing error (%d) by %s in %s\n",
79 ret, pin_name, dev->name);
Patrice Chotardd5a83132018-10-24 14:10:17 +020080 return ret;
81 }
82
83 printf("%-*s: %-*s\n", PINNAME_SIZE, pin_name,
84 PINMUX_SIZE, pin_mux);
85 }
86
Patrick Delaunayfea03452021-05-21 09:47:32 +020087 if (!found)
88 return -ENOENT;
89
Patrice Chotardd5a83132018-10-24 14:10:17 +020090 return 0;
91}
92
Simon Glass09140112020-05-10 11:40:03 -060093static int do_status(struct cmd_tbl *cmdtp, int flag, int argc,
94 char *const argv[])
Patrice Chotardd5a83132018-10-24 14:10:17 +020095{
96 struct udevice *dev;
Patrick Delaunayfea03452021-05-21 09:47:32 +020097 char *name;
98 int ret;
Patrice Chotardd5a83132018-10-24 14:10:17 +020099
Patrick Delaunay4c60fd92021-05-21 09:47:31 +0200100 if (argc < 2) {
101 if (!currdev) {
102 printf("pin-controller device not selected\n");
103 return CMD_RET_FAILURE;
104 }
Patrick Delaunayfea03452021-05-21 09:47:32 +0200105 show_pinmux(currdev, NULL);
Patrick Delaunay4c60fd92021-05-21 09:47:31 +0200106 return CMD_RET_SUCCESS;
107 }
Patrice Chotardd5a83132018-10-24 14:10:17 +0200108
Patrick Delaunay4c60fd92021-05-21 09:47:31 +0200109 if (strcmp(argv[1], "-a"))
Patrick Delaunayfea03452021-05-21 09:47:32 +0200110 name = argv[1];
111 else
112 name = NULL;
Patrice Chotardd5a83132018-10-24 14:10:17 +0200113
114 uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) {
Patrick Delaunayfea03452021-05-21 09:47:32 +0200115 if (!name) {
116 /* insert a separator between each pin-controller display */
117 printf("--------------------------\n");
118 printf("%s:\n", dev->name);
119 }
120 ret = show_pinmux(dev, name);
121 /* stop when the status of requested pin is displayed */
122 if (name && !ret)
123 return CMD_RET_SUCCESS;
124 }
125
126 if (name) {
127 printf("%s not found\n", name);
128 return CMD_RET_FAILURE;
Patrice Chotardd5a83132018-10-24 14:10:17 +0200129 }
130
Patrick Delaunay4c60fd92021-05-21 09:47:31 +0200131 return CMD_RET_SUCCESS;
Patrice Chotardd5a83132018-10-24 14:10:17 +0200132}
133
Simon Glass09140112020-05-10 11:40:03 -0600134static int do_list(struct cmd_tbl *cmdtp, int flag, int argc,
135 char *const argv[])
Patrice Chotardd5a83132018-10-24 14:10:17 +0200136{
137 struct udevice *dev;
138
139 printf("| %-*.*s| %-*.*s| %s\n",
140 LIMIT_DEVNAME, LIMIT_DEVNAME, "Device",
141 LIMIT_DEVNAME, LIMIT_DEVNAME, "Driver",
142 "Parent");
143
144 uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) {
145 printf("| %-*.*s| %-*.*s| %s\n",
146 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name,
147 LIMIT_DEVNAME, LIMIT_DEVNAME, dev->driver->name,
148 dev->parent->name);
149 }
150
151 return CMD_RET_SUCCESS;
152}
153
Simon Glass09140112020-05-10 11:40:03 -0600154static struct cmd_tbl pinmux_subcmd[] = {
Patrice Chotardd5a83132018-10-24 14:10:17 +0200155 U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
156 U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
157 U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""),
158};
159
Simon Glass09140112020-05-10 11:40:03 -0600160static int do_pinmux(struct cmd_tbl *cmdtp, int flag, int argc,
161 char *const argv[])
Patrice Chotardd5a83132018-10-24 14:10:17 +0200162{
Simon Glass09140112020-05-10 11:40:03 -0600163 struct cmd_tbl *cmd;
Patrice Chotardd5a83132018-10-24 14:10:17 +0200164
165 argc--;
166 argv++;
167
168 cmd = find_cmd_tbl(argv[0], pinmux_subcmd, ARRAY_SIZE(pinmux_subcmd));
169 if (!cmd || argc > cmd->maxargs)
170 return CMD_RET_USAGE;
171
172 return cmd->cmd(cmdtp, flag, argc, argv);
173}
174
175U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux,
176 "show pin-controller muxing",
177 "list - list UCLASS_PINCTRL devices\n"
178 "pinmux dev [pincontroller-name] - select pin-controller device\n"
Patrick Delaunayfea03452021-05-21 09:47:32 +0200179 "pinmux status [-a | pin-name] - print pin-controller muxing [for all | for pin-name]\n"
Simon Glass10c398d2023-11-18 14:04:52 -0700180);