• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/powerpc/platforms/86xx/
1/*
2 * Driver for GE FPGA based GPIO
3 *
4 * Author: Martyn Welch <martyn.welch@ge.com>
5 *
6 * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc.
7 *
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.
11 */
12
13/* TODO
14 *
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
18 */
19
20#include <linux/kernel.h>
21#include <linux/compiler.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/of.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
31#define GEF_GPIO_DIRECT		0x00
32#define GEF_GPIO_IN		0x04
33#define GEF_GPIO_OUT		0x08
34#define GEF_GPIO_TRIG		0x0C
35#define GEF_GPIO_POLAR_A	0x10
36#define GEF_GPIO_POLAR_B	0x14
37#define GEF_GPIO_INT_STAT	0x18
38#define GEF_GPIO_OVERRUN	0x1C
39#define GEF_GPIO_MODE		0x20
40
41static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
42{
43	unsigned int data;
44
45	data = ioread32be(reg);
46	/* value: 0=low; 1=high */
47	if (value & 0x1)
48		data = data | (0x1 << offset);
49	else
50		data = data & ~(0x1 << offset);
51
52	iowrite32be(data, reg);
53}
54
55
56static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
57{
58	unsigned int data;
59	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
60
61	data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
62	data = data | (0x1 << offset);
63	iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
64
65	return 0;
66}
67
68static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
69{
70	unsigned int data;
71	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
72
73	/* Set direction before switching to input */
74	_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
75
76	data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
77	data = data & ~(0x1 << offset);
78	iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
79
80	return 0;
81}
82
83static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
84{
85	unsigned int data;
86	int state = 0;
87	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
88
89	data = ioread32be(mmchip->regs + GEF_GPIO_IN);
90	state = (int)((data >> offset) & 0x1);
91
92	return state;
93}
94
95static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
96{
97	struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
98
99	_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
100}
101
102static int __init gef_gpio_init(void)
103{
104	struct device_node *np;
105	int retval;
106	struct of_mm_gpio_chip *gef_gpio_chip;
107
108	for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
109
110		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
111
112		/* Allocate chip structure */
113		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
114		if (!gef_gpio_chip) {
115			pr_err("%s: Unable to allocate structure\n",
116				np->full_name);
117			continue;
118		}
119
120		/* Setup pointers to chip functions */
121		gef_gpio_chip->gc.of_gpio_n_cells = 2;
122		gef_gpio_chip->gc.ngpio = 19;
123		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
124		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
125		gef_gpio_chip->gc.get = gef_gpio_get;
126		gef_gpio_chip->gc.set = gef_gpio_set;
127
128		/* This function adds a memory mapped GPIO chip */
129		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
130		if (retval) {
131			kfree(gef_gpio_chip);
132			pr_err("%s: Unable to add GPIO\n", np->full_name);
133		}
134	}
135
136	for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {
137
138		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
139
140		/* Allocate chip structure */
141		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
142		if (!gef_gpio_chip) {
143			pr_err("%s: Unable to allocate structure\n",
144				np->full_name);
145			continue;
146		}
147
148		/* Setup pointers to chip functions */
149		gef_gpio_chip->gc.of_gpio_n_cells = 2;
150		gef_gpio_chip->gc.ngpio = 6;
151		gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
152		gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
153		gef_gpio_chip->gc.get = gef_gpio_get;
154		gef_gpio_chip->gc.set = gef_gpio_set;
155
156		/* This function adds a memory mapped GPIO chip */
157		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
158		if (retval) {
159			kfree(gef_gpio_chip);
160			pr_err("%s: Unable to add GPIO\n", np->full_name);
161		}
162	}
163
164	return 0;
165};
166arch_initcall(gef_gpio_init);
167
168MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
169MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
170MODULE_LICENSE("GPL");
171