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 11int __mcfgpio_get_value(unsigned gpio); 12void __mcfgpio_set_value(unsigned gpio, int value); 13int __mcfgpio_direction_input(unsigned gpio); 14int __mcfgpio_direction_output(unsigned gpio, int value); 15int __mcfgpio_request(unsigned gpio); 16void __mcfgpio_free(unsigned gpio); 17 18#ifdef CONFIG_GPIOLIB 19#include <linux/gpio.h> 20#else 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_to_irq(unsigned gpio) 38{ 39 return -EINVAL; 40} 41 42static 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 50static 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 58static 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 66static 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 */ 164static 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 */ 207static 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 */ 250static 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