linux/arch/m68k/coldfire/gpio.c
<<
>>
Prefs
   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#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/init.h>
  11#include <linux/device.h>
  12
  13#include <linux/io.h>
  14#include <asm/coldfire.h>
  15#include <asm/mcfsim.h>
  16#include <asm/mcfgpio.h>
  17
  18int __mcfgpio_get_value(unsigned gpio)
  19{
  20        return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
  21}
  22EXPORT_SYMBOL(__mcfgpio_get_value);
  23
  24void __mcfgpio_set_value(unsigned gpio, int value)
  25{
  26        if (gpio < MCFGPIO_SCR_START) {
  27                unsigned long flags;
  28                MCFGPIO_PORTTYPE data;
  29
  30                local_irq_save(flags);
  31                data = mcfgpio_read(__mcfgpio_podr(gpio));
  32                if (value)
  33                        data |= mcfgpio_bit(gpio);
  34                else
  35                        data &= ~mcfgpio_bit(gpio);
  36                mcfgpio_write(data, __mcfgpio_podr(gpio));
  37                local_irq_restore(flags);
  38        } else {
  39                if (value)
  40                        mcfgpio_write(mcfgpio_bit(gpio),
  41                                        MCFGPIO_SETR_PORT(gpio));
  42                else
  43                        mcfgpio_write(~mcfgpio_bit(gpio),
  44                                        MCFGPIO_CLRR_PORT(gpio));
  45        }
  46}
  47EXPORT_SYMBOL(__mcfgpio_set_value);
  48
  49int __mcfgpio_direction_input(unsigned gpio)
  50{
  51        unsigned long flags;
  52        MCFGPIO_PORTTYPE dir;
  53
  54        local_irq_save(flags);
  55        dir = mcfgpio_read(__mcfgpio_pddr(gpio));
  56        dir &= ~mcfgpio_bit(gpio);
  57        mcfgpio_write(dir, __mcfgpio_pddr(gpio));
  58        local_irq_restore(flags);
  59
  60        return 0;
  61}
  62EXPORT_SYMBOL(__mcfgpio_direction_input);
  63
  64int __mcfgpio_direction_output(unsigned gpio, int value)
  65{
  66        unsigned long flags;
  67        MCFGPIO_PORTTYPE data;
  68
  69        local_irq_save(flags);
  70        data = mcfgpio_read(__mcfgpio_pddr(gpio));
  71        data |= mcfgpio_bit(gpio);
  72        mcfgpio_write(data, __mcfgpio_pddr(gpio));
  73
  74        /* now set the data to output */
  75        if (gpio < MCFGPIO_SCR_START) {
  76                data = mcfgpio_read(__mcfgpio_podr(gpio));
  77                if (value)
  78                        data |= mcfgpio_bit(gpio);
  79                else
  80                        data &= ~mcfgpio_bit(gpio);
  81                mcfgpio_write(data, __mcfgpio_podr(gpio));
  82        } else {
  83                 if (value)
  84                        mcfgpio_write(mcfgpio_bit(gpio),
  85                                        MCFGPIO_SETR_PORT(gpio));
  86                 else
  87                         mcfgpio_write(~mcfgpio_bit(gpio),
  88                                         MCFGPIO_CLRR_PORT(gpio));
  89        }
  90        local_irq_restore(flags);
  91        return 0;
  92}
  93EXPORT_SYMBOL(__mcfgpio_direction_output);
  94
  95int __mcfgpio_request(unsigned gpio)
  96{
  97        return 0;
  98}
  99EXPORT_SYMBOL(__mcfgpio_request);
 100
 101void __mcfgpio_free(unsigned gpio)
 102{
 103        __mcfgpio_direction_input(gpio);
 104}
 105EXPORT_SYMBOL(__mcfgpio_free);
 106
 107#ifdef CONFIG_GPIOLIB
 108
 109static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
 110{
 111        return __mcfgpio_direction_input(offset);
 112}
 113
 114static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
 115{
 116        return !!__mcfgpio_get_value(offset);
 117}
 118
 119static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
 120                                    int value)
 121{
 122        return __mcfgpio_direction_output(offset, value);
 123}
 124
 125static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
 126                              int value)
 127{
 128        __mcfgpio_set_value(offset, value);
 129}
 130
 131static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
 132{
 133        return __mcfgpio_request(offset);
 134}
 135
 136static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
 137{
 138        __mcfgpio_free(offset);
 139}
 140
 141static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
 142{
 143#if defined(MCFGPIO_IRQ_MIN)
 144        if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
 145#else
 146        if (offset < MCFGPIO_IRQ_MAX)
 147#endif
 148                return MCFGPIO_IRQ_VECBASE + offset;
 149        else
 150                return -EINVAL;
 151}
 152
 153static struct gpio_chip mcfgpio_chip = {
 154        .label                  = "mcfgpio",
 155        .request                = mcfgpio_request,
 156        .free                   = mcfgpio_free,
 157        .direction_input        = mcfgpio_direction_input,
 158        .direction_output       = mcfgpio_direction_output,
 159        .get                    = mcfgpio_get_value,
 160        .set                    = mcfgpio_set_value,
 161        .to_irq                 = mcfgpio_to_irq,
 162        .base                   = 0,
 163        .ngpio                  = MCFGPIO_PIN_MAX,
 164};
 165
 166static int __init mcfgpio_sysinit(void)
 167{
 168        return gpiochip_add_data(&mcfgpio_chip, NULL);
 169}
 170
 171core_initcall(mcfgpio_sysinit);
 172#endif
 173