linux/drivers/gpio/gpio-generic.c
<<
>>
Prefs
   1/*
   2 * Generic driver for memory-mapped GPIO controllers.
   3 *
   4 * Copyright 2008 MontaVista Software, Inc.
   5 * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com>
   6 *
   7 * This program is free software; you can redistribute  it and/or modify it
   8 * under  the terms of  the GNU General  Public License as published by the
   9 * Free Software Foundation;  either version 2 of the  License, or (at your
  10 * option) any later version.
  11 *
  12 * ....``.```~~~~````.`.`.`.`.```````'',,,.........`````......`.......
  13 * ...``                                                         ```````..
  14 * ..The simplest form of a GPIO controller that the driver supports is``
  15 *  `.just a single "data" register, where GPIO state can be read and/or `
  16 *    `,..written. ,,..``~~~~ .....``.`.`.~~.```.`.........``````.```````
  17 *        `````````
  18                                    ___
  19_/~~|___/~|   . ```~~~~~~       ___/___\___     ,~.`.`.`.`````.~~...,,,,...
  20__________|~$@~~~        %~    /o*o*o*o*o*o\   .. Implementing such a GPIO .
  21o        `                     ~~~~\___/~~~~    ` controller in FPGA is ,.`
  22                                                 `....trivial..'~`.```.```
  23 *                                                    ```````
  24 *  .```````~~~~`..`.``.``.
  25 * .  The driver supports  `...       ,..```.`~~~```````````````....````.``,,
  26 * .   big-endian notation, just`.  .. A bit more sophisticated controllers ,
  27 *  . register the device with -be`. .with a pair of set/clear-bit registers ,
  28 *   `.. suffix.  ```~~`````....`.`   . affecting the data register and the .`
  29 *     ``.`.``...```                  ```.. output pins are also supported.`
  30 *                        ^^             `````.`````````.,``~``~``~~``````
  31 *                                                   .                  ^^
  32 *   ,..`.`.`...````````````......`.`.`.`.`.`..`.`.`..
  33 * .. The expectation is that in at least some cases .    ,-~~~-,
  34 *  .this will be used with roll-your-own ASIC/FPGA .`     \   /
  35 *  .logic in Verilog or VHDL. ~~~`````````..`````~~`       \ /
  36 *  ..````````......```````````                             \o_
  37 *                                                           |
  38 *                              ^^                          / \
  39 *
  40 *           ...`````~~`.....``.`..........``````.`.``.```........``.
  41 *            `  8, 16, 32 and 64 bits registers are supported, and``.
  42 *            . the number of GPIOs is determined by the width of   ~
  43 *             .. the registers. ,............```.`.`..`.`.~~~.`.`.`~
  44 *               `.......````.```
  45 */
  46
  47#include <linux/init.h>
  48#include <linux/err.h>
  49#include <linux/bug.h>
  50#include <linux/kernel.h>
  51#include <linux/module.h>
  52#include <linux/spinlock.h>
  53#include <linux/compiler.h>
  54#include <linux/types.h>
  55#include <linux/errno.h>
  56#include <linux/log2.h>
  57#include <linux/ioport.h>
  58#include <linux/io.h>
  59#include <linux/gpio.h>
  60#include <linux/slab.h>
  61#include <linux/platform_device.h>
  62#include <linux/mod_devicetable.h>
  63#include <linux/basic_mmio_gpio.h>
  64
  65static void bgpio_write8(void __iomem *reg, unsigned long data)
  66{
  67        writeb(data, reg);
  68}
  69
  70static unsigned long bgpio_read8(void __iomem *reg)
  71{
  72        return readb(reg);
  73}
  74
  75static void bgpio_write16(void __iomem *reg, unsigned long data)
  76{
  77        writew(data, reg);
  78}
  79
  80static unsigned long bgpio_read16(void __iomem *reg)
  81{
  82        return readw(reg);
  83}
  84
  85static void bgpio_write32(void __iomem *reg, unsigned long data)
  86{
  87        writel(data, reg);
  88}
  89
  90static unsigned long bgpio_read32(void __iomem *reg)
  91{
  92        return readl(reg);
  93}
  94
  95#if BITS_PER_LONG >= 64
  96static void bgpio_write64(void __iomem *reg, unsigned long data)
  97{
  98        writeq(data, reg);
  99}
 100
 101static unsigned long bgpio_read64(void __iomem *reg)
 102{
 103        return readq(reg);
 104}
 105#endif /* BITS_PER_LONG >= 64 */
 106
 107static void bgpio_write16be(void __iomem *reg, unsigned long data)
 108{
 109        iowrite16be(data, reg);
 110}
 111
 112static unsigned long bgpio_read16be(void __iomem *reg)
 113{
 114        return ioread16be(reg);
 115}
 116
 117static void bgpio_write32be(void __iomem *reg, unsigned long data)
 118{
 119        iowrite32be(data, reg);
 120}
 121
 122static unsigned long bgpio_read32be(void __iomem *reg)
 123{
 124        return ioread32be(reg);
 125}
 126
 127static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin)
 128{
 129        return 1 << pin;
 130}
 131
 132static unsigned long bgpio_pin2mask_be(struct bgpio_chip *bgc,
 133                                       unsigned int pin)
 134{
 135        return 1 << (bgc->bits - 1 - pin);
 136}
 137
 138static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
 139{
 140        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 141
 142        return bgc->read_reg(bgc->reg_dat) & bgc->pin2mask(bgc, gpio);
 143}
 144
 145static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 146{
 147        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 148        unsigned long mask = bgc->pin2mask(bgc, gpio);
 149        unsigned long flags;
 150
 151        spin_lock_irqsave(&bgc->lock, flags);
 152
 153        if (val)
 154                bgc->data |= mask;
 155        else
 156                bgc->data &= ~mask;
 157
 158        bgc->write_reg(bgc->reg_dat, bgc->data);
 159
 160        spin_unlock_irqrestore(&bgc->lock, flags);
 161}
 162
 163static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
 164                                 int val)
 165{
 166        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 167        unsigned long mask = bgc->pin2mask(bgc, gpio);
 168
 169        if (val)
 170                bgc->write_reg(bgc->reg_set, mask);
 171        else
 172                bgc->write_reg(bgc->reg_clr, mask);
 173}
 174
 175static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
 176{
 177        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 178        unsigned long mask = bgc->pin2mask(bgc, gpio);
 179        unsigned long flags;
 180
 181        spin_lock_irqsave(&bgc->lock, flags);
 182
 183        if (val)
 184                bgc->data |= mask;
 185        else
 186                bgc->data &= ~mask;
 187
 188        bgc->write_reg(bgc->reg_set, bgc->data);
 189
 190        spin_unlock_irqrestore(&bgc->lock, flags);
 191}
 192
 193static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio)
 194{
 195        return 0;
 196}
 197
 198static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio,
 199                                int val)
 200{
 201        gc->set(gc, gpio, val);
 202
 203        return 0;
 204}
 205
 206static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 207{
 208        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 209        unsigned long flags;
 210
 211        spin_lock_irqsave(&bgc->lock, flags);
 212
 213        bgc->dir &= ~bgc->pin2mask(bgc, gpio);
 214        bgc->write_reg(bgc->reg_dir, bgc->dir);
 215
 216        spin_unlock_irqrestore(&bgc->lock, flags);
 217
 218        return 0;
 219}
 220
 221static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 222{
 223        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 224        unsigned long flags;
 225
 226        gc->set(gc, gpio, val);
 227
 228        spin_lock_irqsave(&bgc->lock, flags);
 229
 230        bgc->dir |= bgc->pin2mask(bgc, gpio);
 231        bgc->write_reg(bgc->reg_dir, bgc->dir);
 232
 233        spin_unlock_irqrestore(&bgc->lock, flags);
 234
 235        return 0;
 236}
 237
 238static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio)
 239{
 240        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 241        unsigned long flags;
 242
 243        spin_lock_irqsave(&bgc->lock, flags);
 244
 245        bgc->dir |= bgc->pin2mask(bgc, gpio);
 246        bgc->write_reg(bgc->reg_dir, bgc->dir);
 247
 248        spin_unlock_irqrestore(&bgc->lock, flags);
 249
 250        return 0;
 251}
 252
 253static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
 254{
 255        struct bgpio_chip *bgc = to_bgpio_chip(gc);
 256        unsigned long flags;
 257
 258        gc->set(gc, gpio, val);
 259
 260        spin_lock_irqsave(&bgc->lock, flags);
 261
 262        bgc->dir &= ~bgc->pin2mask(bgc, gpio);
 263        bgc->write_reg(bgc->reg_dir, bgc->dir);
 264
 265        spin_unlock_irqrestore(&bgc->lock, flags);
 266
 267        return 0;
 268}
 269
 270static int bgpio_setup_accessors(struct device *dev,
 271                                 struct bgpio_chip *bgc,
 272                                 bool bit_be,
 273                                 bool byte_be)
 274{
 275
 276        switch (bgc->bits) {
 277        case 8:
 278                bgc->read_reg   = bgpio_read8;
 279                bgc->write_reg  = bgpio_write8;
 280                break;
 281        case 16:
 282                if (byte_be) {
 283                        bgc->read_reg   = bgpio_read16be;
 284                        bgc->write_reg  = bgpio_write16be;
 285                } else {
 286                        bgc->read_reg   = bgpio_read16;
 287                        bgc->write_reg  = bgpio_write16;
 288                }
 289                break;
 290        case 32:
 291                if (byte_be) {
 292                        bgc->read_reg   = bgpio_read32be;
 293                        bgc->write_reg  = bgpio_write32be;
 294                } else {
 295                        bgc->read_reg   = bgpio_read32;
 296                        bgc->write_reg  = bgpio_write32;
 297                }
 298                break;
 299#if BITS_PER_LONG >= 64
 300        case 64:
 301                if (byte_be) {
 302                        dev_err(dev,
 303                                "64 bit big endian byte order unsupported\n");
 304                        return -EINVAL;
 305                } else {
 306                        bgc->read_reg   = bgpio_read64;
 307                        bgc->write_reg  = bgpio_write64;
 308                }
 309                break;
 310#endif /* BITS_PER_LONG >= 64 */
 311        default:
 312                dev_err(dev, "unsupported data width %u bits\n", bgc->bits);
 313                return -EINVAL;
 314        }
 315
 316        bgc->pin2mask = bit_be ? bgpio_pin2mask_be : bgpio_pin2mask;
 317
 318        return 0;
 319}
 320
 321/*
 322 * Create the device and allocate the resources.  For setting GPIO's there are
 323 * three supported configurations:
 324 *
 325 *      - single input/output register resource (named "dat").
 326 *      - set/clear pair (named "set" and "clr").
 327 *      - single output register resource and single input resource ("set" and
 328 *      dat").
 329 *
 330 * For the single output register, this drives a 1 by setting a bit and a zero
 331 * by clearing a bit.  For the set clr pair, this drives a 1 by setting a bit
 332 * in the set register and clears it by setting a bit in the clear register.
 333 * The configuration is detected by which resources are present.
 334 *
 335 * For setting the GPIO direction, there are three supported configurations:
 336 *
 337 *      - simple bidirection GPIO that requires no configuration.
 338 *      - an output direction register (named "dirout") where a 1 bit
 339 *      indicates the GPIO is an output.
 340 *      - an input direction register (named "dirin") where a 1 bit indicates
 341 *      the GPIO is an input.
 342 */
 343static int bgpio_setup_io(struct bgpio_chip *bgc,
 344                          void __iomem *dat,
 345                          void __iomem *set,
 346                          void __iomem *clr)
 347{
 348
 349        bgc->reg_dat = dat;
 350        if (!bgc->reg_dat)
 351                return -EINVAL;
 352
 353        if (set && clr) {
 354                bgc->reg_set = set;
 355                bgc->reg_clr = clr;
 356                bgc->gc.set = bgpio_set_with_clear;
 357        } else if (set && !clr) {
 358                bgc->reg_set = set;
 359                bgc->gc.set = bgpio_set_set;
 360        } else {
 361                bgc->gc.set = bgpio_set;
 362        }
 363
 364        bgc->gc.get = bgpio_get;
 365
 366        return 0;
 367}
 368
 369static int bgpio_setup_direction(struct bgpio_chip *bgc,
 370                                 void __iomem *dirout,
 371                                 void __iomem *dirin)
 372{
 373        if (dirout && dirin) {
 374                return -EINVAL;
 375        } else if (dirout) {
 376                bgc->reg_dir = dirout;
 377                bgc->gc.direction_output = bgpio_dir_out;
 378                bgc->gc.direction_input = bgpio_dir_in;
 379        } else if (dirin) {
 380                bgc->reg_dir = dirin;
 381                bgc->gc.direction_output = bgpio_dir_out_inv;
 382                bgc->gc.direction_input = bgpio_dir_in_inv;
 383        } else {
 384                bgc->gc.direction_output = bgpio_simple_dir_out;
 385                bgc->gc.direction_input = bgpio_simple_dir_in;
 386        }
 387
 388        return 0;
 389}
 390
 391int bgpio_remove(struct bgpio_chip *bgc)
 392{
 393        return gpiochip_remove(&bgc->gc);
 394}
 395EXPORT_SYMBOL_GPL(bgpio_remove);
 396
 397int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
 398               unsigned long sz, void __iomem *dat, void __iomem *set,
 399               void __iomem *clr, void __iomem *dirout, void __iomem *dirin,
 400               unsigned long flags)
 401{
 402        int ret;
 403
 404        if (!is_power_of_2(sz))
 405                return -EINVAL;
 406
 407        bgc->bits = sz * 8;
 408        if (bgc->bits > BITS_PER_LONG)
 409                return -EINVAL;
 410
 411        spin_lock_init(&bgc->lock);
 412        bgc->gc.dev = dev;
 413        bgc->gc.label = dev_name(dev);
 414        bgc->gc.base = -1;
 415        bgc->gc.ngpio = bgc->bits;
 416
 417        ret = bgpio_setup_io(bgc, dat, set, clr);
 418        if (ret)
 419                return ret;
 420
 421        ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN,
 422                                    flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER);
 423        if (ret)
 424                return ret;
 425
 426        ret = bgpio_setup_direction(bgc, dirout, dirin);
 427        if (ret)
 428                return ret;
 429
 430        bgc->data = bgc->read_reg(bgc->reg_dat);
 431        if (bgc->gc.set == bgpio_set_set &&
 432                        !(flags & BGPIOF_UNREADABLE_REG_SET))
 433                bgc->data = bgc->read_reg(bgc->reg_set);
 434        if (bgc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR))
 435                bgc->dir = bgc->read_reg(bgc->reg_dir);
 436
 437        return ret;
 438}
 439EXPORT_SYMBOL_GPL(bgpio_init);
 440
 441#ifdef CONFIG_GPIO_GENERIC_PLATFORM
 442
 443static void __iomem *bgpio_map(struct platform_device *pdev,
 444                               const char *name,
 445                               resource_size_t sane_sz,
 446                               int *err)
 447{
 448        struct device *dev = &pdev->dev;
 449        struct resource *r;
 450        resource_size_t start;
 451        resource_size_t sz;
 452        void __iomem *ret;
 453
 454        *err = 0;
 455
 456        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
 457        if (!r)
 458                return NULL;
 459
 460        sz = resource_size(r);
 461        if (sz != sane_sz) {
 462                *err = -EINVAL;
 463                return NULL;
 464        }
 465
 466        start = r->start;
 467        if (!devm_request_mem_region(dev, start, sz, r->name)) {
 468                *err = -EBUSY;
 469                return NULL;
 470        }
 471
 472        ret = devm_ioremap(dev, start, sz);
 473        if (!ret) {
 474                *err = -ENOMEM;
 475                return NULL;
 476        }
 477
 478        return ret;
 479}
 480
 481static int bgpio_pdev_probe(struct platform_device *pdev)
 482{
 483        struct device *dev = &pdev->dev;
 484        struct resource *r;
 485        void __iomem *dat;
 486        void __iomem *set;
 487        void __iomem *clr;
 488        void __iomem *dirout;
 489        void __iomem *dirin;
 490        unsigned long sz;
 491        unsigned long flags = 0;
 492        int err;
 493        struct bgpio_chip *bgc;
 494        struct bgpio_pdata *pdata = dev_get_platdata(dev);
 495
 496        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
 497        if (!r)
 498                return -EINVAL;
 499
 500        sz = resource_size(r);
 501
 502        dat = bgpio_map(pdev, "dat", sz, &err);
 503        if (!dat)
 504                return err ? err : -EINVAL;
 505
 506        set = bgpio_map(pdev, "set", sz, &err);
 507        if (err)
 508                return err;
 509
 510        clr = bgpio_map(pdev, "clr", sz, &err);
 511        if (err)
 512                return err;
 513
 514        dirout = bgpio_map(pdev, "dirout", sz, &err);
 515        if (err)
 516                return err;
 517
 518        dirin = bgpio_map(pdev, "dirin", sz, &err);
 519        if (err)
 520                return err;
 521
 522        if (!strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be"))
 523                flags |= BGPIOF_BIG_ENDIAN;
 524
 525        bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL);
 526        if (!bgc)
 527                return -ENOMEM;
 528
 529        err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, flags);
 530        if (err)
 531                return err;
 532
 533        if (pdata) {
 534                bgc->gc.base = pdata->base;
 535                if (pdata->ngpio > 0)
 536                        bgc->gc.ngpio = pdata->ngpio;
 537        }
 538
 539        platform_set_drvdata(pdev, bgc);
 540
 541        return gpiochip_add(&bgc->gc);
 542}
 543
 544static int bgpio_pdev_remove(struct platform_device *pdev)
 545{
 546        struct bgpio_chip *bgc = platform_get_drvdata(pdev);
 547
 548        return bgpio_remove(bgc);
 549}
 550
 551static const struct platform_device_id bgpio_id_table[] = {
 552        { "basic-mmio-gpio", },
 553        { "basic-mmio-gpio-be", },
 554        {},
 555};
 556MODULE_DEVICE_TABLE(platform, bgpio_id_table);
 557
 558static struct platform_driver bgpio_driver = {
 559        .driver = {
 560                .name = "basic-mmio-gpio",
 561        },
 562        .id_table = bgpio_id_table,
 563        .probe = bgpio_pdev_probe,
 564        .remove = bgpio_pdev_remove,
 565};
 566
 567module_platform_driver(bgpio_driver);
 568
 569#endif /* CONFIG_GPIO_GENERIC_PLATFORM */
 570
 571MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
 572MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
 573MODULE_LICENSE("GPL");
 574
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.