1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2015 Maxime Coquelin
* Copyright (C) 2017 STMicroelectronics
* Copyright (C) 2019 Ahmad Fatoum, Pengutronix
*/
#ifndef __STM32_GPIO_H__
#define __STM32_GPIO_H__
#include <io.h>
#define STM32_GPIO_MODER 0x00
#define STM32_GPIO_TYPER 0x04
#define STM32_GPIO_SPEEDR 0x08
#define STM32_GPIO_PUPDR 0x0c
#define STM32_GPIO_IDR 0x10
#define STM32_GPIO_ODR 0x14
#define STM32_GPIO_BSRR 0x18
#define STM32_GPIO_LCKR 0x1c
#define STM32_GPIO_AFRL 0x20
#define STM32_GPIO_AFRH 0x24
#define STM32_PIN_GPIO 0
#define STM32_PIN_AF(x) ((x) + 1)
#define STM32_PIN_ANALOG (STM32_PIN_AF(15) + 1)
#define STM32_PINMODE_GPIO 0
#define STM32_PINMODE_AF 2
#define STM32_PINMODE_ANALOG 3
#define STM32_GPIO_PINS_PER_BANK 16
enum stm32_pin_bias { STM32_PIN_NO_BIAS, STM32_PIN_PULL_UP, STM32_PIN_PULL_DOWN };
enum stm32_pin_out_type { STM32_PIN_OUT_PUSHPULL, STM32_PIN_OUT_OPENDRAIN };
static inline void __stm32_pmx_set_speed(void __iomem *base,
unsigned offset, u32 speed)
{
u32 val = readl(base + STM32_GPIO_SPEEDR);
val &= ~GENMASK(offset * 2 + 1, offset * 2);
val |= speed << (offset * 2);
writel(val, base + STM32_GPIO_SPEEDR);
}
static inline void __stm32_pmx_set_bias(void __iomem *base, unsigned offset,
enum stm32_pin_bias bias)
{
u32 val = readl(base + STM32_GPIO_PUPDR);
val &= ~GENMASK(offset * 2 + 1, offset * 2);
val |= bias << (offset * 2);
writel(val, base + STM32_GPIO_PUPDR);
}
static inline void __stm32_pmx_set_mode(void __iomem *base,
int pin, u32 mode, u32 alt)
{
u32 val;
int alt_shift = (pin % 8) * 4;
int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4;
val = readl(base + alt_offset);
val &= ~GENMASK(alt_shift + 3, alt_shift);
val |= (alt << alt_shift);
writel(val, base + alt_offset);
val = readl(base + STM32_GPIO_MODER);
val &= ~GENMASK(pin * 2 + 1, pin * 2);
val |= mode << (pin * 2);
writel(val, base + STM32_GPIO_MODER);
}
static inline void __stm32_pmx_get_mode(void __iomem *base, int pin,
u32 *mode, u32 *alt)
{
u32 val;
int alt_shift = (pin % 8) * 4;
int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4;
val = readl(base + alt_offset);
val &= GENMASK(alt_shift + 3, alt_shift);
*alt = val >> alt_shift;
val = readl(base + STM32_GPIO_MODER);
val &= GENMASK(pin * 2 + 1, pin * 2);
*mode = val >> (pin * 2);
}
static inline int __stm32_pmx_gpio_get(void __iomem *base, unsigned offset)
{
return !!(readl(base + STM32_GPIO_IDR) & BIT(offset));
}
static inline void __stm32_pmx_gpio_set(void __iomem *base, unsigned offset,
unsigned value)
{
if (!value)
offset += STM32_GPIO_PINS_PER_BANK;
writel(BIT(offset), base + STM32_GPIO_BSRR);
}
static inline void __stm32_pmx_gpio_input(void __iomem *base, unsigned offset)
{
__stm32_pmx_set_mode(base, offset, 0, 0);
}
static inline void __stm32_pmx_gpio_output(void __iomem *base, unsigned offset,
unsigned value)
{
__stm32_pmx_gpio_set(base, offset, value);
__stm32_pmx_set_mode(base, offset, 1, 0);
}
static inline void __stm32_pmx_set_output_type(void __iomem *base, unsigned offset,
enum stm32_pin_out_type type)
{
u32 val = readl(base + STM32_GPIO_TYPER);
val &= ~BIT(offset);
val |= type << offset;
writel(val, base + STM32_GPIO_TYPER);
}
#endif /* __STM32_GPIO_H__ */
|