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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
/*
* Copyright (C) 2008 Atmel Corporation
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __AVR32_PORTMUX_GPIO_H__
#define __AVR32_PORTMUX_GPIO_H__
#include <asm/io.h>
/* Register offsets */
struct gpio_regs {
u32 GPER;
u32 GPERS;
u32 GPERC;
u32 GPERT;
u32 PMR0;
u32 PMR0S;
u32 PMR0C;
u32 PMR0T;
u32 PMR1;
u32 PMR1S;
u32 PMR1C;
u32 PMR1T;
u32 __reserved0[4];
u32 ODER;
u32 ODERS;
u32 ODERC;
u32 ODERT;
u32 OVR;
u32 OVRS;
u32 OVRC;
u32 OVRT;
u32 PVR;
u32 __reserved_PVRS;
u32 __reserved_PVRC;
u32 __reserved_PVRT;
u32 PUER;
u32 PUERS;
u32 PUERC;
u32 PUERT;
u32 PDER;
u32 PDERS;
u32 PDERC;
u32 PDERT;
u32 IER;
u32 IERS;
u32 IERC;
u32 IERT;
u32 IMR0;
u32 IMR0S;
u32 IMR0C;
u32 IMR0T;
u32 IMR1;
u32 IMR1S;
u32 IMR1C;
u32 IMR1T;
u32 GFER;
u32 GFERS;
u32 GFERC;
u32 GFERT;
u32 IFR;
u32 __reserved_IFRS;
u32 IFRC;
u32 __reserved_IFRT;
u32 ODMER;
u32 ODMERS;
u32 ODMERC;
u32 ODMERT;
u32 __reserved1[4];
u32 ODCR0;
u32 ODCR0S;
u32 ODCR0C;
u32 ODCR0T;
u32 ODCR1;
u32 ODCR1S;
u32 ODCR1C;
u32 ODCR1T;
u32 __reserved2[4];
u32 OSRR0;
u32 OSRR0S;
u32 OSRR0C;
u32 OSRR0T;
u32 __reserved3[8];
u32 STER;
u32 STERS;
u32 STERC;
u32 STERT;
u32 __reserved4[35];
u32 VERSION;
};
/* Register access macros */
#define gpio_readl(port, reg) \
__raw_readl(&((struct gpio_regs *)port)->reg)
#define gpio_writel(gpio, reg, value) \
__raw_writel(value, &((struct gpio_regs *)port)->reg)
/* Portmux API starts here. See doc/README.AVR32-port-muxing */
enum portmux_function {
PORTMUX_FUNC_A,
PORTMUX_FUNC_B,
PORTMUX_FUNC_C,
PORTMUX_FUNC_D,
};
#define PORTMUX_DIR_INPUT (0 << 0)
#define PORTMUX_DIR_OUTPUT (1 << 0)
#define PORTMUX_INIT_LOW (0 << 1)
#define PORTMUX_INIT_HIGH (1 << 1)
#define PORTMUX_PULL_UP (1 << 2)
#define PORTMUX_PULL_DOWN (2 << 2)
#define PORTMUX_BUSKEEPER (3 << 2)
#define PORTMUX_DRIVE_MIN (0 << 4)
#define PORTMUX_DRIVE_LOW (1 << 4)
#define PORTMUX_DRIVE_HIGH (2 << 4)
#define PORTMUX_DRIVE_MAX (3 << 4)
#define PORTMUX_OPEN_DRAIN (1 << 6)
void portmux_select_peripheral(void *port, unsigned long pin_mask,
enum portmux_function func, unsigned long flags);
void portmux_select_gpio(void *port, unsigned long pin_mask,
unsigned long flags);
/* Internal helper functions */
static inline void *gpio_pin_to_port(unsigned int pin)
{
return (void *)GPIO_BASE + (pin >> 5) * 0x200;
}
static inline void __gpio_set_output_value(void *port, unsigned int pin,
int value)
{
if (value)
gpio_writel(port, OVRS, 1 << pin);
else
gpio_writel(port, OVRC, 1 << pin);
}
static inline int __gpio_get_input_value(void *port, unsigned int pin)
{
return (gpio_readl(port, PVR) >> pin) & 1;
}
void gpio_set_output_value(unsigned int pin, int value);
int gpio_get_input_value(unsigned int pin);
/* GPIO API starts here */
/*
* GCC doesn't realize that the constant case is extremely trivial,
* so we need to help it make the right decision by using
* always_inline.
*/
__attribute__((always_inline))
static inline void gpio_set_value(unsigned int pin, int value)
{
if (__builtin_constant_p(pin))
__gpio_set_output_value(gpio_pin_to_port(pin),
pin & 0x1f, value);
else
gpio_set_output_value(pin, value);
}
__attribute__((always_inline))
static inline int gpio_get_value(unsigned int pin)
{
if (__builtin_constant_p(pin))
return __gpio_get_input_value(gpio_pin_to_port(pin),
pin & 0x1f);
else
return gpio_get_input_value(pin);
}
#endif /* __AVR32_PORTMUX_GPIO_H__ */
|