aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
authorMarc Zyngier <maz@misterjones.org>2009-11-14 07:47:03 -0500
committerEric Miao <eric.y.miao@gmail.com>2009-12-13 08:42:58 -0500
commite491a11c77a4ed93ec14cc052b1f048bddc9e99a (patch)
tree463e4d3dcd3a7bd26a3be10882427f019fad551b /arch/arm/mach-pxa
parent1b82e4c32fba96d8805b1e2126ba5382e56fac32 (diff)
[ARM] pxa/zeus: basic support for Arcom Zeus SBC
Signed-off-by: Marc Zyngier <maz@misterjones.org> Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Kconfig7
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/include/mach/zeus.h82
-rw-r--r--arch/arm/mach-pxa/zeus.c791
4 files changed, 881 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index d89c6adbe8bc..fc553e896b1b 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -64,6 +64,13 @@ config ARCH_VIPER
64 select PXA_HAVE_BOARD_IRQS 64 select PXA_HAVE_BOARD_IRQS
65 select PXA_HAVE_ISA_IRQS 65 select PXA_HAVE_ISA_IRQS
66 66
67config MACH_ARCOM_ZEUS
68 bool "Arcom/Eurotech ZEUS SBC"
69 select PXA27x
70 select ISA
71 select PXA_HAVE_BOARD_IRQS
72 select PXA_HAVE_ISA_IRQS
73
67config MACH_BALLOON3 74config MACH_BALLOON3
68 bool "Balloon 3 board" 75 bool "Balloon 3 board"
69 select PXA27x 76 select PXA27x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index b5d29e60a341..f64afda7e6f6 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_MACH_SAAR) += saar.o
38# 3rd Party Dev Platforms 38# 3rd Party Dev Platforms
39obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 39obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
40obj-$(CONFIG_ARCH_VIPER) += viper.o 40obj-$(CONFIG_ARCH_VIPER) += viper.o
41obj-$(CONFIG_MACH_ARCOM_ZEUS) += zeus.o
41obj-$(CONFIG_MACH_BALLOON3) += balloon3.o 42obj-$(CONFIG_MACH_BALLOON3) += balloon3.o
42obj-$(CONFIG_MACH_CSB726) += csb726.o 43obj-$(CONFIG_MACH_CSB726) += csb726.o
43obj-$(CONFIG_CSB726_CSB701) += csb701.o 44obj-$(CONFIG_CSB726_CSB701) += csb701.o
diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h
new file mode 100644
index 000000000000..c387046d2f28
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/zeus.h
@@ -0,0 +1,82 @@
1/*
2 * arch/arm/mach-pxa/include/mach/zeus.h
3 *
4 * Author: David Vrabel
5 * Created: Sept 28, 2005
6 * Copyright: Arcom Control Systems Ltd.
7 *
8 * Maintained by: Marc Zyngier <maz@misterjones.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _MACH_ZEUS_H
16#define _MACH_ZEUS_H
17
18/* Physical addresses */
19#define ZEUS_FLASH_PHYS PXA_CS0_PHYS
20#define ZEUS_ETH0_PHYS PXA_CS1_PHYS
21#define ZEUS_ETH1_PHYS PXA_CS2_PHYS
22#define ZEUS_CPLD_PHYS (PXA_CS4_PHYS+0x2000000)
23#define ZEUS_SRAM_PHYS PXA_CS5_PHYS
24#define ZEUS_PC104IO_PHYS (0x30000000)
25
26#define ZEUS_CPLD_VERSION_PHYS (ZEUS_CPLD_PHYS + 0x00000000)
27#define ZEUS_CPLD_ISA_IRQ_PHYS (ZEUS_CPLD_PHYS + 0x00800000)
28#define ZEUS_CPLD_CONTROL_PHYS (ZEUS_CPLD_PHYS + 0x01000000)
29#define ZEUS_CPLD_EXTWDOG_PHYS (ZEUS_CPLD_PHYS + 0x01800000)
30
31/* GPIOs */
32#define ZEUS_AC97_GPIO 0
33#define ZEUS_WAKEUP_GPIO 1
34#define ZEUS_UARTA_GPIO 9
35#define ZEUS_UARTB_GPIO 10
36#define ZEUS_UARTC_GPIO 12
37#define ZEUS_UARTD_GPIO 11
38#define ZEUS_ETH0_GPIO 14
39#define ZEUS_ISA_GPIO 17
40#define ZEUS_BKLEN_GPIO 19
41#define ZEUS_USB2_PWREN_GPIO 22
42#define ZEUS_PTT_GPIO 27
43#define ZEUS_CF_CD_GPIO 35
44#define ZEUS_MMC_WP_GPIO 52
45#define ZEUS_MMC_CD_GPIO 53
46#define ZEUS_EXTGPIO_GPIO 91
47#define ZEUS_CF_PWEN_GPIO 97
48#define ZEUS_CF_RDY_GPIO 99
49#define ZEUS_LCD_EN_GPIO 101
50#define ZEUS_ETH1_GPIO 113
51#define ZEUS_CAN_GPIO 116
52
53#define ZEUS_EXT0_GPIO_BASE 128
54#define ZEUS_EXT1_GPIO_BASE 160
55#define ZEUS_USER_GPIO_BASE 192
56
57#define ZEUS_EXT0_GPIO(x) (ZEUS_EXT0_GPIO_BASE + (x))
58#define ZEUS_EXT1_GPIO(x) (ZEUS_EXT1_GPIO_BASE + (x))
59#define ZEUS_USER_GPIO(x) (ZEUS_USER_GPIO_BASE + (x))
60
61/*
62 * CPLD registers:
63 * Only 4 registers, but spreaded over a 32MB address space.
64 * Be gentle, and remap that over 32kB...
65 */
66
67#define ZEUS_CPLD (0xf0000000)
68#define ZEUS_CPLD_VERSION (ZEUS_CPLD + 0x0000)
69#define ZEUS_CPLD_ISA_IRQ (ZEUS_CPLD + 0x1000)
70#define ZEUS_CPLD_CONTROL (ZEUS_CPLD + 0x2000)
71#define ZEUS_CPLD_EXTWDOG (ZEUS_CPLD + 0x3000)
72
73/* CPLD register bits */
74#define ZEUS_CPLD_CONTROL_CF_RST 0x01
75
76#define ZEUS_PC104IO (0xf1000000)
77
78#define ZEUS_SRAM_SIZE (256 * 1024)
79
80#endif
81
82
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
new file mode 100644
index 000000000000..ae1c3d2f6d5b
--- /dev/null
+++ b/arch/arm/mach-pxa/zeus.c
@@ -0,0 +1,791 @@
1/*
2 * Support for the Arcom ZEUS.
3 *
4 * Copyright (C) 2006 Arcom Control Systems Ltd.
5 *
6 * Loosely based on Arcom's 2.6.16.28.
7 * Maintained by Marc Zyngier <maz@misterjones.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/cpufreq.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/pm.h>
18#include <linux/gpio.h>
19#include <linux/serial_8250.h>
20#include <linux/dm9000.h>
21#include <linux/mmc/host.h>
22#include <linux/spi/spi.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/mtd/physmap.h>
26#include <linux/i2c.h>
27#include <linux/i2c/pca953x.h>
28
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/map.h>
32
33#include <plat/i2c.h>
34
35#include <mach/pxa2xx-regs.h>
36#include <mach/regs-uart.h>
37#include <mach/ohci.h>
38#include <mach/mmc.h>
39#include <mach/pxa27x-udc.h>
40#include <mach/udc.h>
41#include <mach/pxafb.h>
42#include <mach/pxa2xx_spi.h>
43#include <mach/mfp-pxa27x.h>
44#include <mach/pm.h>
45#include <mach/audio.h>
46#include <mach/zeus.h>
47
48#include "generic.h"
49
50/*
51 * Interrupt handling
52 */
53
54static unsigned long zeus_irq_enabled_mask;
55static const int zeus_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, };
56static const int zeus_isa_irq_map[] = {
57 0, /* ISA irq #0, invalid */
58 0, /* ISA irq #1, invalid */
59 0, /* ISA irq #2, invalid */
60 1 << 0, /* ISA irq #3 */
61 1 << 1, /* ISA irq #4 */
62 1 << 2, /* ISA irq #5 */
63 1 << 3, /* ISA irq #6 */
64 1 << 4, /* ISA irq #7 */
65 0, /* ISA irq #8, invalid */
66 0, /* ISA irq #9, invalid */
67 1 << 5, /* ISA irq #10 */
68 1 << 6, /* ISA irq #11 */
69 1 << 7, /* ISA irq #12 */
70};
71
72static inline int zeus_irq_to_bitmask(unsigned int irq)
73{
74 return zeus_isa_irq_map[irq - PXA_ISA_IRQ(0)];
75}
76
77static inline int zeus_bit_to_irq(int bit)
78{
79 return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0);
80}
81
82static void zeus_ack_irq(unsigned int irq)
83{
84 __raw_writew(zeus_irq_to_bitmask(irq), ZEUS_CPLD_ISA_IRQ);
85}
86
87static void zeus_mask_irq(unsigned int irq)
88{
89 zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(irq));
90}
91
92static void zeus_unmask_irq(unsigned int irq)
93{
94 zeus_irq_enabled_mask |= zeus_irq_to_bitmask(irq);
95}
96
97static inline unsigned long zeus_irq_pending(void)
98{
99 return __raw_readw(ZEUS_CPLD_ISA_IRQ) & zeus_irq_enabled_mask;
100}
101
102static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc)
103{
104 unsigned long pending;
105
106 pending = zeus_irq_pending();
107 do {
108 /* we're in a chained irq handler,
109 * so ack the interrupt by hand */
110 desc->chip->ack(gpio_to_irq(ZEUS_ISA_GPIO));
111
112 if (likely(pending)) {
113 irq = zeus_bit_to_irq(__ffs(pending));
114 generic_handle_irq(irq);
115 }
116 pending = zeus_irq_pending();
117 } while (pending);
118}
119
120static struct irq_chip zeus_irq_chip = {
121 .name = "ISA",
122 .ack = zeus_ack_irq,
123 .mask = zeus_mask_irq,
124 .unmask = zeus_unmask_irq,
125};
126
127static void __init zeus_init_irq(void)
128{
129 int level;
130 int isa_irq;
131
132 pxa27x_init_irq();
133
134 /* Peripheral IRQs. It would be nice to move those inside driver
135 configuration, but it is not supported at the moment. */
136 set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING);
137 set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING);
138 set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING);
139 set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), IRQ_TYPE_EDGE_FALLING);
140 set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING);
141
142 /* Setup ISA IRQs */
143 for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) {
144 isa_irq = zeus_bit_to_irq(level);
145 set_irq_chip(isa_irq, &zeus_irq_chip);
146 set_irq_handler(isa_irq, handle_edge_irq);
147 set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
148 }
149
150 set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING);
151 set_irq_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler);
152}
153
154
155/*
156 * Platform devices
157 */
158
159/* Flash */
160static struct resource zeus_mtd_resources[] = {
161 [0] = { /* NOR Flash (up to 64MB) */
162 .start = ZEUS_FLASH_PHYS,
163 .end = ZEUS_FLASH_PHYS + SZ_64M - 1,
164 .flags = IORESOURCE_MEM,
165 },
166 [1] = { /* SRAM */
167 .start = ZEUS_SRAM_PHYS,
168 .end = ZEUS_SRAM_PHYS + SZ_512K - 1,
169 .flags = IORESOURCE_MEM,
170 },
171};
172
173static struct physmap_flash_data zeus_flash_data[] = {
174 [0] = {
175 .width = 2,
176 .parts = NULL,
177 .nr_parts = 0,
178 },
179};
180
181static struct platform_device zeus_mtd_devices[] = {
182 [0] = {
183 .name = "physmap-flash",
184 .id = 0,
185 .dev = {
186 .platform_data = &zeus_flash_data[0],
187 },
188 .resource = &zeus_mtd_resources[0],
189 .num_resources = 1,
190 },
191};
192
193/* Serial */
194static struct resource zeus_serial_resources[] = {
195 {
196 .start = 0x10000000,
197 .end = 0x1000000f,
198 .flags = IORESOURCE_MEM,
199 },
200 {
201 .start = 0x10800000,
202 .end = 0x1080000f,
203 .flags = IORESOURCE_MEM,
204 },
205 {
206 .start = 0x11000000,
207 .end = 0x1100000f,
208 .flags = IORESOURCE_MEM,
209 },
210 {
211 .start = 0x40100000,
212 .end = 0x4010001f,
213 .flags = IORESOURCE_MEM,
214 },
215 {
216 .start = 0x40200000,
217 .end = 0x4020001f,
218 .flags = IORESOURCE_MEM,
219 },
220 {
221 .start = 0x40700000,
222 .end = 0x4070001f,
223 .flags = IORESOURCE_MEM,
224 },
225};
226
227static struct plat_serial8250_port serial_platform_data[] = {
228 /* External UARTs */
229 /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */
230 { /* COM1 */
231 .mapbase = 0x10000000,
232 .irq = gpio_to_irq(ZEUS_UARTA_GPIO),
233 .irqflags = IRQF_TRIGGER_RISING,
234 .uartclk = 14745600,
235 .regshift = 1,
236 .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
237 .iotype = UPIO_MEM,
238 },
239 { /* COM2 */
240 .mapbase = 0x10800000,
241 .irq = gpio_to_irq(ZEUS_UARTB_GPIO),
242 .irqflags = IRQF_TRIGGER_RISING,
243 .uartclk = 14745600,
244 .regshift = 1,
245 .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
246 .iotype = UPIO_MEM,
247 },
248 { /* COM3 */
249 .mapbase = 0x11000000,
250 .irq = gpio_to_irq(ZEUS_UARTC_GPIO),
251 .irqflags = IRQF_TRIGGER_RISING,
252 .uartclk = 14745600,
253 .regshift = 1,
254 .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
255 .iotype = UPIO_MEM,
256 },
257 { /* COM4 */
258 .mapbase = 0x11800000,
259 .irq = gpio_to_irq(ZEUS_UARTD_GPIO),
260 .irqflags = IRQF_TRIGGER_RISING,
261 .uartclk = 14745600,
262 .regshift = 1,
263 .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
264 .iotype = UPIO_MEM,
265 },
266 /* Internal UARTs */
267 { /* FFUART */
268 .membase = (void *)&FFUART,
269 .mapbase = __PREG(FFUART),
270 .irq = IRQ_FFUART,
271 .uartclk = 921600 * 16,
272 .regshift = 2,
273 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
274 .iotype = UPIO_MEM,
275 },
276 { /* BTUART */
277 .membase = (void *)&BTUART,
278 .mapbase = __PREG(BTUART),
279 .irq = IRQ_BTUART,
280 .uartclk = 921600 * 16,
281 .regshift = 2,
282 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
283 .iotype = UPIO_MEM,
284 },
285 { /* STUART */
286 .membase = (void *)&STUART,
287 .mapbase = __PREG(STUART),
288 .irq = IRQ_STUART,
289 .uartclk = 921600 * 16,
290 .regshift = 2,
291 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
292 .iotype = UPIO_MEM,
293 },
294 { },
295};
296
297static struct platform_device zeus_serial_device = {
298 .name = "serial8250",
299 .id = PLAT8250_DEV_PLATFORM,
300 .dev = {
301 .platform_data = serial_platform_data,
302 },
303 .num_resources = ARRAY_SIZE(zeus_serial_resources),
304 .resource = zeus_serial_resources,
305};
306
307/* Ethernet */
308static struct resource zeus_dm9k0_resource[] = {
309 [0] = {
310 .start = ZEUS_ETH0_PHYS,
311 .end = ZEUS_ETH0_PHYS + 1,
312 .flags = IORESOURCE_MEM
313 },
314 [1] = {
315 .start = ZEUS_ETH0_PHYS + 2,
316 .end = ZEUS_ETH0_PHYS + 3,
317 .flags = IORESOURCE_MEM
318 },
319 [2] = {
320 .start = gpio_to_irq(ZEUS_ETH0_GPIO),
321 .end = gpio_to_irq(ZEUS_ETH0_GPIO),
322 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
323 },
324};
325
326static struct resource zeus_dm9k1_resource[] = {
327 [0] = {
328 .start = ZEUS_ETH1_PHYS,
329 .end = ZEUS_ETH1_PHYS + 1,
330 .flags = IORESOURCE_MEM
331 },
332 [1] = {
333 .start = ZEUS_ETH1_PHYS + 2,
334 .end = ZEUS_ETH1_PHYS + 3,
335 .flags = IORESOURCE_MEM,
336 },
337 [2] = {
338 .start = gpio_to_irq(ZEUS_ETH1_GPIO),
339 .end = gpio_to_irq(ZEUS_ETH1_GPIO),
340 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
341 },
342};
343
344static struct dm9000_plat_data zeus_dm9k_platdata = {
345 .flags = DM9000_PLATF_16BITONLY,
346};
347
348static struct platform_device zeus_dm9k0_device = {
349 .name = "dm9000",
350 .id = 0,
351 .num_resources = ARRAY_SIZE(zeus_dm9k0_resource),
352 .resource = zeus_dm9k0_resource,
353 .dev = {
354 .platform_data = &zeus_dm9k_platdata,
355 }
356};
357
358static struct platform_device zeus_dm9k1_device = {
359 .name = "dm9000",
360 .id = 1,
361 .num_resources = ARRAY_SIZE(zeus_dm9k1_resource),
362 .resource = zeus_dm9k1_resource,
363 .dev = {
364 .platform_data = &zeus_dm9k_platdata,
365 }
366};
367
368/* External SRAM */
369static struct resource zeus_sram_resource = {
370 .start = ZEUS_SRAM_PHYS,
371 .end = ZEUS_SRAM_PHYS + ZEUS_SRAM_SIZE * 2 - 1,
372 .flags = IORESOURCE_MEM,
373};
374
375static struct platform_device zeus_sram_device = {
376 .name = "pxa2xx-8bit-sram",
377 .id = 0,
378 .num_resources = 1,
379 .resource = &zeus_sram_resource,
380};
381
382/* SPI interface on SSP3 */
383static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = {
384 .num_chipselect = 1,
385 .enable_dma = 1,
386};
387
388static struct platform_device pxa2xx_spi_ssp3_device = {
389 .name = "pxa2xx-spi",
390 .id = 3,
391 .dev = {
392 .platform_data = &pxa2xx_spi_ssp3_master_info,
393 },
394};
395
396/* Leds */
397static struct gpio_led zeus_leds[] = {
398 [0] = {
399 .name = "zeus:yellow:1",
400 .default_trigger = "heartbeat",
401 .gpio = ZEUS_EXT0_GPIO(3),
402 .active_low = 1,
403 },
404 [1] = {
405 .name = "zeus:yellow:2",
406 .default_trigger = "default-on",
407 .gpio = ZEUS_EXT0_GPIO(4),
408 .active_low = 1,
409 },
410 [2] = {
411 .name = "zeus:yellow:3",
412 .default_trigger = "default-on",
413 .gpio = ZEUS_EXT0_GPIO(5),
414 .active_low = 1,
415 },
416};
417
418static struct gpio_led_platform_data zeus_leds_info = {
419 .leds = zeus_leds,
420 .num_leds = ARRAY_SIZE(zeus_leds),
421};
422
423static struct platform_device zeus_leds_device = {
424 .name = "leds-gpio",
425 .id = -1,
426 .dev = {
427 .platform_data = &zeus_leds_info,
428 },
429};
430
431static struct platform_device *zeus_devices[] __initdata = {
432 &zeus_serial_device,
433 &zeus_mtd_devices[0],
434 &zeus_dm9k0_device,
435 &zeus_dm9k1_device,
436 &zeus_sram_device,
437 &pxa2xx_spi_ssp3_device,
438 &zeus_leds_device,
439};
440
441/* AC'97 */
442static pxa2xx_audio_ops_t zeus_ac97_info = {
443 .reset_gpio = 95,
444};
445
446
447/*
448 * USB host
449 */
450
451static int zeus_ohci_init(struct device *dev)
452{
453 int err;
454
455 /* Switch on port 2. */
456 if ((err = gpio_request(ZEUS_USB2_PWREN_GPIO, "USB2_PWREN"))) {
457 dev_err(dev, "Can't request USB2_PWREN\n");
458 return err;
459 }
460
461 if ((err = gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 1))) {
462 gpio_free(ZEUS_USB2_PWREN_GPIO);
463 dev_err(dev, "Can't enable USB2_PWREN\n");
464 return err;
465 }
466
467 /* Port 2 is shared between host and client interface. */
468 UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
469
470 return 0;
471}
472
473static void zeus_ohci_exit(struct device *dev)
474{
475 /* Power-off port 2 */
476 gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 0);
477 gpio_free(ZEUS_USB2_PWREN_GPIO);
478}
479
480static struct pxaohci_platform_data zeus_ohci_platform_data = {
481 .port_mode = PMM_NPS_MODE,
482 .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
483 .init = zeus_ohci_init,
484 .exit = zeus_ohci_exit,
485};
486
487/*
488 * Flat Panel
489 */
490
491static void zeus_lcd_power(int on, struct fb_var_screeninfo *si)
492{
493 gpio_set_value(ZEUS_LCD_EN_GPIO, on);
494}
495
496static void zeus_backlight_power(int on)
497{
498 gpio_set_value(ZEUS_BKLEN_GPIO, on);
499}
500
501static int zeus_setup_fb_gpios(void)
502{
503 int err;
504
505 if ((err = gpio_request(ZEUS_LCD_EN_GPIO, "LCD_EN")))
506 goto out_err;
507
508 if ((err = gpio_direction_output(ZEUS_LCD_EN_GPIO, 0)))
509 goto out_err_lcd;
510
511 if ((err = gpio_request(ZEUS_BKLEN_GPIO, "BKLEN")))
512 goto out_err_lcd;
513
514 if ((err = gpio_direction_output(ZEUS_BKLEN_GPIO, 0)))
515 goto out_err_bkl;
516
517 return 0;
518
519out_err_bkl:
520 gpio_free(ZEUS_BKLEN_GPIO);
521out_err_lcd:
522 gpio_free(ZEUS_LCD_EN_GPIO);
523out_err:
524 return err;
525}
526
527static struct pxafb_mode_info zeus_fb_mode_info[] = {
528 {
529 .pixclock = 39722,
530
531 .xres = 640,
532 .yres = 480,
533
534 .bpp = 16,
535
536 .hsync_len = 63,
537 .left_margin = 16,
538 .right_margin = 81,
539
540 .vsync_len = 2,
541 .upper_margin = 12,
542 .lower_margin = 31,
543
544 .sync = 0,
545 },
546};
547
548static struct pxafb_mach_info zeus_fb_info = {
549 .modes = zeus_fb_mode_info,
550 .num_modes = 1,
551 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
552 .pxafb_lcd_power = zeus_lcd_power,
553 .pxafb_backlight_power = zeus_backlight_power,
554};
555
556/*
557 * MMC/SD Device
558 *
559 * The card detect interrupt isn't debounced so we delay it by 250ms
560 * to give the card a chance to fully insert/eject.
561 */
562
563static struct pxamci_platform_data zeus_mci_platform_data = {
564 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
565 .detect_delay = HZ/4,
566 .gpio_card_detect = ZEUS_MMC_CD_GPIO,
567 .gpio_card_ro = ZEUS_MMC_WP_GPIO,
568 .gpio_card_ro_invert = 1,
569 .gpio_power = -1
570};
571
572/*
573 * USB Device Controller
574 */
575static void zeus_udc_command(int cmd)
576{
577 switch (cmd) {
578 case PXA2XX_UDC_CMD_DISCONNECT:
579 pr_info("zeus: disconnecting USB client\n");
580 UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
581 break;
582
583 case PXA2XX_UDC_CMD_CONNECT:
584 pr_info("zeus: connecting USB client\n");
585 UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
586 break;
587 }
588}
589
590static struct pxa2xx_udc_mach_info zeus_udc_info = {
591 .udc_command = zeus_udc_command,
592};
593
594static void zeus_power_off(void)
595{
596 local_irq_disable();
597 pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP);
598}
599
600int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio,
601 unsigned ngpio, void *context)
602{
603 int i;
604 u8 pcb_info = 0;
605
606 for (i = 0; i < 8; i++) {
607 int pcb_bit = gpio + i + 8;
608
609 if (gpio_request(pcb_bit, "pcb info")) {
610 dev_err(&client->dev, "Can't request pcb info %d\n", i);
611 continue;
612 }
613
614 if (gpio_direction_input(pcb_bit)) {
615 dev_err(&client->dev, "Can't read pcb info %d\n", i);
616 gpio_free(pcb_bit);
617 continue;
618 }
619
620 pcb_info |= !!gpio_get_value(pcb_bit) << i;
621
622 gpio_free(pcb_bit);
623 }
624
625 dev_info(&client->dev, "Zeus PCB version %d issue %d\n",
626 pcb_info >> 4, pcb_info & 0xf);
627
628 return 0;
629}
630
631static struct pca953x_platform_data zeus_pca953x_pdata[] = {
632 [0] = { .gpio_base = ZEUS_EXT0_GPIO_BASE, },
633 [1] = {
634 .gpio_base = ZEUS_EXT1_GPIO_BASE,
635 .setup = zeus_get_pcb_info,
636 },
637 [2] = { .gpio_base = ZEUS_USER_GPIO_BASE, },
638};
639
640static struct i2c_board_info __initdata zeus_i2c_devices[] = {
641 {
642 I2C_BOARD_INFO("pca9535", 0x21),
643 .platform_data = &zeus_pca953x_pdata[0],
644 },
645 {
646 I2C_BOARD_INFO("pca9535", 0x22),
647 .platform_data = &zeus_pca953x_pdata[1],
648 },
649 {
650 I2C_BOARD_INFO("pca9535", 0x20),
651 .platform_data = &zeus_pca953x_pdata[2],
652 .irq = gpio_to_irq(ZEUS_EXTGPIO_GPIO),
653 },
654 { I2C_BOARD_INFO("lm75a", 0x48) },
655 { I2C_BOARD_INFO("24c01", 0x50) },
656 { I2C_BOARD_INFO("isl1208", 0x6f) },
657};
658
659static mfp_cfg_t zeus_pin_config[] __initdata = {
660 GPIO15_nCS_1,
661 GPIO78_nCS_2,
662 GPIO80_nCS_4,
663 GPIO33_nCS_5,
664
665 GPIO22_GPIO,
666 GPIO32_MMC_CLK,
667 GPIO92_MMC_DAT_0,
668 GPIO109_MMC_DAT_1,
669 GPIO110_MMC_DAT_2,
670 GPIO111_MMC_DAT_3,
671 GPIO112_MMC_CMD,
672
673 GPIO88_USBH1_PWR,
674 GPIO89_USBH1_PEN,
675 GPIO119_USBH2_PWR,
676 GPIO120_USBH2_PEN,
677
678 GPIO86_LCD_LDD_16,
679 GPIO87_LCD_LDD_17,
680
681 GPIO102_GPIO,
682 GPIO104_CIF_DD_2,
683 GPIO105_CIF_DD_1,
684
685 GPIO48_nPOE,
686 GPIO49_nPWE,
687 GPIO50_nPIOR,
688 GPIO51_nPIOW,
689 GPIO85_nPCE_1,
690 GPIO54_nPCE_2,
691 GPIO79_PSKTSEL,
692 GPIO55_nPREG,
693 GPIO56_nPWAIT,
694 GPIO57_nIOIS16,
695 GPIO36_GPIO, /* CF CD */
696 GPIO97_GPIO, /* CF PWREN */
697 GPIO99_GPIO, /* CF RDY */
698};
699
700static void __init zeus_init(void)
701{
702 u16 dm9000_msc = 0xe279;
703
704 system_rev = __raw_readw(ZEUS_CPLD_VERSION);
705 pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f));
706
707 /* Fix timings for dm9000s (CS1/CS2)*/
708 MSC0 = (MSC0 & 0xffff) | (dm9000_msc << 16);
709 MSC1 = (MSC1 & 0xffff0000) | dm9000_msc;
710
711 pm_power_off = zeus_power_off;
712
713 pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config));
714
715 platform_add_devices(zeus_devices, ARRAY_SIZE(zeus_devices));
716
717 pxa_set_ohci_info(&zeus_ohci_platform_data);
718
719 if (zeus_setup_fb_gpios())
720 pr_err("Failed to setup fb gpios\n");
721 else
722 set_pxa_fb_info(&zeus_fb_info);
723
724 pxa_set_mci_info(&zeus_mci_platform_data);
725 pxa_set_udc_info(&zeus_udc_info);
726 pxa_set_ac97_info(&zeus_ac97_info);
727 pxa_set_i2c_info(NULL);
728 i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices));
729}
730
731static struct map_desc zeus_io_desc[] __initdata = {
732 {
733 .virtual = ZEUS_CPLD_VERSION,
734 .pfn = __phys_to_pfn(ZEUS_CPLD_VERSION_PHYS),
735 .length = 0x1000,
736 .type = MT_DEVICE,
737 },
738 {
739 .virtual = ZEUS_CPLD_ISA_IRQ,
740 .pfn = __phys_to_pfn(ZEUS_CPLD_ISA_IRQ_PHYS),
741 .length = 0x1000,
742 .type = MT_DEVICE,
743 },
744 {
745 .virtual = ZEUS_CPLD_CONTROL,
746 .pfn = __phys_to_pfn(ZEUS_CPLD_CONTROL_PHYS),
747 .length = 0x1000,
748 .type = MT_DEVICE,
749 },
750 {
751 .virtual = ZEUS_CPLD_EXTWDOG,
752 .pfn = __phys_to_pfn(ZEUS_CPLD_EXTWDOG_PHYS),
753 .length = 0x1000,
754 .type = MT_DEVICE,
755 },
756 {
757 .virtual = ZEUS_PC104IO,
758 .pfn = __phys_to_pfn(ZEUS_PC104IO_PHYS),
759 .length = 0x00800000,
760 .type = MT_DEVICE,
761 },
762};
763
764static void __init zeus_map_io(void)
765{
766 pxa_map_io();
767
768 iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc));
769
770 /* Clear PSPR to ensure a full restart on wake-up. */
771 PMCR = PSPR = 0;
772
773 /* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */
774 OSCC |= OSCC_OON;
775
776 /* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...).
777 * float chip selects and PCMCIA */
778 PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP;
779}
780
781MACHINE_START(ARCOM_ZEUS, "Arcom ZEUS")
782 /* Maintainer: Marc Zyngier <maz@misterjones.org> */
783 .phys_io = 0x40000000,
784 .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc),
785 .boot_params = 0xa0000100,
786 .map_io = zeus_map_io,
787 .init_irq = zeus_init_irq,
788 .timer = &pxa_timer,
789 .init_machine = zeus_init,
790MACHINE_END
791