aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-sa1100
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-sa1100')
-rw-r--r--arch/arm/mach-sa1100/Makefile3
-rw-r--r--arch/arm/mach-sa1100/Makefile.boot5
-rw-r--r--arch/arm/mach-sa1100/assabet.c3
-rw-r--r--arch/arm/mach-sa1100/generic.c2
-rw-r--r--arch/arm/mach-sa1100/gpio.c65
-rw-r--r--arch/arm/mach-sa1100/include/mach/gpio.h4
-rw-r--r--arch/arm/mach-sa1100/include/mach/io.h6
-rw-r--r--arch/arm/mach-sa1100/include/mach/simpad.h94
-rw-r--r--arch/arm/mach-sa1100/leds-simpad.c100
-rw-r--r--arch/arm/mach-sa1100/leds.c2
-rw-r--r--arch/arm/mach-sa1100/leds.h1
-rw-r--r--arch/arm/mach-sa1100/simpad.c213
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
6obj-y := clock.o generic.o gpio.o irq.o dma.o time.o #nmi-oopser.o 6obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
7obj-m := 7obj-m :=
8obj-n := 8obj-n :=
9obj- := 9obj- :=
@@ -45,7 +45,6 @@ obj-$(CONFIG_SA1100_PLEB) += pleb.o
45obj-$(CONFIG_SA1100_SHANNON) += shannon.o 45obj-$(CONFIG_SA1100_SHANNON) += shannon.o
46 46
47obj-$(CONFIG_SA1100_SIMPAD) += simpad.o 47obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
48led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
49 48
50# LEDs support 49# LEDs support
51obj-$(CONFIG_LEDS) += $(led-y) 50obj-$(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
2ifeq ($(CONFIG_ARCH_SA1100),y) 1ifeq ($(CONFIG_ARCH_SA1100),y)
3 zreladdr-$(CONFIG_SA1111) := 0xc0208000 2 zreladdr-$(CONFIG_SA1111) += 0xc0208000
3else
4 zreladdr-y += 0xc0008000
4endif 5endif
5params_phys-y := 0xc0000100 6params_phys-y := 0xc0000100
6initrd_phys-y := 0xc0800000 7initrd_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
303static void __init 303static void __init
304fixup_assabet(struct machine_desc *desc, struct tag *tags, 304fixup_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
18static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
19{
20 return GPLR & GPIO_GPIO(offset);
21}
22
23static 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
31static 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
41static 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
52static 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
62void __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
31static inline int gpio_get_value(unsigned gpio) 33static 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 94long simpad_get_cs3_ro(void);
57#define VCC_3V_EN 0x0002 // FOR 3.3V PCMCIA 95long simpad_get_cs3_shadow(void);
58#define EN1 0x0004 // This is only for EPROM's 96void simpad_set_cs3_bit(int value);
59#define EN0 0x0008 // Both should be enable for 3.3V or 5V 97void 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 ---*/
77struct simpad_battery { 125struct 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
19static unsigned int led_state;
20static unsigned int hw_led_state;
21
22#define LED_GREEN (1)
23#define LED_MASK (1)
24
25extern void set_cs3_bit(int value);
26extern void clear_cs3_bit(int value);
27
28void 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);
11extern void graphicsmaster_leds_event(led_event_t evt); 11extern void graphicsmaster_leds_event(led_event_t evt);
12extern void adsbitsy_leds_event(led_event_t evt); 12extern void adsbitsy_leds_event(led_event_t evt);
13extern void system3_leds_event(led_event_t evt); 13extern void system3_leds_event(led_event_t evt);
14extern 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
34long cs3_shadow; 39/*
40 * CS3 support
41 */
35 42
36long get_cs3_shadow(void) 43static long cs3_shadow;
44static spinlock_t cs3_lock;
45static struct gpio_chip cs3_gpio;
46
47long simpad_get_cs3_ro(void)
48{
49 return readl(CS3_BASE);
50}
51EXPORT_SYMBOL(simpad_get_cs3_ro);
52
53long simpad_get_cs3_shadow(void)
37{ 54{
38 return cs3_shadow; 55 return cs3_shadow;
39} 56}
57EXPORT_SYMBOL(simpad_get_cs3_shadow);
40 58
41void set_cs3(long value) 59static void __simpad_write_cs3(void)
42{ 60{
43 *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value; 61 writel(cs3_shadow, CS3_BASE);
44} 62}
45 63
46void set_cs3_bit(int value) 64void 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}
73EXPORT_SYMBOL(simpad_set_cs3_bit);
51 74
52void clear_cs3_bit(int value) 75void 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}
84EXPORT_SYMBOL(simpad_clear_cs3_bit);
85
86static 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
96static 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
58EXPORT_SYMBOL(set_cs3_bit); 103static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
59EXPORT_SYMBOL(clear_cs3_bit); 104{
105 if (offset > 15)
106 return 0;
107 return -EINVAL;
108};
109
110static 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
61static struct map_desc simpad_io_desc[] __initdata = { 119static 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 [] = {
132static struct mcp_plat_data simpad_mcp_data = { 190static 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
171static void simpad_power_off(void) 231static 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
260static struct gpio_keys_button simpad_button_table[] = {
261 { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
262};
263
264static struct gpio_keys_platform_data simpad_keys_data = {
265 .buttons = simpad_button_table,
266 .nbuttons = ARRAY_SIZE(simpad_button_table),
267};
268
269static struct platform_device simpad_keys = {
270 .name = "gpio-keys",
271 .dev = {
272 .platform_data = &simpad_keys_data,
273 },
274};
275
276static 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
285static 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
291static 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
302static 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
311static struct gpio_led_platform_data simpad_led_data = {
312 .num_leds = ARRAY_SIZE(simpad_leds),
313 .leds = simpad_leds,
314};
315
316static 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 */
327static 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
334static 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
204static struct platform_device *devices[] __initdata = { 350static 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,