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        return !!(TQMX86_DIR_INPUT_MASK & BIT(offset));
 105}
 106
 107static void tqmx86_gpio_irq_mask(struct irq_data *data)
 108{
 109        unsigned int offset = (data->hwirq - TQMX86_NGPO);
 110        struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 111                irq_data_get_irq_chip_data(data));
 112        unsigned long flags;
 113        u8 gpiic, mask;
 114
 115        mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 116
 117        raw_spin_lock_irqsave(&gpio->spinlock, flags);
 118        gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 119        gpiic &= ~mask;
 120        tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 121        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 122}
 123
 124static void tqmx86_gpio_irq_unmask(struct irq_data *data)
 125{
 126        unsigned int offset = (data->hwirq - TQMX86_NGPO);
 127        struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 128                irq_data_get_irq_chip_data(data));
 129        unsigned long flags;
 130        u8 gpiic, mask;
 131
 132        mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 133
 134        raw_spin_lock_irqsave(&gpio->spinlock, flags);
 135        gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 136        gpiic &= ~mask;
 137        gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
 138        tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 139        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 140}
 141
 142static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
 143{
 144        struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 145                irq_data_get_irq_chip_data(data));
 146        unsigned int offset = (data->hwirq - TQMX86_NGPO);
 147        unsigned int edge_type = type & IRQF_TRIGGER_MASK;
 148        unsigned long flags;
 149        u8 new_type, gpiic;
 150
 151        switch (edge_type) {
 152        case IRQ_TYPE_EDGE_RISING:
 153                new_type = TQMX86_GPII_RISING;
 154                break;
 155        case IRQ_TYPE_EDGE_FALLING:
 156                new_type = TQMX86_GPII_FALLING;
 157                break;
 158        case IRQ_TYPE_EDGE_BOTH:
 159                new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
 160                break;
 161        default:
 162                return -EINVAL; /* not supported */
 163        }
 164
 165        gpio->irq_type[offset] = new_type;
 166
 167        raw_spin_lock_irqsave(&gpio->spinlock, flags);
 168        gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
 169        gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
 170        gpiic |= new_type << (offset * TQMX86_GPII_BITS);
 171        tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
 172        raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 173
 174        return 0;
 175}
 176
 177static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
 178{
 179        struct gpio_chip *chip = irq_desc_get_handler_data(desc);
 180        struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 181        struct irq_chip *irq_chip = irq_desc_get_chip(desc);
 182        unsigned long irq_bits;
 183        int i = 0, child_irq;
 184        u8 irq_status;
 185
 186        chained_irq_enter(irq_chip, desc);
 187
 188        irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 189        tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 190
 191        irq_bits = irq_status;
 192        for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
 193                child_irq = irq_find_mapping(gpio->chip.irq.domain,
 194                                             i + TQMX86_NGPO);
 195                generic_handle_irq(child_irq);
 196        }
 197
 198        chained_irq_exit(irq_chip, desc);
 199}
 200
 201/* Minimal runtime PM is needed by the IRQ subsystem */
 202static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)
 203{
 204        return 0;
 205}
 206
 207static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev)
 208{
 209        return 0;
 210}
 211
 212static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
 213        SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend,
 214                           tqmx86_gpio_runtime_resume, NULL)
 215};
 216
 217static int tqmx86_gpio_probe(struct platform_device *pdev)
 218{
 219        struct device *dev = &pdev->dev;
 220        struct tqmx86_gpio_data *gpio;
 221        struct gpio_chip *chip;
 222        void __iomem *io_base;
 223        struct resource *res;
 224        int ret, irq;
 225
 226        irq = platform_get_irq(pdev, 0);
 227        if (irq < 0)
 228                return irq;
 229
 230        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 231        if (!res) {
 232                dev_err(&pdev->dev, "Cannot get I/O\n");
 233                return -ENODEV;
 234        }
 235
 236        io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
 237        if (!io_base)
 238                return -ENOMEM;
 239
 240        gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
 241        if (!gpio)
 242                return -ENOMEM;
 243
 244        raw_spin_lock_init(&gpio->spinlock);
 245        gpio->io_base = io_base;
 246
 247        tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
 248
 249        platform_set_drvdata(pdev, gpio);
 250
 251        chip = &gpio->chip;
 252        chip->label = "gpio-tqmx86";
 253        chip->owner = THIS_MODULE;
 254        chip->can_sleep = false;
 255        chip->base = -1;
 256        chip->direction_input = tqmx86_gpio_direction_input;
 257        chip->direction_output = tqmx86_gpio_direction_output;
 258        chip->get_direction = tqmx86_gpio_get_direction;
 259        chip->get = tqmx86_gpio_get;
 260        chip->set = tqmx86_gpio_set;
 261        chip->ngpio = TQMX86_NGPIO;
 262        chip->irq.need_valid_mask = true;
 263        chip->parent = pdev->dev.parent;
 264
 265        pm_runtime_enable(&pdev->dev);
 266
 267        ret = devm_gpiochip_add_data(dev, chip, gpio);
 268        if (ret) {
 269                dev_err(dev, "Could not register GPIO chip\n");
 270                goto out_pm_dis;
 271        }
 272
 273        if (irq) {
 274                struct irq_chip *irq_chip = &gpio->irq_chip;
 275                u8 irq_status;
 276
 277                irq_chip->name = chip->label;
 278                irq_chip->parent_device = &pdev->dev;
 279                irq_chip->irq_mask = tqmx86_gpio_irq_mask;
 280                irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
 281                irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
 282
 283                /* Mask all interrupts */
 284                tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
 285
 286                /* Clear all pending interrupts */
 287                irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 288                tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 289
 290                ret = gpiochip_irqchip_add(chip, irq_chip,
 291                                           0, handle_simple_irq,
 292                                           IRQ_TYPE_EDGE_BOTH);
 293                if (ret) {
 294                        dev_err(dev, "Could not add irq chip\n");
 295                        goto out_pm_dis;
 296                }
 297
 298                gpiochip_set_chained_irqchip(chip, irq_chip,
 299                                             irq, tqmx86_gpio_irq_handler);
 300        }
 301
 302        /* Only GPIOs 4-7 are valid for interrupts. Clear the others */
 303        clear_bit(0, chip->irq.valid_mask);
 304        clear_bit(1, chip->irq.valid_mask);
 305        clear_bit(2, chip->irq.valid_mask);
 306        clear_bit(3, chip->irq.valid_mask);
 307
 308        dev_info(dev, "GPIO functionality initialized with %d pins\n",
 309                 chip->ngpio);
 310
 311        return 0;
 312
 313out_pm_dis:
 314        pm_runtime_disable(&pdev->dev);
 315
 316        return ret;
 317}
 318
 319static struct platform_driver tqmx86_gpio_driver = {
 320        .driver = {
 321                .name = "tqmx86-gpio",
 322                .pm = &tqmx86_gpio_dev_pm_ops,
 323        },
 324        .probe          = tqmx86_gpio_probe,
 325};
 326
 327module_platform_driver(tqmx86_gpio_driver);
 328
 329MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
 330MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
 331MODULE_LICENSE("GPL");
 332MODULE_ALIAS("platform:tqmx86-gpio");
 333