1 /*
2 *
3 * Macros for external SMP-safe access to the PMC MSP71xx reference
4 * board GPIO pins
5 *
6 * Copyright 2010 PMC-Sierra, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29 #ifndef __MSP_GPIO_MACROS_H__
30 #define __MSP_GPIO_MACROS_H__
31
32 #include <msp_regops.h>
33 #include <msp_regs.h>
34
35 #ifdef CONFIG_PMC_MSP7120_GW
36 #define MSP_NUM_GPIOS 20
37 #else
38 #define MSP_NUM_GPIOS 28
39 #endif
40
41 /* -- GPIO Enumerations -- */
42 enum msp_gpio_data {
43 MSP_GPIO_LO = 0,
44 MSP_GPIO_HI = 1,
45 MSP_GPIO_NONE, /* Special - Means pin is out of range */
46 MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */
47 };
48
49 enum msp_gpio_mode {
50 MSP_GPIO_INPUT = 0x0,
51 /* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */
52 MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */
53 MSP_GPIO_OUTPUT = 0x8,
54 MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */
55 MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */
56 MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */
57 MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */
58 };
59
60 /* -- Static Tables -- */
61
62 /* Maps pins to data register */
63 static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
64 /* GPIO 0 and 1 on the first register */
65 GPIO_DATA1_REG, GPIO_DATA1_REG,
66 /* GPIO 2, 3, 4, and 5 on the second register */
67 GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
68 /* GPIO 6, 7, 8, and 9 on the third register */
69 GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
70 /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
71 GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
72 GPIO_DATA4_REG, GPIO_DATA4_REG,
73 /* GPIO 16 - 23 on the first strange EXTENDED register */
74 EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
75 EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
76 EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
77 /* GPIO 24 - 27 on the second strange EXTENDED register */
78 EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
79 EXTENDED_GPIO2_REG,
80 };
81
82 /* Maps pins to mode register */
83 static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
84 /* GPIO 0 and 1 on the first register */
85 GPIO_CFG1_REG, GPIO_CFG1_REG,
86 /* GPIO 2, 3, 4, and 5 on the second register */
87 GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
88 /* GPIO 6, 7, 8, and 9 on the third register */
89 GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
90 /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
91 GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
92 GPIO_CFG4_REG, GPIO_CFG4_REG,
93 /* GPIO 16 - 23 on the first strange EXTENDED register */
94 EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
95 EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
96 EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
97 /* GPIO 24 - 27 on the second strange EXTENDED register */
98 EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
99 EXTENDED_GPIO2_REG,
100 };
101
102 /* Maps 'basic' pins to relative offset from 0 per register */
103 static int MSP_GPIO_OFFSET[] = {
104 /* GPIO 0 and 1 on the first register */
105 0, 0,
106 /* GPIO 2, 3, 4, and 5 on the second register */
107 2, 2, 2, 2,
108 /* GPIO 6, 7, 8, and 9 on the third register */
109 6, 6, 6, 6,
110 /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
111 10, 10, 10, 10, 10, 10,
112 };
113
114 /* Maps MODE to allowed pin mask */
115 static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
116 0xffffffff, /* Mode 0 - INPUT */
117 0x00000, /* Mode 1 - INTERRUPT */
118 0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/
119 0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */
120 0xffffffff, /* Mode 8 - OUTPUT */
121 0x0000f, /* Mode 9 - UART_OUTPUT/
122 PERF_TIMERA (GPIO 0, 1, 2, 3) */
123 0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */
124 0x00000, /* Mode b - Not really a mode! */
125 };
126
127 /* -- Bit masks -- */
128
129 /* This gives you the 'register relative offset gpio' number */
130 #define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio])
131
132 /* These take the 'register relative offset gpio' number */
133 #define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio)
134 #define BASIC_MODE_REG_VALUE(mode, ogpio) \
135 (mode << BASIC_MODE_REG_SHIFT(ogpio))
136 #define BASIC_MODE_REG_MASK(ogpio) \
137 BASIC_MODE_REG_VALUE(0xf, ogpio)
138 #define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4)
139 #define BASIC_MODE_REG_FROM_REG(data, ogpio) \
140 ((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))
141
142 /* These take the actual GPIO number (0 through 15) */
143 #define BASIC_DATA_MASK(gpio) \
144 BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
145 #define BASIC_MODE_MASK(gpio) \
146 BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
147 #define BASIC_MODE(mode, gpio) \
148 BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
149 #define BASIC_MODE_SHIFT(gpio) \
150 BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
151 #define BASIC_MODE_FROM_REG(data, gpio) \
152 BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))
153
154 /*
155 * Each extended GPIO register is 32 bits long and is responsible for up to
156 * eight GPIOs. The least significant 16 bits contain the set and clear bit
157 * pair for each of the GPIOs. The most significant 16 bits contain the
158 * disable and enable bit pair for each of the GPIOs. For example, the
159 * extended GPIO reg for GPIOs 16-23 is as follows:
160 *
161 * 31: GPIO23_DISABLE
162 * ...
163 * 19: GPIO17_DISABLE
164 * 18: GPIO17_ENABLE
165 * 17: GPIO16_DISABLE
166 * 16: GPIO16_ENABLE
167 * ...
168 * 3: GPIO17_SET
169 * 2: GPIO17_CLEAR
170 * 1: GPIO16_SET
171 * 0: GPIO16_CLEAR
172 */
173
174 /* This gives the 'register relative offset gpio' number */
175 #define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24)
176
177 /* These take the 'register relative offset gpio' number */
178 #define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16))
179 #define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16))
180 #define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2))
181 #define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2))
182
183 /* These take the actual GPIO number (16 through 27) */
184 #define EXTENDED_DISABLE(gpio) \
185 EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
186 #define EXTENDED_ENABLE(gpio) \
187 EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
188 #define EXTENDED_SET(gpio) \
189 EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
190 #define EXTENDED_CLR(gpio) \
191 EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))
192
193 #define EXTENDED_FULL_MASK (0xffffffff)
194
195 /* -- API inline-functions -- */
196
197 /*
198 * Gets the current value of the specified pin
199 */
msp_gpio_pin_get(unsigned int gpio)200 static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio)
201 {
202 u32 pinhi_mask = 0, pinhi_mask2 = 0;
203
204 if (gpio >= MSP_NUM_GPIOS)
205 return MSP_GPIO_NONE;
206
207 if (gpio < 16) {
208 pinhi_mask = BASIC_DATA_MASK(gpio);
209 } else {
210 /*
211 * Two cases are possible with the EXTENDED register:
212 * - In output mode (ENABLED flag set), check the CLR bit
213 * - In input mode (ENABLED flag not set), check the SET bit
214 */
215 pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio);
216 pinhi_mask2 = EXTENDED_SET(gpio);
217 }
218 if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) ||
219 (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2))
220 return MSP_GPIO_HI;
221 else
222 return MSP_GPIO_LO;
223 }
224
225 /* Sets the specified pin to the specified value */
msp_gpio_pin_set(enum msp_gpio_data data,unsigned int gpio)226 static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio)
227 {
228 if (gpio >= MSP_NUM_GPIOS)
229 return;
230
231 if (gpio < 16) {
232 if (data == MSP_GPIO_TOGGLE)
233 toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio],
234 BASIC_DATA_MASK(gpio));
235 else if (data == MSP_GPIO_HI)
236 set_reg32(MSP_GPIO_DATA_REGISTER[gpio],
237 BASIC_DATA_MASK(gpio));
238 else
239 clear_reg32(MSP_GPIO_DATA_REGISTER[gpio],
240 BASIC_DATA_MASK(gpio));
241 } else {
242 if (data == MSP_GPIO_TOGGLE) {
243 /* Special ugly case:
244 * We have to read the CLR bit.
245 * If set, we write the CLR bit.
246 * If not, we write the SET bit.
247 */
248 u32 tmpdata;
249
250 custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio],
251 tmpdata);
252 if (tmpdata & EXTENDED_CLR(gpio))
253 tmpdata = EXTENDED_CLR(gpio);
254 else
255 tmpdata = EXTENDED_SET(gpio);
256 custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio],
257 tmpdata);
258 } else {
259 u32 newdata;
260
261 if (data == MSP_GPIO_HI)
262 newdata = EXTENDED_SET(gpio);
263 else
264 newdata = EXTENDED_CLR(gpio);
265 set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio],
266 EXTENDED_FULL_MASK, newdata);
267 }
268 }
269 }
270
271 /* Sets the specified pin to the specified value */
msp_gpio_pin_hi(unsigned int gpio)272 static inline void msp_gpio_pin_hi(unsigned int gpio)
273 {
274 msp_gpio_pin_set(MSP_GPIO_HI, gpio);
275 }
276
277 /* Sets the specified pin to the specified value */
msp_gpio_pin_lo(unsigned int gpio)278 static inline void msp_gpio_pin_lo(unsigned int gpio)
279 {
280 msp_gpio_pin_set(MSP_GPIO_LO, gpio);
281 }
282
283 /* Sets the specified pin to the opposite value */
msp_gpio_pin_toggle(unsigned int gpio)284 static inline void msp_gpio_pin_toggle(unsigned int gpio)
285 {
286 msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio);
287 }
288
289 /* Gets the mode of the specified pin */
msp_gpio_pin_get_mode(unsigned int gpio)290 static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
291 {
292 enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN;
293 uint32_t data;
294
295 if (gpio >= MSP_NUM_GPIOS)
296 return retval;
297
298 data = *MSP_GPIO_MODE_REGISTER[gpio];
299
300 if (gpio < 16) {
301 retval = BASIC_MODE_FROM_REG(data, gpio);
302 } else {
303 /* Extended pins can only be either INPUT or OUTPUT */
304 if (data & EXTENDED_ENABLE(gpio))
305 retval = MSP_GPIO_OUTPUT;
306 else
307 retval = MSP_GPIO_INPUT;
308 }
309
310 return retval;
311 }
312
313 /*
314 * Sets the specified mode on the requested pin
315 * Returns 0 on success, or -1 if that mode is not allowed on this pin
316 */
msp_gpio_pin_mode(enum msp_gpio_mode mode,unsigned int gpio)317 static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio)
318 {
319 u32 modemask, newmode;
320
321 if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode])
322 return -1;
323
324 if (gpio >= MSP_NUM_GPIOS)
325 return -1;
326
327 if (gpio < 16) {
328 modemask = BASIC_MODE_MASK(gpio);
329 newmode = BASIC_MODE(mode, gpio);
330 } else {
331 modemask = EXTENDED_FULL_MASK;
332 if (mode == MSP_GPIO_INPUT)
333 newmode = EXTENDED_DISABLE(gpio);
334 else
335 newmode = EXTENDED_ENABLE(gpio);
336 }
337 /* Do the set atomically */
338 set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode);
339
340 return 0;
341 }
342
343 #endif /* __MSP_GPIO_MACROS_H__ */
344