Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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 -- */
 42enum 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
 49enum 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 */
 63static 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 */
 83static 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 */
103static 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 */
115static 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 */
200static 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 */
226static 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 */
272static 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 */
278static 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 */
284static 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 */
290static 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 */
317static 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__ */