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/tx4938 | |
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/tx4938')
-rw-r--r-- | arch/mips/tx4938/toshiba_rbtx4938/setup.c | 104 |
1 files changed, 104 insertions, 0 deletions
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 | } | ||