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