1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/init.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h>
18#include <linux/ptrace.h>
19#include <linux/delay.h>
20#include <linux/serial_core.h>
21
22#include <asm/hardware.h>
23#include <asm/hardware/sa1111.h>
24#include <asm/setup.h>
25#include <asm/irq.h>
26
27#include <asm/mach/irq.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/mach/serial_sa1100.h>
31
32#include <asm/arch/irq.h>
33
34#include "generic.h"
35#include "sa1111.h"
36
37
38
39
40
41
42
43static int adsbitsyplus_connector_board_rev_number = 0xA;
44
45static int __init adsbitsyplus_connector_board_rev_setup(char *str)
46{
47 adsbitsyplus_connector_board_rev_number = simple_strtol(str,NULL,0);
48 return 1;
49}
50
51int adsbitsyplus_connector_board_rev(void)
52{
53 static int only_once = 1;
54 if (only_once) {
55 printk(KERN_INFO "Bitsy Connector Board REV: %#x\n", adsbitsyplus_connector_board_rev_number);
56 only_once = 0;
57 }
58 return adsbitsyplus_connector_board_rev_number;
59}
60
61static int __init adsbitsyplus_init(void)
62{
63 int ret;
64
65 if (!machine_is_adsbitsyplus())
66 return -ENODEV;
67
68
69
70
71
72 sa1110_mb_disable();
73
74
75
76
77
78
79 PPAR &= ~PPAR_SSPGPIO;
80 ADS_CPLD_SUPPC |= ADS_SUPPC_AVR_WKP;
81 mdelay(100);
82 ADS_CPLD_SUPPC &= ~ADS_SUPPC_AVR_WKP;
83
84
85
86
87 GPCR |= GPIO_GPIO26;
88 udelay(1000);
89 GPSR |= GPIO_GPIO26;
90
91#ifndef CONFIG_LEDS_TIMER
92
93 PGSR |= GPIO_GPIO15 | GPIO_GPIO20;
94#else
95
96
97 PGSR |= GPIO_GPIO15;
98#endif
99
100
101 PGSR |= GPIO_GPIO19;
102
103
104
105
106 ret = sa1111_probe(ADSBITSYPLUS_SA1111_BASE);
107 if (ret < 0)
108 return ret;
109
110
111
112
113 sa1111_wake();
114
115
116
117
118
119
120
121
122 sa1111_configure_smc(1,
123 FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
124 FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
125
126
127
128
129
130 SKPCR |= SKPCR_DCLKEN;
131
132
133
134
135 sa1110_mb_enable();
136
137 set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
138 sa1111_init_irq(IRQ_GPIO0);
139
140 return 0;
141}
142
143__initcall(adsbitsyplus_init);
144
145static void __init adsbitsyplus_init_irq(void)
146{
147
148 sa1100_init_irq();
149}
150
151
152
153
154void adsbitsyplus_sa1111_wake(unsigned long pa_dwr)
155{
156
157 GPCR |= GPIO_GPIO26;
158 mdelay(1);
159 GPSR |= GPIO_GPIO26;
160
161 GAFR |= GPIO_32_768kHz;
162 GPDR |= GPIO_32_768kHz;
163 TUCR = TUCR_3_6864MHz;
164
165 SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
166 udelay(100);
167 SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
168
169 GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
170 GPDR |= GPIO_MBGNT;
171 GPDR &= ~GPIO_MBREQ;
172 TUCR |= TUCR_MR;
173
174 sa1111_configure_smc(1,
175 FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
176 FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
177 SKPCR |= SKPCR_DCLKEN;
178
179
180 PCCR = 0xFF;
181 mdelay(100);
182 PA_DDR = 0x00;
183
184
185 PA_DWR = pa_dwr;
186 PCCR = ~(PCCR_S0_RST | PCCR_S1_RST);
187
188#ifdef CONFIG_USB_OHCI_SA1111
189
190 SKPCR |= SKPCR_UCLKEN;
191 udelay(100);
192
193
194 USB_RESET = 0x01;
195 USB_RESET |= 0x02;
196 udelay(100);
197
198
199 USB_RESET = 0;
200 USB_RESET = USB_RESET_PWRSENSELOW;
201 USB_STATUS = 0;
202 udelay(10);
203#endif
204}
205
206
207static struct map_desc adsbitsyplus_io_desc[] __initdata = {
208
209 { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 },
210 { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 },
211 { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 },
212 { 0xf1000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
213 LAST_DESC
214};
215
216
217
218
219
220static int uart_wake_count[3] = {1, 1, 1};
221
222enum {UART_SHUTDOWN, UART_WAKEUP};
223
224static void update_uart_counts(int line, int state)
225{
226 switch (state) {
227 case UART_WAKEUP:
228 uart_wake_count[line]++;
229 break;
230 case UART_SHUTDOWN:
231 uart_wake_count[line]--;
232 break;
233 }
234}
235
236static int adsbitsyplus_uart_open(struct uart_port *port, struct uart_info *info)
237{
238 if (port->mapbase == _Ser1UTCR0) {
239 Ser1SDCR0 |= SDCR0_UART;
240 } else if (port->mapbase == _Ser2UTCR0) {
241 Ser2UTCR4 = Ser2HSCR0 = 0;
242 }
243 return 0;
244}
245
246void adsbitsyplus_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
247{
248
249
250
251 if (port->mapbase == _Ser1UTCR0) {
252 if (state) {
253 update_uart_counts(1, UART_SHUTDOWN);
254
255 Ser1UTCR3 = 0;
256 }
257 else {
258 update_uart_counts(1, UART_WAKEUP);
259 }
260 }
261 else if (port->mapbase == _Ser2UTCR0) {
262 if (state) {
263 update_uart_counts(2, UART_SHUTDOWN);
264
265 Ser2UTCR3 = 0;
266 Ser2HSCR0 = 0;
267 }
268 else {
269 update_uart_counts(2, UART_WAKEUP);
270 }
271 }
272 else if (port->mapbase == _Ser3UTCR0) {
273 if (state) {
274 update_uart_counts(0, UART_SHUTDOWN);
275
276 Ser3UTCR3 = 0;
277 }
278 else {
279 update_uart_counts(0, UART_WAKEUP);
280 }
281 }
282 if (state == 0) {
283
284 if (uart_wake_count[0] + uart_wake_count[1] != 0) {
285
286 ADS_CPLD_PCON |= ADS_PCON_COM1_3_ON;
287 }
288 if (uart_wake_count[2] != 0) {
289 if (adsbitsyplus_connector_board_rev() >= 0x0a)
290 ADS_CPLD_PCON |= ADS_PCON_CONN_B_PE2;
291 }
292 }
293 else {
294
295 if (uart_wake_count[0] + uart_wake_count[1] == 0) {
296
297 ADS_CPLD_PCON &= ~ADS_PCON_COM1_3_ON;
298 GAFR &= ~(GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20);
299 GPDR |= GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20;
300 }
301 if (uart_wake_count[2] == 0) {
302 if (adsbitsyplus_connector_board_rev() >= 0x0a)
303 ADS_CPLD_PCON &= ~ADS_PCON_CONN_B_PE2;
304 }
305 }
306}
307
308static void adsbitsyplus_set_mctrl(struct uart_port *port, u_int mctrl)
309{
310
311 if (port->mapbase == _Ser1UTCR0) {
312 if (mctrl & TIOCM_RTS)
313
314 GPCR = GPIO_GPIO15;
315 else
316
317 GPSR = GPIO_GPIO15;
318 if (mctrl & TIOCM_DTR)
319
320 GPCR = GPIO_GPIO20;
321 else
322
323 GPSR = GPIO_GPIO20;
324 } else if (port->mapbase == _Ser3UTCR0) {
325 if (mctrl & TIOCM_RTS)
326
327 GPCR = GPIO_GPIO19;
328 else
329
330 GPSR = GPIO_GPIO19;
331 }
332}
333
334static u_int adsbitsyplus_get_mctrl(struct uart_port *port)
335{
336 u_int ret = 0;
337
338
339 if (port->mapbase == _Ser1UTCR0) {
340 if (!(GPLR & GPIO_GPIO14))
341 ret |= TIOCM_CTS;
342 if (!(GPLR & GPIO_GPIO24))
343 ret |= TIOCM_DSR;
344 if (!(GPLR & GPIO_GPIO16))
345 ret |= TIOCM_RI;
346 if (!(GPLR & GPIO_GPIO17))
347 ret |= TIOCM_CD;
348 } else if (port->mapbase == _Ser3UTCR0) {
349 if (!(GPLR & GPIO_GPIO18))
350 ret |= TIOCM_CTS;
351 }
352
353 return ret;
354}
355
356static struct sa1100_port_fns adsbitsyplus_port_fns __initdata = {
357 .set_mctrl = adsbitsyplus_set_mctrl,
358 .get_mctrl = adsbitsyplus_get_mctrl,
359 .open = adsbitsyplus_uart_open,
360 .pm = adsbitsyplus_uart_pm,
361};
362
363static void __init adsbitsyplus_map_io(void)
364{
365 sa1100_map_io();
366 iotable_init(adsbitsyplus_io_desc);
367
368 sa1100_register_uart_fns(&adsbitsyplus_port_fns);
369 sa1100_register_uart(0, 3);
370 sa1100_register_uart(1, 1);
371
372
373#ifndef CONFIG_SA1100_FIR
374 sa1100_register_uart(2, 2);
375#endif
376
377
378 GPDR |= GPIO_GPIO15 | GPIO_GPIO20;
379
380 GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17);
381
382
383 GPDR |= GPIO_GPIO19;
384
385 GPDR &= ~GPIO_GPIO18;
386}
387
388__setup("adsbitsyplus_conn_board_rev=", adsbitsyplus_connector_board_rev_setup);
389
390MACHINE_START(ADSBITSYPLUS, "ADS Bitsy Plus")
391 BOOT_PARAMS(0xc000003c)
392 BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
393 MAPIO(adsbitsyplus_map_io)
394 INITIRQ(adsbitsyplus_init_irq)
395MACHINE_END
396