mcfgpio.h (8268B)
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 <asm-generic/gpio.h> 13#else 14 15int __mcfgpio_get_value(unsigned gpio); 16void __mcfgpio_set_value(unsigned gpio, int value); 17int __mcfgpio_direction_input(unsigned gpio); 18int __mcfgpio_direction_output(unsigned gpio, int value); 19int __mcfgpio_request(unsigned gpio); 20void __mcfgpio_free(unsigned gpio); 21 22/* our alternate 'gpiolib' functions */ 23static 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 31static inline void __gpio_set_value(unsigned gpio, int value) 32{ 33 if (gpio < MCFGPIO_PIN_MAX) 34 __mcfgpio_set_value(gpio, value); 35} 36 37static inline int __gpio_cansleep(unsigned gpio) 38{ 39 if (gpio < MCFGPIO_PIN_MAX) 40 return 0; 41 else 42 return -EINVAL; 43} 44 45static inline int __gpio_to_irq(unsigned gpio) 46{ 47 return -EINVAL; 48} 49 50static 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 58static 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 66static 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 74static 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 */ 172static 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 */ 215static 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 */ 258static 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 */