1/*
2 * linux/arch/arm/mach-sa1100/simpad.c
3 *
4 */
5
6#include <linux/config.h>
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/tty.h>
11#include <linux/proc_fs.h>
12#include <linux/string.h>
13
14#include <asm/hardware.h>
15#include <asm/setup.h>
16
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <asm/mach/serial_sa1100.h>
20#include <linux/serial_core.h>
21
22#include "generic.h"
23
24long cs3_shadow;
25
26long get_cs3_shadow()
27{
28	return cs3_shadow;
29}
30
31void set_cs3_bit(int value)
32{
33	cs3_shadow |= value;
34	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
35}
36
37void clear_cs3_bit(int value)
38{
39	cs3_shadow &= ~value;
40	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
41}
42
43static void __init
44fixup_simpad(struct machine_desc *desc, struct param_struct *params,
45		   char **cmdline, struct meminfo *mi)
46{
47#ifdef CONFIG_SA1100_SIMPAD_DRAM_64MB     /* DRAM */
48	SET_BANK( 0, 0xc0000000, 64*1024*1024 );
49#else
50	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
51#endif
52	mi->nr_banks = 1;
53	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
54	setup_ramdisk( 1, 0, 0, 8192 );
55	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
56}
57
58
59static struct map_desc simpad_io_desc[] __initdata = {
60  /* virtual	physical    length	domain	   r  w  c  b */
61  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 },
62  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */
63  { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Paules CS3, write only */
64  LAST_DESC
65};
66
67
68static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
69{
70	if (port->mapbase == (u_int)&Ser1UTCR0) {
71		if (state)
72			clear_cs3_bit(RS232_ON);
73		else
74			set_cs3_bit(RS232_ON);
75	}
76}
77
78static struct sa1100_port_fns simpad_port_fns __initdata = {
79	pm:	simpad_uart_pm,
80};
81
82static void __init simpad_map_io(void)
83{
84	sa1100_map_io();
85	iotable_init(simpad_io_desc);
86
87	PSPR = 0xc0008000;
88	GPDR &= ~GPIO_GPIO0;
89	cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
90		      ENABLE_5V | RESET_SIMCARD);
91	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
92
93	//It is only possible to register 3 UART in serial_sa1100.c
94	sa1100_register_uart(0, 3);
95	sa1100_register_uart(1, 1);
96
97	set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE);
98}
99
100#ifdef CONFIG_PROC_FS
101
102static char* name[]={
103  "VCC_5V_EN",
104  "VCC_3V_EN",
105  "EN1",
106  "EN0",
107  "DISPLAY_ON",
108  "PCMCIA_BUFF_DIS",
109  "MQ_RESET",
110  "PCMCIA_RESET",
111  "DECT_POWER_ON",
112  "IRDA_SD",
113  "RS232_ON",
114  "SD_MEDIAQ",
115  "LED2_ON",
116  "IRDA_MODE",
117  "ENABLE_5V",
118  "RESET_SIMCARD"
119};
120
121static int proc_cs3_read(char *page, char **start, off_t off,
122			  int count, int *eof, void *data)
123{
124	char *p = page;
125	int len, i;
126
127	p += sprintf(p, "Chipselect3 : %x\n", cs3_shadow);
128	for (i = 0; i <= 15; i++) {
129		if(cs3_shadow & (1<<i)) {
130			p += sprintf(p, "%s\t: TRUE \n",name[i]);
131		} else
132			p += sprintf(p, "%s\t: FALSE \n",name[i]);
133	}
134	len = (p - page) - off;
135	if (len < 0)
136		len = 0;
137
138	*eof = (len <= count) ? 1 : 0;
139	*start = page + off;
140
141	return len;
142}
143
144
145static struct proc_dir_entry *proc_cs3;
146
147static int __init cs3_init(void)
148{
149	proc_cs3 = create_proc_entry("cs3", 0, 0);
150	if (proc_cs3)
151		proc_cs3->read_proc = proc_cs3_read;
152	return 0;
153}
154
155static int __exit cs3_exit(void)
156{
157	if (proc_cs3)
158		remove_proc_entry( "cs3", 0);
159	return 0;
160}
161__initcall(cs3_init);
162
163#endif // CONFIG_PROC_FS
164
165MACHINE_START(SIMPAD, "Simpad")
166	MAINTAINER("Juergen Messerer")
167	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
168	FIXUP(fixup_simpad)
169	MAPIO(simpad_map_io)
170	INITIRQ(sa1100_init_irq)
171MACHINE_END
172