1 /* 2 * Coldfire generic GPIO support. 3 * 4 * (C) Copyright 2009, Steven King <sfking@fdwdc.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16 #ifndef mcfgpio_h 17 #define mcfgpio_h 18 19 #ifdef CONFIG_GPIOLIB 20 #include <asm-generic/gpio.h> 21 #else 22 23 int __mcfgpio_get_value(unsigned gpio); 24 void __mcfgpio_set_value(unsigned gpio, int value); 25 int __mcfgpio_direction_input(unsigned gpio); 26 int __mcfgpio_direction_output(unsigned gpio, int value); 27 int __mcfgpio_request(unsigned gpio); 28 void __mcfgpio_free(unsigned gpio); 29 30 /* our alternate 'gpiolib' functions */ 31 static inline int __gpio_get_value(unsigned gpio) 32 { 33 if (gpio < MCFGPIO_PIN_MAX) 34 return __mcfgpio_get_value(gpio); 35 else 36 return -EINVAL; 37 } 38 39 static inline void __gpio_set_value(unsigned gpio, int value) 40 { 41 if (gpio < MCFGPIO_PIN_MAX) 42 __mcfgpio_set_value(gpio, value); 43 } 44 45 static inline int __gpio_cansleep(unsigned gpio) 46 { 47 if (gpio < MCFGPIO_PIN_MAX) 48 return 0; 49 else 50 return -EINVAL; 51 } 52 53 static inline int __gpio_to_irq(unsigned gpio) 54 { 55 return -EINVAL; 56 } 57 58 static inline int gpio_direction_input(unsigned gpio) 59 { 60 if (gpio < MCFGPIO_PIN_MAX) 61 return __mcfgpio_direction_input(gpio); 62 else 63 return -EINVAL; 64 } 65 66 static inline int gpio_direction_output(unsigned gpio, int value) 67 { 68 if (gpio < MCFGPIO_PIN_MAX) 69 return __mcfgpio_direction_output(gpio, value); 70 else 71 return -EINVAL; 72 } 73 74 static inline int gpio_request(unsigned gpio, const char *label) 75 { 76 if (gpio < MCFGPIO_PIN_MAX) 77 return __mcfgpio_request(gpio); 78 else 79 return -EINVAL; 80 } 81 82 static inline void gpio_free(unsigned gpio) 83 { 84 if (gpio < MCFGPIO_PIN_MAX) 85 __mcfgpio_free(gpio); 86 } 87 88 #endif /* CONFIG_GPIOLIB */ 89 90 91 /* 92 * The Freescale Coldfire family is quite varied in how they implement GPIO. 93 * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have 94 * only one port, others have multiple ports; some have a single data latch 95 * for both input and output, others have a separate pin data register to read 96 * input; some require a read-modify-write access to change an output, others 97 * have set and clear registers for some of the outputs; Some have all the 98 * GPIOs in a single control area, others have some GPIOs implemented in 99 * different modules. 100 * 101 * This implementation attempts accommodate the differences while presenting 102 * a generic interface that will optimize to as few instructions as possible. 103 */ 104 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 105 defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 106 defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 107 defined(CONFIG_M532x) || defined(CONFIG_M54xx) 108 109 /* These parts have GPIO organized by 8 bit ports */ 110 111 #define MCFGPIO_PORTTYPE u8 112 #define MCFGPIO_PORTSIZE 8 113 #define mcfgpio_read(port) __raw_readb(port) 114 #define mcfgpio_write(data, port) __raw_writeb(data, port) 115 116 #elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) 117 118 /* These parts have GPIO organized by 16 bit ports */ 119 120 #define MCFGPIO_PORTTYPE u16 121 #define MCFGPIO_PORTSIZE 16 122 #define mcfgpio_read(port) __raw_readw(port) 123 #define mcfgpio_write(data, port) __raw_writew(data, port) 124 125 #elif defined(CONFIG_M5249) 126 127 /* These parts have GPIO organized by 32 bit ports */ 128 129 #define MCFGPIO_PORTTYPE u32 130 #define MCFGPIO_PORTSIZE 32 131 #define mcfgpio_read(port) __raw_readl(port) 132 #define mcfgpio_write(data, port) __raw_writel(data, port) 133 134 #endif 135 136 #define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) 137 #define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) 138 139 #if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 140 defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) 141 /* 142 * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses 143 * read-modify-write to change an output and a GPIO module which has separate 144 * set/clr registers to directly change outputs with a single write access. 145 */ 146 #if defined(CONFIG_M528x) 147 /* 148 * The 528x also has GPIOs in other modules (GPT, QADC) which use 149 * read-modify-write as well as those controlled by the EPORT and GPIO modules. 150 */ 151 #define MCFGPIO_SCR_START 40 152 #else 153 #define MCFGPIO_SCR_START 8 154 #endif 155 156 #define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ 157 mcfgpio_port(gpio - MCFGPIO_SCR_START)) 158 159 #define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ 160 mcfgpio_port(gpio - MCFGPIO_SCR_START)) 161 #else 162 163 #define MCFGPIO_SCR_START MCFGPIO_PIN_MAX 164 /* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ 165 #define MCFGPIO_SETR_PORT(gpio) 0 166 #define MCFGPIO_CLRR_PORT(gpio) 0 167 168 #endif 169 /* 170 * Coldfire specific helper functions 171 */ 172 173 /* return the port pin data register for a gpio */ 174 static inline u32 __mcfgpio_ppdr(unsigned gpio) 175 { 176 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 177 defined(CONFIG_M5307) || defined(CONFIG_M5407) 178 return MCFSIM_PADAT; 179 #elif defined(CONFIG_M5272) 180 if (gpio < 16) 181 return MCFSIM_PADAT; 182 else if (gpio < 32) 183 return MCFSIM_PBDAT; 184 else 185 return MCFSIM_PCDAT; 186 #elif defined(CONFIG_M5249) 187 if (gpio < 32) 188 return MCFSIM2_GPIOREAD; 189 else 190 return MCFSIM2_GPIO1READ; 191 #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 192 defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) 193 if (gpio < 8) 194 return MCFEPORT_EPPDR; 195 #if defined(CONFIG_M528x) 196 else if (gpio < 16) 197 return MCFGPTA_GPTPORT; 198 else if (gpio < 24) 199 return MCFGPTB_GPTPORT; 200 else if (gpio < 32) 201 return MCFQADC_PORTQA; 202 else if (gpio < 40) 203 return MCFQADC_PORTQB; 204 #endif 205 else 206 return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); 207 #else 208 return 0; 209 #endif 210 } 211 212 /* return the port output data register for a gpio */ 213 static inline u32 __mcfgpio_podr(unsigned gpio) 214 { 215 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 216 defined(CONFIG_M5307) || defined(CONFIG_M5407) 217 return MCFSIM_PADAT; 218 #elif defined(CONFIG_M5272) 219 if (gpio < 16) 220 return MCFSIM_PADAT; 221 else if (gpio < 32) 222 return MCFSIM_PBDAT; 223 else 224 return MCFSIM_PCDAT; 225 #elif defined(CONFIG_M5249) 226 if (gpio < 32) 227 return MCFSIM2_GPIOWRITE; 228 else 229 return MCFSIM2_GPIO1WRITE; 230 #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 231 defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) 232 if (gpio < 8) 233 return MCFEPORT_EPDR; 234 #if defined(CONFIG_M528x) 235 else if (gpio < 16) 236 return MCFGPTA_GPTPORT; 237 else if (gpio < 24) 238 return MCFGPTB_GPTPORT; 239 else if (gpio < 32) 240 return MCFQADC_PORTQA; 241 else if (gpio < 40) 242 return MCFQADC_PORTQB; 243 #endif 244 else 245 return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); 246 #else 247 return 0; 248 #endif 249 } 250 251 /* return the port direction data register for a gpio */ 252 static inline u32 __mcfgpio_pddr(unsigned gpio) 253 { 254 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 255 defined(CONFIG_M5307) || defined(CONFIG_M5407) 256 return MCFSIM_PADDR; 257 #elif defined(CONFIG_M5272) 258 if (gpio < 16) 259 return MCFSIM_PADDR; 260 else if (gpio < 32) 261 return MCFSIM_PBDDR; 262 else 263 return MCFSIM_PCDDR; 264 #elif defined(CONFIG_M5249) 265 if (gpio < 32) 266 return MCFSIM2_GPIOENABLE; 267 else 268 return MCFSIM2_GPIO1ENABLE; 269 #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 270 defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) 271 if (gpio < 8) 272 return MCFEPORT_EPDDR; 273 #if defined(CONFIG_M528x) 274 else if (gpio < 16) 275 return MCFGPTA_GPTDDR; 276 else if (gpio < 24) 277 return MCFGPTB_GPTDDR; 278 else if (gpio < 32) 279 return MCFQADC_DDRQA; 280 else if (gpio < 40) 281 return MCFQADC_DDRQB; 282 #endif 283 else 284 return MCFGPIO_PDDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); 285 #else 286 return 0; 287 #endif 288 } 289 290 #endif /* mcfgpio_h */ 291