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