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 void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
 218                                       unsigned long *valid_mask,
 219                                       unsigned int ngpios)
 220{
 221        /* Only GPIOs 4-7 are valid for interrupts. Clear the others */
 222        clear_bit(0, valid_mask);
 223        clear_bit(1, valid_mask);
 224        clear_bit(2, valid_mask);
 225        clear_bit(3, valid_mask);
 226}
 227
 228static int tqmx86_gpio_probe(struct platform_device *pdev)
 229{
 230        struct device *dev = &pdev->dev;
 231        struct tqmx86_gpio_data *gpio;
 232        struct gpio_chip *chip;
 233        struct gpio_irq_chip *girq;
 234        void __iomem *io_base;
 235        struct resource *res;
 236        int ret, irq;
 237
 238        irq = platform_get_irq(pdev, 0);
 239        if (irq < 0)
 240                return irq;
 241
 242        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 243        if (!res) {
 244                dev_err(&pdev->dev, "Cannot get I/O\n");
 245                return -ENODEV;
 246        }
 247
 248        io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
 249        if (!io_base)
 250                return -ENOMEM;
 251
 252        gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
 253        if (!gpio)
 254                return -ENOMEM;
 255
 256        raw_spin_lock_init(&gpio->spinlock);
 257        gpio->io_base = io_base;
 258
 259        tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
 260
 261        platform_set_drvdata(pdev, gpio);
 262
 263        chip = &gpio->chip;
 264        chip->label = "gpio-tqmx86";
 265        chip->owner = THIS_MODULE;
 266        chip->can_sleep = false;
 267        chip->base = -1;
 268        chip->direction_input = tqmx86_gpio_direction_input;
 269        chip->direction_output = tqmx86_gpio_direction_output;
 270        chip->get_direction = tqmx86_gpio_get_direction;
 271        chip->get = tqmx86_gpio_get;
 272        chip->set = tqmx86_gpio_set;
 273        chip->ngpio = TQMX86_NGPIO;
 274        chip->parent = pdev->dev.parent;
 275
 276        pm_runtime_enable(&pdev->dev);
 277
 278        if (irq) {
 279                struct irq_chip *irq_chip = &gpio->irq_chip;
 280                u8 irq_status;
 281
 282                irq_chip->name = chip->label;
 283                irq_chip->parent_device = &pdev->dev;
 284                irq_chip->irq_mask = tqmx86_gpio_irq_mask;
 285                irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
 286                irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
 287
 288                /* Mask all interrupts */
 289                tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
 290
 291                /* Clear all pending interrupts */
 292                irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
 293                tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 294
 295                girq = &chip->irq;
 296                girq->chip = irq_chip;
 297                girq->parent_handler = tqmx86_gpio_irq_handler;
 298                girq->num_parents = 1;
 299                girq->parents = devm_kcalloc(&pdev->dev, 1,
 300                                             sizeof(*girq->parents),
 301                                             GFP_KERNEL);
 302                if (!girq->parents) {
 303                        ret = -ENOMEM;
 304                        goto out_pm_dis;
 305                }
 306                girq->parents[0] = irq;
 307                girq->default_type = IRQ_TYPE_NONE;
 308                girq->handler = handle_simple_irq;
 309                girq->init_valid_mask = tqmx86_init_irq_valid_mask;
 310        }
 311
 312        ret = devm_gpiochip_add_data(dev, chip, gpio);
 313        if (ret) {
 314                dev_err(dev, "Could not register GPIO chip\n");
 315                goto out_pm_dis;
 316        }
 317
 318        dev_info(dev, "GPIO functionality initialized with %d pins\n",
 319                 chip->ngpio);
 320
 321        return 0;
 322
 323out_pm_dis:
 324        pm_runtime_disable(&pdev->dev);
 325
 326        return ret;
 327}
 328
 329static struct platform_driver tqmx86_gpio_driver = {
 330        .driver = {
 331                .name = "tqmx86-gpio",
 332                .pm = &tqmx86_gpio_dev_pm_ops,
 333        },
 334        .probe          = tqmx86_gpio_probe,
 335};
 336
 337module_platform_driver(tqmx86_gpio_driver);
 338
 339MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
 340MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
 341MODULE_LICENSE("GPL");
 342MODULE_ALIAS("platform:tqmx86-gpio");
 343