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#ifdef CONFIG_ARCH_ZYNQ
  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 * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks
  44 * gpio_state: GPIO state shadow register
  45 * gpio_dir: GPIO direction shadow register
  46 * offset: GPIO channel offset
  47 * gpio_lock: Lock used for synchronization
  48 */
  49struct xgpio_instance {
  50        struct of_mm_gpio_chip mmchip;
  51        u32 gpio_state;
  52        u32 gpio_dir;
  53        u32 offset;
  54        spinlock_t gpio_lock;
  55};
  56
  57/**
  58 * xgpio_get - Read the specified signal of the GPIO device.
  59 * @gc:     Pointer to gpio_chip device structure.
  60 * @gpio:   GPIO signal number.
  61 *
  62 * This function reads the specified signal of the GPIO device. It returns 0 if
  63 * the signal clear, 1 if signal is set or negative value on error.
  64 */
  65static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
  66{
  67        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  68        struct xgpio_instance *chip =
  69            container_of(mm_gc, struct xgpio_instance, mmchip);
  70
  71        void __iomem *regs = mm_gc->regs + chip->offset;
  72
  73        return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio));
  74}
  75
  76/**
  77 * xgpio_set - Write the specified signal of the GPIO device.
  78 * @gc:     Pointer to gpio_chip device structure.
  79 * @gpio:   GPIO signal number.
  80 * @val:    Value to be written to specified signal.
  81 *
  82 * This function writes the specified value in to the specified signal of the
  83 * GPIO device.
  84 */
  85static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  86{
  87        unsigned long flags;
  88        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  89        struct xgpio_instance *chip =
  90            container_of(mm_gc, struct xgpio_instance, mmchip);
  91        void __iomem *regs = mm_gc->regs;
  92
  93        spin_lock_irqsave(&chip->gpio_lock, flags);
  94
  95        /* Write to GPIO signal and set its direction to output */
  96        if (val)
  97                chip->gpio_state |= BIT(gpio);
  98        else
  99                chip->gpio_state &= ~BIT(gpio);
 100
 101        xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
 102                                                         chip->gpio_state);
 103
 104        spin_unlock_irqrestore(&chip->gpio_lock, flags);
 105}
 106
 107/**
 108 * xgpio_dir_in - Set the direction of the specified GPIO signal as input.
 109 * @gc:     Pointer to gpio_chip device structure.
 110 * @gpio:   GPIO signal number.
 111 *
 112 * This function sets the direction of specified GPIO signal as input.
 113 * It returns 0 if direction of GPIO signals is set as input otherwise it
 114 * returns negative error value.
 115 */
 116static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 117{
 118        unsigned long flags;
 119        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 120        struct xgpio_instance *chip =
 121            container_of(mm_gc, struct xgpio_instance, mmchip);
 122        void __iomem *regs = mm_gc->regs;
 123
 124        spin_lock_irqsave(&chip->gpio_lock, flags);
 125
 126        /* Set the GPIO bit in shadow register and set direction as input */
 127        chip->gpio_dir |= BIT(gpio);
 128        xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
 129
 130        spin_unlock_irqrestore(&chip->gpio_lock, flags);
 131
 132        return 0;
 133}
 134
 135/**
 136 * xgpio_dir_out - Set the direction of the specified GPIO signal as output.
 137 * @gc:     Pointer to gpio_chip device structure.
 138 * @gpio:   GPIO signal number.
 139 * @val:    Value to be written to specified signal.
 140 *
 141 * This function sets the direction of specified GPIO signal as output. If all
 142 * GPIO signals of GPIO chip is configured as input then it returns
 143 * error otherwise it returns 0.
 144 */
 145static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 146{
 147        unsigned long flags;
 148        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 149        struct xgpio_instance *chip =
 150            container_of(mm_gc, struct xgpio_instance, mmchip);
 151        void __iomem *regs = mm_gc->regs;
 152
 153        spin_lock_irqsave(&chip->gpio_lock, flags);
 154
 155        /* Write state of GPIO signal */
 156        if (val)
 157                chip->gpio_state |= BIT(gpio);
 158        else
 159                chip->gpio_state &= ~BIT(gpio);
 160        xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
 161                       chip->gpio_state);
 162
 163        /* Clear the GPIO bit in shadow register and set direction as output */
 164        chip->gpio_dir &= ~BIT(gpio);
 165        xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
 166
 167        spin_unlock_irqrestore(&chip->gpio_lock, flags);
 168
 169        return 0;
 170}
 171
 172/**
 173 * xgpio_save_regs - Set initial values of GPIO pins
 174 * @mm_gc: pointer to memory mapped GPIO chip structure
 175 */
 176static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 177{
 178        struct xgpio_instance *chip =
 179            container_of(mm_gc, struct xgpio_instance, mmchip);
 180
 181        xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET,
 182                                                        chip->gpio_state);
 183        xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_TRI_OFFSET,
 184                                                         chip->gpio_dir);
 185}
 186
 187/**
 188 * xgpio_of_probe - Probe method for the GPIO device.
 189 * @np: pointer to device tree node
 190 *
 191 * This function probes the GPIO device in the device tree. It initializes the
 192 * driver data structure. It returns 0, if the driver is bound to the GPIO
 193 * device, or a negative value if there is an error.
 194 */
 195static int xgpio_of_probe(struct device_node *np)
 196{
 197        struct xgpio_instance *chip;
 198        int status = 0;
 199        const u32 *tree_info;
 200
 201        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 202        if (!chip)
 203                return -ENOMEM;
 204
 205        /* Update GPIO state shadow register with default value */
 206        of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state);
 207
 208        /* By default, all pins are inputs */
 209        chip->gpio_dir = 0xFFFFFFFF;
 210
 211        /* Update GPIO direction shadow register with default value */
 212        of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir);
 213
 214        /* By default assume full GPIO controller */
 215        chip->mmchip.gc.ngpio = 32;
 216
 217        /* Check device node and parent device node for device width */
 218        of_property_read_u32(np, "xlnx,gpio-width",
 219                              (u32 *)&chip->mmchip.gc.ngpio);
 220
 221        spin_lock_init(&chip->gpio_lock);
 222
 223        chip->mmchip.gc.direction_input = xgpio_dir_in;
 224        chip->mmchip.gc.direction_output = xgpio_dir_out;
 225        chip->mmchip.gc.get = xgpio_get;
 226        chip->mmchip.gc.set = xgpio_set;
 227
 228        chip->mmchip.save_regs = xgpio_save_regs;
 229
 230        /* Call the OF gpio helper to setup and register the GPIO device */
 231        status = of_mm_gpiochip_add(np, &chip->mmchip);
 232        if (status) {
 233                kfree(chip);
 234                pr_err("%s: error in probe function with status %d\n",
 235                       np->full_name, status);
 236                return status;
 237        }
 238
 239        pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
 240                                                        chip->mmchip.gc.base);
 241
 242        tree_info = of_get_property(np, "xlnx,is-dual", NULL);
 243        if (tree_info && be32_to_cpup(tree_info)) {
 244                chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 245                if (!chip)
 246                        return -ENOMEM;
 247
 248                /* Add dual channel offset */
 249                chip->offset = XGPIO_CHANNEL_OFFSET;
 250
 251                /* Update GPIO state shadow register with default value */
 252                of_property_read_u32(np, "xlnx,dout-default-2",
 253                                     &chip->gpio_state);
 254
 255                /* By default, all pins are inputs */
 256                chip->gpio_dir = 0xFFFFFFFF;
 257
 258                /* Update GPIO direction shadow register with default value */
 259                of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir);
 260
 261                /* By default assume full GPIO controller */
 262                chip->mmchip.gc.ngpio = 32;
 263
 264                /* Check device node and parent device node for device width */
 265                of_property_read_u32(np, "xlnx,gpio2-width",
 266                                     (u32 *)&chip->mmchip.gc.ngpio);
 267
 268                spin_lock_init(&chip->gpio_lock);
 269
 270                chip->mmchip.gc.direction_input = xgpio_dir_in;
 271                chip->mmchip.gc.direction_output = xgpio_dir_out;
 272                chip->mmchip.gc.get = xgpio_get;
 273                chip->mmchip.gc.set = xgpio_set;
 274
 275                chip->mmchip.save_regs = xgpio_save_regs;
 276
 277                /* Call the OF gpio helper to setup and register the GPIO dev */
 278                status = of_mm_gpiochip_add(np, &chip->mmchip);
 279                if (status) {
 280                        kfree(chip);
 281                        pr_err("%s: error in probe function with status %d\n",
 282                        np->full_name, status);
 283                        return status;
 284                }
 285                pr_info("XGpio: %s: dual channel registered, base is %d\n",
 286                                        np->full_name, chip->mmchip.gc.base);
 287        }
 288
 289        return 0;
 290}
 291
 292static struct of_device_id xgpio_of_match[] = {
 293        { .compatible = "xlnx,xps-gpio-1.00.a", },
 294        { /* end of list */ },
 295};
 296
 297static int __init xgpio_init(void)
 298{
 299        struct device_node *np;
 300
 301        for_each_matching_node(np, xgpio_of_match)
 302                xgpio_of_probe(np);
 303
 304        return 0;
 305}
 306
 307/* Make sure we get initialized before anyone else tries to use us */
 308subsys_initcall(xgpio_init);
 309/* No exit call at the moment as we cannot unregister of GPIO chips */
 310
 311MODULE_AUTHOR("Xilinx, Inc.");
 312MODULE_DESCRIPTION("Xilinx GPIO driver");
 313MODULE_LICENSE("GPL");
 314
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.