diff options
Diffstat (limited to 'arch/arm/mach-sa1100')
-rw-r--r-- | arch/arm/mach-sa1100/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/Makefile.boot | 5 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/assabet.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/generic.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/gpio.c | 65 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/include/mach/gpio.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/include/mach/io.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/include/mach/simpad.h | 94 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/leds-simpad.c | 100 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/leds.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/leds.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/simpad.c | 213 |
12 files changed, 269 insertions, 229 deletions
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index 41252d22e659..ed7408d3216c 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := clock.o generic.o gpio.o irq.o dma.o time.o #nmi-oopser.o | 6 | obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o |
7 | obj-m := | 7 | obj-m := |
8 | obj-n := | 8 | obj-n := |
9 | obj- := | 9 | obj- := |
@@ -45,7 +45,6 @@ obj-$(CONFIG_SA1100_PLEB) += pleb.o | |||
45 | obj-$(CONFIG_SA1100_SHANNON) += shannon.o | 45 | obj-$(CONFIG_SA1100_SHANNON) += shannon.o |
46 | 46 | ||
47 | obj-$(CONFIG_SA1100_SIMPAD) += simpad.o | 47 | obj-$(CONFIG_SA1100_SIMPAD) += simpad.o |
48 | led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o | ||
49 | 48 | ||
50 | # LEDs support | 49 | # LEDs support |
51 | obj-$(CONFIG_LEDS) += $(led-y) | 50 | obj-$(CONFIG_LEDS) += $(led-y) |
diff --git a/arch/arm/mach-sa1100/Makefile.boot b/arch/arm/mach-sa1100/Makefile.boot index a56ad0417cf2..5a616f6e5612 100644 --- a/arch/arm/mach-sa1100/Makefile.boot +++ b/arch/arm/mach-sa1100/Makefile.boot | |||
@@ -1,6 +1,7 @@ | |||
1 | zreladdr-y := 0xc0008000 | ||
2 | ifeq ($(CONFIG_ARCH_SA1100),y) | 1 | ifeq ($(CONFIG_ARCH_SA1100),y) |
3 | zreladdr-$(CONFIG_SA1111) := 0xc0208000 | 2 | zreladdr-$(CONFIG_SA1111) += 0xc0208000 |
3 | else | ||
4 | zreladdr-y += 0xc0008000 | ||
4 | endif | 5 | endif |
5 | params_phys-y := 0xc0000100 | 6 | params_phys-y := 0xc0000100 |
6 | initrd_phys-y := 0xc0800000 | 7 | initrd_phys-y := 0xc0800000 |
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index d40da5f1f37b..3dd133f18415 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
@@ -301,8 +301,7 @@ static void __init get_assabet_scr(void) | |||
301 | } | 301 | } |
302 | 302 | ||
303 | static void __init | 303 | static void __init |
304 | fixup_assabet(struct machine_desc *desc, struct tag *tags, | 304 | fixup_assabet(struct tag *tags, char **cmdline, struct meminfo *mi) |
305 | char **cmdline, struct meminfo *mi) | ||
306 | { | 305 | { |
307 | /* This must be done before any call to machine_has_neponset() */ | 306 | /* This must be done before any call to machine_has_neponset() */ |
308 | map_sa1100_gpio_regs(); | 307 | map_sa1100_gpio_regs(); |
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index e21f3470eece..5fa5ae1f39e1 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | #include <linux/gpio.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -24,7 +25,6 @@ | |||
24 | #include <asm/mach/map.h> | 25 | #include <asm/mach/map.h> |
25 | #include <asm/mach/flash.h> | 26 | #include <asm/mach/flash.h> |
26 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
27 | #include <asm/gpio.h> | ||
28 | 28 | ||
29 | #include "generic.h" | 29 | #include "generic.h" |
30 | 30 | ||
diff --git a/arch/arm/mach-sa1100/gpio.c b/arch/arm/mach-sa1100/gpio.c deleted file mode 100644 index 0d3829a8c2c1..000000000000 --- a/arch/arm/mach-sa1100/gpio.c +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-sa1100/gpio.c | ||
3 | * | ||
4 | * Generic SA-1100 GPIO handling | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include <asm/gpio.h> | ||
15 | #include <mach/hardware.h> | ||
16 | #include "generic.h" | ||
17 | |||
18 | static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
19 | { | ||
20 | return GPLR & GPIO_GPIO(offset); | ||
21 | } | ||
22 | |||
23 | static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
24 | { | ||
25 | if (value) | ||
26 | GPSR = GPIO_GPIO(offset); | ||
27 | else | ||
28 | GPCR = GPIO_GPIO(offset); | ||
29 | } | ||
30 | |||
31 | static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset) | ||
32 | { | ||
33 | unsigned long flags; | ||
34 | |||
35 | local_irq_save(flags); | ||
36 | GPDR &= ~GPIO_GPIO(offset); | ||
37 | local_irq_restore(flags); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value) | ||
42 | { | ||
43 | unsigned long flags; | ||
44 | |||
45 | local_irq_save(flags); | ||
46 | sa1100_gpio_set(chip, offset, value); | ||
47 | GPDR |= GPIO_GPIO(offset); | ||
48 | local_irq_restore(flags); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static struct gpio_chip sa1100_gpio_chip = { | ||
53 | .label = "gpio", | ||
54 | .direction_input = sa1100_direction_input, | ||
55 | .direction_output = sa1100_direction_output, | ||
56 | .set = sa1100_gpio_set, | ||
57 | .get = sa1100_gpio_get, | ||
58 | .base = 0, | ||
59 | .ngpio = GPIO_MAX + 1, | ||
60 | }; | ||
61 | |||
62 | void __init sa1100_init_gpio(void) | ||
63 | { | ||
64 | gpiochip_add(&sa1100_gpio_chip); | ||
65 | } | ||
diff --git a/arch/arm/mach-sa1100/include/mach/gpio.h b/arch/arm/mach-sa1100/include/mach/gpio.h index 7befc104e9a9..703631887c94 100644 --- a/arch/arm/mach-sa1100/include/mach/gpio.h +++ b/arch/arm/mach-sa1100/include/mach/gpio.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm-generic/gpio.h> | 29 | #include <asm-generic/gpio.h> |
30 | 30 | ||
31 | #define __ARM_GPIOLIB_COMPLEX | ||
32 | |||
31 | static inline int gpio_get_value(unsigned gpio) | 33 | static inline int gpio_get_value(unsigned gpio) |
32 | { | 34 | { |
33 | if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX)) | 35 | if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX)) |
@@ -51,7 +53,5 @@ static inline void gpio_set_value(unsigned gpio, int value) | |||
51 | 53 | ||
52 | #define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \ | 54 | #define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \ |
53 | (IRQ_GPIO11 - 11 + gpio)) | 55 | (IRQ_GPIO11 - 11 + gpio)) |
54 | #define irq_to_gpio(irq) ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \ | ||
55 | (irq - IRQ_GPIO11 + 11)) | ||
56 | 56 | ||
57 | #endif | 57 | #endif |
diff --git a/arch/arm/mach-sa1100/include/mach/io.h b/arch/arm/mach-sa1100/include/mach/io.h index d8b43f3dcd2d..dfc27ff08344 100644 --- a/arch/arm/mach-sa1100/include/mach/io.h +++ b/arch/arm/mach-sa1100/include/mach/io.h | |||
@@ -10,11 +10,9 @@ | |||
10 | #ifndef __ASM_ARM_ARCH_IO_H | 10 | #ifndef __ASM_ARM_ARCH_IO_H |
11 | #define __ASM_ARM_ARCH_IO_H | 11 | #define __ASM_ARM_ARCH_IO_H |
12 | 12 | ||
13 | #define IO_SPACE_LIMIT 0xffffffff | ||
14 | |||
15 | /* | 13 | /* |
16 | * We don't actually have real ISA nor PCI buses, but there is so many | 14 | * __io() is required to be an equivalent mapping to __mem_pci() for |
17 | * drivers out there that might just work if we fake them... | 15 | * SOC_COMMON to work. |
18 | */ | 16 | */ |
19 | #define __io(a) __typesafe_io(a) | 17 | #define __io(a) __typesafe_io(a) |
20 | #define __mem_pci(a) (a) | 18 | #define __mem_pci(a) (a) |
diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h index 9296c4513ce1..db28118103eb 100644 --- a/arch/arm/mach-sa1100/include/mach/simpad.h +++ b/arch/arm/mach-sa1100/include/mach/simpad.h | |||
@@ -48,32 +48,80 @@ | |||
48 | #define GPIO_SMART_CARD GPIO_GPIO10 | 48 | #define GPIO_SMART_CARD GPIO_GPIO10 |
49 | #define IRQ_GPIO_SMARD_CARD IRQ_GPIO10 | 49 | #define IRQ_GPIO_SMARD_CARD IRQ_GPIO10 |
50 | 50 | ||
51 | // CS3 Latch is write only, a shadow is necessary | 51 | /*--- ucb1x00 GPIO ---*/ |
52 | #define SIMPAD_UCB1X00_GPIO_BASE (GPIO_MAX + 1) | ||
53 | #define SIMPAD_UCB1X00_GPIO_PROG1 (SIMPAD_UCB1X00_GPIO_BASE) | ||
54 | #define SIMPAD_UCB1X00_GPIO_PROG2 (SIMPAD_UCB1X00_GPIO_BASE + 1) | ||
55 | #define SIMPAD_UCB1X00_GPIO_UP (SIMPAD_UCB1X00_GPIO_BASE + 2) | ||
56 | #define SIMPAD_UCB1X00_GPIO_DOWN (SIMPAD_UCB1X00_GPIO_BASE + 3) | ||
57 | #define SIMPAD_UCB1X00_GPIO_LEFT (SIMPAD_UCB1X00_GPIO_BASE + 4) | ||
58 | #define SIMPAD_UCB1X00_GPIO_RIGHT (SIMPAD_UCB1X00_GPIO_BASE + 5) | ||
59 | #define SIMPAD_UCB1X00_GPIO_6 (SIMPAD_UCB1X00_GPIO_BASE + 6) | ||
60 | #define SIMPAD_UCB1X00_GPIO_7 (SIMPAD_UCB1X00_GPIO_BASE + 7) | ||
61 | #define SIMPAD_UCB1X00_GPIO_HEADSET (SIMPAD_UCB1X00_GPIO_BASE + 8) | ||
62 | #define SIMPAD_UCB1X00_GPIO_SPEAKER (SIMPAD_UCB1X00_GPIO_BASE + 9) | ||
63 | |||
64 | /*--- CS3 Latch ---*/ | ||
65 | #define SIMPAD_CS3_GPIO_BASE (GPIO_MAX + 11) | ||
66 | #define SIMPAD_CS3_VCC_5V_EN (SIMPAD_CS3_GPIO_BASE) | ||
67 | #define SIMPAD_CS3_VCC_3V_EN (SIMPAD_CS3_GPIO_BASE + 1) | ||
68 | #define SIMPAD_CS3_EN1 (SIMPAD_CS3_GPIO_BASE + 2) | ||
69 | #define SIMPAD_CS3_EN0 (SIMPAD_CS3_GPIO_BASE + 3) | ||
70 | #define SIMPAD_CS3_DISPLAY_ON (SIMPAD_CS3_GPIO_BASE + 4) | ||
71 | #define SIMPAD_CS3_PCMCIA_BUFF_DIS (SIMPAD_CS3_GPIO_BASE + 5) | ||
72 | #define SIMPAD_CS3_MQ_RESET (SIMPAD_CS3_GPIO_BASE + 6) | ||
73 | #define SIMPAD_CS3_PCMCIA_RESET (SIMPAD_CS3_GPIO_BASE + 7) | ||
74 | #define SIMPAD_CS3_DECT_POWER_ON (SIMPAD_CS3_GPIO_BASE + 8) | ||
75 | #define SIMPAD_CS3_IRDA_SD (SIMPAD_CS3_GPIO_BASE + 9) | ||
76 | #define SIMPAD_CS3_RS232_ON (SIMPAD_CS3_GPIO_BASE + 10) | ||
77 | #define SIMPAD_CS3_SD_MEDIAQ (SIMPAD_CS3_GPIO_BASE + 11) | ||
78 | #define SIMPAD_CS3_LED2_ON (SIMPAD_CS3_GPIO_BASE + 12) | ||
79 | #define SIMPAD_CS3_IRDA_MODE (SIMPAD_CS3_GPIO_BASE + 13) | ||
80 | #define SIMPAD_CS3_ENABLE_5V (SIMPAD_CS3_GPIO_BASE + 14) | ||
81 | #define SIMPAD_CS3_RESET_SIMCARD (SIMPAD_CS3_GPIO_BASE + 15) | ||
82 | |||
83 | #define SIMPAD_CS3_PCMCIA_BVD1 (SIMPAD_CS3_GPIO_BASE + 16) | ||
84 | #define SIMPAD_CS3_PCMCIA_BVD2 (SIMPAD_CS3_GPIO_BASE + 17) | ||
85 | #define SIMPAD_CS3_PCMCIA_VS1 (SIMPAD_CS3_GPIO_BASE + 18) | ||
86 | #define SIMPAD_CS3_PCMCIA_VS2 (SIMPAD_CS3_GPIO_BASE + 19) | ||
87 | #define SIMPAD_CS3_LOCK_IND (SIMPAD_CS3_GPIO_BASE + 20) | ||
88 | #define SIMPAD_CS3_CHARGING_STATE (SIMPAD_CS3_GPIO_BASE + 21) | ||
89 | #define SIMPAD_CS3_PCMCIA_SHORT (SIMPAD_CS3_GPIO_BASE + 22) | ||
90 | #define SIMPAD_CS3_GPIO_23 (SIMPAD_CS3_GPIO_BASE + 23) | ||
52 | 91 | ||
53 | #define CS3BUSTYPE unsigned volatile long | ||
54 | #define CS3_BASE 0xf1000000 | 92 | #define CS3_BASE 0xf1000000 |
55 | 93 | ||
56 | #define VCC_5V_EN 0x0001 // For 5V PCMCIA | 94 | long simpad_get_cs3_ro(void); |
57 | #define VCC_3V_EN 0x0002 // FOR 3.3V PCMCIA | 95 | long simpad_get_cs3_shadow(void); |
58 | #define EN1 0x0004 // This is only for EPROM's | 96 | void simpad_set_cs3_bit(int value); |
59 | #define EN0 0x0008 // Both should be enable for 3.3V or 5V | 97 | void simpad_clear_cs3_bit(int value); |
60 | #define DISPLAY_ON 0x0010 | 98 | |
61 | #define PCMCIA_BUFF_DIS 0x0020 | 99 | #define VCC_5V_EN 0x0001 /* For 5V PCMCIA */ |
62 | #define MQ_RESET 0x0040 | 100 | #define VCC_3V_EN 0x0002 /* FOR 3.3V PCMCIA */ |
63 | #define PCMCIA_RESET 0x0080 | 101 | #define EN1 0x0004 /* This is only for EPROM's */ |
64 | #define DECT_POWER_ON 0x0100 | 102 | #define EN0 0x0008 /* Both should be enable for 3.3V or 5V */ |
65 | #define IRDA_SD 0x0200 // Shutdown for powersave | 103 | #define DISPLAY_ON 0x0010 |
66 | #define RS232_ON 0x0400 | 104 | #define PCMCIA_BUFF_DIS 0x0020 |
67 | #define SD_MEDIAQ 0x0800 // Shutdown for powersave | 105 | #define MQ_RESET 0x0040 |
68 | #define LED2_ON 0x1000 | 106 | #define PCMCIA_RESET 0x0080 |
69 | #define IRDA_MODE 0x2000 // Fast/Slow IrDA mode | 107 | #define DECT_POWER_ON 0x0100 |
70 | #define ENABLE_5V 0x4000 // Enable 5V circuit | 108 | #define IRDA_SD 0x0200 /* Shutdown for powersave */ |
71 | #define RESET_SIMCARD 0x8000 | 109 | #define RS232_ON 0x0400 |
72 | 110 | #define SD_MEDIAQ 0x0800 /* Shutdown for powersave */ | |
73 | #define RS232_ENABLE 0x0440 | 111 | #define LED2_ON 0x1000 |
74 | #define PCMCIAMASK 0x402f | 112 | #define IRDA_MODE 0x2000 /* Fast/Slow IrDA mode */ |
75 | 113 | #define ENABLE_5V 0x4000 /* Enable 5V circuit */ | |
76 | 114 | #define RESET_SIMCARD 0x8000 | |
115 | |||
116 | #define PCMCIA_BVD1 0x01 | ||
117 | #define PCMCIA_BVD2 0x02 | ||
118 | #define PCMCIA_VS1 0x04 | ||
119 | #define PCMCIA_VS2 0x08 | ||
120 | #define LOCK_IND 0x10 | ||
121 | #define CHARGING_STATE 0x20 | ||
122 | #define PCMCIA_SHORT 0x40 | ||
123 | |||
124 | /*--- Battery ---*/ | ||
77 | struct simpad_battery { | 125 | struct simpad_battery { |
78 | unsigned char ac_status; /* line connected yes/no */ | 126 | unsigned char ac_status; /* line connected yes/no */ |
79 | unsigned char status; /* battery loading yes/no */ | 127 | unsigned char status; /* battery loading yes/no */ |
diff --git a/arch/arm/mach-sa1100/leds-simpad.c b/arch/arm/mach-sa1100/leds-simpad.c deleted file mode 100644 index d50f4eeaa12e..000000000000 --- a/arch/arm/mach-sa1100/leds-simpad.c +++ /dev/null | |||
@@ -1,100 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-sa1100/leds-simpad.c | ||
3 | * | ||
4 | * Author: Juergen Messerer <juergen.messerer@siemens.ch> | ||
5 | */ | ||
6 | #include <linux/init.h> | ||
7 | |||
8 | #include <mach/hardware.h> | ||
9 | #include <asm/leds.h> | ||
10 | #include <asm/system.h> | ||
11 | #include <mach/simpad.h> | ||
12 | |||
13 | #include "leds.h" | ||
14 | |||
15 | |||
16 | #define LED_STATE_ENABLED 1 | ||
17 | #define LED_STATE_CLAIMED 2 | ||
18 | |||
19 | static unsigned int led_state; | ||
20 | static unsigned int hw_led_state; | ||
21 | |||
22 | #define LED_GREEN (1) | ||
23 | #define LED_MASK (1) | ||
24 | |||
25 | extern void set_cs3_bit(int value); | ||
26 | extern void clear_cs3_bit(int value); | ||
27 | |||
28 | void simpad_leds_event(led_event_t evt) | ||
29 | { | ||
30 | switch (evt) | ||
31 | { | ||
32 | case led_start: | ||
33 | hw_led_state = LED_GREEN; | ||
34 | led_state = LED_STATE_ENABLED; | ||
35 | break; | ||
36 | |||
37 | case led_stop: | ||
38 | led_state &= ~LED_STATE_ENABLED; | ||
39 | break; | ||
40 | |||
41 | case led_claim: | ||
42 | led_state |= LED_STATE_CLAIMED; | ||
43 | hw_led_state = LED_GREEN; | ||
44 | break; | ||
45 | |||
46 | case led_release: | ||
47 | led_state &= ~LED_STATE_CLAIMED; | ||
48 | hw_led_state = LED_GREEN; | ||
49 | break; | ||
50 | |||
51 | #ifdef CONFIG_LEDS_TIMER | ||
52 | case led_timer: | ||
53 | if (!(led_state & LED_STATE_CLAIMED)) | ||
54 | hw_led_state ^= LED_GREEN; | ||
55 | break; | ||
56 | #endif | ||
57 | |||
58 | #ifdef CONFIG_LEDS_CPU | ||
59 | case led_idle_start: | ||
60 | break; | ||
61 | |||
62 | case led_idle_end: | ||
63 | break; | ||
64 | #endif | ||
65 | |||
66 | case led_halted: | ||
67 | break; | ||
68 | |||
69 | case led_green_on: | ||
70 | if (led_state & LED_STATE_CLAIMED) | ||
71 | hw_led_state |= LED_GREEN; | ||
72 | break; | ||
73 | |||
74 | case led_green_off: | ||
75 | if (led_state & LED_STATE_CLAIMED) | ||
76 | hw_led_state &= ~LED_GREEN; | ||
77 | break; | ||
78 | |||
79 | case led_amber_on: | ||
80 | break; | ||
81 | |||
82 | case led_amber_off: | ||
83 | break; | ||
84 | |||
85 | case led_red_on: | ||
86 | break; | ||
87 | |||
88 | case led_red_off: | ||
89 | break; | ||
90 | |||
91 | default: | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | if (led_state & LED_STATE_ENABLED) | ||
96 | set_cs3_bit(LED2_ON); | ||
97 | else | ||
98 | clear_cs3_bit(LED2_ON); | ||
99 | } | ||
100 | |||
diff --git a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c index bbfe197fb4d6..5fe71a0f1053 100644 --- a/arch/arm/mach-sa1100/leds.c +++ b/arch/arm/mach-sa1100/leds.c | |||
@@ -42,8 +42,6 @@ sa1100_leds_init(void) | |||
42 | leds_event = adsbitsy_leds_event; | 42 | leds_event = adsbitsy_leds_event; |
43 | if (machine_is_pt_system3()) | 43 | if (machine_is_pt_system3()) |
44 | leds_event = system3_leds_event; | 44 | leds_event = system3_leds_event; |
45 | if (machine_is_simpad()) | ||
46 | leds_event = simpad_leds_event; /* what about machine registry? including led, apm... -zecke */ | ||
47 | 45 | ||
48 | leds_event(led_start); | 46 | leds_event(led_start); |
49 | return 0; | 47 | return 0; |
diff --git a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h index 68cc9f773d6d..776b6020f550 100644 --- a/arch/arm/mach-sa1100/leds.h +++ b/arch/arm/mach-sa1100/leds.h | |||
@@ -11,4 +11,3 @@ extern void pfs168_leds_event(led_event_t evt); | |||
11 | extern void graphicsmaster_leds_event(led_event_t evt); | 11 | extern void graphicsmaster_leds_event(led_event_t evt); |
12 | extern void adsbitsy_leds_event(led_event_t evt); | 12 | extern void adsbitsy_leds_event(led_event_t evt); |
13 | extern void system3_leds_event(led_event_t evt); | 13 | extern void system3_leds_event(led_event_t evt); |
14 | extern void simpad_leds_event(led_event_t evt); | ||
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index a1c2427655da..4790f3f3d008 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/mtd/mtd.h> | 13 | #include <linux/mtd/mtd.h> |
14 | #include <linux/mtd/partitions.h> | 14 | #include <linux/mtd/partitions.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/gpio.h> | ||
16 | 17 | ||
17 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
18 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
@@ -28,35 +29,92 @@ | |||
28 | 29 | ||
29 | #include <linux/serial_core.h> | 30 | #include <linux/serial_core.h> |
30 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/input.h> | ||
33 | #include <linux/gpio_keys.h> | ||
34 | #include <linux/leds.h> | ||
35 | #include <linux/i2c-gpio.h> | ||
31 | 36 | ||
32 | #include "generic.h" | 37 | #include "generic.h" |
33 | 38 | ||
34 | long cs3_shadow; | 39 | /* |
40 | * CS3 support | ||
41 | */ | ||
35 | 42 | ||
36 | long get_cs3_shadow(void) | 43 | static long cs3_shadow; |
44 | static spinlock_t cs3_lock; | ||
45 | static struct gpio_chip cs3_gpio; | ||
46 | |||
47 | long simpad_get_cs3_ro(void) | ||
48 | { | ||
49 | return readl(CS3_BASE); | ||
50 | } | ||
51 | EXPORT_SYMBOL(simpad_get_cs3_ro); | ||
52 | |||
53 | long simpad_get_cs3_shadow(void) | ||
37 | { | 54 | { |
38 | return cs3_shadow; | 55 | return cs3_shadow; |
39 | } | 56 | } |
57 | EXPORT_SYMBOL(simpad_get_cs3_shadow); | ||
40 | 58 | ||
41 | void set_cs3(long value) | 59 | static void __simpad_write_cs3(void) |
42 | { | 60 | { |
43 | *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value; | 61 | writel(cs3_shadow, CS3_BASE); |
44 | } | 62 | } |
45 | 63 | ||
46 | void set_cs3_bit(int value) | 64 | void simpad_set_cs3_bit(int value) |
47 | { | 65 | { |
66 | unsigned long flags; | ||
67 | |||
68 | spin_lock_irqsave(&cs3_lock, flags); | ||
48 | cs3_shadow |= value; | 69 | cs3_shadow |= value; |
49 | *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; | 70 | __simpad_write_cs3(); |
71 | spin_unlock_irqrestore(&cs3_lock, flags); | ||
50 | } | 72 | } |
73 | EXPORT_SYMBOL(simpad_set_cs3_bit); | ||
51 | 74 | ||
52 | void clear_cs3_bit(int value) | 75 | void simpad_clear_cs3_bit(int value) |
53 | { | 76 | { |
77 | unsigned long flags; | ||
78 | |||
79 | spin_lock_irqsave(&cs3_lock, flags); | ||
54 | cs3_shadow &= ~value; | 80 | cs3_shadow &= ~value; |
55 | *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; | 81 | __simpad_write_cs3(); |
82 | spin_unlock_irqrestore(&cs3_lock, flags); | ||
56 | } | 83 | } |
84 | EXPORT_SYMBOL(simpad_clear_cs3_bit); | ||
85 | |||
86 | static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
87 | { | ||
88 | if (offset > 15) | ||
89 | return; | ||
90 | if (value) | ||
91 | simpad_set_cs3_bit(1 << offset); | ||
92 | else | ||
93 | simpad_clear_cs3_bit(1 << offset); | ||
94 | }; | ||
95 | |||
96 | static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
97 | { | ||
98 | if (offset > 15) | ||
99 | return simpad_get_cs3_ro() & (1 << (offset - 16)); | ||
100 | return simpad_get_cs3_shadow() & (1 << offset); | ||
101 | }; | ||
57 | 102 | ||
58 | EXPORT_SYMBOL(set_cs3_bit); | 103 | static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
59 | EXPORT_SYMBOL(clear_cs3_bit); | 104 | { |
105 | if (offset > 15) | ||
106 | return 0; | ||
107 | return -EINVAL; | ||
108 | }; | ||
109 | |||
110 | static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
111 | int value) | ||
112 | { | ||
113 | if (offset > 15) | ||
114 | return -EINVAL; | ||
115 | cs3_gpio_set(chip, offset, value); | ||
116 | return 0; | ||
117 | }; | ||
60 | 118 | ||
61 | static struct map_desc simpad_io_desc[] __initdata = { | 119 | static struct map_desc simpad_io_desc[] __initdata = { |
62 | { /* MQ200 */ | 120 | { /* MQ200 */ |
@@ -64,9 +122,9 @@ static struct map_desc simpad_io_desc[] __initdata = { | |||
64 | .pfn = __phys_to_pfn(0x4b800000), | 122 | .pfn = __phys_to_pfn(0x4b800000), |
65 | .length = 0x00800000, | 123 | .length = 0x00800000, |
66 | .type = MT_DEVICE | 124 | .type = MT_DEVICE |
67 | }, { /* Paules CS3, write only */ | 125 | }, { /* Simpad CS3 */ |
68 | .virtual = 0xf1000000, | 126 | .virtual = CS3_BASE, |
69 | .pfn = __phys_to_pfn(0x18000000), | 127 | .pfn = __phys_to_pfn(SA1100_CS3_PHYS), |
70 | .length = 0x00100000, | 128 | .length = 0x00100000, |
71 | .type = MT_DEVICE | 129 | .type = MT_DEVICE |
72 | }, | 130 | }, |
@@ -78,12 +136,12 @@ static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate) | |||
78 | if (port->mapbase == (u_int)&Ser1UTCR0) { | 136 | if (port->mapbase == (u_int)&Ser1UTCR0) { |
79 | if (state) | 137 | if (state) |
80 | { | 138 | { |
81 | clear_cs3_bit(RS232_ON); | 139 | simpad_clear_cs3_bit(RS232_ON); |
82 | clear_cs3_bit(DECT_POWER_ON); | 140 | simpad_clear_cs3_bit(DECT_POWER_ON); |
83 | }else | 141 | }else |
84 | { | 142 | { |
85 | set_cs3_bit(RS232_ON); | 143 | simpad_set_cs3_bit(RS232_ON); |
86 | set_cs3_bit(DECT_POWER_ON); | 144 | simpad_set_cs3_bit(DECT_POWER_ON); |
87 | } | 145 | } |
88 | } | 146 | } |
89 | } | 147 | } |
@@ -132,6 +190,7 @@ static struct resource simpad_flash_resources [] = { | |||
132 | static struct mcp_plat_data simpad_mcp_data = { | 190 | static struct mcp_plat_data simpad_mcp_data = { |
133 | .mccr0 = MCCR0_ADM, | 191 | .mccr0 = MCCR0_ADM, |
134 | .sclk_rate = 11981000, | 192 | .sclk_rate = 11981000, |
193 | .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, | ||
135 | }; | 194 | }; |
136 | 195 | ||
137 | 196 | ||
@@ -142,9 +201,10 @@ static void __init simpad_map_io(void) | |||
142 | 201 | ||
143 | iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc)); | 202 | iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc)); |
144 | 203 | ||
145 | set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | | 204 | /* Initialize CS3 */ |
146 | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON); | 205 | cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | |
147 | 206 | RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON); | |
207 | __simpad_write_cs3(); /* Spinlocks not yet initialized */ | ||
148 | 208 | ||
149 | sa1100_register_uart_fns(&simpad_port_fns); | 209 | sa1100_register_uart_fns(&simpad_port_fns); |
150 | sa1100_register_uart(0, 3); /* serial interface */ | 210 | sa1100_register_uart(0, 3); /* serial interface */ |
@@ -170,13 +230,14 @@ static void __init simpad_map_io(void) | |||
170 | 230 | ||
171 | static void simpad_power_off(void) | 231 | static void simpad_power_off(void) |
172 | { | 232 | { |
173 | local_irq_disable(); // was cli | 233 | local_irq_disable(); |
174 | set_cs3(0x800); /* only SD_MEDIAQ */ | 234 | cs3_shadow = SD_MEDIAQ; |
235 | __simpad_write_cs3(); /* Bypass spinlock here */ | ||
175 | 236 | ||
176 | /* disable internal oscillator, float CS lines */ | 237 | /* disable internal oscillator, float CS lines */ |
177 | PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); | 238 | PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); |
178 | /* enable wake-up on GPIO0 (Assabet...) */ | 239 | /* enable wake-up on GPIO0 */ |
179 | PWER = GFER = GRER = 1; | 240 | PWER = GFER = GRER = PWER_GPIO0; |
180 | /* | 241 | /* |
181 | * set scratchpad to zero, just in case it is used as a | 242 | * set scratchpad to zero, just in case it is used as a |
182 | * restart address by the bootloader. | 243 | * restart address by the bootloader. |
@@ -192,6 +253,91 @@ static void simpad_power_off(void) | |||
192 | 253 | ||
193 | } | 254 | } |
194 | 255 | ||
256 | /* | ||
257 | * gpio_keys | ||
258 | */ | ||
259 | |||
260 | static struct gpio_keys_button simpad_button_table[] = { | ||
261 | { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" }, | ||
262 | }; | ||
263 | |||
264 | static struct gpio_keys_platform_data simpad_keys_data = { | ||
265 | .buttons = simpad_button_table, | ||
266 | .nbuttons = ARRAY_SIZE(simpad_button_table), | ||
267 | }; | ||
268 | |||
269 | static struct platform_device simpad_keys = { | ||
270 | .name = "gpio-keys", | ||
271 | .dev = { | ||
272 | .platform_data = &simpad_keys_data, | ||
273 | }, | ||
274 | }; | ||
275 | |||
276 | static struct gpio_keys_button simpad_polled_button_table[] = { | ||
277 | { KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" }, | ||
278 | { KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" }, | ||
279 | { KEY_UP, SIMPAD_UCB1X00_GPIO_UP, 1, "up button" }, | ||
280 | { KEY_DOWN, SIMPAD_UCB1X00_GPIO_DOWN, 1, "down button" }, | ||
281 | { KEY_LEFT, SIMPAD_UCB1X00_GPIO_LEFT, 1, "left button" }, | ||
282 | { KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" }, | ||
283 | }; | ||
284 | |||
285 | static struct gpio_keys_platform_data simpad_polled_keys_data = { | ||
286 | .buttons = simpad_polled_button_table, | ||
287 | .nbuttons = ARRAY_SIZE(simpad_polled_button_table), | ||
288 | .poll_interval = 50, | ||
289 | }; | ||
290 | |||
291 | static struct platform_device simpad_polled_keys = { | ||
292 | .name = "gpio-keys-polled", | ||
293 | .dev = { | ||
294 | .platform_data = &simpad_polled_keys_data, | ||
295 | }, | ||
296 | }; | ||
297 | |||
298 | /* | ||
299 | * GPIO LEDs | ||
300 | */ | ||
301 | |||
302 | static struct gpio_led simpad_leds[] = { | ||
303 | { | ||
304 | .name = "simpad:power", | ||
305 | .gpio = SIMPAD_CS3_LED2_ON, | ||
306 | .active_low = 0, | ||
307 | .default_trigger = "default-on", | ||
308 | }, | ||
309 | }; | ||
310 | |||
311 | static struct gpio_led_platform_data simpad_led_data = { | ||
312 | .num_leds = ARRAY_SIZE(simpad_leds), | ||
313 | .leds = simpad_leds, | ||
314 | }; | ||
315 | |||
316 | static struct platform_device simpad_gpio_leds = { | ||
317 | .name = "leds-gpio", | ||
318 | .id = 0, | ||
319 | .dev = { | ||
320 | .platform_data = &simpad_led_data, | ||
321 | }, | ||
322 | }; | ||
323 | |||
324 | /* | ||
325 | * i2c | ||
326 | */ | ||
327 | static struct i2c_gpio_platform_data simpad_i2c_data = { | ||
328 | .sda_pin = GPIO_GPIO21, | ||
329 | .scl_pin = GPIO_GPIO25, | ||
330 | .udelay = 10, | ||
331 | .timeout = HZ, | ||
332 | }; | ||
333 | |||
334 | static struct platform_device simpad_i2c = { | ||
335 | .name = "i2c-gpio", | ||
336 | .id = 0, | ||
337 | .dev = { | ||
338 | .platform_data = &simpad_i2c_data, | ||
339 | }, | ||
340 | }; | ||
195 | 341 | ||
196 | /* | 342 | /* |
197 | * MediaQ Video Device | 343 | * MediaQ Video Device |
@@ -202,7 +348,11 @@ static struct platform_device simpad_mq200fb = { | |||
202 | }; | 348 | }; |
203 | 349 | ||
204 | static struct platform_device *devices[] __initdata = { | 350 | static struct platform_device *devices[] __initdata = { |
205 | &simpad_mq200fb | 351 | &simpad_keys, |
352 | &simpad_polled_keys, | ||
353 | &simpad_mq200fb, | ||
354 | &simpad_gpio_leds, | ||
355 | &simpad_i2c, | ||
206 | }; | 356 | }; |
207 | 357 | ||
208 | 358 | ||
@@ -211,6 +361,19 @@ static int __init simpad_init(void) | |||
211 | { | 361 | { |
212 | int ret; | 362 | int ret; |
213 | 363 | ||
364 | spin_lock_init(&cs3_lock); | ||
365 | |||
366 | cs3_gpio.label = "simpad_cs3"; | ||
367 | cs3_gpio.base = SIMPAD_CS3_GPIO_BASE; | ||
368 | cs3_gpio.ngpio = 24; | ||
369 | cs3_gpio.set = cs3_gpio_set; | ||
370 | cs3_gpio.get = cs3_gpio_get; | ||
371 | cs3_gpio.direction_input = cs3_gpio_direction_input; | ||
372 | cs3_gpio.direction_output = cs3_gpio_direction_output; | ||
373 | ret = gpiochip_add(&cs3_gpio); | ||
374 | if (ret) | ||
375 | printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device"); | ||
376 | |||
214 | pm_power_off = simpad_power_off; | 377 | pm_power_off = simpad_power_off; |
215 | 378 | ||
216 | sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, | 379 | sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, |