aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/files/arch
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2009-08-31 08:29:19 +0000
committerGabor Juhos <juhosg@openwrt.org>2009-08-31 08:29:19 +0000
commitf3909502b0729717af8e85bef3b304cae6c061c2 (patch)
tree1d5ef9c303430d1f66026b966b382e0151a7be3d /target/linux/ramips/files/arch
parentb070e258c244a584c44081380d1fa5af9e1a3699 (diff)
downloadmaster-187ad058-f3909502b0729717af8e85bef3b304cae6c061c2.tar.gz
master-187ad058-f3909502b0729717af8e85bef3b304cae6c061c2.tar.bz2
master-187ad058-f3909502b0729717af8e85bef3b304cae6c061c2.zip
[ramips] fix GPIOLIB support
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@17446 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ramips/files/arch')
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h44
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x/ralink_soc.h20
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h1
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x/ralink_soc.h20
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h1
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/common/Makefile2
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/common/gpio.c224
7 files changed, 273 insertions, 39 deletions
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h
index e8a0836a32..f68ee16856 100644
--- a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h
@@ -1,5 +1,5 @@
/*
- * Ralink RT288x GPIO API definitions
+ * Ralink SoC GPIO API support
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
@@ -10,43 +10,15 @@
*
*/
-#ifndef __ASM_MACH_RT288X_GPIO_H
-#define __ASM_MACH_RT288X_GPIO_H
+#ifndef __ASM_MACH_RALINK_GPIO_H
+#define __ASM_MACH_RALINK_GPIO_H
-#define ARCH_NR_GPIOS 64
+#define ARCH_NR_GPIOS 128
#include <asm-generic/gpio.h>
-#include <asm/mach-ralink/rt288x.h>
-
-extern void __rt288x_gpio_set_value(unsigned gpio, int value);
-extern int __rt288x_gpio_get_value(unsigned gpio);
-
-static inline int gpio_to_irq(unsigned gpio)
-{
- return RT288X_GPIO_IRQ(gpio);
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
- return irq - RT288X_GPIO_IRQ_BASE;
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
- if (gpio < RT288X_GPIO_COUNT)
- return __rt288x_gpio_get_value(gpio);
-
- return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- if (gpio < RT288X_GPIO_COUNT)
- __rt288x_gpio_set_value(gpio, value);
- else
- __gpio_set_value(gpio, value);
-}
-
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
-#endif /* __ASM_MACH_RT288X_GPIO_H */
+#endif /* __ASM_MACH_RALINK_GPIO_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x/ralink_soc.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x/ralink_soc.h
new file mode 100644
index 0000000000..c379f39195
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x/ralink_soc.h
@@ -0,0 +1,20 @@
+/*
+ * Ralink RT288x specific SOC defines
+ *
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __RT288X_RALINK_SOC_H
+#define __RT288X_RALINK_SOC_H
+
+#define RALINK_SOC_GPIO_BASE 0x300600
+
+#define RALINK_SOC_GPIO0_COUNT 24
+#define RALINK_SOC_GPIO1_COUNT 16
+#define RALINK_SOC_GPIO2_COUNT 32
+
+#endif /* __RT288X_RALINK_SOC_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h
index 98308ffe01..dfd5b31599 100644
--- a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h
@@ -16,7 +16,6 @@
#define RT2880_SYSC_BASE 0x00300000
#define RT2880_TIMER_BASE 0x00300100
-#define RT2880_INTC_BASE 0x00300200
#define RT2880_MEMC_BASE 0x00300300
#define RT2880_UART0_BASE 0x00300500
#define RT2880_PIO_BASE 0x00300600
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x/ralink_soc.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x/ralink_soc.h
new file mode 100644
index 0000000000..144cc4ea46
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x/ralink_soc.h
@@ -0,0 +1,20 @@
+/*
+ * Ralink RT305x specific SOC defines
+ *
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __RT288X_RALINK_SOC_H
+#define __RT288X_RALINK_SOC_H
+
+#define RALINK_SOC_GPIO_BASE 0x10000600
+
+#define RALINK_SOC_GPIO0_COUNT 24
+#define RALINK_SOC_GPIO1_COUNT 16
+#define RALINK_SOC_GPIO2_COUNT 12
+
+#endif /* __RT288X_RALINK_SOC_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h
index 139dc92e54..d4a1920633 100644
--- a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h
@@ -20,7 +20,6 @@
#define RT305X_MEMC_BASE 0x10000300
#define RT305X_PCM_BASE 0x10000400
#define RT305X_UART0_BASE 0x10000500
-#define RT305X_PIO_BASE 0x10000600
#define RT305X_GDMA_BASE 0x10000700
#define RT305X_NANDC_BASE 0x10000800
#define RT305X_I2C_BASE 0x10000900
diff --git a/target/linux/ramips/files/arch/mips/ralink/common/Makefile b/target/linux/ramips/files/arch/mips/ralink/common/Makefile
index 2816a67089..08e16dd5c2 100644
--- a/target/linux/ramips/files/arch/mips/ralink/common/Makefile
+++ b/target/linux/ramips/files/arch/mips/ralink/common/Makefile
@@ -7,4 +7,4 @@
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
-obj-y := intc.o
+obj-y := intc.o gpio.o
diff --git a/target/linux/ramips/files/arch/mips/ralink/common/gpio.c b/target/linux/ramips/files/arch/mips/ralink/common/gpio.c
new file mode 100644
index 0000000000..af4cac7386
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/common/gpio.c
@@ -0,0 +1,224 @@
+/*
+ * Ralink SoC specific GPIO support
+ *
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <linux/gpio.h>
+
+#include <ralink_soc.h>
+
+#define GPIO0_REG_INT 0x00
+#define GPIO0_REG_EDGE 0x04
+#define GPIO0_REG_RENA 0x08
+#define GPIO0_REG_FENA 0x0c
+#define GPIO0_REG_DATA 0x20
+#define GPIO0_REG_DIR 0x24
+#define GPIO0_REG_POL 0x28
+#define GPIO0_REG_SET 0x2c
+#define GPIO0_REG_RESET 0x30
+#define GPIO0_REG_TOGGLE 0x34
+
+#define GPIO1_REG_INT 0x38
+#define GPIO1_REG_EDGE 0x3c
+#define GPIO1_REG_RENA 0x40
+#define GPIO1_REG_FENA 0x44
+#define GPIO1_REG_DATA 0x48
+#define GPIO1_REG_DIR 0x4c
+#define GPIO1_REG_POL 0x50
+#define GPIO1_REG_SET 0x54
+#define GPIO1_REG_RESET 0x58
+#define GPIO1_REG_TOGGLE 0x5c
+
+#define GPIO2_REG_INT 0x60
+#define GPIO2_REG_EDGE 0x64
+#define GPIO2_REG_RENA 0x68
+#define GPIO2_REG_FENA 0x6c
+#define GPIO2_REG_DATA 0x70
+#define GPIO2_REG_DIR 0x74
+#define GPIO2_REG_POL 0x78
+#define GPIO2_REG_SET 0x7c
+#define GPIO2_REG_RESET 0x80
+#define GPIO2_REG_TOGGLE 0x84
+
+enum ramips_pio_reg {
+ RAMIPS_GPIO_REG_INT, /* Interrupt status */
+ RAMIPS_GPIO_REG_EDGE,
+ RAMIPS_GPIO_REG_RENA,
+ RAMIPS_GPIO_REG_DATA,
+ RAMIPS_GPIO_REG_DIR, /* Direction, 0:in, 1: out */
+ RAMIPS_GPIO_REG_POL, /* Polarity, 0: normal, 1: invert */
+ RAMIPS_GPIO_REG_SET,
+ RAMIPS_GPIO_REG_RESET,
+ RAMIPS_GPIO_REG_TOGGLE,
+ RAMIPS_GPIO_REG_MAX
+};
+
+struct ramips_gpio_chip {
+ struct gpio_chip chip;
+ u8 regs[RAMIPS_GPIO_REG_MAX];
+};
+
+static void __iomem *ramips_gpio_base;
+
+static inline struct ramips_gpio_chip *to_ramips_gpio(struct gpio_chip *chip)
+{
+ struct ramips_gpio_chip *rg;
+
+ rg = container_of(chip, struct ramips_gpio_chip, chip);
+ return rg;
+}
+
+static inline void ramips_gpio_wr(struct ramips_gpio_chip *rg, u8 reg, u32 val)
+{
+ __raw_writel(val, ramips_gpio_base + rg->regs[reg]);
+}
+
+static inline u32 ramips_gpio_rr(struct ramips_gpio_chip *rg, u8 reg)
+{
+ return __raw_readl(ramips_gpio_base + rg->regs[reg]);
+}
+
+static int ramips_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ramips_gpio_chip *rg = to_ramips_gpio(chip);
+ u32 t;
+
+ t = ramips_gpio_rr(rg, RAMIPS_GPIO_REG_DIR);
+ t &= ~(1 << offset);
+ ramips_gpio_wr(rg, RAMIPS_GPIO_REG_DIR, t);
+
+ return 0;
+}
+
+static int ramips_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct ramips_gpio_chip *rg = to_ramips_gpio(chip);
+ u32 reg;
+ u32 t;
+
+ reg = (value) ? RAMIPS_GPIO_REG_SET : RAMIPS_GPIO_REG_RESET;
+ ramips_gpio_wr(rg, reg, 1 << offset);
+
+ t = ramips_gpio_rr(rg, RAMIPS_GPIO_REG_DIR);
+ t |= 1 << offset;
+ ramips_gpio_wr(rg, RAMIPS_GPIO_REG_DIR, t);
+
+ return 0;
+}
+
+static void ramips_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct ramips_gpio_chip *rg = to_ramips_gpio(chip);
+ u32 reg;
+
+ reg = (value) ? RAMIPS_GPIO_REG_SET : RAMIPS_GPIO_REG_RESET;
+ ramips_gpio_wr(rg, reg, 1 << offset);
+}
+
+static int ramips_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ramips_gpio_chip *rg = to_ramips_gpio(chip);
+ u32 t;
+
+ t = ramips_gpio_rr(rg, RAMIPS_GPIO_REG_DATA);
+ return (t & (1 << offset));
+}
+
+static struct ramips_gpio_chip ramips_gpio_chip0 = {
+ .chip = {
+ .label = "ramips-gpio0",
+ .direction_input = ramips_gpio_direction_input,
+ .direction_output = ramips_gpio_direction_output,
+ .get = ramips_gpio_get,
+ .set = ramips_gpio_set,
+ .base = 0,
+ .ngpio = RALINK_SOC_GPIO0_COUNT,
+ },
+ .regs = {
+ [RAMIPS_GPIO_REG_INT] = GPIO0_REG_INT,
+ [RAMIPS_GPIO_REG_EDGE] = GPIO0_REG_EDGE,
+ [RAMIPS_GPIO_REG_RENA] = GPIO0_REG_RENA,
+ [RAMIPS_GPIO_REG_DATA] = GPIO0_REG_DATA,
+ [RAMIPS_GPIO_REG_DIR] = GPIO0_REG_DIR,
+ [RAMIPS_GPIO_REG_POL] = GPIO0_REG_POL,
+ [RAMIPS_GPIO_REG_SET] = GPIO0_REG_SET,
+ [RAMIPS_GPIO_REG_RESET] = GPIO0_REG_RESET,
+ [RAMIPS_GPIO_REG_TOGGLE] = GPIO0_REG_TOGGLE,
+ },
+};
+
+static struct ramips_gpio_chip ramips_gpio_chip1 = {
+ .chip = {
+ .label = "ramips-gpio1",
+ .direction_input = ramips_gpio_direction_input,
+ .direction_output = ramips_gpio_direction_output,
+ .get = ramips_gpio_get,
+ .set = ramips_gpio_set,
+ .base = 32,
+ .ngpio = RALINK_SOC_GPIO1_COUNT,
+ },
+ .regs = {
+ [RAMIPS_GPIO_REG_INT] = GPIO1_REG_INT,
+ [RAMIPS_GPIO_REG_EDGE] = GPIO1_REG_EDGE,
+ [RAMIPS_GPIO_REG_RENA] = GPIO1_REG_RENA,
+ [RAMIPS_GPIO_REG_DATA] = GPIO1_REG_DATA,
+ [RAMIPS_GPIO_REG_DIR] = GPIO1_REG_DIR,
+ [RAMIPS_GPIO_REG_POL] = GPIO1_REG_POL,
+ [RAMIPS_GPIO_REG_SET] = GPIO1_REG_SET,
+ [RAMIPS_GPIO_REG_RESET] = GPIO1_REG_RESET,
+ [RAMIPS_GPIO_REG_TOGGLE] = GPIO1_REG_TOGGLE,
+ },
+};
+
+static struct ramips_gpio_chip ramips_gpio_chip2 = {
+ .chip = {
+ .label = "ramips-gpio2",
+ .direction_input = ramips_gpio_direction_input,
+ .direction_output = ramips_gpio_direction_output,
+ .get = ramips_gpio_get,
+ .set = ramips_gpio_set,
+ .base = 64,
+ .ngpio = RALINK_SOC_GPIO2_COUNT,
+ },
+ .regs = {
+ [RAMIPS_GPIO_REG_INT] = GPIO2_REG_INT,
+ [RAMIPS_GPIO_REG_EDGE] = GPIO2_REG_EDGE,
+ [RAMIPS_GPIO_REG_RENA] = GPIO2_REG_RENA,
+ [RAMIPS_GPIO_REG_DATA] = GPIO2_REG_DATA,
+ [RAMIPS_GPIO_REG_DIR] = GPIO2_REG_DIR,
+ [RAMIPS_GPIO_REG_POL] = GPIO2_REG_POL,
+ [RAMIPS_GPIO_REG_SET] = GPIO2_REG_SET,
+ [RAMIPS_GPIO_REG_RESET] = GPIO2_REG_RESET,
+ [RAMIPS_GPIO_REG_TOGGLE] = GPIO2_REG_TOGGLE,
+ },
+};
+
+static __init void ramips_gpio_chip_add(struct ramips_gpio_chip *rg)
+{
+ /* set priority to low for all lines */
+ ramips_gpio_wr(rg, RAMIPS_GPIO_REG_POL, 0);
+
+ gpiochip_add(&rg->chip);
+}
+
+__init int ramips_gpio_init(void)
+{
+ ramips_gpio_base = ioremap_nocache(RALINK_SOC_GPIO_BASE, PAGE_SIZE);
+
+ ramips_gpio_chip_add(&ramips_gpio_chip0);
+ ramips_gpio_chip_add(&ramips_gpio_chip1);
+ ramips_gpio_chip_add(&ramips_gpio_chip2);
+
+ return 0;
+}
+
+arch_initcall(ramips_gpio_init);