Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 123068
b: refs/heads/master
c: 965dc5f
h: refs/heads/master
v: v3
  • Loading branch information
Martyn Welch authored and Kumar Gala committed Dec 3, 2008
1 parent 86bc298 commit f304460
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 09a3fba8c132a55f153fd65fc1085b717a6193c8
refs/heads/master: 965dc5fc55fa0201fd8241ba7c0efc8f96f0ec84
6 changes: 6 additions & 0 deletions trunk/arch/powerpc/boot/dts/gef_sbc610.dts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@
interrupt-parent = <&mpic>;

};
gef_gpio: gpio@7,14000 {
#gpio-cells = <2>;
compatible = "gef,sbc610-gpio";
reg = <0x7 0x14000 0x24>;
gpio-controller;
};
};

soc@fef00000 {
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/platforms/86xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ config MPC8610_HPCD
config GEF_SBC610
bool "GE Fanuc SBC610"
select DEFAULT_UIMAGE
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select HAS_RAPIDIO
help
This option enables support for GE Fanuc's SBC610.
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/powerpc/platforms/86xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o
obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
obj-$(CONFIG_SBC8641D) += sbc8641d.o
obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o
gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y)
143 changes: 143 additions & 0 deletions trunk/arch/powerpc/platforms/86xx/gef_gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* Driver for GE Fanuc's FPGA based GPIO pins
*
* Author: Martyn Welch <martyn.welch@gefanuc.com>
*
* 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/

/* TODO
*
* Configuration of output modes (totem-pole/open-drain)
* Interrupt configuration - interrupts are always generated the FPGA relies on
* the I/O interrupt controllers mask to stop them propergating
*/

#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>

#define GEF_GPIO_DIRECT 0x00
#define GEF_GPIO_IN 0x04
#define GEF_GPIO_OUT 0x08
#define GEF_GPIO_TRIG 0x0C
#define GEF_GPIO_POLAR_A 0x10
#define GEF_GPIO_POLAR_B 0x14
#define GEF_GPIO_INT_STAT 0x18
#define GEF_GPIO_OVERRUN 0x1C
#define GEF_GPIO_MODE 0x20

#define NUM_GPIO 19

static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
{
unsigned int data;

data = ioread32be(reg);
/* value: 0=low; 1=high */
if (value & 0x1)
data = data | (0x1 << offset);
else
data = data & ~(0x1 << offset);

iowrite32be(data, reg);
}


static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
{
unsigned int data;
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
data = data | (0x1 << offset);
iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);

return 0;
}

static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
{
unsigned int data;
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

/* Set direction before switching to input */
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);

data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
data = data & ~(0x1 << offset);
iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);

return 0;
}

static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
{
unsigned int data;
int state = 0;
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

data = ioread32be(mmchip->regs + GEF_GPIO_IN);
state = (int)((data >> offset) & 0x1);

return state;
}

static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);

_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
}

static int __init gef_gpio_init(void)
{
struct device_node *np;

for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
int retval;
struct of_mm_gpio_chip *gef_gpio_chip;

pr_debug("%s: Initialising GEF GPIO\n", np->full_name);

/* Allocate chip structure */
gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
if (!gef_gpio_chip) {
pr_err("%s: Unable to allocate structure\n",
np->full_name);
continue;
}

/* Setup pointers to chip functions */
gef_gpio_chip->of_gc.gpio_cells = 2;
gef_gpio_chip->of_gc.gc.ngpio = NUM_GPIO;
gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
gef_gpio_chip->of_gc.gc.set = gef_gpio_set;

/* This function adds a memory mapped GPIO chip */
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
if (retval) {
kfree(gef_gpio_chip);
pr_err("%s: Unable to add GPIO\n", np->full_name);
}
}

return 0;
};
arch_initcall(gef_gpio_init);

MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver");
MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
MODULE_LICENSE("GPL");

0 comments on commit f304460

Please sign in to comment.