3 #include <dm/pinctrl.h>
4 #include <asm/arch/gpio.h>
8 DECLARE_GLOBAL_DATA_PTR
;
10 #define MAX_PINS_ONE_IP 70
11 #define MODE_BITS_MASK 3
17 static int stm32_gpio_config(struct gpio_desc
*desc
,
18 const struct stm32_gpio_ctl
*ctl
)
20 struct stm32_gpio_priv
*priv
= dev_get_priv(desc
->dev
);
21 struct stm32_gpio_regs
*regs
= priv
->regs
;
24 if (!ctl
|| ctl
->af
> 15 || ctl
->mode
> 3 || ctl
->otype
> 1 ||
25 ctl
->pupd
> 2 || ctl
->speed
> 3)
28 index
= (desc
->offset
& 0x07) * 4;
29 clrsetbits_le32(®s
->afr
[desc
->offset
>> 3], AFR_MASK
<< index
,
32 index
= desc
->offset
* 2;
33 clrsetbits_le32(®s
->moder
, MODE_BITS_MASK
<< index
,
35 clrsetbits_le32(®s
->ospeedr
, OSPEED_MASK
<< index
,
37 clrsetbits_le32(®s
->pupdr
, PUPD_MASK
<< index
, ctl
->pupd
<< index
);
40 clrsetbits_le32(®s
->otyper
, OTYPE_MSK
<< index
, ctl
->otype
<< index
);
44 static int prep_gpio_dsc(struct stm32_gpio_dsc
*gpio_dsc
, u32 port_pin
)
46 gpio_dsc
->port
= (port_pin
& 0xF000) >> 12;
47 gpio_dsc
->pin
= (port_pin
& 0x0F00) >> 8;
48 debug("%s: GPIO:port= %d, pin= %d\n", __func__
, gpio_dsc
->port
,
54 static int prep_gpio_ctl(struct stm32_gpio_ctl
*gpio_ctl
, u32 gpio_fn
, int node
)
61 gpio_ctl
->mode
= STM32_GPIO_MODE_IN
;
64 gpio_ctl
->mode
= STM32_GPIO_MODE_AF
;
65 gpio_ctl
->af
= gpio_fn
- 1;
68 gpio_ctl
->mode
= STM32_GPIO_MODE_AN
;
71 gpio_ctl
->mode
= STM32_GPIO_MODE_OUT
;
75 gpio_ctl
->speed
= fdtdec_get_int(gd
->fdt_blob
, node
, "slew-rate", 0);
77 if (fdtdec_get_bool(gd
->fdt_blob
, node
, "drive-open-drain"))
78 gpio_ctl
->otype
= STM32_GPIO_OTYPE_OD
;
80 gpio_ctl
->otype
= STM32_GPIO_OTYPE_PP
;
82 if (fdtdec_get_bool(gd
->fdt_blob
, node
, "bias-pull-up"))
83 gpio_ctl
->pupd
= STM32_GPIO_PUPD_UP
;
84 else if (fdtdec_get_bool(gd
->fdt_blob
, node
, "bias-pull-down"))
85 gpio_ctl
->pupd
= STM32_GPIO_PUPD_DOWN
;
87 gpio_ctl
->pupd
= STM32_GPIO_PUPD_NO
;
89 debug("%s: gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n",
90 __func__
, gpio_fn
, gpio_ctl
->speed
, gpio_ctl
->otype
,
96 static int stm32_pinctrl_config(int offset
)
98 u32 pin_mux
[MAX_PINS_ONE_IP
];
102 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for
103 * usart1) of pin controller phandle "pinctrl-0"
105 fdt_for_each_subnode(offset
, gd
->fdt_blob
, offset
) {
106 struct stm32_gpio_dsc gpio_dsc
;
107 struct stm32_gpio_ctl gpio_ctl
;
110 len
= fdtdec_get_int_array_count(gd
->fdt_blob
, offset
,
112 ARRAY_SIZE(pin_mux
));
113 debug("%s: no of pinmux entries= %d\n", __func__
, len
);
116 for (i
= 0; i
< len
; i
++) {
117 struct gpio_desc desc
;
118 debug("%s: pinmux = %x\n", __func__
, *(pin_mux
+ i
));
119 prep_gpio_dsc(&gpio_dsc
, *(pin_mux
+ i
));
120 prep_gpio_ctl(&gpio_ctl
, *(pin_mux
+ i
), offset
);
121 rv
= uclass_get_device_by_seq(UCLASS_GPIO
,
122 gpio_dsc
.port
, &desc
.dev
);
125 desc
.offset
= gpio_dsc
.pin
;
126 rv
= stm32_gpio_config(&desc
, &gpio_ctl
);
127 debug("%s: rv = %d\n\n", __func__
, rv
);
136 #if CONFIG_IS_ENABLED(PINCTRL_FULL)
137 static int stm32_pinctrl_set_state(struct udevice
*dev
, struct udevice
*config
)
139 return stm32_pinctrl_config(dev_of_offset(config
));
141 #else /* PINCTRL_FULL */
142 static int stm32_pinctrl_set_state_simple(struct udevice
*dev
,
143 struct udevice
*periph
)
145 const void *fdt
= gd
->fdt_blob
;
151 list
= fdt_getprop(fdt
, dev_of_offset(periph
), "pinctrl-0", &size
);
155 debug("%s: periph->name = %s\n", __func__
, periph
->name
);
157 size
/= sizeof(*list
);
158 for (i
= 0; i
< size
; i
++) {
159 phandle
= fdt32_to_cpu(*list
++);
161 config_node
= fdt_node_offset_by_phandle(fdt
, phandle
);
162 if (config_node
< 0) {
163 pr_err("prop pinctrl-0 index %d invalid phandle\n", i
);
167 ret
= stm32_pinctrl_config(config_node
);
174 #endif /* PINCTRL_FULL */
176 static struct pinctrl_ops stm32_pinctrl_ops
= {
177 #if CONFIG_IS_ENABLED(PINCTRL_FULL)
178 .set_state
= stm32_pinctrl_set_state
,
179 #else /* PINCTRL_FULL */
180 .set_state_simple
= stm32_pinctrl_set_state_simple
,
181 #endif /* PINCTRL_FULL */
184 static const struct udevice_id stm32_pinctrl_ids
[] = {
185 { .compatible
= "st,stm32f746-pinctrl" },
186 { .compatible
= "st,stm32h743-pinctrl" },
190 U_BOOT_DRIVER(pinctrl_stm32
) = {
191 .name
= "pinctrl_stm32",
192 .id
= UCLASS_PINCTRL
,
193 .of_match
= stm32_pinctrl_ids
,
194 .ops
= &stm32_pinctrl_ops
,
195 .bind
= dm_scan_fdt_dev
,