diff options
| author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2007-06-22 10:21:55 -0400 |
|---|---|---|
| committer | Ralf Baechle <ralf@linux-mips.org> | 2007-07-10 12:33:03 -0400 |
| commit | 3896b05418b9b8548a678231db754206b3ebe56e (patch) | |
| tree | 6da9c0461d9e28f750a1c1a0063bb9132f74acc6 /arch/mips | |
| parent | 06cf5583fd9ac782cf34996cdabb48afdf478e37 (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>
Diffstat (limited to 'arch/mips')
| -rw-r--r-- | arch/mips/Kconfig | 1 | ||||
| -rw-r--r-- | arch/mips/configs/rbhma4500_defconfig | 1 | ||||
| -rw-r--r-- | arch/mips/tx4938/toshiba_rbtx4938/setup.c | 104 |
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 | |||
| 80 | CONFIG_DMA_NEED_PCI_MAP_STATE=y | 80 | CONFIG_DMA_NEED_PCI_MAP_STATE=y |
| 81 | CONFIG_GENERIC_ISA_DMA=y | 81 | CONFIG_GENERIC_ISA_DMA=y |
| 82 | CONFIG_I8259=y | 82 | CONFIG_I8259=y |
| 83 | CONFIG_GENERIC_GPIO=y | ||
| 83 | # CONFIG_CPU_BIG_ENDIAN is not set | 84 | # CONFIG_CPU_BIG_ENDIAN is not set |
| 84 | CONFIG_CPU_LITTLE_ENDIAN=y | 85 | CONFIG_CPU_LITTLE_ENDIAN=y |
| 85 | CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y | 86 | CONFIG_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 | } |
| 1059 | device_initcall(rbtx4938_ne_init); | 1060 | device_initcall(rbtx4938_ne_init); |
| 1061 | |||
| 1062 | /* GPIO support */ | ||
| 1063 | |||
| 1064 | static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); | ||
| 1065 | |||
| 1066 | static 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 | |||
| 1082 | static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value) | ||
| 1083 | { | ||
| 1084 | rbtx4938_spi_gpio_set(gpio, value); | ||
| 1085 | return 0; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | static DEFINE_SPINLOCK(tx4938_gpio_lock); | ||
| 1089 | |||
| 1090 | static int tx4938_gpio_get(unsigned gpio) | ||
| 1091 | { | ||
| 1092 | return tx4938_pioptr->din & (1 << gpio); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | static 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 | |||
| 1106 | static 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 | |||
| 1115 | static 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 | |||
| 1124 | static 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 | |||
| 1134 | int gpio_direction_input(unsigned gpio) | ||
| 1135 | { | ||
| 1136 | if (gpio < 16) | ||
| 1137 | return tx4938_gpio_dir_in(gpio); | ||
| 1138 | return -EINVAL; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | int 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 | |||
| 1150 | int gpio_get_value(unsigned gpio) | ||
| 1151 | { | ||
| 1152 | if (gpio < 16) | ||
| 1153 | return tx4938_gpio_get(gpio); | ||
| 1154 | return 0; | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | void 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 | } | ||
