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