MIPS: Whitespace cleanup.
[linux-drm-fsl-dcu.git] / arch / mips / include / asm / pmc-sierra / msp71xx / msp_gpio_macros.h
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  */
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 {
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  */
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__ */