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__ */ 344