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_M53xx) || defined(CONFIG_M54xx) || \ 108 defined(CONFIG_M5441x) 109 110 /* These parts have GPIO organized by 8 bit ports */ 111 112 #define MCFGPIO_PORTTYPE u8 113 #define MCFGPIO_PORTSIZE 8 114 #define mcfgpio_read(port) __raw_readb(port) 115 #define mcfgpio_write(data, port) __raw_writeb(data, port) 116 117 #elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) 118 119 /* These parts have GPIO organized by 16 bit ports */ 120 121 #define MCFGPIO_PORTTYPE u16 122 #define MCFGPIO_PORTSIZE 16 123 #define mcfgpio_read(port) __raw_readw(port) 124 #define mcfgpio_write(data, port) __raw_writew(data, port) 125 126 #elif defined(CONFIG_M5249) || defined(CONFIG_M525x) 127 128 /* These parts have GPIO organized by 32 bit ports */ 129 130 #define MCFGPIO_PORTTYPE u32 131 #define MCFGPIO_PORTSIZE 32 132 #define mcfgpio_read(port) __raw_readl(port) 133 #define mcfgpio_write(data, port) __raw_writel(data, port) 134 135 #endif 136 137 #define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) 138 #define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) 139 140 #if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 141 defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 142 defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \ 143 defined(CONFIG_M5441x) 144 /* 145 * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses 146 * read-modify-write to change an output and a GPIO module which has separate 147 * set/clr registers to directly change outputs with a single write access. 148 */ 149 #if defined(CONFIG_M528x) 150 /* 151 * The 528x also has GPIOs in other modules (GPT, QADC) which use 152 * read-modify-write as well as those controlled by the EPORT and GPIO modules. 153 */ 154 #define MCFGPIO_SCR_START 40 155 #elif defined(CONFIGM5441x) 156 /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */ 157 #define MCFGPIO_SCR_START 0 158 #else 159 #define MCFGPIO_SCR_START 8 160 #endif 161 162 #define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ 163 mcfgpio_port(gpio - MCFGPIO_SCR_START)) 164 165 #define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ 166 mcfgpio_port(gpio - MCFGPIO_SCR_START)) 167 #else 168 169 #define MCFGPIO_SCR_START MCFGPIO_PIN_MAX 170 /* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ 171 #define MCFGPIO_SETR_PORT(gpio) 0 172 #define MCFGPIO_CLRR_PORT(gpio) 0 173 174 #endif 175 /* 176 * Coldfire specific helper functions 177 */ 178 179 /* return the port pin data register for a gpio */ 180 static inline u32 __mcfgpio_ppdr(unsigned gpio) 181 { 182 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 183 defined(CONFIG_M5307) || defined(CONFIG_M5407) 184 return MCFSIM_PADAT; 185 #elif defined(CONFIG_M5272) 186 if (gpio < 16) 187 return MCFSIM_PADAT; 188 else if (gpio < 32) 189 return MCFSIM_PBDAT; 190 else 191 return MCFSIM_PCDAT; 192 #elif defined(CONFIG_M5249) || defined(CONFIG_M525x) 193 if (gpio < 32) 194 return MCFSIM2_GPIOREAD; 195 else 196 return MCFSIM2_GPIO1READ; 197 #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 198 defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 199 defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \ 200 defined(CONFIG_M5441x) 201 #if !defined(CONFIG_M5441x) 202 if (gpio < 8) 203 return MCFEPORT_EPPDR; 204 #if defined(CONFIG_M528x) 205 else if (gpio < 16) 206 return MCFGPTA_GPTPORT; 207 else if (gpio < 24) 208 return MCFGPTB_GPTPORT; 209 else if (gpio < 32) 210 return MCFQADC_PORTQA; 211 else if (gpio < 40) 212 return MCFQADC_PORTQB; 213 #endif /* defined(CONFIG_M528x) */ 214 else 215 #endif /* !defined(CONFIG_M5441x) */ 216 return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); 217 #else 218 return 0; 219 #endif 220 } 221 222 /* return the port output data register for a gpio */ 223 static inline u32 __mcfgpio_podr(unsigned gpio) 224 { 225 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 226 defined(CONFIG_M5307) || defined(CONFIG_M5407) 227 return MCFSIM_PADAT; 228 #elif defined(CONFIG_M5272) 229 if (gpio < 16) 230 return MCFSIM_PADAT; 231 else if (gpio < 32) 232 return MCFSIM_PBDAT; 233 else 234 return MCFSIM_PCDAT; 235 #elif defined(CONFIG_M5249) || defined(CONFIG_M525x) 236 if (gpio < 32) 237 return MCFSIM2_GPIOWRITE; 238 else 239 return MCFSIM2_GPIO1WRITE; 240 #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 241 defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 242 defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \ 243 defined(CONFIG_M5441x) 244 #if !defined(CONFIG_M5441x) 245 if (gpio < 8) 246 return MCFEPORT_EPDR; 247 #if defined(CONFIG_M528x) 248 else if (gpio < 16) 249 return MCFGPTA_GPTPORT; 250 else if (gpio < 24) 251 return MCFGPTB_GPTPORT; 252 else if (gpio < 32) 253 return MCFQADC_PORTQA; 254 else if (gpio < 40) 255 return MCFQADC_PORTQB; 256 #endif /* defined(CONFIG_M528x) */ 257 else 258 #endif /* !defined(CONFIG_M5441x) */ 259 return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); 260 #else 261 return 0; 262 #endif 263 } 264 265 /* return the port direction data register for a gpio */ 266 static inline u32 __mcfgpio_pddr(unsigned gpio) 267 { 268 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ 269 defined(CONFIG_M5307) || defined(CONFIG_M5407) 270 return MCFSIM_PADDR; 271 #elif defined(CONFIG_M5272) 272 if (gpio < 16) 273 return MCFSIM_PADDR; 274 else if (gpio < 32) 275 return MCFSIM_PBDDR; 276 else 277 return MCFSIM_PCDDR; 278 #elif defined(CONFIG_M5249) || defined(CONFIG_M525x) 279 if (gpio < 32) 280 return MCFSIM2_GPIOENABLE; 281 else 282 return MCFSIM2_GPIO1ENABLE; 283 #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ 284 defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 285 defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \ 286 defined(CONFIG_M5441x) 287 #if !defined(CONFIG_M5441x) 288 if (gpio < 8) 289 return MCFEPORT_EPDDR; 290 #if defined(CONFIG_M528x) 291 else if (gpio < 16) 292 return MCFGPTA_GPTDDR; 293 else if (gpio < 24) 294 return MCFGPTB_GPTDDR; 295 else if (gpio < 32) 296 return MCFQADC_DDRQA; 297 else if (gpio < 40) 298 return MCFQADC_DDRQB; 299 #endif /* defined(CONFIG_M528x) */ 300 else 301 #endif /* !defined(CONFIG_M5441x) */ 302 return MCFGPIO_PDDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); 303 #else 304 return 0; 305 #endif 306 } 307 308 #endif /* mcfgpio_h */ 309