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