/*1* Xilinx gpio driver2*3* Copyright 2008 Xilinx, Inc.4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 27* as published by the Free Software Foundation.8*9* You should have received a copy of the GNU General Public License10* along with this program; if not, write to the Free Software11* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA12*/1314#include <linux/init.h>15#include <linux/errno.h>16#include <linux/of_device.h>17#include <linux/of_platform.h>18#include <linux/of_gpio.h>19#include <linux/io.h>20#include <linux/gpio.h>21#include <linux/slab.h>2223/* Register Offset Definitions */24#define XGPIO_DATA_OFFSET (0x0) /* Data register */25#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */2627struct xgpio_instance {28struct of_mm_gpio_chip mmchip;29u32 gpio_state; /* GPIO state shadow register */30u32 gpio_dir; /* GPIO direction shadow register */31spinlock_t gpio_lock; /* Lock used for synchronization */32};3334/**35* xgpio_get - Read the specified signal of the GPIO device.36* @gc: Pointer to gpio_chip device structure.37* @gpio: GPIO signal number.38*39* This function reads the specified signal of the GPIO device. It returns 0 if40* the signal clear, 1 if signal is set or negative value on error.41*/42static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)43{44struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);4546return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1;47}4849/**50* xgpio_set - Write the specified signal of the GPIO device.51* @gc: Pointer to gpio_chip device structure.52* @gpio: GPIO signal number.53* @val: Value to be written to specified signal.54*55* This function writes the specified value in to the specified signal of the56* GPIO device.57*/58static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)59{60unsigned long flags;61struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);62struct xgpio_instance *chip =63container_of(mm_gc, struct xgpio_instance, mmchip);6465spin_lock_irqsave(&chip->gpio_lock, flags);6667/* Write to GPIO signal and set its direction to output */68if (val)69chip->gpio_state |= 1 << gpio;70else71chip->gpio_state &= ~(1 << gpio);72out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);7374spin_unlock_irqrestore(&chip->gpio_lock, flags);75}7677/**78* xgpio_dir_in - Set the direction of the specified GPIO signal as input.79* @gc: Pointer to gpio_chip device structure.80* @gpio: GPIO signal number.81*82* This function sets the direction of specified GPIO signal as input.83* It returns 0 if direction of GPIO signals is set as input otherwise it84* returns negative error value.85*/86static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)87{88unsigned long flags;89struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);90struct xgpio_instance *chip =91container_of(mm_gc, struct xgpio_instance, mmchip);9293spin_lock_irqsave(&chip->gpio_lock, flags);9495/* Set the GPIO bit in shadow register and set direction as input */96chip->gpio_dir |= (1 << gpio);97out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);9899spin_unlock_irqrestore(&chip->gpio_lock, flags);100101return 0;102}103104/**105* xgpio_dir_out - Set the direction of the specified GPIO signal as output.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 sets the direction of specified GPIO signal as output. If all111* GPIO signals of GPIO chip is configured as input then it returns112* error otherwise it returns 0.113*/114static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)115{116unsigned long flags;117struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);118struct xgpio_instance *chip =119container_of(mm_gc, struct xgpio_instance, mmchip);120121spin_lock_irqsave(&chip->gpio_lock, flags);122123/* Write state of GPIO signal */124if (val)125chip->gpio_state |= 1 << gpio;126else127chip->gpio_state &= ~(1 << gpio);128out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);129130/* Clear the GPIO bit in shadow register and set direction as output */131chip->gpio_dir &= (~(1 << gpio));132out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);133134spin_unlock_irqrestore(&chip->gpio_lock, flags);135136return 0;137}138139/**140* xgpio_save_regs - Set initial values of GPIO pins141* @mm_gc: pointer to memory mapped GPIO chip structure142*/143static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)144{145struct xgpio_instance *chip =146container_of(mm_gc, struct xgpio_instance, mmchip);147148out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);149out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);150}151152/**153* xgpio_of_probe - Probe method for the GPIO device.154* @np: pointer to device tree node155*156* This function probes the GPIO device in the device tree. It initializes the157* driver data structure. It returns 0, if the driver is bound to the GPIO158* device, or a negative value if there is an error.159*/160static int __devinit xgpio_of_probe(struct device_node *np)161{162struct xgpio_instance *chip;163int status = 0;164const u32 *tree_info;165166chip = kzalloc(sizeof(*chip), GFP_KERNEL);167if (!chip)168return -ENOMEM;169170/* Update GPIO state shadow register with default value */171tree_info = of_get_property(np, "xlnx,dout-default", NULL);172if (tree_info)173chip->gpio_state = be32_to_cpup(tree_info);174175/* Update GPIO direction shadow register with default value */176chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */177tree_info = of_get_property(np, "xlnx,tri-default", NULL);178if (tree_info)179chip->gpio_dir = be32_to_cpup(tree_info);180181/* Check device node and parent device node for device width */182chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */183tree_info = of_get_property(np, "xlnx,gpio-width", NULL);184if (!tree_info)185tree_info = of_get_property(np->parent,186"xlnx,gpio-width", NULL);187if (tree_info)188chip->mmchip.gc.ngpio = be32_to_cpup(tree_info);189190spin_lock_init(&chip->gpio_lock);191192chip->mmchip.gc.direction_input = xgpio_dir_in;193chip->mmchip.gc.direction_output = xgpio_dir_out;194chip->mmchip.gc.get = xgpio_get;195chip->mmchip.gc.set = xgpio_set;196197chip->mmchip.save_regs = xgpio_save_regs;198199/* Call the OF gpio helper to setup and register the GPIO device */200status = of_mm_gpiochip_add(np, &chip->mmchip);201if (status) {202kfree(chip);203pr_err("%s: error in probe function with status %d\n",204np->full_name, status);205return status;206}207pr_info("XGpio: %s: registered\n", np->full_name);208return 0;209}210211static struct of_device_id xgpio_of_match[] __devinitdata = {212{ .compatible = "xlnx,xps-gpio-1.00.a", },213{ /* end of list */ },214};215216static int __init xgpio_init(void)217{218struct device_node *np;219220for_each_matching_node(np, xgpio_of_match)221xgpio_of_probe(np);222223return 0;224}225226/* Make sure we get initialized before anyone else tries to use us */227subsys_initcall(xgpio_init);228/* No exit call at the moment as we cannot unregister of GPIO chips */229230MODULE_AUTHOR("Xilinx, Inc.");231MODULE_DESCRIPTION("Xilinx GPIO driver");232MODULE_LICENSE("GPL");233234235