2
* Driver for GE FPGA based GPIO
4
* Author: Martyn Welch <martyn.welch@ge.com>
6
* 2008 (c) GE Intelligent Platforms Embedded Systems, Inc.
8
* This file is licensed under the terms of the GNU General Public License
9
* version 2. This program is licensed "as is" without any warranty of any
10
* kind, whether express or implied.
15
* Configuration of output modes (totem-pole/open-drain)
16
* Interrupt configuration - interrupts are always generated the FPGA relies on
17
* the I/O interrupt controllers mask to stop them propergating
20
#include <linux/kernel.h>
21
#include <linux/compiler.h>
22
#include <linux/init.h>
25
#include <linux/of_device.h>
26
#include <linux/of_platform.h>
27
#include <linux/of_gpio.h>
28
#include <linux/gpio.h>
29
#include <linux/slab.h>
30
#include <linux/module.h>
32
#define GEF_GPIO_DIRECT 0x00
33
#define GEF_GPIO_IN 0x04
34
#define GEF_GPIO_OUT 0x08
35
#define GEF_GPIO_TRIG 0x0C
36
#define GEF_GPIO_POLAR_A 0x10
37
#define GEF_GPIO_POLAR_B 0x14
38
#define GEF_GPIO_INT_STAT 0x18
39
#define GEF_GPIO_OVERRUN 0x1C
40
#define GEF_GPIO_MODE 0x20
42
static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
46
data = ioread32be(reg);
47
/* value: 0=low; 1=high */
49
data = data | (0x1 << offset);
51
data = data & ~(0x1 << offset);
53
iowrite32be(data, reg);
57
static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
60
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
62
data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
63
data = data | (0x1 << offset);
64
iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
69
static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
72
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
74
/* Set direction before switching to input */
75
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
77
data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
78
data = data & ~(0x1 << offset);
79
iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
84
static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
88
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
90
data = ioread32be(mmchip->regs + GEF_GPIO_IN);
91
state = (int)((data >> offset) & 0x1);
96
static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
98
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
100
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
103
static int __init gef_gpio_init(void)
105
struct device_node *np;
107
struct of_mm_gpio_chip *gef_gpio_chip;
109
for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
111
pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
113
/* Allocate chip structure */
114
gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
115
if (!gef_gpio_chip) {
116
pr_err("%s: Unable to allocate structure\n",
121
/* Setup pointers to chip functions */
122
gef_gpio_chip->gc.of_gpio_n_cells = 2;
123
gef_gpio_chip->gc.ngpio = 19;
124
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
125
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
126
gef_gpio_chip->gc.get = gef_gpio_get;
127
gef_gpio_chip->gc.set = gef_gpio_set;
129
/* This function adds a memory mapped GPIO chip */
130
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
132
kfree(gef_gpio_chip);
133
pr_err("%s: Unable to add GPIO\n", np->full_name);
137
for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {
139
pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
141
/* Allocate chip structure */
142
gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
143
if (!gef_gpio_chip) {
144
pr_err("%s: Unable to allocate structure\n",
149
/* Setup pointers to chip functions */
150
gef_gpio_chip->gc.of_gpio_n_cells = 2;
151
gef_gpio_chip->gc.ngpio = 6;
152
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
153
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
154
gef_gpio_chip->gc.get = gef_gpio_get;
155
gef_gpio_chip->gc.set = gef_gpio_set;
157
/* This function adds a memory mapped GPIO chip */
158
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
160
kfree(gef_gpio_chip);
161
pr_err("%s: Unable to add GPIO\n", np->full_name);
167
arch_initcall(gef_gpio_init);
169
MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
170
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
171
MODULE_LICENSE("GPL");