linux/drivers/gpio/gpio-tqmx86.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * TQ-Systems TQMx86 PLD GPIO driver
   4 *
   5 * Based on vendor driver by:
   6 *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
   7 */
   8
   9#include <linux/bitops.h>
  10#include <linux/errno.h>
  11#include <linux/gpio/driver.h>
  12#include <linux/init.h>
  13#include <linux/interrupt.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/platform_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/slab.h>
  19
  20#define TQMX86_NGPIO    8
  21#define TQMX86_NGPO     4       /* 0-3 - output */
  22#define TQMX86_NGPI     4       /* 4-7 - input */
  23#define TQMX86_DIR_INPUT_MASK   0xf0    /* 0-3 - output, 4-7 - input */
  24
  25#define TQMX86_GPIODD   0       /* GPIO Data Direction Register */
  26#define TQMX86_GPIOD    1       /* GPIO Data Register */
  27#define TQMX86_GPIIC    3       /* GPI Interrupt Configuration Register */
  28#define TQMX86_GPIIS    4       /* GPI Interrupt Status Register */
  29
  30#define TQMX86_GPII_FALLING     BIT(0)
  31#define TQMX86_GPII_RISING      BIT(1)
  32#define TQMX86_GPII_MASK        (BIT(0) | BIT(1))
  33#define TQMX86_GPII_BITS        2
  34
  35struct tqmx86_gpio_data {
  36        struct gpio_chip        chip;
  37        struct irq_chip         irq_chip;
  38        void __iomem            *io_base;
  39        int                     irq;
  40        raw_spinlock_t          spinlock;
  41        u8                      irq_type[TQMX86_NGPI];
  42};
  43
  44static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
  45{
  46        return ioread8(gd->io_base + reg);
  47}
  48
  49static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,
  50                              unsigned int reg)
  51{
  52        iowrite8(val, gd->io_base + reg);
  53}
  54
  55static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
  56{
  57        struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
  58
  59        return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
  60}
  61
  62static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
  63                            int value)
  64{
  65        struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
  66        unsigned long flags;
  67        u8 val;
  68
  69        raw_spin_lock_irqsave(&gpio->spinlock, flags);
  70        val = tqmx86_gpio_read(gpio, TQMX86_GPIOD);
  71        if (value)
  72                val |= BIT(offset);
  73        else
  74                val &= ~BIT(offset);
  75        tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
  76        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
  77}
  78
  79static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
  80                                       unsigned int offset)
  81{
  82        /* Direction cannot be changed. Validate is an input. */
  83        if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
  84                return 0;
  85        else
  86                return -EINVAL;
  87}
  88
  89static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
  90                                        unsigned int offset,
  91                                        int value)
  92{
  93        /* Direction cannot be changed, validate is an output */
  94        if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
  95                return -EINVAL;
  96
  97        tqmx86_gpio_set(chip, offset, value);
  98        return 0;
  99}
 100
 101static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
 102                                     unsigned int offset)
 103{
 104        if (TQMX86_DIR_INPUT_MASK & BIT(offset))
 105                return GPIO_LINE_DIRECTION_IN;
 106
 107        return GPIO_LINE_DIRECTION_OUT;
 108}
 109
 110static void tqmx86_gpio_irq_mask(struct irq_data *data)
 111{
 112        unsigned int offset = (data->hwirq - TQMX86_NGPO);
 113        struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 114                irq_data_get_irq_chip_data(data));
 115        unsigned long flags;
 116        u8 gpiic, mask;
 117
 118        mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 119
 120        raw_spin_lock_irqsave(&gpio->spinlock, flags);
 121        gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 122        gpiic &= ~mask;
 123        tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 124        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 125}
 126
 127static void tqmx86_gpio_irq_unmask(struct irq_data *data)
 128{
 129        unsigned int offset = (data->hwirq - TQMX86_NGPO);
 130        struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 131                irq_data_get_irq_chip_data(data));
 132        unsigned long flags;
 133        u8 gpiic, mask;
 134
 135        mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 136
 137        raw_spin_lock_irqsave(&gpio->spinlock, flags);
 138        gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 139        gpiic &= ~mask;
 140        gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
 141        tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 142        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 143}
 144
 145static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
 146{
 147        struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 148                irq_data_get_irq_chip_data(data));
 149        unsigned int offset = (data->hwirq - TQMX86_NGPO);
 150        unsigned int edge_type = type & IRQF_TRIGGER_MASK;
 151        unsigned long flags;
 152        u8 new_type, gpiic;
 153
 154        switch (edge_type) {
 155        case IRQ_TYPE_EDGE_RISING:
 156                new_type = TQMX86_GPII_RISING;
 157                break;
 158        case IRQ_TYPE_EDGE_FALLING:
 159                new_type = TQMX86_GPII_FALLING;
 160                break;
 161        case IRQ_TYPE_EDGE_BOTH:
 162                new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
 163                break;
 164        default:
 165                return -EINVAL; /* not supported */
 166        }
 167
 168        gpio->irq_type[offset] = new_type;
 169
 170        raw_spin_lock_irqsave(&gpio->spinlock, flags);
 171        gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 172        gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
 173        gpiic |= new_type << (offset * TQMX86_GPII_BITS);
 174        tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 175        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 176
 177        return 0;
 178}
 179
 180static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
 181{
 182        struct gpio_chip *chip = irq_desc_get_handler_data(desc);
 183        struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 184        struct irq_chip *irq_chip = irq_desc_get_chip(desc);
 185        unsigned long irq_bits;
 186        int i = 0;
 187        u8 irq_status;
 188
 189        chained_irq_enter(irq_chip, desc);
 190
 191        irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 192        tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 193
 194        irq_bits = irq_status;
 195        for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
 196                generic_handle_domain_irq(gpio->chip.irq.domain,
 197                                          i + TQMX86_NGPO);
 198
 199        chained_irq_exit(irq_chip, desc);
 200}
 201
 202/* Minimal runtime PM is needed by the IRQ subsystem */
 203static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)
 204{
 205        return 0;
 206}
 207
 208static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev)
 209{
 210        return 0;
 211}
 212
 213static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
 214        SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend,
 215                           tqmx86_gpio_runtime_resume, NULL)
 216};
 217
 218static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
 219                                       unsigned long *valid_mask,
 220                                       unsigned int ngpios)
 221{
 222        /* Only GPIOs 4-7 are valid for interrupts. Clear the others */
 223        clear_bit(0, valid_mask);
 224        clear_bit(1, valid_mask);
 225        clear_bit(2, valid_mask);
 226        clear_bit(3, valid_mask);
 227}
 228
 229static int tqmx86_gpio_probe(struct platform_device *pdev)
 230{
 231        struct device *dev = &pdev->dev;
 232        struct tqmx86_gpio_data *gpio;
 233        struct gpio_chip *chip;
 234        struct gpio_irq_chip *girq;
 235        void __iomem *io_base;
 236        struct resource *res;
 237        int ret, irq;
 238
 239        irq = platform_get_irq_optional(pdev, 0);
 240        if (irq < 0 && irq != -ENXIO)
 241                return irq;
 242
 243        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 244        if (!res) {
 245                dev_err(&pdev->dev, "Cannot get I/O\n");
 246                return -ENODEV;
 247        }
 248
 249        io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
 250        if (!io_base)
 251                return -ENOMEM;
 252
 253        gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
 254        if (!gpio)
 255                return -ENOMEM;
 256
 257        raw_spin_lock_init(&gpio->spinlock);
 258        gpio->io_base = io_base;
 259
 260        tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
 261
 262        platform_set_drvdata(pdev, gpio);
 263
 264        chip = &gpio->chip;
 265        chip->label = "gpio-tqmx86";
 266        chip->owner = THIS_MODULE;
 267        chip->can_sleep = false;
 268        chip->base = -1;
 269        chip->direction_input = tqmx86_gpio_direction_input;
 270        chip->direction_output = tqmx86_gpio_direction_output;
 271        chip->get_direction = tqmx86_gpio_get_direction;
 272        chip->get = tqmx86_gpio_get;
 273        chip->set = tqmx86_gpio_set;
 274        chip->ngpio = TQMX86_NGPIO;
 275        chip->parent = pdev->dev.parent;
 276
 277        pm_runtime_enable(&pdev->dev);
 278
 279        if (irq > 0) {
 280                struct irq_chip *irq_chip = &gpio->irq_chip;
 281                u8 irq_status;
 282
 283                irq_chip->name = chip->label;
 284                irq_chip->parent_device = &pdev->dev;
 285                irq_chip->irq_mask = tqmx86_gpio_irq_mask;
 286                irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
 287                irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
 288
 289                /* Mask all interrupts */
 290                tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
 291
 292                /* Clear all pending interrupts */
 293                irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 294                tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 295
 296                girq = &chip->irq;
 297                girq->chip = irq_chip;
 298                girq->parent_handler = tqmx86_gpio_irq_handler;
 299                girq->num_parents = 1;
 300                girq->parents = devm_kcalloc(&pdev->dev, 1,
 301                                             sizeof(*girq->parents),
 302                                             GFP_KERNEL);
 303                if (!girq->parents) {
 304                        ret = -ENOMEM;
 305                        goto out_pm_dis;
 306                }
 307                girq->parents[0] = irq;
 308                girq->default_type = IRQ_TYPE_NONE;
 309                girq->handler = handle_simple_irq;
 310                girq->init_valid_mask = tqmx86_init_irq_valid_mask;
 311        }
 312
 313        ret = devm_gpiochip_add_data(dev, chip, gpio);
 314        if (ret) {
 315                dev_err(dev, "Could not register GPIO chip\n");
 316                goto out_pm_dis;
 317        }
 318
 319        dev_info(dev, "GPIO functionality initialized with %d pins\n",
 320                 chip->ngpio);
 321
 322        return 0;
 323
 324out_pm_dis:
 325        pm_runtime_disable(&pdev->dev);
 326
 327        return ret;
 328}
 329
 330static struct platform_driver tqmx86_gpio_driver = {
 331        .driver = {
 332                .name = "tqmx86-gpio",
 333                .pm = &tqmx86_gpio_dev_pm_ops,
 334        },
 335        .probe          = tqmx86_gpio_probe,
 336};
 337
 338module_platform_driver(tqmx86_gpio_driver);
 339
 340MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
 341MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
 342MODULE_LICENSE("GPL");
 343MODULE_ALIAS("platform:tqmx86-gpio");
 344