linux/arch/m68k/include/asm/gpio.h
<<
>>
Prefs
   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 coldfire_gpio_h
  17#define coldfire_gpio_h
  18
  19#include <linux/io.h>
  20#include <asm-generic/gpio.h>
  21#include <asm/coldfire.h>
  22#include <asm/mcfsim.h>
  23
  24/*
  25 * The Freescale Coldfire family is quite varied in how they implement GPIO.
  26 * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have
  27 * only one port, others have multiple ports; some have a single data latch
  28 * for both input and output, others have a separate pin data register to read
  29 * input; some require a read-modify-write access to change an output, others
  30 * have set and clear registers for some of the outputs; Some have all the
  31 * GPIOs in a single control area, others have some GPIOs implemented in
  32 * different modules.
  33 *
  34 * This implementation attempts accomodate the differences while presenting
  35 * a generic interface that will optimize to as few instructions as possible.
  36 */
  37#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
  38    defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
  39    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
  40
  41/* These parts have GPIO organized by 8 bit ports */
  42
  43#define MCFGPIO_PORTTYPE                u8
  44#define MCFGPIO_PORTSIZE                8
  45#define mcfgpio_read(port)              __raw_readb(port)
  46#define mcfgpio_write(data, port)       __raw_writeb(data, port)
  47
  48#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272)
  49
  50/* These parts have GPIO organized by 16 bit ports */
  51
  52#define MCFGPIO_PORTTYPE                u16
  53#define MCFGPIO_PORTSIZE                16
  54#define mcfgpio_read(port)              __raw_readw(port)
  55#define mcfgpio_write(data, port)       __raw_writew(data, port)
  56
  57#elif defined(CONFIG_M5249)
  58
  59/* These parts have GPIO organized by 32 bit ports */
  60
  61#define MCFGPIO_PORTTYPE                u32
  62#define MCFGPIO_PORTSIZE                32
  63#define mcfgpio_read(port)              __raw_readl(port)
  64#define mcfgpio_write(data, port)       __raw_writel(data, port)
  65
  66#endif
  67
  68#define mcfgpio_bit(gpio)               (1 << ((gpio) %  MCFGPIO_PORTSIZE))
  69#define mcfgpio_port(gpio)              ((gpio) / MCFGPIO_PORTSIZE)
  70
  71#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
  72    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
  73/*
  74 * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses
  75 * read-modify-write to change an output and a GPIO module which has separate
  76 * set/clr registers to directly change outputs with a single write access.
  77 */
  78#if defined(CONFIG_M528x)
  79/*
  80 * The 528x also has GPIOs in other modules (GPT, QADC) which use
  81 * read-modify-write as well as those controlled by the EPORT and GPIO modules.
  82 */
  83#define MCFGPIO_SCR_START               40
  84#else
  85#define MCFGPIO_SCR_START               8
  86#endif
  87
  88#define MCFGPIO_SETR_PORT(gpio)         (MCFGPIO_SETR + \
  89                                        mcfgpio_port(gpio - MCFGPIO_SCR_START))
  90
  91#define MCFGPIO_CLRR_PORT(gpio)         (MCFGPIO_CLRR + \
  92                                        mcfgpio_port(gpio - MCFGPIO_SCR_START))
  93#else
  94
  95#define MCFGPIO_SCR_START               MCFGPIO_PIN_MAX
  96/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */
  97#define MCFGPIO_SETR_PORT(gpio)         0
  98#define MCFGPIO_CLRR_PORT(gpio)         0
  99
 100#endif
 101/*
 102 * Coldfire specific helper functions
 103 */
 104
 105/* return the port pin data register for a gpio */
 106static inline u32 __mcf_gpio_ppdr(unsigned gpio)
 107{
 108#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
 109    defined(CONFIG_M5307) || defined(CONFIG_M5407)
 110        return MCFSIM_PADAT;
 111#elif defined(CONFIG_M5272)
 112        if (gpio < 16)
 113                return MCFSIM_PADAT;
 114        else if (gpio < 32)
 115                return MCFSIM_PBDAT;
 116        else
 117                return MCFSIM_PCDAT;
 118#elif defined(CONFIG_M5249)
 119        if (gpio < 32)
 120                return MCFSIM2_GPIOREAD;
 121        else
 122                return MCFSIM2_GPIO1READ;
 123#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
 124      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
 125        if (gpio < 8)
 126                return MCFEPORT_EPPDR;
 127#if defined(CONFIG_M528x)
 128        else if (gpio < 16)
 129                return MCFGPTA_GPTPORT;
 130        else if (gpio < 24)
 131                return MCFGPTB_GPTPORT;
 132        else if (gpio < 32)
 133                return MCFQADC_PORTQA;
 134        else if (gpio < 40)
 135                return MCFQADC_PORTQB;
 136#endif
 137        else
 138                return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
 139#endif
 140}
 141
 142/* return the port output data register for a gpio */
 143static inline u32 __mcf_gpio_podr(unsigned gpio)
 144{
 145#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
 146    defined(CONFIG_M5307) || defined(CONFIG_M5407)
 147        return MCFSIM_PADAT;
 148#elif defined(CONFIG_M5272)
 149        if (gpio < 16)
 150                return MCFSIM_PADAT;
 151        else if (gpio < 32)
 152                return MCFSIM_PBDAT;
 153        else
 154                return MCFSIM_PCDAT;
 155#elif defined(CONFIG_M5249)
 156        if (gpio < 32)
 157                return MCFSIM2_GPIOWRITE;
 158        else
 159                return MCFSIM2_GPIO1WRITE;
 160#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
 161      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
 162        if (gpio < 8)
 163                return MCFEPORT_EPDR;
 164#if defined(CONFIG_M528x)
 165        else if (gpio < 16)
 166                return MCFGPTA_GPTPORT;
 167        else if (gpio < 24)
 168                return MCFGPTB_GPTPORT;
 169        else if (gpio < 32)
 170                return MCFQADC_PORTQA;
 171        else if (gpio < 40)
 172                return MCFQADC_PORTQB;
 173#endif
 174        else
 175                return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
 176#endif
 177}
 178
 179/*
 180 * The Generic GPIO functions
 181 *
 182 * If the gpio is a compile time constant and is one of the Coldfire gpios,
 183 * use the inline version, otherwise dispatch thru gpiolib.
 184 */
 185
 186static inline int gpio_get_value(unsigned gpio)
 187{
 188        if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX)
 189                return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio);
 190        else
 191                return __gpio_get_value(gpio);
 192}
 193
 194static inline void gpio_set_value(unsigned gpio, int value)
 195{
 196        if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) {
 197                if (gpio < MCFGPIO_SCR_START) {
 198                        unsigned long flags;
 199                        MCFGPIO_PORTTYPE data;
 200
 201                        local_irq_save(flags);
 202                        data = mcfgpio_read(__mcf_gpio_podr(gpio));
 203                        if (value)
 204                                data |= mcfgpio_bit(gpio);
 205                        else
 206                                data &= ~mcfgpio_bit(gpio);
 207                        mcfgpio_write(data, __mcf_gpio_podr(gpio));
 208                        local_irq_restore(flags);
 209                } else {
 210                        if (value)
 211                                mcfgpio_write(mcfgpio_bit(gpio),
 212                                                MCFGPIO_SETR_PORT(gpio));
 213                        else
 214                                mcfgpio_write(~mcfgpio_bit(gpio),
 215                                                MCFGPIO_CLRR_PORT(gpio));
 216                }
 217        } else
 218                __gpio_set_value(gpio, value);
 219}
 220
 221static inline int gpio_to_irq(unsigned gpio)
 222{
 223        return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL;
 224}
 225
 226static inline int irq_to_gpio(unsigned irq)
 227{
 228        return (irq >= MCFGPIO_IRQ_VECBASE &&
 229                irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ?
 230                irq - MCFGPIO_IRQ_VECBASE : -ENXIO;
 231}
 232
 233static inline int gpio_cansleep(unsigned gpio)
 234{
 235        return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
 236}
 237
 238#endif
 239