3 * Macros for external SMP-safe access to the PMC MSP71xx reference
6 * Copyright 2010 PMC-Sierra, Inc.
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.
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.
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.
29 #ifndef __MSP_GPIO_MACROS_H__
30 #define __MSP_GPIO_MACROS_H__
32 #include <msp_regops.h>
35 #ifdef CONFIG_PMC_MSP7120_GW
36 #define MSP_NUM_GPIOS 20
38 #define MSP_NUM_GPIOS 28
41 /* -- GPIO Enumerations -- */
45 MSP_GPIO_NONE
, /* Special - Means pin is out of range */
46 MSP_GPIO_TOGGLE
, /* Special - Sets pin to opposite */
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 */
60 /* -- Static Tables -- */
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
,
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
,
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 */
106 /* GPIO 2, 3, 4, and 5 on the second register */
108 /* GPIO 6, 7, 8, and 9 on the third register */
110 /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
111 10, 10, 10, 10, 10, 10,
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! */
127 /* -- Bit masks -- */
129 /* This gives you the 'register relative offset gpio' number */
130 #define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio])
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))
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))
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:
174 /* This gives the 'register relative offset gpio' number */
175 #define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24)
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))
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))
193 #define EXTENDED_FULL_MASK (0xffffffff)
195 /* -- API inline-functions -- */
198 * Gets the current value of the specified pin
200 static inline enum msp_gpio_data
msp_gpio_pin_get(unsigned int gpio
)
202 u32 pinhi_mask
= 0, pinhi_mask2
= 0;
204 if (gpio
>= MSP_NUM_GPIOS
)
205 return MSP_GPIO_NONE
;
208 pinhi_mask
= BASIC_DATA_MASK(gpio
);
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
215 pinhi_mask
= EXTENDED_ENABLE(gpio
) | EXTENDED_CLR(gpio
);
216 pinhi_mask2
= EXTENDED_SET(gpio
);
218 if (((*MSP_GPIO_DATA_REGISTER
[gpio
] & pinhi_mask
) == pinhi_mask
) ||
219 (*MSP_GPIO_DATA_REGISTER
[gpio
] & pinhi_mask2
))
225 /* Sets the specified pin to the specified value */
226 static inline void msp_gpio_pin_set(enum msp_gpio_data data
, unsigned int gpio
)
228 if (gpio
>= MSP_NUM_GPIOS
)
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
));
239 clear_reg32(MSP_GPIO_DATA_REGISTER
[gpio
],
240 BASIC_DATA_MASK(gpio
));
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.
250 custom_read_reg32(MSP_GPIO_DATA_REGISTER
[gpio
],
252 if (tmpdata
& EXTENDED_CLR(gpio
))
253 tmpdata
= EXTENDED_CLR(gpio
);
255 tmpdata
= EXTENDED_SET(gpio
);
256 custom_write_reg32(MSP_GPIO_DATA_REGISTER
[gpio
],
261 if (data
== MSP_GPIO_HI
)
262 newdata
= EXTENDED_SET(gpio
);
264 newdata
= EXTENDED_CLR(gpio
);
265 set_value_reg32(MSP_GPIO_DATA_REGISTER
[gpio
],
266 EXTENDED_FULL_MASK
, newdata
);
271 /* Sets the specified pin to the specified value */
272 static inline void msp_gpio_pin_hi(unsigned int gpio
)
274 msp_gpio_pin_set(MSP_GPIO_HI
, gpio
);
277 /* Sets the specified pin to the specified value */
278 static inline void msp_gpio_pin_lo(unsigned int gpio
)
280 msp_gpio_pin_set(MSP_GPIO_LO
, gpio
);
283 /* Sets the specified pin to the opposite value */
284 static inline void msp_gpio_pin_toggle(unsigned int gpio
)
286 msp_gpio_pin_set(MSP_GPIO_TOGGLE
, gpio
);
289 /* Gets the mode of the specified pin */
290 static inline enum msp_gpio_mode
msp_gpio_pin_get_mode(unsigned int gpio
)
292 enum msp_gpio_mode retval
= MSP_GPIO_UNKNOWN
;
295 if (gpio
>= MSP_NUM_GPIOS
)
298 data
= *MSP_GPIO_MODE_REGISTER
[gpio
];
301 retval
= BASIC_MODE_FROM_REG(data
, gpio
);
303 /* Extended pins can only be either INPUT or OUTPUT */
304 if (data
& EXTENDED_ENABLE(gpio
))
305 retval
= MSP_GPIO_OUTPUT
;
307 retval
= MSP_GPIO_INPUT
;
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
317 static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode
, unsigned int gpio
)
319 u32 modemask
, newmode
;
321 if ((1 << gpio
) & ~MSP_GPIO_MODE_ALLOWED
[mode
])
324 if (gpio
>= MSP_NUM_GPIOS
)
328 modemask
= BASIC_MODE_MASK(gpio
);
329 newmode
= BASIC_MODE(mode
, gpio
);
331 modemask
= EXTENDED_FULL_MASK
;
332 if (mode
== MSP_GPIO_INPUT
)
333 newmode
= EXTENDED_DISABLE(gpio
);
335 newmode
= EXTENDED_ENABLE(gpio
);
337 /* Do the set atomically */
338 set_value_reg32(MSP_GPIO_MODE_REGISTER
[gpio
], modemask
, newmode
);
343 #endif /* __MSP_GPIO_MACROS_H__ */