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