Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
msp_gpio_macros.h
Go to the documentation of this file.
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 -- */
45  MSP_GPIO_NONE, /* Special - Means pin is out of range */
46  MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */
47 };
48 
51  /* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */
52  MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */
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 */
66  /* GPIO 2, 3, 4, and 5 on the second register */
68  /* GPIO 6, 7, 8, and 9 on the third register */
70  /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
73  /* GPIO 16 - 23 on the first strange EXTENDED register */
77  /* GPIO 24 - 27 on the second strange EXTENDED register */
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 */
86  /* GPIO 2, 3, 4, and 5 on the second register */
88  /* GPIO 6, 7, 8, and 9 on the third register */
90  /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
93  /* GPIO 16 - 23 on the first strange EXTENDED register */
97  /* GPIO 24 - 27 on the second strange EXTENDED register */
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  */
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 */
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 */
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 */
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 */
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 */
290 static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
291 {
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  */
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__ */