blob: b755fa42b4f70155ab8ba60ec2babc6291d82597 [file] [log] [blame]
Patrick Delaunay10bccd02020-09-09 17:50:15 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017-2020 STMicroelectronics - All Rights Reserved
4 */
5
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +01006#define LOG_CATEGORY UCLASS_PINCTRL
7
Vikas Manocha94d53082017-02-12 10:25:49 -08008#include <common.h>
Vikas Manocha94d53082017-02-12 10:25:49 -08009#include <dm.h>
Benjamin Gaignard075b0182018-11-27 13:49:53 +010010#include <hwspinlock.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060011#include <log.h>
Simon Glass336d4612020-02-03 07:36:16 -070012#include <malloc.h>
Vikas Manocha77417102017-04-10 15:02:57 -070013#include <asm/gpio.h>
14#include <asm/io.h>
Simon Glass336d4612020-02-03 07:36:16 -070015#include <dm/device_compat.h>
Patrice Chotard73858262019-07-30 19:16:10 +020016#include <dm/lists.h>
17#include <dm/pinctrl.h>
Simon Glasscd93d622020-05-10 11:40:13 -060018#include <linux/bitops.h>
Simon Glass61b29b82020-02-03 07:36:15 -070019#include <linux/err.h>
Simon Glass4d72caa2020-05-10 11:40:01 -060020#include <linux/libfdt.h>
Vikas Manocha94d53082017-02-12 10:25:49 -080021
Patrick Delaunay56a368f2021-10-22 20:12:34 +020022#include "../gpio/stm32_gpio_priv.h"
23
Vikas Manocha58fb3c82017-04-10 15:03:04 -070024#define MAX_PINS_ONE_IP 70
Vikas Manocha77417102017-04-10 15:02:57 -070025#define MODE_BITS_MASK 3
26#define OSPEED_MASK 3
27#define PUPD_MASK 3
28#define OTYPE_MSK 1
29#define AFR_MASK 0xF
30
Patrice Chotard8f651ca2018-10-24 14:10:18 +020031struct stm32_pinctrl_priv {
Benjamin Gaignard075b0182018-11-27 13:49:53 +010032 struct hwspinlock hws;
Patrice Chotard8f651ca2018-10-24 14:10:18 +020033 int pinctrl_ngpios;
34 struct list_head gpio_dev;
35};
36
37struct stm32_gpio_bank {
38 struct udevice *gpio_dev;
39 struct list_head list;
40};
41
Benjamin Gaignard075b0182018-11-27 13:49:53 +010042#ifndef CONFIG_SPL_BUILD
43
Patrice Chotard4ff1c202018-10-24 14:10:19 +020044static char pin_name[PINNAME_SIZE];
Patrice Chotard4382e552022-04-22 09:38:29 +020045static const char * const pinmux_mode[GPIOF_COUNT] = {
46 [GPIOF_INPUT] = "gpio input",
47 [GPIOF_OUTPUT] = "gpio output",
48 [GPIOF_UNUSED] = "analog",
49 [GPIOF_UNKNOWN] = "unknown",
50 [GPIOF_FUNC] = "alt function",
Patrice Chotardb42d9382018-10-24 14:10:20 +020051};
52
Patrick Delaunayb305dbc2020-10-28 10:49:07 +010053static const char * const pinmux_bias[] = {
54 [STM32_GPIO_PUPD_NO] = "",
55 [STM32_GPIO_PUPD_UP] = "pull-up",
56 [STM32_GPIO_PUPD_DOWN] = "pull-down",
Patrick Delaunayda7a0bb2020-06-04 14:30:33 +020057};
58
Patrick Delaunay1da42692021-01-21 17:39:07 +010059static const char * const pinmux_otype[] = {
Patrick Delaunayb305dbc2020-10-28 10:49:07 +010060 [STM32_GPIO_OTYPE_PP] = "push-pull",
61 [STM32_GPIO_OTYPE_OD] = "open-drain",
Patrick Delaunayda7a0bb2020-06-04 14:30:33 +020062};
63
Patrice Chotardb42d9382018-10-24 14:10:20 +020064static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset)
65{
66 struct stm32_gpio_priv *priv = dev_get_priv(dev);
67 struct stm32_gpio_regs *regs = priv->regs;
68 u32 af;
69 u32 alt_shift = (offset % 8) * 4;
70 u32 alt_index = offset / 8;
71
72 af = (readl(&regs->afr[alt_index]) &
73 GENMASK(alt_shift + 3, alt_shift)) >> alt_shift;
74
75 return af;
76}
77
Patrice Chotard04355042018-12-03 10:52:50 +010078static int stm32_populate_gpio_dev_list(struct udevice *dev)
79{
80 struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
81 struct udevice *gpio_dev;
82 struct udevice *child;
83 struct stm32_gpio_bank *gpio_bank;
84 int ret;
85
86 /*
87 * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
88 * a list with all gpio device reference which belongs to the
89 * current pin-controller. This list is used to find pin_name and
90 * pin muxing
91 */
92 list_for_each_entry(child, &dev->child_head, sibling_node) {
93 ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
94 &gpio_dev);
95 if (ret < 0)
96 continue;
97
98 gpio_bank = malloc(sizeof(*gpio_bank));
99 if (!gpio_bank) {
100 dev_err(dev, "Not enough memory\n");
101 return -ENOMEM;
102 }
103
104 gpio_bank->gpio_dev = gpio_dev;
105 list_add_tail(&gpio_bank->list, &priv->gpio_dev);
106 }
107
108 return 0;
109}
110
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200111static int stm32_pinctrl_get_pins_count(struct udevice *dev)
112{
113 struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
114 struct gpio_dev_priv *uc_priv;
115 struct stm32_gpio_bank *gpio_bank;
116
117 /*
118 * if get_pins_count has already been executed once on this
119 * pin-controller, no need to run it again
120 */
121 if (priv->pinctrl_ngpios)
122 return priv->pinctrl_ngpios;
123
Patrice Chotard04355042018-12-03 10:52:50 +0100124 if (list_empty(&priv->gpio_dev))
125 stm32_populate_gpio_dev_list(dev);
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200126 /*
127 * walk through all banks to retrieve the pin-controller
128 * pins number
129 */
130 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
131 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
132
133 priv->pinctrl_ngpios += uc_priv->gpio_count;
134 }
135
136 return priv->pinctrl_ngpios;
137}
138
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200139static struct udevice *stm32_pinctrl_get_gpio_dev(struct udevice *dev,
Patrice Chotard530b63c2018-12-03 10:52:54 +0100140 unsigned int selector,
141 unsigned int *idx)
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200142{
143 struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
144 struct stm32_gpio_bank *gpio_bank;
145 struct gpio_dev_priv *uc_priv;
Patrice Chotard530b63c2018-12-03 10:52:54 +0100146 int pin_count = 0;
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200147
Patrice Chotard04355042018-12-03 10:52:50 +0100148 if (list_empty(&priv->gpio_dev))
149 stm32_populate_gpio_dev_list(dev);
150
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200151 /* look up for the bank which owns the requested pin */
152 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
153 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
154
Patrice Chotard530b63c2018-12-03 10:52:54 +0100155 if (selector < (pin_count + uc_priv->gpio_count)) {
156 /*
157 * we found the bank, convert pin selector to
158 * gpio bank index
159 */
Patrice Chotard427f4522022-04-22 09:38:31 +0200160 *idx = selector - pin_count;
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200161
Patrice Chotard530b63c2018-12-03 10:52:54 +0100162 return gpio_bank->gpio_dev;
163 }
164 pin_count += uc_priv->gpio_count;
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200165 }
166
167 return NULL;
168}
169
170static const char *stm32_pinctrl_get_pin_name(struct udevice *dev,
171 unsigned int selector)
172{
173 struct gpio_dev_priv *uc_priv;
174 struct udevice *gpio_dev;
Patrice Chotard530b63c2018-12-03 10:52:54 +0100175 unsigned int gpio_idx;
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200176
177 /* look up for the bank which owns the requested pin */
Patrice Chotard530b63c2018-12-03 10:52:54 +0100178 gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200179 if (!gpio_dev) {
180 snprintf(pin_name, PINNAME_SIZE, "Error");
181 } else {
182 uc_priv = dev_get_uclass_priv(gpio_dev);
183
184 snprintf(pin_name, PINNAME_SIZE, "%s%d",
185 uc_priv->bank_name,
Patrice Chotard530b63c2018-12-03 10:52:54 +0100186 gpio_idx);
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200187 }
188
189 return pin_name;
190}
Patrice Chotardb42d9382018-10-24 14:10:20 +0200191
192static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
193 unsigned int selector,
194 char *buf,
195 int size)
196{
197 struct udevice *gpio_dev;
Patrick Delaunayda7a0bb2020-06-04 14:30:33 +0200198 struct stm32_gpio_priv *priv;
Patrice Chotardb42d9382018-10-24 14:10:20 +0200199 const char *label;
Patrice Chotardb42d9382018-10-24 14:10:20 +0200200 int mode;
201 int af_num;
Patrice Chotard530b63c2018-12-03 10:52:54 +0100202 unsigned int gpio_idx;
Patrick Delaunayda7a0bb2020-06-04 14:30:33 +0200203 u32 pupd, otype;
Patrice Chotardb42d9382018-10-24 14:10:20 +0200204
205 /* look up for the bank which owns the requested pin */
Patrice Chotard530b63c2018-12-03 10:52:54 +0100206 gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
Patrice Chotardb42d9382018-10-24 14:10:20 +0200207
208 if (!gpio_dev)
209 return -ENODEV;
210
Patrice Chotard530b63c2018-12-03 10:52:54 +0100211 mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label);
Patrice Chotard530b63c2018-12-03 10:52:54 +0100212 dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n",
213 selector, gpio_idx, mode);
Patrick Delaunayda7a0bb2020-06-04 14:30:33 +0200214 priv = dev_get_priv(gpio_dev);
Patrick Delaunayb305dbc2020-10-28 10:49:07 +0100215 pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) & PUPD_MASK;
Patrick Delaunay1da42692021-01-21 17:39:07 +0100216 otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK;
Patrice Chotardb42d9382018-10-24 14:10:20 +0200217
218 switch (mode) {
219 case GPIOF_UNKNOWN:
Patrice Chotardb42d9382018-10-24 14:10:20 +0200220 case GPIOF_UNUSED:
221 snprintf(buf, size, "%s", pinmux_mode[mode]);
222 break;
223 case GPIOF_FUNC:
Patrice Chotard530b63c2018-12-03 10:52:54 +0100224 af_num = stm32_pinctrl_get_af(gpio_dev, gpio_idx);
Patrick Delaunay1da42692021-01-21 17:39:07 +0100225 snprintf(buf, size, "%s %d %s %s", pinmux_mode[mode], af_num,
226 pinmux_otype[otype], pinmux_bias[pupd]);
Patrice Chotardb42d9382018-10-24 14:10:20 +0200227 break;
228 case GPIOF_OUTPUT:
Patrick Delaunay1da42692021-01-21 17:39:07 +0100229 snprintf(buf, size, "%s %s %s %s",
230 pinmux_mode[mode], pinmux_otype[otype],
231 pinmux_bias[pupd], label ? label : "");
Patrick Delaunayda7a0bb2020-06-04 14:30:33 +0200232 break;
Patrice Chotardb42d9382018-10-24 14:10:20 +0200233 case GPIOF_INPUT:
Patrick Delaunay1da42692021-01-21 17:39:07 +0100234 snprintf(buf, size, "%s %s %s", pinmux_mode[mode],
Patrick Delaunayb305dbc2020-10-28 10:49:07 +0100235 pinmux_bias[pupd], label ? label : "");
Patrice Chotardb42d9382018-10-24 14:10:20 +0200236 break;
237 }
238
239 return 0;
240}
241
Benjamin Gaignard075b0182018-11-27 13:49:53 +0100242#endif
243
Patrick Delaunay91ca91e2019-06-21 15:26:52 +0200244static int stm32_pinctrl_probe(struct udevice *dev)
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200245{
246 struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200247 int ret;
248
249 INIT_LIST_HEAD(&priv->gpio_dev);
250
Benjamin Gaignard075b0182018-11-27 13:49:53 +0100251 /* hwspinlock property is optional, just log the error */
252 ret = hwspinlock_get_by_index(dev, 0, &priv->hws);
253 if (ret)
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100254 dev_dbg(dev, "hwspinlock_get_by_index may have failed (%d)\n",
255 ret);
Benjamin Gaignard075b0182018-11-27 13:49:53 +0100256
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200257 return 0;
258}
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200259
Patrice Chotard2c38f7c2022-08-30 14:09:13 +0200260static int stm32_gpio_config(ofnode node,
261 struct gpio_desc *desc,
Vikas Manocha77417102017-04-10 15:02:57 -0700262 const struct stm32_gpio_ctl *ctl)
263{
264 struct stm32_gpio_priv *priv = dev_get_priv(desc->dev);
Patrice Chotard2c38f7c2022-08-30 14:09:13 +0200265 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev);
Vikas Manocha77417102017-04-10 15:02:57 -0700266 struct stm32_gpio_regs *regs = priv->regs;
Benjamin Gaignard075b0182018-11-27 13:49:53 +0100267 struct stm32_pinctrl_priv *ctrl_priv;
268 int ret;
Vikas Manocha77417102017-04-10 15:02:57 -0700269 u32 index;
270
271 if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 ||
272 ctl->pupd > 2 || ctl->speed > 3)
273 return -EINVAL;
274
Benjamin Gaignard075b0182018-11-27 13:49:53 +0100275 ctrl_priv = dev_get_priv(dev_get_parent(desc->dev));
276 ret = hwspinlock_lock_timeout(&ctrl_priv->hws, 10);
277 if (ret == -ETIME) {
278 dev_err(desc->dev, "HWSpinlock timeout\n");
279 return ret;
280 }
281
Vikas Manocha77417102017-04-10 15:02:57 -0700282 index = (desc->offset & 0x07) * 4;
283 clrsetbits_le32(&regs->afr[desc->offset >> 3], AFR_MASK << index,
284 ctl->af << index);
285
286 index = desc->offset * 2;
287 clrsetbits_le32(&regs->moder, MODE_BITS_MASK << index,
288 ctl->mode << index);
289 clrsetbits_le32(&regs->ospeedr, OSPEED_MASK << index,
290 ctl->speed << index);
291 clrsetbits_le32(&regs->pupdr, PUPD_MASK << index, ctl->pupd << index);
292
293 index = desc->offset;
294 clrsetbits_le32(&regs->otyper, OTYPE_MSK << index, ctl->otype << index);
295
Patrice Chotard2c38f7c2022-08-30 14:09:13 +0200296 uc_priv->name[desc->offset] = strdup(ofnode_get_name(node));
297
Benjamin Gaignard075b0182018-11-27 13:49:53 +0100298 hwspinlock_unlock(&ctrl_priv->hws);
299
Vikas Manocha77417102017-04-10 15:02:57 -0700300 return 0;
301}
Patrick Delaunay8aeba622018-03-12 10:46:13 +0100302
Vikas Manocha94d53082017-02-12 10:25:49 -0800303static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin)
304{
Patrick Delaunay8aeba622018-03-12 10:46:13 +0100305 gpio_dsc->port = (port_pin & 0x1F000) >> 12;
Vikas Manocha94d53082017-02-12 10:25:49 -0800306 gpio_dsc->pin = (port_pin & 0x0F00) >> 8;
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100307 log_debug("GPIO:port= %d, pin= %d\n", gpio_dsc->port, gpio_dsc->pin);
Vikas Manocha94d53082017-02-12 10:25:49 -0800308
309 return 0;
310}
311
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200312static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn,
313 ofnode node)
Vikas Manocha94d53082017-02-12 10:25:49 -0800314{
315 gpio_fn &= 0x00FF;
Vikas Manocha77417102017-04-10 15:02:57 -0700316 gpio_ctl->af = 0;
Vikas Manocha94d53082017-02-12 10:25:49 -0800317
318 switch (gpio_fn) {
319 case 0:
320 gpio_ctl->mode = STM32_GPIO_MODE_IN;
321 break;
322 case 1 ... 16:
323 gpio_ctl->mode = STM32_GPIO_MODE_AF;
324 gpio_ctl->af = gpio_fn - 1;
325 break;
326 case 17:
327 gpio_ctl->mode = STM32_GPIO_MODE_AN;
328 break;
329 default:
330 gpio_ctl->mode = STM32_GPIO_MODE_OUT;
331 break;
332 }
333
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200334 gpio_ctl->speed = ofnode_read_u32_default(node, "slew-rate", 0);
Vikas Manocha94d53082017-02-12 10:25:49 -0800335
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200336 if (ofnode_read_bool(node, "drive-open-drain"))
Vikas Manocha94d53082017-02-12 10:25:49 -0800337 gpio_ctl->otype = STM32_GPIO_OTYPE_OD;
338 else
339 gpio_ctl->otype = STM32_GPIO_OTYPE_PP;
340
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200341 if (ofnode_read_bool(node, "bias-pull-up"))
Vikas Manocha94d53082017-02-12 10:25:49 -0800342 gpio_ctl->pupd = STM32_GPIO_PUPD_UP;
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200343 else if (ofnode_read_bool(node, "bias-pull-down"))
Vikas Manocha94d53082017-02-12 10:25:49 -0800344 gpio_ctl->pupd = STM32_GPIO_PUPD_DOWN;
345 else
346 gpio_ctl->pupd = STM32_GPIO_PUPD_NO;
347
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100348 log_debug("gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n",
349 gpio_fn, gpio_ctl->speed, gpio_ctl->otype,
350 gpio_ctl->pupd);
Vikas Manocha94d53082017-02-12 10:25:49 -0800351
352 return 0;
353}
354
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200355static int stm32_pinctrl_config(ofnode node)
Vikas Manocha94d53082017-02-12 10:25:49 -0800356{
Vikas Manocha58fb3c82017-04-10 15:03:04 -0700357 u32 pin_mux[MAX_PINS_ONE_IP];
Vikas Manocha94d53082017-02-12 10:25:49 -0800358 int rv, len;
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200359 ofnode subnode;
Vikas Manocha94d53082017-02-12 10:25:49 -0800360
Vikas Manocha94d53082017-02-12 10:25:49 -0800361 /*
362 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for
363 * usart1) of pin controller phandle "pinctrl-0"
364 * */
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200365 ofnode_for_each_subnode(subnode, node) {
Vikas Manocha94d53082017-02-12 10:25:49 -0800366 struct stm32_gpio_dsc gpio_dsc;
367 struct stm32_gpio_ctl gpio_ctl;
368 int i;
369
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200370 rv = ofnode_read_size(subnode, "pinmux");
371 if (rv < 0)
372 return rv;
373 len = rv / sizeof(pin_mux[0]);
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100374 log_debug("No of pinmux entries= %d\n", len);
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200375 if (len > MAX_PINS_ONE_IP)
Vikas Manocha94d53082017-02-12 10:25:49 -0800376 return -EINVAL;
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200377 rv = ofnode_read_u32_array(subnode, "pinmux", pin_mux, len);
378 if (rv < 0)
379 return rv;
Vikas Manocha94d53082017-02-12 10:25:49 -0800380 for (i = 0; i < len; i++) {
Vikas Manocha280057b2017-04-10 15:02:59 -0700381 struct gpio_desc desc;
Patrick Delaunay8aeba622018-03-12 10:46:13 +0100382
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100383 log_debug("pinmux = %x\n", *(pin_mux + i));
Vikas Manocha94d53082017-02-12 10:25:49 -0800384 prep_gpio_dsc(&gpio_dsc, *(pin_mux + i));
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200385 prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), subnode);
Vikas Manocha280057b2017-04-10 15:02:59 -0700386 rv = uclass_get_device_by_seq(UCLASS_GPIO,
Patrick Delaunay8aeba622018-03-12 10:46:13 +0100387 gpio_dsc.port,
388 &desc.dev);
Vikas Manocha280057b2017-04-10 15:02:59 -0700389 if (rv)
390 return rv;
391 desc.offset = gpio_dsc.pin;
Patrice Chotard2c38f7c2022-08-30 14:09:13 +0200392 rv = stm32_gpio_config(node, &desc, &gpio_ctl);
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100393 log_debug("rv = %d\n\n", rv);
Vikas Manocha94d53082017-02-12 10:25:49 -0800394 if (rv)
395 return rv;
396 }
397 }
398
399 return 0;
400}
401
Patrice Chotard158abbf2019-06-21 15:39:23 +0200402static int stm32_pinctrl_bind(struct udevice *dev)
403{
404 ofnode node;
405 const char *name;
406 int ret;
407
408 dev_for_each_subnode(node, dev) {
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100409 dev_dbg(dev, "bind %s\n", ofnode_get_name(node));
Patrice Chotard158abbf2019-06-21 15:39:23 +0200410
Patrick Delaunay4363aac2021-01-21 17:39:08 +0100411 if (!ofnode_is_enabled(node))
412 continue;
413
Patrice Chotard158abbf2019-06-21 15:39:23 +0200414 ofnode_get_property(node, "gpio-controller", &ret);
415 if (ret < 0)
416 continue;
417 /* Get the name of each gpio node */
418 name = ofnode_get_name(node);
419 if (!name)
420 return -EINVAL;
421
422 /* Bind each gpio node */
423 ret = device_bind_driver_to_node(dev, "gpio_stm32",
424 name, node, NULL);
425 if (ret)
426 return ret;
427
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100428 dev_dbg(dev, "bind %s\n", name);
Patrice Chotard158abbf2019-06-21 15:39:23 +0200429 }
430
431 return 0;
432}
433
Christophe Kerellobb44b962017-06-20 17:04:19 +0200434#if CONFIG_IS_ENABLED(PINCTRL_FULL)
435static int stm32_pinctrl_set_state(struct udevice *dev, struct udevice *config)
436{
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200437 return stm32_pinctrl_config(dev_ofnode(config));
Christophe Kerellobb44b962017-06-20 17:04:19 +0200438}
439#else /* PINCTRL_FULL */
Christophe Kerelload0376e2017-06-20 17:04:18 +0200440static int stm32_pinctrl_set_state_simple(struct udevice *dev,
441 struct udevice *periph)
442{
Christophe Kerelload0376e2017-06-20 17:04:18 +0200443 const fdt32_t *list;
444 uint32_t phandle;
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200445 ofnode config_node;
Christophe Kerelload0376e2017-06-20 17:04:18 +0200446 int size, i, ret;
447
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200448 list = ofnode_get_property(dev_ofnode(periph), "pinctrl-0", &size);
Christophe Kerelload0376e2017-06-20 17:04:18 +0200449 if (!list)
450 return -EINVAL;
451
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100452 dev_dbg(dev, "periph->name = %s\n", periph->name);
Christophe Kerelload0376e2017-06-20 17:04:18 +0200453
454 size /= sizeof(*list);
455 for (i = 0; i < size; i++) {
456 phandle = fdt32_to_cpu(*list++);
457
Patrick Delaunayd3bfad22020-09-09 17:50:14 +0200458 config_node = ofnode_get_by_phandle(phandle);
459 if (!ofnode_valid(config_node)) {
Patrick Delaunay28b3e7b2020-11-06 19:01:32 +0100460 dev_err(periph,
461 "prop pinctrl-0 index %d invalid phandle\n", i);
Christophe Kerelload0376e2017-06-20 17:04:18 +0200462 return -EINVAL;
463 }
464
465 ret = stm32_pinctrl_config(config_node);
466 if (ret)
467 return ret;
468 }
469
470 return 0;
471}
Christophe Kerellobb44b962017-06-20 17:04:19 +0200472#endif /* PINCTRL_FULL */
Christophe Kerelload0376e2017-06-20 17:04:18 +0200473
Vikas Manocha94d53082017-02-12 10:25:49 -0800474static struct pinctrl_ops stm32_pinctrl_ops = {
Christophe Kerellobb44b962017-06-20 17:04:19 +0200475#if CONFIG_IS_ENABLED(PINCTRL_FULL)
476 .set_state = stm32_pinctrl_set_state,
477#else /* PINCTRL_FULL */
Vikas Manocha94d53082017-02-12 10:25:49 -0800478 .set_state_simple = stm32_pinctrl_set_state_simple,
Christophe Kerellobb44b962017-06-20 17:04:19 +0200479#endif /* PINCTRL_FULL */
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200480#ifndef CONFIG_SPL_BUILD
Patrice Chotard4ff1c202018-10-24 14:10:19 +0200481 .get_pin_name = stm32_pinctrl_get_pin_name,
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200482 .get_pins_count = stm32_pinctrl_get_pins_count,
Patrice Chotardb42d9382018-10-24 14:10:20 +0200483 .get_pin_muxing = stm32_pinctrl_get_pin_muxing,
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200484#endif
Vikas Manocha94d53082017-02-12 10:25:49 -0800485};
486
487static const struct udevice_id stm32_pinctrl_ids[] = {
Patrice Chotard98693c22017-12-12 09:49:35 +0100488 { .compatible = "st,stm32f429-pinctrl" },
489 { .compatible = "st,stm32f469-pinctrl" },
Vikas Manocha94d53082017-02-12 10:25:49 -0800490 { .compatible = "st,stm32f746-pinctrl" },
Patrice Chotarddd18df42018-12-11 14:49:18 +0100491 { .compatible = "st,stm32f769-pinctrl" },
Patrice Chotard092e72c2017-09-13 18:00:04 +0200492 { .compatible = "st,stm32h743-pinctrl" },
Patrick Delaunay8aeba622018-03-12 10:46:13 +0100493 { .compatible = "st,stm32mp157-pinctrl" },
494 { .compatible = "st,stm32mp157-z-pinctrl" },
Patrick Delaunaycf1d0fd2022-05-20 18:24:48 +0200495 { .compatible = "st,stm32mp135-pinctrl" },
Vikas Manocha94d53082017-02-12 10:25:49 -0800496 { }
497};
498
499U_BOOT_DRIVER(pinctrl_stm32) = {
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200500 .name = "pinctrl_stm32",
501 .id = UCLASS_PINCTRL,
502 .of_match = stm32_pinctrl_ids,
503 .ops = &stm32_pinctrl_ops,
Patrice Chotard158abbf2019-06-21 15:39:23 +0200504 .bind = stm32_pinctrl_bind,
Patrice Chotard8f651ca2018-10-24 14:10:18 +0200505 .probe = stm32_pinctrl_probe,
Simon Glass41575d82020-12-03 16:55:17 -0700506 .priv_auto = sizeof(struct stm32_pinctrl_priv),
Vikas Manocha94d53082017-02-12 10:25:49 -0800507};