http://downloads.netgear.com/files/GPL/GPL_Source_V361j_DM111PSP_series_consumer_rele...
[bcm963xx.git] / kernel / linux / arch / arm / mach-sa1100 / simpad.c
1 /*
2  * linux/arch/arm/mach-sa1100/simpad.c
3  */
4
5 #include <linux/config.h>
6 #include <linux/module.h>
7 #include <linux/init.h>
8 #include <linux/kernel.h>
9 #include <linux/tty.h>
10 #include <linux/proc_fs.h>
11 #include <linux/string.h> 
12 #include <linux/pm.h>
13
14 #include <asm/irq.h>
15 #include <asm/hardware.h>
16 #include <asm/setup.h>
17
18 #include <asm/mach-types.h>
19 #include <asm/mach/arch.h>
20 #include <asm/mach/map.h>
21 #include <asm/mach/serial_sa1100.h>
22 #include <asm/arch/simpad.h>
23 #include <asm/arch/registry.h>
24
25 #include <linux/serial_core.h>
26 #include <linux/ioport.h>
27 #include <asm/io.h>
28
29 #include "generic.h"
30
31 long cs3_shadow;
32
33 long get_cs3_shadow(void)
34 {
35         return cs3_shadow;
36 }
37
38 void set_cs3(long value)
39 {
40         *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
41 }
42
43 void set_cs3_bit(int value)
44 {
45         cs3_shadow |= value;
46         *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
47 }
48
49 void clear_cs3_bit(int value)
50 {
51         cs3_shadow &= ~value;
52         *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
53 }
54
55 EXPORT_SYMBOL(set_cs3_bit);
56 EXPORT_SYMBOL(clear_cs3_bit);
57
58 static struct map_desc simpad_io_desc[] __initdata = {
59         /* virtual      physical    length      type */
60         /* MQ200 */
61         { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE },
62         /* Paules CS3, write only */
63         { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE },
64 };
65
66
67 static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
68 {
69         if (port->mapbase == (u_int)&Ser1UTCR0) {
70                 if (state)
71                 {
72                         clear_cs3_bit(RS232_ON);
73                         clear_cs3_bit(DECT_POWER_ON);
74                 }else
75                 {
76                         set_cs3_bit(RS232_ON);
77                         set_cs3_bit(DECT_POWER_ON);
78                 }
79         }
80 }
81
82 static struct sa1100_port_fns simpad_port_fns __initdata = {
83         .pm        = simpad_uart_pm,
84 };
85
86 static void __init simpad_map_io(void)
87 {
88         sa1100_map_io();
89
90         iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
91
92         set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
93                       ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
94
95
96         sa1100_register_uart_fns(&simpad_port_fns);
97         sa1100_register_uart(0, 3);  /* serial interface */
98         sa1100_register_uart(1, 1);  /* DECT             */
99
100         // Reassign UART 1 pins
101         GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
102         GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
103         GPDR &= ~GPIO_UART_RXD;
104         PPAR |= PPAR_UPR;
105
106         /*
107          * Set up registers for sleep mode.
108          */
109
110
111         PWER = PWER_GPIO0| PWER_RTC;
112         PGSR = 0x818;
113         PCFR = 0;
114         PSDR = 0;
115
116
117 }
118
119 #ifdef CONFIG_PROC_FS
120
121 static char* name[]={
122   "VCC_5V_EN",
123   "VCC_3V_EN",
124   "EN1",
125   "EN0",
126   "DISPLAY_ON",
127   "PCMCIA_BUFF_DIS",
128   "MQ_RESET",
129   "PCMCIA_RESET",
130   "DECT_POWER_ON",
131   "IRDA_SD",
132   "RS232_ON",
133   "SD_MEDIAQ",
134   "LED2_ON",
135   "IRDA_MODE",
136   "ENABLE_5V",
137   "RESET_SIMCARD"
138 };
139
140 static int proc_cs3_read(char *page, char **start, off_t off,
141                           int count, int *eof, void *data)
142 {
143         char *p = page;
144         int len, i;
145         
146         p += sprintf(p, "Chipselect3 : %x\n", (uint)cs3_shadow);
147         for (i = 0; i <= 15; i++) {
148                 if(cs3_shadow & (1<<i)) {
149                         p += sprintf(p, "%s\t: TRUE \n",name[i]);
150                 } else
151                         p += sprintf(p, "%s\t: FALSE \n",name[i]);
152         }
153         len = (p - page) - off;
154         if (len < 0)
155                 len = 0;
156  
157         *eof = (len <= count) ? 1 : 0;
158         *start = page + off;
159  
160         return len;
161 }
162
163 static int proc_cs3_write(struct file * file, const char * buffer,
164                           size_t count, loff_t *ppos)
165 {
166         unsigned long newRegValue;
167         char *endp;
168
169         newRegValue = simple_strtoul(buffer,&endp,0);
170         set_cs3( newRegValue );
171         return (count+endp-buffer);
172 }
173
174 #endif
175  
176 static int __init cs3_init(void)
177 {
178
179 #ifdef CONFIG_PROC_FS
180         struct proc_dir_entry *proc_cs3 = create_proc_entry("CS3", 0, 0);
181         if (proc_cs3)
182         {
183                 proc_cs3->read_proc = proc_cs3_read;
184                 proc_cs3->write_proc = (void*)proc_cs3_write;
185         }
186 #endif
187
188
189
190         return 0;
191 }
192  
193 arch_initcall(cs3_init);
194
195 static void simpad_power_off(void)
196 {
197         local_irq_disable(); // was cli
198         set_cs3(0x800);        /* only SD_MEDIAQ */
199
200         /* disable internal oscillator, float CS lines */
201         PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
202         /* enable wake-up on GPIO0 (Assabet...) */
203         PWER = GFER = GRER = 1;
204         /*
205          * set scratchpad to zero, just in case it is used as a
206          * restart address by the bootloader.
207          */
208         PSPR = 0;
209         PGSR = 0;
210         /* enter sleep mode */
211         PMCR = PMCR_SF;
212         while(1);
213
214         local_irq_enable(); /* we won't ever call it */
215
216
217 }
218
219 static int __init simpad_init(void)
220 {
221         set_power_off_handler( simpad_power_off );
222         return 0;
223 }
224
225 arch_initcall(simpad_init);
226
227
228 MACHINE_START(SIMPAD, "Simpad")
229         MAINTAINER("Juergen Messerer")
230         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
231         BOOT_PARAMS(0xc0000100)
232         MAPIO(simpad_map_io)
233         INITIRQ(sa1100_init_irq)
234         INITTIME(sa1100_init_time)
235 MACHINE_END