aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2007-06-22 10:21:55 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-07-10 12:33:03 -0400
commit3896b05418b9b8548a678231db754206b3ebe56e (patch)
tree6da9c0461d9e28f750a1c1a0063bb9132f74acc6
parent06cf5583fd9ac782cf34996cdabb48afdf478e37 (diff)
[MIPS] rbtx4938: Add generic GPIO support
GPIO 0..15 are for TX4938 PIO pins, GPIO 16..18 are for FPGA-driven chipselect signals for SPI devices. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c104
3 files changed, 106 insertions, 0 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 24661d60bc8f..823a6285c55a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -660,6 +660,7 @@ config TOSHIBA_RBTX4938
660 select SYS_SUPPORTS_BIG_ENDIAN 660 select SYS_SUPPORTS_BIG_ENDIAN
661 select SYS_SUPPORTS_KGDB 661 select SYS_SUPPORTS_KGDB
662 select GENERIC_HARDIRQS_NO__DO_IRQ 662 select GENERIC_HARDIRQS_NO__DO_IRQ
663 select GENERIC_GPIO
663 help 664 help
664 This Toshiba board is based on the TX4938 processor. Say Y here to 665 This Toshiba board is based on the TX4938 processor. Say Y here to
665 support this machine type 666 support this machine type
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index b0abd16fae29..6e10c15cecf7 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -80,6 +80,7 @@ CONFIG_DMA_NONCOHERENT=y
80CONFIG_DMA_NEED_PCI_MAP_STATE=y 80CONFIG_DMA_NEED_PCI_MAP_STATE=y
81CONFIG_GENERIC_ISA_DMA=y 81CONFIG_GENERIC_ISA_DMA=y
82CONFIG_I8259=y 82CONFIG_I8259=y
83CONFIG_GENERIC_GPIO=y
83# CONFIG_CPU_BIG_ENDIAN is not set 84# CONFIG_CPU_BIG_ENDIAN is not set
84CONFIG_CPU_LITTLE_ENDIAN=y 85CONFIG_CPU_LITTLE_ENDIAN=y
85CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y 86CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index f5d1ce739fcc..12b9f4f9c3a2 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -29,6 +29,7 @@
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/bootinfo.h> 31#include <asm/bootinfo.h>
32#include <asm/gpio.h>
32#include <asm/tx4938/rbtx4938.h> 33#include <asm/tx4938/rbtx4938.h>
33#ifdef CONFIG_SERIAL_TXX9 34#ifdef CONFIG_SERIAL_TXX9
34#include <linux/tty.h> 35#include <linux/tty.h>
@@ -1057,3 +1058,106 @@ static int __init rbtx4938_ne_init(void)
1057 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 1058 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
1058} 1059}
1059device_initcall(rbtx4938_ne_init); 1060device_initcall(rbtx4938_ne_init);
1061
1062/* GPIO support */
1063
1064static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
1065
1066static void rbtx4938_spi_gpio_set(unsigned gpio, int value)
1067{
1068 u8 val;
1069 unsigned long flags;
1070 gpio -= 16;
1071 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
1072 val = *rbtx4938_spics_ptr;
1073 if (value)
1074 val |= 1 << gpio;
1075 else
1076 val &= ~(1 << gpio);
1077 *rbtx4938_spics_ptr = val;
1078 mmiowb();
1079 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
1080}
1081
1082static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value)
1083{
1084 rbtx4938_spi_gpio_set(gpio, value);
1085 return 0;
1086}
1087
1088static DEFINE_SPINLOCK(tx4938_gpio_lock);
1089
1090static int tx4938_gpio_get(unsigned gpio)
1091{
1092 return tx4938_pioptr->din & (1 << gpio);
1093}
1094
1095static void tx4938_gpio_set_raw(unsigned gpio, int value)
1096{
1097 u32 val;
1098 val = tx4938_pioptr->dout;
1099 if (value)
1100 val |= 1 << gpio;
1101 else
1102 val &= ~(1 << gpio);
1103 tx4938_pioptr->dout = val;
1104}
1105
1106static void tx4938_gpio_set(unsigned gpio, int value)
1107{
1108 unsigned long flags;
1109 spin_lock_irqsave(&tx4938_gpio_lock, flags);
1110 tx4938_gpio_set_raw(gpio, value);
1111 mmiowb();
1112 spin_unlock_irqrestore(&tx4938_gpio_lock, flags);
1113}
1114
1115static int tx4938_gpio_dir_in(unsigned gpio)
1116{
1117 spin_lock_irq(&tx4938_gpio_lock);
1118 tx4938_pioptr->dir &= ~(1 << gpio);
1119 mmiowb();
1120 spin_unlock_irq(&tx4938_gpio_lock);
1121 return 0;
1122}
1123
1124static int tx4938_gpio_dir_out(unsigned int gpio, int value)
1125{
1126 spin_lock_irq(&tx4938_gpio_lock);
1127 tx4938_gpio_set_raw(gpio, value);
1128 tx4938_pioptr->dir |= 1 << gpio;
1129 mmiowb();
1130 spin_unlock_irq(&tx4938_gpio_lock);
1131 return 0;
1132}
1133
1134int gpio_direction_input(unsigned gpio)
1135{
1136 if (gpio < 16)
1137 return tx4938_gpio_dir_in(gpio);
1138 return -EINVAL;
1139}
1140
1141int gpio_direction_output(unsigned gpio, int value)
1142{
1143 if (gpio < 16)
1144 return tx4938_gpio_dir_out(gpio, value);
1145 if (gpio < 16 + 3)
1146 return rbtx4938_spi_gpio_dir_out(gpio, value);
1147 return -EINVAL;
1148}
1149
1150int gpio_get_value(unsigned gpio)
1151{
1152 if (gpio < 16)
1153 return tx4938_gpio_get(gpio);
1154 return 0;
1155}
1156
1157void gpio_set_value(unsigned gpio, int value)
1158{
1159 if (gpio < 16)
1160 tx4938_gpio_set(gpio, value);
1161 else
1162 rbtx4938_spi_gpio_set(gpio, value);
1163}