linux/drivers/gpio/gpio-xilinx.c
<<
>>
Prefs
   1/*
   2 * Xilinx gpio driver for xps/axi_gpio IP.
   3 *
   4 * Copyright 2008 - 2013 Xilinx, Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2
   8 * as published by the Free Software Foundation.
   9 *
  10 * You should have received a copy of the GNU General Public License
  11 * along with this program; if not, write to the Free Software
  12 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  13 */
  14
  15#include <linux/bitops.h>
  16#include <linux/init.h>
  17#include <linux/errno.h>
  18#include <linux/module.h>
  19#include <linux/of_device.h>
  20#include <linux/of_platform.h>
  21#include <linux/of_gpio.h>
  22#include <linux/io.h>
  23#include <linux/gpio.h>
  24#include <linux/slab.h>
  25
  26/* Register Offset Definitions */
  27#define XGPIO_DATA_OFFSET   (0x0)       /* Data register  */
  28#define XGPIO_TRI_OFFSET    (0x4)       /* I/O direction register  */
  29
  30#define XGPIO_CHANNEL_OFFSET    0x8
  31
  32/* Read/Write access to the GPIO registers */
  33#if defined(CONFIG_ARCH_ZYNQ) || defined(CONFIG_X86)
  34# define xgpio_readreg(offset)          readl(offset)
  35# define xgpio_writereg(offset, val)    writel(val, offset)
  36#else
  37# define xgpio_readreg(offset)          __raw_readl(offset)
  38# define xgpio_writereg(offset, val)    __raw_writel(val, offset)
  39#endif
  40
  41/**
  42 * struct xgpio_instance - Stores information about GPIO device
  43 * @mmchip: OF GPIO chip for memory mapped banks
  44 * @gpio_width: GPIO width for every channel
  45 * @gpio_state: GPIO state shadow register
  46 * @gpio_dir: GPIO direction shadow register
  47 * @gpio_lock: Lock used for synchronization
  48 */
  49struct xgpio_instance {
  50        struct of_mm_gpio_chip mmchip;
  51        unsigned int gpio_width[2];
  52        u32 gpio_state[2];
  53        u32 gpio_dir[2];
  54        spinlock_t gpio_lock[2];
  55};
  56
  57static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
  58{
  59        if (gpio >= chip->gpio_width[0])
  60                return 1;
  61
  62        return 0;
  63}
  64
  65static inline int xgpio_regoffset(struct xgpio_instance *chip, int gpio)
  66{
  67        if (xgpio_index(chip, gpio))
  68                return XGPIO_CHANNEL_OFFSET;
  69
  70        return 0;
  71}
  72
  73static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
  74{
  75        if (xgpio_index(chip, gpio))
  76                return gpio - chip->gpio_width[0];
  77
  78        return gpio;
  79}
  80
  81/**
  82 * xgpio_get - Read the specified signal of the GPIO device.
  83 * @gc:     Pointer to gpio_chip device structure.
  84 * @gpio:   GPIO signal number.
  85 *
  86 * This function reads the specified signal of the GPIO device.
  87 *
  88 * Return:
  89 * 0 if direction of GPIO signals is set as input otherwise it
  90 * returns negative error value.
  91 */
  92static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
  93{
  94        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  95        struct xgpio_instance *chip = gpiochip_get_data(gc);
  96        u32 val;
  97
  98        val = xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET +
  99                            xgpio_regoffset(chip, gpio));
 100
 101        return !!(val & BIT(xgpio_offset(chip, gpio)));
 102}
 103
 104/**
 105 * xgpio_set - Write the specified signal of the GPIO device.
 106 * @gc:     Pointer to gpio_chip device structure.
 107 * @gpio:   GPIO signal number.
 108 * @val:    Value to be written to specified signal.
 109 *
 110 * This function writes the specified value in to the specified signal of the
 111 * GPIO device.
 112 */
 113static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 114{
 115        unsigned long flags;
 116        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 117        struct xgpio_instance *chip = gpiochip_get_data(gc);
 118        int index =  xgpio_index(chip, gpio);
 119        int offset =  xgpio_offset(chip, gpio);
 120
 121        spin_lock_irqsave(&chip->gpio_lock[index], flags);
 122
 123        /* Write to GPIO signal and set its direction to output */
 124        if (val)
 125                chip->gpio_state[index] |= BIT(offset);
 126        else
 127                chip->gpio_state[index] &= ~BIT(offset);
 128
 129        xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
 130                       xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
 131
 132        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
 133}
 134
 135/**
 136 * xgpio_set_multiple - Write the specified signals of the GPIO device.
 137 * @gc:     Pointer to gpio_chip device structure.
 138 * @mask:   Mask of the GPIOS to modify.
 139 * @bits:   Value to be wrote on each GPIO
 140 *
 141 * This function writes the specified values into the specified signals of the
 142 * GPIO devices.
 143 */
 144static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 145                               unsigned long *bits)
 146{
 147        unsigned long flags;
 148        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 149        struct xgpio_instance *chip = gpiochip_get_data(gc);
 150        int index = xgpio_index(chip, 0);
 151        int offset, i;
 152
 153        spin_lock_irqsave(&chip->gpio_lock[index], flags);
 154
 155        /* Write to GPIO signals */
 156        for (i = 0; i < gc->ngpio; i++) {
 157                if (*mask == 0)
 158                        break;
 159                if (index !=  xgpio_index(chip, i)) {
 160                        xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
 161                                       xgpio_regoffset(chip, i),
 162                                       chip->gpio_state[index]);
 163                        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
 164                        index =  xgpio_index(chip, i);
 165                        spin_lock_irqsave(&chip->gpio_lock[index], flags);
 166                }
 167                if (__test_and_clear_bit(i, mask)) {
 168                        offset =  xgpio_offset(chip, i);
 169                        if (test_bit(i, bits))
 170                                chip->gpio_state[index] |= BIT(offset);
 171                        else
 172                                chip->gpio_state[index] &= ~BIT(offset);
 173                }
 174        }
 175
 176        xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
 177                       xgpio_regoffset(chip, i), chip->gpio_state[index]);
 178
 179        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
 180}
 181
 182/**
 183 * xgpio_dir_in - Set the direction of the specified GPIO signal as input.
 184 * @gc:     Pointer to gpio_chip device structure.
 185 * @gpio:   GPIO signal number.
 186 *
 187 * Return:
 188 * 0 - if direction of GPIO signals is set as input
 189 * otherwise it returns negative error value.
 190 */
 191static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 192{
 193        unsigned long flags;
 194        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 195        struct xgpio_instance *chip = gpiochip_get_data(gc);
 196        int index =  xgpio_index(chip, gpio);
 197        int offset =  xgpio_offset(chip, gpio);
 198
 199        spin_lock_irqsave(&chip->gpio_lock[index], flags);
 200
 201        /* Set the GPIO bit in shadow register and set direction as input */
 202        chip->gpio_dir[index] |= BIT(offset);
 203        xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
 204                       xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
 205
 206        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
 207
 208        return 0;
 209}
 210
 211/**
 212 * xgpio_dir_out - Set the direction of the specified GPIO signal as output.
 213 * @gc:     Pointer to gpio_chip device structure.
 214 * @gpio:   GPIO signal number.
 215 * @val:    Value to be written to specified signal.
 216 *
 217 * This function sets the direction of specified GPIO signal as output.
 218 *
 219 * Return:
 220 * If all GPIO signals of GPIO chip is configured as input then it returns
 221 * error otherwise it returns 0.
 222 */
 223static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 224{
 225        unsigned long flags;
 226        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 227        struct xgpio_instance *chip = gpiochip_get_data(gc);
 228        int index =  xgpio_index(chip, gpio);
 229        int offset =  xgpio_offset(chip, gpio);
 230
 231        spin_lock_irqsave(&chip->gpio_lock[index], flags);
 232
 233        /* Write state of GPIO signal */
 234        if (val)
 235                chip->gpio_state[index] |= BIT(offset);
 236        else
 237                chip->gpio_state[index] &= ~BIT(offset);
 238        xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
 239                        xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
 240
 241        /* Clear the GPIO bit in shadow register and set direction as output */
 242        chip->gpio_dir[index] &= ~BIT(offset);
 243        xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
 244                        xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
 245
 246        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
 247
 248        return 0;
 249}
 250
 251/**
 252 * xgpio_save_regs - Set initial values of GPIO pins
 253 * @mm_gc: Pointer to memory mapped GPIO chip structure
 254 */
 255static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 256{
 257        struct xgpio_instance *chip =
 258                container_of(mm_gc, struct xgpio_instance, mmchip);
 259
 260        xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
 261        xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
 262
 263        if (!chip->gpio_width[1])
 264                return;
 265
 266        xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
 267                       chip->gpio_state[1]);
 268        xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
 269                       chip->gpio_dir[1]);
 270}
 271
 272/**
 273 * xgpio_remove - Remove method for the GPIO device.
 274 * @pdev: pointer to the platform device
 275 *
 276 * This function remove gpiochips and frees all the allocated resources.
 277 *
 278 * Return: 0 always
 279 */
 280static int xgpio_remove(struct platform_device *pdev)
 281{
 282        struct xgpio_instance *chip = platform_get_drvdata(pdev);
 283
 284        of_mm_gpiochip_remove(&chip->mmchip);
 285
 286        return 0;
 287}
 288
 289/**
 290 * xgpio_of_probe - Probe method for the GPIO device.
 291 * @pdev: pointer to the platform device
 292 *
 293 * Return:
 294 * It returns 0, if the driver is bound to the GPIO device, or
 295 * a negative value if there is an error.
 296 */
 297static int xgpio_probe(struct platform_device *pdev)
 298{
 299        struct xgpio_instance *chip;
 300        int status = 0;
 301        struct device_node *np = pdev->dev.of_node;
 302        u32 is_dual;
 303
 304        chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 305        if (!chip)
 306                return -ENOMEM;
 307
 308        platform_set_drvdata(pdev, chip);
 309
 310        /* Update GPIO state shadow register with default value */
 311        of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0]);
 312
 313        /* Update GPIO direction shadow register with default value */
 314        if (of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir[0]))
 315                chip->gpio_dir[0] = 0xFFFFFFFF;
 316
 317        /*
 318         * Check device node and parent device node for device width
 319         * and assume default width of 32
 320         */
 321        if (of_property_read_u32(np, "xlnx,gpio-width", &chip->gpio_width[0]))
 322                chip->gpio_width[0] = 32;
 323
 324        spin_lock_init(&chip->gpio_lock[0]);
 325
 326        if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
 327                is_dual = 0;
 328
 329        if (is_dual) {
 330                /* Update GPIO state shadow register with default value */
 331                of_property_read_u32(np, "xlnx,dout-default-2",
 332                                     &chip->gpio_state[1]);
 333
 334                /* Update GPIO direction shadow register with default value */
 335                if (of_property_read_u32(np, "xlnx,tri-default-2",
 336                                         &chip->gpio_dir[1]))
 337                        chip->gpio_dir[1] = 0xFFFFFFFF;
 338
 339                /*
 340                 * Check device node and parent device node for device width
 341                 * and assume default width of 32
 342                 */
 343                if (of_property_read_u32(np, "xlnx,gpio2-width",
 344                                         &chip->gpio_width[1]))
 345                        chip->gpio_width[1] = 32;
 346
 347                spin_lock_init(&chip->gpio_lock[1]);
 348        }
 349
 350        chip->mmchip.gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
 351        chip->mmchip.gc.parent = &pdev->dev;
 352        chip->mmchip.gc.direction_input = xgpio_dir_in;
 353        chip->mmchip.gc.direction_output = xgpio_dir_out;
 354        chip->mmchip.gc.get = xgpio_get;
 355        chip->mmchip.gc.set = xgpio_set;
 356        chip->mmchip.gc.set_multiple = xgpio_set_multiple;
 357
 358        chip->mmchip.save_regs = xgpio_save_regs;
 359
 360        /* Call the OF gpio helper to setup and register the GPIO device */
 361        status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip);
 362        if (status) {
 363                pr_err("%s: error in probe function with status %d\n",
 364                       np->full_name, status);
 365                return status;
 366        }
 367
 368        return 0;
 369}
 370
 371static const struct of_device_id xgpio_of_match[] = {
 372        { .compatible = "xlnx,xps-gpio-1.00.a", },
 373        { /* end of list */ },
 374};
 375
 376MODULE_DEVICE_TABLE(of, xgpio_of_match);
 377
 378static struct platform_driver xgpio_plat_driver = {
 379        .probe          = xgpio_probe,
 380        .remove         = xgpio_remove,
 381        .driver         = {
 382                        .name = "gpio-xilinx",
 383                        .of_match_table = xgpio_of_match,
 384        },
 385};
 386
 387static int __init xgpio_init(void)
 388{
 389        return platform_driver_register(&xgpio_plat_driver);
 390}
 391
 392subsys_initcall(xgpio_init);
 393
 394static void __exit xgpio_exit(void)
 395{
 396        platform_driver_unregister(&xgpio_plat_driver);
 397}
 398module_exit(xgpio_exit);
 399
 400MODULE_AUTHOR("Xilinx, Inc.");
 401MODULE_DESCRIPTION("Xilinx GPIO driver");
 402MODULE_LICENSE("GPL");
 403