Commit | Line | Data |
---|---|---|
af39bb8b | 1 | /* |
2 | * Coldfire generic GPIO support | |
3 | * | |
4 | * (C) Copyright 2009, Steven King <sfking@fdwdc.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; version 2 of the License. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | */ | |
15 | ||
16 | #ifndef coldfire_gpio_h | |
17 | #define coldfire_gpio_h | |
18 | ||
19 | #include <linux/io.h> | |
20 | #include <asm-generic/gpio.h> | |
21 | #include <asm/coldfire.h> | |
22 | #include <asm/mcfsim.h> | |
23 | ||
24 | /* | |
25 | * The Freescale Coldfire family is quite varied in how they implement GPIO. | |
26 | * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have | |
27 | * only one port, others have multiple ports; some have a single data latch | |
28 | * for both input and output, others have a separate pin data register to read | |
29 | * input; some require a read-modify-write access to change an output, others | |
30 | * have set and clear registers for some of the outputs; Some have all the | |
31 | * GPIOs in a single control area, others have some GPIOs implemented in | |
32 | * different modules. | |
33 | * | |
25985edc | 34 | * This implementation attempts accommodate the differences while presenting |
af39bb8b | 35 | * a generic interface that will optimize to as few instructions as possible. |
36 | */ | |
37 | #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ | |
38 | defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ | |
ea49f8ff | 39 | defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
5b2e6555 | 40 | defined(CONFIG_M532x) || defined(CONFIG_M54xx) |
af39bb8b | 41 | |
42 | /* These parts have GPIO organized by 8 bit ports */ | |
43 | ||
44 | #define MCFGPIO_PORTTYPE u8 | |
45 | #define MCFGPIO_PORTSIZE 8 | |
46 | #define mcfgpio_read(port) __raw_readb(port) | |
47 | #define mcfgpio_write(data, port) __raw_writeb(data, port) | |
48 | ||
49 | #elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) | |
50 | ||
51 | /* These parts have GPIO organized by 16 bit ports */ | |
52 | ||
53 | #define MCFGPIO_PORTTYPE u16 | |
54 | #define MCFGPIO_PORTSIZE 16 | |
55 | #define mcfgpio_read(port) __raw_readw(port) | |
56 | #define mcfgpio_write(data, port) __raw_writew(data, port) | |
57 | ||
58 | #elif defined(CONFIG_M5249) | |
59 | ||
60 | /* These parts have GPIO organized by 32 bit ports */ | |
61 | ||
62 | #define MCFGPIO_PORTTYPE u32 | |
63 | #define MCFGPIO_PORTSIZE 32 | |
64 | #define mcfgpio_read(port) __raw_readl(port) | |
65 | #define mcfgpio_write(data, port) __raw_writel(data, port) | |
66 | ||
67 | #endif | |
68 | ||
69 | #define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) | |
70 | #define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) | |
71 | ||
72 | #if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ | |
73 | defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) | |
74 | /* | |
75 | * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses | |
76 | * read-modify-write to change an output and a GPIO module which has separate | |
77 | * set/clr registers to directly change outputs with a single write access. | |
78 | */ | |
79 | #if defined(CONFIG_M528x) | |
80 | /* | |
81 | * The 528x also has GPIOs in other modules (GPT, QADC) which use | |
82 | * read-modify-write as well as those controlled by the EPORT and GPIO modules. | |
83 | */ | |
84 | #define MCFGPIO_SCR_START 40 | |
85 | #else | |
86 | #define MCFGPIO_SCR_START 8 | |
87 | #endif | |
88 | ||
89 | #define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ | |
90 | mcfgpio_port(gpio - MCFGPIO_SCR_START)) | |
91 | ||
92 | #define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ | |
93 | mcfgpio_port(gpio - MCFGPIO_SCR_START)) | |
94 | #else | |
95 | ||
96 | #define MCFGPIO_SCR_START MCFGPIO_PIN_MAX | |
97 | /* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ | |
98 | #define MCFGPIO_SETR_PORT(gpio) 0 | |
99 | #define MCFGPIO_CLRR_PORT(gpio) 0 | |
100 | ||
101 | #endif | |
102 | /* | |
103 | * Coldfire specific helper functions | |
104 | */ | |
105 | ||
106 | /* return the port pin data register for a gpio */ | |
107 | static inline u32 __mcf_gpio_ppdr(unsigned gpio) | |
108 | { | |
109 | #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ | |
110 | defined(CONFIG_M5307) || defined(CONFIG_M5407) | |
111 | return MCFSIM_PADAT; | |
112 | #elif defined(CONFIG_M5272) | |
113 | if (gpio < 16) | |
114 | return MCFSIM_PADAT; | |
115 | else if (gpio < 32) | |
116 | return MCFSIM_PBDAT; | |
117 | else | |
118 | return MCFSIM_PCDAT; | |
119 | #elif defined(CONFIG_M5249) | |
120 | if (gpio < 32) | |
121 | return MCFSIM2_GPIOREAD; | |
122 | else | |
123 | return MCFSIM2_GPIO1READ; | |
124 | #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ | |
125 | defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) | |
126 | if (gpio < 8) | |
127 | return MCFEPORT_EPPDR; | |
128 | #if defined(CONFIG_M528x) | |
129 | else if (gpio < 16) | |
130 | return MCFGPTA_GPTPORT; | |
131 | else if (gpio < 24) | |
132 | return MCFGPTB_GPTPORT; | |
133 | else if (gpio < 32) | |
134 | return MCFQADC_PORTQA; | |
135 | else if (gpio < 40) | |
136 | return MCFQADC_PORTQB; | |
137 | #endif | |
138 | else | |
139 | return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); | |
ea49f8ff PDM |
140 | #else |
141 | return 0; | |
af39bb8b | 142 | #endif |
143 | } | |
144 | ||
145 | /* return the port output data register for a gpio */ | |
146 | static inline u32 __mcf_gpio_podr(unsigned gpio) | |
147 | { | |
148 | #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ | |
149 | defined(CONFIG_M5307) || defined(CONFIG_M5407) | |
150 | return MCFSIM_PADAT; | |
151 | #elif defined(CONFIG_M5272) | |
152 | if (gpio < 16) | |
153 | return MCFSIM_PADAT; | |
154 | else if (gpio < 32) | |
155 | return MCFSIM_PBDAT; | |
156 | else | |
157 | return MCFSIM_PCDAT; | |
158 | #elif defined(CONFIG_M5249) | |
159 | if (gpio < 32) | |
160 | return MCFSIM2_GPIOWRITE; | |
161 | else | |
162 | return MCFSIM2_GPIO1WRITE; | |
163 | #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ | |
164 | defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) | |
165 | if (gpio < 8) | |
166 | return MCFEPORT_EPDR; | |
167 | #if defined(CONFIG_M528x) | |
168 | else if (gpio < 16) | |
169 | return MCFGPTA_GPTPORT; | |
170 | else if (gpio < 24) | |
171 | return MCFGPTB_GPTPORT; | |
172 | else if (gpio < 32) | |
173 | return MCFQADC_PORTQA; | |
174 | else if (gpio < 40) | |
175 | return MCFQADC_PORTQB; | |
176 | #endif | |
177 | else | |
178 | return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); | |
ea49f8ff PDM |
179 | #else |
180 | return 0; | |
af39bb8b | 181 | #endif |
182 | } | |
183 | ||
184 | /* | |
185 | * The Generic GPIO functions | |
186 | * | |
187 | * If the gpio is a compile time constant and is one of the Coldfire gpios, | |
188 | * use the inline version, otherwise dispatch thru gpiolib. | |
189 | */ | |
190 | ||
191 | static inline int gpio_get_value(unsigned gpio) | |
192 | { | |
193 | if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) | |
194 | return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio); | |
195 | else | |
196 | return __gpio_get_value(gpio); | |
197 | } | |
198 | ||
199 | static inline void gpio_set_value(unsigned gpio, int value) | |
200 | { | |
201 | if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) { | |
202 | if (gpio < MCFGPIO_SCR_START) { | |
203 | unsigned long flags; | |
204 | MCFGPIO_PORTTYPE data; | |
205 | ||
206 | local_irq_save(flags); | |
207 | data = mcfgpio_read(__mcf_gpio_podr(gpio)); | |
208 | if (value) | |
209 | data |= mcfgpio_bit(gpio); | |
210 | else | |
211 | data &= ~mcfgpio_bit(gpio); | |
212 | mcfgpio_write(data, __mcf_gpio_podr(gpio)); | |
213 | local_irq_restore(flags); | |
214 | } else { | |
215 | if (value) | |
216 | mcfgpio_write(mcfgpio_bit(gpio), | |
217 | MCFGPIO_SETR_PORT(gpio)); | |
218 | else | |
219 | mcfgpio_write(~mcfgpio_bit(gpio), | |
220 | MCFGPIO_CLRR_PORT(gpio)); | |
221 | } | |
222 | } else | |
223 | __gpio_set_value(gpio, value); | |
224 | } | |
225 | ||
226 | static inline int gpio_to_irq(unsigned gpio) | |
227 | { | |
228 | return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL; | |
229 | } | |
230 | ||
231 | static inline int irq_to_gpio(unsigned irq) | |
232 | { | |
233 | return (irq >= MCFGPIO_IRQ_VECBASE && | |
234 | irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ? | |
235 | irq - MCFGPIO_IRQ_VECBASE : -ENXIO; | |
236 | } | |
237 | ||
238 | static inline int gpio_cansleep(unsigned gpio) | |
239 | { | |
240 | return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); | |
241 | } | |
242 | ||
243 | #endif |