cregit-Linux how code gets into the kernel

Release 4.14 arch/mips/include/asm/mach-pmcs-msp71xx/msp_gpio_macros.h

/*
 *
 * Macros for external SMP-safe access to the PMC MSP71xx reference
 * board GPIO pins
 *
 * Copyright 2010 PMC-Sierra, Inc.
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __MSP_GPIO_MACROS_H__

#define __MSP_GPIO_MACROS_H__

#include <msp_regops.h>
#include <msp_regs.h>

#ifdef CONFIG_PMC_MSP7120_GW

#define MSP_NUM_GPIOS		20
#else

#define MSP_NUM_GPIOS		28
#endif

/* -- GPIO Enumerations -- */

enum msp_gpio_data {
	
MSP_GPIO_LO = 0,
	
MSP_GPIO_HI = 1,
	
MSP_GPIO_NONE,		/* Special - Means pin is out of range */
	
MSP_GPIO_TOGGLE,	/* Special - Sets pin to opposite */
};


enum msp_gpio_mode {
	
MSP_GPIO_INPUT		= 0x0,
	/* MSP_GPIO_ INTERRUPT  = 0x1,  Not supported yet */
	
MSP_GPIO_UART_INPUT	= 0x2,	/* Only GPIO 4 or 5 */
	
MSP_GPIO_OUTPUT		= 0x8,
	
MSP_GPIO_UART_OUTPUT	= 0x9,	/* Only GPIO 2 or 3 */
	
MSP_GPIO_PERIF_TIMERA	= 0x9,	/* Only GPIO 0 or 1 */
	
MSP_GPIO_PERIF_TIMERB	= 0xa,	/* Only GPIO 0 or 1 */
	
MSP_GPIO_UNKNOWN	= 0xb,	/* No such GPIO or mode */
};

/* -- Static Tables -- */

/* Maps pins to data register */

static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
	/* GPIO 0 and 1 on the first register */
	GPIO_DATA1_REG, GPIO_DATA1_REG,
	/* GPIO 2, 3, 4, and 5 on the second register */
	GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
	/* GPIO 6, 7, 8, and 9 on the third register */
	GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
	GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
	GPIO_DATA4_REG, GPIO_DATA4_REG,
	/* GPIO 16 - 23 on the first strange EXTENDED register */
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	/* GPIO 24 - 27 on the second strange EXTENDED register */
	EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
	EXTENDED_GPIO2_REG,
};

/* Maps pins to mode register */

static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
	/* GPIO 0 and 1 on the first register */
	GPIO_CFG1_REG, GPIO_CFG1_REG,
	/* GPIO 2, 3, 4, and 5 on the second register */
	GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
	/* GPIO 6, 7, 8, and 9 on the third register */
	GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
	GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
	GPIO_CFG4_REG, GPIO_CFG4_REG,
	/* GPIO 16 - 23 on the first strange EXTENDED register */
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
	/* GPIO 24 - 27 on the second strange EXTENDED register */
	EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
	EXTENDED_GPIO2_REG,
};

/* Maps 'basic' pins to relative offset from 0 per register */

static int MSP_GPIO_OFFSET[] = {
	/* GPIO 0 and 1 on the first register */
	0, 0,
	/* GPIO 2, 3, 4, and 5 on the second register */
	2, 2, 2, 2,
	/* GPIO 6, 7, 8, and 9 on the third register */
	6, 6, 6, 6,
	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
	10, 10, 10, 10, 10, 10,
};

/* Maps MODE to allowed pin mask */

static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
	0xffffffff,	/* Mode 0 - INPUT */
	0x00000,	/* Mode 1 - INTERRUPT */
	0x00030,	/* Mode 2 - UART_INPUT (GPIO 4, 5)*/
	0, 0, 0, 0, 0,	/* Modes 3, 4, 5, 6, and 7 are reserved */
	0xffffffff,	/* Mode 8 - OUTPUT */
	0x0000f,	/* Mode 9 - UART_OUTPUT/
                                PERF_TIMERA (GPIO 0, 1, 2, 3) */
	0x00003,	/* Mode a - PERF_TIMERB (GPIO 0, 1) */
	0x00000,	/* Mode b - Not really a mode! */
};

/* -- Bit masks -- */

/* This gives you the 'register relative offset gpio' number */

#define OFFSET_GPIO_NUMBER(gpio)	(gpio - MSP_GPIO_OFFSET[gpio])

/* These take the 'register relative offset gpio' number */

#define BASIC_DATA_REG_MASK(ogpio)		(1 << ogpio)

#define BASIC_MODE_REG_VALUE(mode, ogpio)	\
	(mode << BASIC_MODE_REG_SHIFT(ogpio))

#define BASIC_MODE_REG_MASK(ogpio)		\
	BASIC_MODE_REG_VALUE(0xf, ogpio)

#define BASIC_MODE_REG_SHIFT(ogpio)		(ogpio * 4)

#define BASIC_MODE_REG_FROM_REG(data, ogpio)	\
	((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))

/* These take the actual GPIO number (0 through 15) */

#define BASIC_DATA_MASK(gpio)	\
	BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))

#define BASIC_MODE_MASK(gpio)	\
	BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))

#define BASIC_MODE(mode, gpio)	\
	BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))

#define BASIC_MODE_SHIFT(gpio)	\
	BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))

#define BASIC_MODE_FROM_REG(data, gpio) \
	BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))

/*
 * Each extended GPIO register is 32 bits long and is responsible for up to
 * eight GPIOs. The least significant 16 bits contain the set and clear bit
 * pair for each of the GPIOs. The most significant 16 bits contain the
 * disable and enable bit pair for each of the GPIOs. For example, the
 * extended GPIO reg for GPIOs 16-23 is as follows:
 *
 *      31: GPIO23_DISABLE
 *      ...
 *      19: GPIO17_DISABLE
 *      18: GPIO17_ENABLE
 *      17: GPIO16_DISABLE
 *      16: GPIO16_ENABLE
 *      ...
 *      3:  GPIO17_SET
 *      2:  GPIO17_CLEAR
 *      1:  GPIO16_SET
 *      0:  GPIO16_CLEAR
 */

/* This gives the 'register relative offset gpio' number */

#define EXTENDED_OFFSET_GPIO(gpio)	(gpio < 24 ? gpio - 16 : gpio - 24)

/* These take the 'register relative offset gpio' number */

#define EXTENDED_REG_DISABLE(ogpio)	(0x2 << ((ogpio * 2) + 16))

#define EXTENDED_REG_ENABLE(ogpio)	(0x1 << ((ogpio * 2) + 16))

#define EXTENDED_REG_SET(ogpio)		(0x2 << (ogpio * 2))

#define EXTENDED_REG_CLR(ogpio)		(0x1 << (ogpio * 2))

/* These take the actual GPIO number (16 through 27) */

#define EXTENDED_DISABLE(gpio)	\
	EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))

#define EXTENDED_ENABLE(gpio)	\
	EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))

#define EXTENDED_SET(gpio)	\
	EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))

#define EXTENDED_CLR(gpio)	\
	EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))


#define EXTENDED_FULL_MASK		(0xffffffff)

/* -- API inline-functions -- */

/*
 * Gets the current value of the specified pin
 */

static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio) { u32 pinhi_mask = 0, pinhi_mask2 = 0; if (gpio >= MSP_NUM_GPIOS) return MSP_GPIO_NONE; if (gpio < 16) { pinhi_mask = BASIC_DATA_MASK(gpio); } else { /* * Two cases are possible with the EXTENDED register: * - In output mode (ENABLED flag set), check the CLR bit * - In input mode (ENABLED flag not set), check the SET bit */ pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio); pinhi_mask2 = EXTENDED_SET(gpio); } if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) || (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2)) return MSP_GPIO_HI; else return MSP_GPIO_LO; }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A101100.00%1100.00%
Total101100.00%1100.00%

/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio) { if (gpio >= MSP_NUM_GPIOS) return; if (gpio < 16) { if (data == MSP_GPIO_TOGGLE) toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio], BASIC_DATA_MASK(gpio)); else if (data == MSP_GPIO_HI) set_reg32(MSP_GPIO_DATA_REGISTER[gpio], BASIC_DATA_MASK(gpio)); else clear_reg32(MSP_GPIO_DATA_REGISTER[gpio], BASIC_DATA_MASK(gpio)); } else { if (data == MSP_GPIO_TOGGLE) { /* Special ugly case: * We have to read the CLR bit. * If set, we write the CLR bit. * If not, we write the SET bit. */ u32 tmpdata; custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio], tmpdata); if (tmpdata & EXTENDED_CLR(gpio)) tmpdata = EXTENDED_CLR(gpio); else tmpdata = EXTENDED_SET(gpio); custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio], tmpdata); } else { u32 newdata; if (data == MSP_GPIO_HI) newdata = EXTENDED_SET(gpio); else newdata = EXTENDED_CLR(gpio); set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio], EXTENDED_FULL_MASK, newdata); } } }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A181100.00%1100.00%
Total181100.00%1100.00%

/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_hi(unsigned int gpio) { msp_gpio_pin_set(MSP_GPIO_HI, gpio); }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A18100.00%1100.00%
Total18100.00%1100.00%

/* Sets the specified pin to the specified value */
static inline void msp_gpio_pin_lo(unsigned int gpio) { msp_gpio_pin_set(MSP_GPIO_LO, gpio); }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A18100.00%1100.00%
Total18100.00%1100.00%

/* Sets the specified pin to the opposite value */
static inline void msp_gpio_pin_toggle(unsigned int gpio) { msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio); }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A18100.00%1100.00%
Total18100.00%1100.00%

/* Gets the mode of the specified pin */
static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio) { enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN; uint32_t data; if (gpio >= MSP_NUM_GPIOS) return retval; data = *MSP_GPIO_MODE_REGISTER[gpio]; if (gpio < 16) { retval = BASIC_MODE_FROM_REG(data, gpio); } else { /* Extended pins can only be either INPUT or OUTPUT */ if (data & EXTENDED_ENABLE(gpio)) retval = MSP_GPIO_OUTPUT; else retval = MSP_GPIO_INPUT; } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A80100.00%1100.00%
Total80100.00%1100.00%

/* * Sets the specified mode on the requested pin * Returns 0 on success, or -1 if that mode is not allowed on this pin */
static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio) { u32 modemask, newmode; if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode]) return -1; if (gpio >= MSP_NUM_GPIOS) return -1; if (gpio < 16) { modemask = BASIC_MODE_MASK(gpio); newmode = BASIC_MODE(mode, gpio); } else { modemask = EXTENDED_FULL_MASK; if (mode == MSP_GPIO_INPUT) newmode = EXTENDED_DISABLE(gpio); else newmode = EXTENDED_ENABLE(gpio); } /* Do the set atomically */ set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A116100.00%1100.00%
Total116100.00%1100.00%

#endif /* __MSP_GPIO_MACROS_H__ */

Overall Contributors

PersonTokensPropCommitsCommitProp
Anoop P A1035100.00%1100.00%
Total1035100.00%1100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.