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