linux/drivers/gpio/gpio-xilinx.c
<<
>>
Prefs
   1/*
   2 * Xilinx gpio driver
   3 *
   4 * Copyright 2008 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/init.h>
  16#include <linux/errno.h>
  17#include <linux/module.h>
  18#include <linux/of_device.h>
  19#include <linux/of_platform.h>
  20#include <linux/of_gpio.h>
  21#include <linux/io.h>
  22#include <linux/gpio.h>
  23#include <linux/slab.h>
  24
  25/* Register Offset Definitions */
  26#define XGPIO_DATA_OFFSET   (0x0)       /* Data register  */
  27#define XGPIO_TRI_OFFSET    (0x4)       /* I/O direction register  */
  28
  29struct xgpio_instance {
  30        struct of_mm_gpio_chip mmchip;
  31        u32 gpio_state;         /* GPIO state shadow register */
  32        u32 gpio_dir;           /* GPIO direction shadow register */
  33        spinlock_t gpio_lock;   /* Lock used for synchronization */
  34};
  35
  36/**
  37 * xgpio_get - Read the specified signal of the GPIO device.
  38 * @gc:     Pointer to gpio_chip device structure.
  39 * @gpio:   GPIO signal number.
  40 *
  41 * This function reads the specified signal of the GPIO device. It returns 0 if
  42 * the signal clear, 1 if signal is set or negative value on error.
  43 */
  44static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
  45{
  46        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  47
  48        return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1;
  49}
  50
  51/**
  52 * xgpio_set - Write the specified signal of the GPIO device.
  53 * @gc:     Pointer to gpio_chip device structure.
  54 * @gpio:   GPIO signal number.
  55 * @val:    Value to be written to specified signal.
  56 *
  57 * This function writes the specified value in to the specified signal of the
  58 * GPIO device.
  59 */
  60static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  61{
  62        unsigned long flags;
  63        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  64        struct xgpio_instance *chip =
  65            container_of(mm_gc, struct xgpio_instance, mmchip);
  66
  67        spin_lock_irqsave(&chip->gpio_lock, flags);
  68
  69        /* Write to GPIO signal and set its direction to output */
  70        if (val)
  71                chip->gpio_state |= 1 << gpio;
  72        else
  73                chip->gpio_state &= ~(1 << gpio);
  74        out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
  75
  76        spin_unlock_irqrestore(&chip->gpio_lock, flags);
  77}
  78
  79/**
  80 * xgpio_dir_in - Set the direction of the specified GPIO signal as input.
  81 * @gc:     Pointer to gpio_chip device structure.
  82 * @gpio:   GPIO signal number.
  83 *
  84 * This function sets the direction of specified GPIO signal as input.
  85 * It returns 0 if direction of GPIO signals is set as input otherwise it
  86 * returns negative error value.
  87 */
  88static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
  89{
  90        unsigned long flags;
  91        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  92        struct xgpio_instance *chip =
  93            container_of(mm_gc, struct xgpio_instance, mmchip);
  94
  95        spin_lock_irqsave(&chip->gpio_lock, flags);
  96
  97        /* Set the GPIO bit in shadow register and set direction as input */
  98        chip->gpio_dir |= (1 << gpio);
  99        out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
 100
 101        spin_unlock_irqrestore(&chip->gpio_lock, flags);
 102
 103        return 0;
 104}
 105
 106/**
 107 * xgpio_dir_out - Set the direction of the specified GPIO signal as output.
 108 * @gc:     Pointer to gpio_chip device structure.
 109 * @gpio:   GPIO signal number.
 110 * @val:    Value to be written to specified signal.
 111 *
 112 * This function sets the direction of specified GPIO signal as output. If all
 113 * GPIO signals of GPIO chip is configured as input then it returns
 114 * error otherwise it returns 0.
 115 */
 116static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 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
 123        spin_lock_irqsave(&chip->gpio_lock, flags);
 124
 125        /* Write state of GPIO signal */
 126        if (val)
 127                chip->gpio_state |= 1 << gpio;
 128        else
 129                chip->gpio_state &= ~(1 << gpio);
 130        out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
 131
 132        /* Clear the GPIO bit in shadow register and set direction as output */
 133        chip->gpio_dir &= (~(1 << gpio));
 134        out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
 135
 136        spin_unlock_irqrestore(&chip->gpio_lock, flags);
 137
 138        return 0;
 139}
 140
 141/**
 142 * xgpio_save_regs - Set initial values of GPIO pins
 143 * @mm_gc: pointer to memory mapped GPIO chip structure
 144 */
 145static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
 146{
 147        struct xgpio_instance *chip =
 148            container_of(mm_gc, struct xgpio_instance, mmchip);
 149
 150        out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
 151        out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
 152}
 153
 154/**
 155 * xgpio_of_probe - Probe method for the GPIO device.
 156 * @np: pointer to device tree node
 157 *
 158 * This function probes the GPIO device in the device tree. It initializes the
 159 * driver data structure. It returns 0, if the driver is bound to the GPIO
 160 * device, or a negative value if there is an error.
 161 */
 162static int xgpio_of_probe(struct device_node *np)
 163{
 164        struct xgpio_instance *chip;
 165        int status = 0;
 166        const u32 *tree_info;
 167
 168        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 169        if (!chip)
 170                return -ENOMEM;
 171
 172        /* Update GPIO state shadow register with default value */
 173        tree_info = of_get_property(np, "xlnx,dout-default", NULL);
 174        if (tree_info)
 175                chip->gpio_state = be32_to_cpup(tree_info);
 176
 177        /* Update GPIO direction shadow register with default value */
 178        chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */
 179        tree_info = of_get_property(np, "xlnx,tri-default", NULL);
 180        if (tree_info)
 181                chip->gpio_dir = be32_to_cpup(tree_info);
 182
 183        /* Check device node and parent device node for device width */
 184        chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */
 185        tree_info = of_get_property(np, "xlnx,gpio-width", NULL);
 186        if (!tree_info)
 187                tree_info = of_get_property(np->parent,
 188                                            "xlnx,gpio-width", NULL);
 189        if (tree_info)
 190                chip->mmchip.gc.ngpio = be32_to_cpup(tree_info);
 191
 192        spin_lock_init(&chip->gpio_lock);
 193
 194        chip->mmchip.gc.direction_input = xgpio_dir_in;
 195        chip->mmchip.gc.direction_output = xgpio_dir_out;
 196        chip->mmchip.gc.get = xgpio_get;
 197        chip->mmchip.gc.set = xgpio_set;
 198
 199        chip->mmchip.save_regs = xgpio_save_regs;
 200
 201        /* Call the OF gpio helper to setup and register the GPIO device */
 202        status = of_mm_gpiochip_add(np, &chip->mmchip);
 203        if (status) {
 204                kfree(chip);
 205                pr_err("%s: error in probe function with status %d\n",
 206                       np->full_name, status);
 207                return status;
 208        }
 209        return 0;
 210}
 211
 212static struct of_device_id xgpio_of_match[] = {
 213        { .compatible = "xlnx,xps-gpio-1.00.a", },
 214        { /* end of list */ },
 215};
 216
 217static int __init xgpio_init(void)
 218{
 219        struct device_node *np;
 220
 221        for_each_matching_node(np, xgpio_of_match)
 222                xgpio_of_probe(np);
 223
 224        return 0;
 225}
 226
 227/* Make sure we get initialized before anyone else tries to use us */
 228subsys_initcall(xgpio_init);
 229/* No exit call at the moment as we cannot unregister of GPIO chips */
 230
 231MODULE_AUTHOR("Xilinx, Inc.");
 232MODULE_DESCRIPTION("Xilinx GPIO driver");
 233MODULE_LICENSE("GPL");
 234
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.