[ARM] 4747/1: pcm027: support for pcm990 baseboard for phyCORE-PXA270
authorRobert Schwebel <robert@schwebel.de>
Tue, 8 Jan 2008 07:52:04 +0000 (08:52 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 28 Jan 2008 13:13:24 +0000 (13:13 +0000)
This patch adds baseboard support for the phyCORE-PXA270 development
kit (aka PCM-990).

This example shows how to use some phyCORE-PXA270 CPU module features
on a baseboard in a standard manner. It could be used as a starting
point for custom baseboard development.

V2:
 After comments by Eric Miao:
  - IRQ chained handler fixed
  - video/graphic support moved to separate patch
  - ifdef/endif hell reduced ;-)

V3:
 After comments by Russell King
  - initialise the mmci platform data statically

V4:
 After comments by Russell King
  - wrong return value in pcm990_mci_init() fixed

Signed-off-by: Juergen Beisert <j.beisert@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/pcm990-baseboard.c [new file with mode: 0644]
include/asm-arm/arch-pxa/pcm990_baseboard.h [new file with mode: 0644]

index 958303c100b00437920c5ce645fabde34f038ea6..e5b7063ed81807470077d5890fe69199a18ef9c6 100644 (file)
@@ -130,6 +130,15 @@ config MACH_PCM027
 
 endchoice
 
+choice
+       prompt "Used baseboard"
+       depends on MACH_PCM027
+
+config MACH_PCM990_BASEBOARD
+       bool "PHYTEC PCM-990 development board"
+
+endchoice
+
 if PXA_SHARPSL
 
 choice
index 61d301805c80f2b1f1d518575bffa551f5d816a0..1af56805b9545966faab751e7c7b16e7aca0df3a 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o sp
 obj-$(CONFIG_MACH_AKITA)       += akita-ioexp.o
 obj-$(CONFIG_MACH_POODLE)      += poodle.o corgi_ssp.o
 obj-$(CONFIG_MACH_PCM027)      += pcm027.o
+obj-$(CONFIG_MACH_PCM990_BASEBOARD)    += pcm990-baseboard.o
 obj-$(CONFIG_MACH_TOSA)                += tosa.o
 obj-$(CONFIG_MACH_EM_X270)     += em-x270.o
 obj-$(CONFIG_MACH_MAGICIAN)    += magician.o
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
new file mode 100644 (file)
index 0000000..3dda16a
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ *  arch/arm/mach-pxa/pcm990-baseboard.c
+ *  Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
+ *
+ *  Refer
+ *   http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
+ *  for additional hardware info
+ *
+ *  Author:    Juergen Kilb
+ *  Created:   April 05, 2005
+ *  Copyright: Phytec Messtechnik GmbH
+ *  e-Mail:    armlinux@phytec.de
+ *
+ *  based on Intel Mainstone Board
+ *
+ *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ide.h>
+#include <asm/mach/map.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/pcm990_baseboard.h>
+
+/*
+ * The PCM-990 development baseboard uses PCM-027's hardeware in the
+ * following way:
+ *
+ * - LCD support is in use
+ *  - GPIO16 is output for back light on/off with PWM
+ *  - GPIO58 ... GPIO73 are outputs for display data
+ *  - GPIO74 is output output for LCDFCLK
+ *  - GPIO75 is output for LCDLCLK
+ *  - GPIO76 is output for LCDPCLK
+ *  - GPIO77 is output for LCDBIAS
+ * - MMC support is in use
+ *  - GPIO32 is output for MMCCLK
+ *  - GPIO92 is MMDAT0
+ *  - GPIO109 is MMDAT1
+ *  - GPIO110 is MMCS0
+ *  - GPIO111 is MMCS1
+ *  - GPIO112 is MMCMD
+ * - IDE/CF card is in use
+ *  - GPIO48 is output /POE
+ *  - GPIO49 is output /PWE
+ *  - GPIO50 is output /PIOR
+ *  - GPIO51 is output /PIOW
+ *  - GPIO54 is output /PCE2
+ *  - GPIO55 is output /PREG
+ *  - GPIO56 is input /PWAIT
+ *  - GPIO57 is output /PIOS16
+ *  - GPIO79 is output PSKTSEL
+ *  - GPIO85 is output /PCE1
+ * - FFUART is in use
+ *  - GPIO34 is input FFRXD
+ *  - GPIO35 is input FFCTS
+ *  - GPIO36 is input FFDCD
+ *  - GPIO37 is input FFDSR
+ *  - GPIO38 is input FFRI
+ *  - GPIO39 is output FFTXD
+ *  - GPIO40 is output FFDTR
+ *  - GPIO41 is output FFRTS
+ * - BTUART is in use
+ *  - GPIO42 is input BTRXD
+ *  - GPIO43 is output BTTXD
+ *  - GPIO44 is input BTCTS
+ *  - GPIO45 is output BTRTS
+ * - IRUART is in use
+ *  - GPIO46 is input STDRXD
+ *  - GPIO47 is output STDTXD
+ * - AC97 is in use*)
+ *  - GPIO28 is input AC97CLK
+ *  - GPIO29 is input AC97DatIn
+ *  - GPIO30 is output AC97DatO
+ *  - GPIO31 is output AC97SYNC
+ *  - GPIO113 is output AC97_RESET
+ * - SSP is in use
+ *  - GPIO23 is output SSPSCLK
+ *  - GPIO24 is output chip select to Max7301
+ *  - GPIO25 is output SSPTXD
+ *  - GPIO26 is input SSPRXD
+ *  - GPIO27 is input for Max7301 IRQ
+ *  - GPIO53 is input SSPSYSCLK
+ * - SSP3 is in use
+ *  - GPIO81 is output SSPTXD3
+ *  - GPIO82 is input SSPRXD3
+ *  - GPIO83 is output SSPSFRM
+ *  - GPIO84 is output SSPCLK3
+ *
+ * Otherwise claimed GPIOs:
+ * GPIO1 -> IRQ from user switch
+ * GPIO9 -> IRQ from power management
+ * GPIO10 -> IRQ from WML9712 AC97 controller
+ * GPIO11 -> IRQ from IDE controller
+ * GPIO12 -> IRQ from CF controller
+ * GPIO13 -> IRQ from CF controller
+ * GPIO14 -> GPIO free
+ * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
+ * GPIO19 -> GPIO free
+ * GPIO20 -> /SDCS2
+ * GPIO21 -> /CS3 PC card socket select
+ * GPIO33 -> /CS5  network controller select
+ * GPIO78 -> /CS2  (16 bit wide data path)
+ * GPIO80 -> /CS4  (16 bit wide data path)
+ * GPIO86 -> GPIO free
+ * GPIO87 -> GPIO free
+ * GPIO90 -> LED0 on CPU module
+ * GPIO91 -> LED1 on CPI module
+ * GPIO117 -> SCL
+ * GPIO118 -> SDA
+ */
+
+static unsigned long pcm990_irq_enabled;
+
+static void pcm990_mask_ack_irq(unsigned int irq)
+{
+       int pcm990_irq = (irq - PCM027_IRQ(0));
+       PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
+}
+
+static void pcm990_unmask_irq(unsigned int irq)
+{
+       int pcm990_irq = (irq - PCM027_IRQ(0));
+       /* the irq can be acknowledged only if deasserted, so it's done here */
+       PCM990_INTSETCLR |= 1 << pcm990_irq;
+       PCM990_INTMSKENA  = (pcm990_irq_enabled |= (1 << pcm990_irq));
+}
+
+static struct irq_chip pcm990_irq_chip = {
+       .mask_ack       = pcm990_mask_ack_irq,
+       .unmask         = pcm990_unmask_irq,
+};
+
+static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+
+       do {
+               GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
+                                       GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
+               if (likely(pending)) {
+                       irq = PCM027_IRQ(0) + __ffs(pending);
+                       desc = irq_desc + irq;
+                       desc_handle_irq(irq, desc);
+               }
+               pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+       } while (pending);
+}
+
+static void __init pcm990_init_irq(void)
+{
+       int irq;
+
+       /* setup extra PCM990 irqs */
+       for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
+               set_irq_chip(irq, &pcm990_irq_chip);
+               set_irq_handler(irq, handle_level_irq);
+               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+       }
+
+       PCM990_INTMSKENA = 0x00;        /* disable all Interrupts */
+       PCM990_INTSETCLR = 0xFF;
+
+       set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
+       set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
+}
+
+static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
+                       void *data)
+{
+       int err;
+
+       /*
+        * enable GPIO for PXA27x MMC controller
+        */
+       pxa_gpio_mode(GPIO32_MMCCLK_MD);
+       pxa_gpio_mode(GPIO112_MMCCMD_MD);
+       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+       err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
+                            "MMC card detect", data);
+       if (err)
+               printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
+                               "card detect IRQ\n");
+
+       return err;
+}
+
+static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
+{
+       struct pxamci_platform_data *p_d = dev->platform_data;
+
+       if ((1 << vdd) & p_d->ocr_mask)
+               __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
+                                               PCM990_CTRL_MMC2PWR;
+       else
+               __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
+                                               ~PCM990_CTRL_MMC2PWR;
+}
+
+static void pcm990_mci_exit(struct device *dev, void *data)
+{
+       free_irq(PCM027_MMCDET_IRQ, data);
+}
+
+#define MSECS_PER_JIFFY (1000/HZ)
+
+static struct pxamci_platform_data pcm990_mci_platform_data = {
+       .detect_delay   = 250 / MSECS_PER_JIFFY,
+       .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .init           = pcm990_mci_init,
+       .setpower       = pcm990_mci_setpower,
+       .exit           = pcm990_mci_exit,
+};
+
+/*
+ * init OHCI hardware to work with
+ *
+ * Note: Only USB port 1 (host only) is connected
+ *
+ * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
+ * GPIO89 (USBHPEN#1): power-on out, on when low
+ */
+static int pcm990_ohci_init(struct device *dev)
+{
+       pxa_gpio_mode(PCM990_USB_OVERCURRENT);
+       pxa_gpio_mode(PCM990_USB_PWR_EN);
+       /*
+        * disable USB port 2 and 3
+        * power sense is active low
+        */
+       UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
+                               UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
+       /*
+        * wait 10ms after Power on
+        * overcurrent per port
+        * power switch per port
+        */
+       UHCRHDA = (5<<24) | (1<<11) | (1<<8);   /* FIXME: Required? */
+
+       return 0;
+}
+
+static struct pxaohci_platform_data pcm990_ohci_platform_data = {
+       .port_mode      = PMM_PERPORT_MODE,
+       .init           = pcm990_ohci_init,
+       .exit           = NULL,
+};
+
+/*
+ * AC97 support
+ * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ
+ */
+static struct resource pxa27x_ac97_resources[] = {
+       [0] = {
+               .start  = 0x40500000,
+               .end    = 0x40500000 + 0xfff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_AC97,
+               .end    = IRQ_AC97,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static u64 pxa_ac97_dmamask = 0xffffffffUL;
+
+static struct platform_device pxa27x_device_ac97 = {
+       .name           = "pxa2xx-ac97",
+       .id             = -1,
+       .dev            = {
+               .dma_mask = &pxa_ac97_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(pxa27x_ac97_resources),
+       .resource       = pxa27x_ac97_resources,
+};
+
+/*
+ * enable generic access to the base board control CPLDs U6 and U7
+ */
+static struct map_desc pcm990_io_desc[] __initdata = {
+       {
+               .virtual        = PCM990_CTRL_BASE,
+               .pfn            = __phys_to_pfn(PCM990_CTRL_PHYS),
+               .length         = PCM990_CTRL_SIZE,
+               .type           = MT_DEVICE     /* CPLD */
+       }, {
+               .virtual        = PCM990_CF_PLD_BASE,
+               .pfn            = __phys_to_pfn(PCM990_CF_PLD_PHYS),
+               .length         = PCM990_CF_PLD_SIZE,
+               .type           = MT_DEVICE     /* CPLD */
+       }
+};
+
+/*
+ * system init for baseboard usage. Will be called by pcm027 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init pcm990_baseboard_init(void)
+{
+       /* register CPLD access */
+       iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc));
+
+       /* register CPLD's IRQ controller */
+       pcm990_init_irq();
+
+       platform_device_register(&pxa27x_device_ac97);
+
+       /* MMC */
+       pxa_set_mci_info(&pcm990_mci_platform_data);
+
+       /* USB host */
+       pxa_set_ohci_info(&pcm990_ohci_platform_data);
+
+       printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n");
+}
diff --git a/include/asm-arm/arch-pxa/pcm990_baseboard.h b/include/asm-arm/arch-pxa/pcm990_baseboard.h
new file mode 100644 (file)
index 0000000..b699d0d
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * include/asm-arm/arch-pxa/pcm990_baseboard.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <asm/arch/pcm027.h>
+
+/*
+ * definitions relevant only when the PCM-990
+ * development base board is in use
+ */
+
+/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
+#define PCM990_CTRL_INT_IRQ_GPIO       9
+#define PCM990_CTRL_INT_IRQ            IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO)
+#define PCM990_CTRL_INT_IRQ_EDGE       IRQT_RISING
+#define PCM990_CTRL_PHYS               PXA_CS1_PHYS    /* 16-Bit */
+#define PCM990_CTRL_BASE               0xea000000
+#define PCM990_CTRL_SIZE               (1*1024*1024)
+
+#define PCM990_CTRL_PWR_IRQ_GPIO       14
+#define PCM990_CTRL_PWR_IRQ            IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO)
+#define PCM990_CTRL_PWR_IRQ_EDGE       IRQT_RISING
+
+/* visible CPLD (U7) registers */
+#define PCM990_CTRL_REG0       0x0000  /* RESET REGISTER */
+#define PCM990_CTRL_SYSRES     0x0001  /* System RESET REGISTER */
+#define PCM990_CTRL_RESOUT     0x0002  /* RESETOUT Enable REGISTER */
+#define PCM990_CTRL_RESGPIO    0x0004  /* RESETGPIO Enable REGISTER */
+
+#define PCM990_CTRL_REG1       0x0002  /* Power REGISTER */
+#define PCM990_CTRL_5VOFF      0x0001  /* Disable  5V Regulators */
+#define PCM990_CTRL_CANPWR     0x0004  /* Enable CANPWR ADUM */
+#define PCM990_CTRL_PM_5V      0x0008  /* Read 5V OK */
+
+#define PCM990_CTRL_REG2       0x0004  /* LED REGISTER */
+#define PCM990_CTRL_LEDPWR     0x0001  /* POWER LED enable */
+#define PCM990_CTRL_LEDBAS     0x0002  /* BASIS LED enable */
+#define PCM990_CTRL_LEDUSR     0x0004  /* USER LED enable */
+
+#define PCM990_CTRL_REG3       0x0006  /* LCD CTRL REGISTER 3 */
+#define PCM990_CTRL_LCDPWR     0x0001  /* RW LCD Power on */
+#define PCM990_CTRL_LCDON      0x0002  /* RW LCD Latch on */
+#define PCM990_CTRL_LCDPOS1    0x0004  /* RW POS 1 */
+#define PCM990_CTRL_LCDPOS2    0x0008  /* RW POS 2 */
+
+#define PCM990_CTRL_REG4       0x0008  /* MMC1 CTRL REGISTER 4 */
+#define PCM990_CTRL_MMC1PWR    0x0001 /* RW MMC1 Power on */
+
+#define PCM990_CTRL_REG5       0x000A  /* MMC2 CTRL REGISTER 5 */
+#define PCM990_CTRL_MMC2PWR    0x0001  /* RW MMC2 Power on */
+#define PCM990_CTRL_MMC2LED    0x0002  /* RW MMC2 LED */
+#define PCM990_CTRL_MMC2DE     0x0004  /* R MMC2 Card detect */
+#define PCM990_CTRL_MMC2WP     0x0008  /* R MMC2 Card write protect */
+
+#define PCM990_CTRL_REG6       0x000C  /* Interrupt Clear REGISTER */
+#define PCM990_CTRL_INTC0      0x0001  /* Clear Reg BT Detect */
+#define PCM990_CTRL_INTC1      0x0002  /* Clear Reg FR RI */
+#define PCM990_CTRL_INTC2      0x0004  /* Clear Reg MMC1 Detect */
+#define PCM990_CTRL_INTC3      0x0008  /* Clear Reg PM_5V off */
+
+#define PCM990_CTRL_REG7       0x000E  /* Interrupt Enable REGISTER */
+#define PCM990_CTRL_ENAINT0    0x0001  /* Enable Int BT Detect */
+#define PCM990_CTRL_ENAINT1    0x0002  /* Enable Int FR RI */
+#define PCM990_CTRL_ENAINT2    0x0004  /* Enable Int MMC1 Detect */
+#define PCM990_CTRL_ENAINT3    0x0008  /* Enable Int PM_5V off */
+
+#define PCM990_CTRL_REG8       0x0014  /* Uart REGISTER */
+#define PCM990_CTRL_FFSD       0x0001  /* BT Uart Enable */
+#define PCM990_CTRL_BTSD       0x0002  /* FF Uart Enable */
+#define PCM990_CTRL_FFRI       0x0004  /* FF Uart RI detect */
+#define PCM990_CTRL_BTRX       0x0008  /* BT Uart Rx detect */
+
+#define PCM990_CTRL_REG9       0x0010  /* AC97 Flash REGISTER */
+#define PCM990_CTRL_FLWP       0x0001  /* pC Flash Write Protect */
+#define PCM990_CTRL_FLDIS      0x0002  /* pC Flash Disable */
+#define PCM990_CTRL_AC97ENA    0x0004  /* Enable AC97 Expansion */
+
+#define PCM990_CTRL_REG10      0x0012  /* GPS-REGISTER */
+#define PCM990_CTRL_GPSPWR     0x0004  /* GPS-Modul Power on */
+#define PCM990_CTRL_GPSENA     0x0008  /* GPS-Modul Enable */
+
+#define PCM990_CTRL_REG11      0x0014  /* Accu REGISTER */
+#define PCM990_CTRL_ACENA      0x0001  /* Charge Enable */
+#define PCM990_CTRL_ACSEL      0x0002  /* Charge Akku -> DC Enable */
+#define PCM990_CTRL_ACPRES     0x0004  /* DC Present */
+#define PCM990_CTRL_ACALARM    0x0008  /* Error Akku */
+
+#define PCM990_CTRL_P2V(x)     ((x) - PCM990_CTRL_PHYS + PCM990_CTRL_BASE)
+#define PCM990_CTRL_V2P(x)     ((x) - PCM990_CTRL_BASE + PCM990_CTRL_PHYS)
+
+#ifndef __ASSEMBLY__
+#  define __PCM990_CTRL_REG(x) \
+               (*((volatile unsigned char *)PCM990_CTRL_P2V(x)))
+#else
+#  define __PCM990_CTRL_REG(x) PCM990_CTRL_P2V(x)
+#endif
+
+#define PCM990_INTMSKENA __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
+#define PCM990_INTSETCLR __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
+#define PCM990_CTRL0   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG0)
+#define PCM990_CTRL1   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG1)
+#define PCM990_CTRL2   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG2)
+#define PCM990_CTRL3   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3)
+#define PCM990_CTRL4   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG4)
+#define PCM990_CTRL5   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5)
+#define PCM990_CTRL6   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
+#define PCM990_CTRL7   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
+#define PCM990_CTRL8   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG8)
+#define PCM990_CTRL9   __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG9)
+#define PCM990_CTRL10  __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG10)
+#define PCM990_CTRL11  __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG11)
+
+
+/*
+ * IDE
+ */
+#define PCM990_IDE_IRQ_GPIO    13
+#define PCM990_IDE_IRQ         IRQ_GPIO(PCM990_IDE_IRQ_GPIO)
+#define PCM990_IDE_IRQ_EDGE    IRQT_RISING
+#define PCM990_IDE_PLD_PHYS    0x20000000      /* 16 bit wide */
+#define PCM990_IDE_PLD_BASE    0xee000000
+#define PCM990_IDE_PLD_SIZE    (1*1024*1024)
+
+/* visible CPLD (U6) registers */
+#define PCM990_IDE_PLD_REG0    0x1000  /* OFFSET IDE REGISTER 0 */
+#define PCM990_IDE_PM5V                0x0004  /* R System VCC_5V */
+#define PCM990_IDE_STBY                0x0008  /* R System StandBy */
+
+#define PCM990_IDE_PLD_REG1    0x1002  /* OFFSET IDE REGISTER 1 */
+#define PCM990_IDE_IDEMODE     0x0001  /* R TrueIDE Mode */
+#define PCM990_IDE_DMAENA      0x0004  /* RW DMA Enable */
+#define PCM990_IDE_DMA1_0      0x0008  /* RW 1=DREQ1 0=DREQ0 */
+
+#define PCM990_IDE_PLD_REG2    0x1004  /* OFFSET IDE REGISTER 2 */
+#define PCM990_IDE_RESENA      0x0001  /* RW IDE Reset Bit enable */
+#define PCM990_IDE_RES         0x0002  /* RW IDE Reset Bit */
+#define PCM990_IDE_RDY         0x0008  /* RDY */
+
+#define PCM990_IDE_PLD_REG3    0x1006  /* OFFSET IDE REGISTER 3 */
+#define PCM990_IDE_IDEOE       0x0001  /* RW Latch on Databus */
+#define PCM990_IDE_IDEON       0x0002  /* RW Latch on Control Address */
+#define PCM990_IDE_IDEIN       0x0004  /* RW Latch on Interrupt usw. */
+
+#define PCM990_IDE_PLD_REG4    0x1008  /* OFFSET IDE REGISTER 4 */
+#define PCM990_IDE_PWRENA      0x0001  /* RW IDE Power enable */
+#define PCM990_IDE_5V          0x0002  /* R IDE Power 5V */
+#define PCM990_IDE_PWG         0x0008  /* R IDE Power is on */
+
+#define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
+#define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)
+
+#ifndef __ASSEMBLY__
+# define  __PCM990_IDE_PLD_REG(x) \
+       (*((volatile unsigned char *)PCM990_IDE_PLD_P2V(x)))
+#else
+# define  __PCM990_IDE_PLD_REG(x)      PCM990_IDE_PLD_P2V(x)
+#endif
+
+#define PCM990_IDE0 \
+       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG0)
+#define PCM990_IDE1 \
+       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG1)
+#define PCM990_IDE2 \
+       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG2)
+#define PCM990_IDE3 \
+       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG3)
+#define PCM990_IDE4 \
+       __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG4)
+
+/*
+ * Compact Flash
+ */
+#define PCM990_CF_IRQ_GPIO     11
+#define PCM990_CF_IRQ          IRQ_GPIO(PCM990_CF_IRQ_GPIO)
+#define PCM990_CF_IRQ_EDGE     IRQT_RISING
+
+#define PCM990_CF_CD_GPIO      12
+#define PCM990_CF_CD           IRQ_GPIO(PCM990_CF_CD_GPIO)
+#define PCM990_CF_CD_EDGE      IRQT_RISING
+
+#define PCM990_CF_PLD_PHYS     0x30000000      /* 16 bit wide */
+#define PCM990_CF_PLD_BASE     0xef000000
+#define PCM990_CF_PLD_SIZE     (1*1024*1024)
+#define PCM990_CF_PLD_P2V(x)   ((x) - PCM990_CF_PLD_PHYS + PCM990_CF_PLD_BASE)
+#define PCM990_CF_PLD_V2P(x)   ((x) - PCM990_CF_PLD_BASE + PCM990_CF_PLD_PHYS)
+
+/* visible CPLD (U6) registers */
+#define PCM990_CF_PLD_REG0     0x1000  /* OFFSET CF REGISTER 0 */
+#define PCM990_CF_REG0_LED     0x0001  /* RW LED on */
+#define PCM990_CF_REG0_BLK     0x0002  /* RW LED flash when access */
+#define PCM990_CF_REG0_PM5V    0x0004  /* R System VCC_5V enable */
+#define PCM990_CF_REG0_STBY    0x0008  /* R System StandBy */
+
+#define PCM990_CF_PLD_REG1     0x1002  /* OFFSET CF REGISTER 1 */
+#define PCM990_CF_REG1_IDEMODE 0x0001  /* RW CF card run as TrueIDE */
+#define PCM990_CF_REG1_CF0     0x0002  /* RW CF card at ADDR 0x28000000 */
+
+#define PCM990_CF_PLD_REG2     0x1004  /* OFFSET CF REGISTER 2 */
+#define PCM990_CF_REG2_RES     0x0002  /* RW CF RESET BIT */
+#define PCM990_CF_REG2_RDYENA  0x0004  /* RW Enable CF_RDY */
+#define PCM990_CF_REG2_RDY     0x0008  /* R CF_RDY auf PWAIT */
+
+#define PCM990_CF_PLD_REG3     0x1006  /* OFFSET CF REGISTER 3 */
+#define PCM990_CF_REG3_CFOE    0x0001  /* RW Latch on Databus */
+#define PCM990_CF_REG3_CFON    0x0002  /* RW Latch on Control Address */
+#define PCM990_CF_REG3_CFIN    0x0004  /* RW Latch on Interrupt usw. */
+#define PCM990_CF_REG3_CFCD    0x0008  /* RW Latch on CD1/2 VS1/2 usw */
+
+#define PCM990_CF_PLD_REG4     0x1008  /* OFFSET CF REGISTER 4 */
+#define PCM990_CF_REG4_PWRENA  0x0001  /* RW CF Power on (CD1/2 = "00") */
+#define PCM990_CF_REG4_5_3V    0x0002  /* RW 1 = 5V CF_VCC 0 = 3 V CF_VCC */
+#define PCM990_CF_REG4_3B      0x0004  /* RW 3.0V Backup from VCC (5_3V=0) */
+#define PCM990_CF_REG4_PWG     0x0008  /* R CF-Power is on */
+
+#define PCM990_CF_PLD_REG5     0x100A  /* OFFSET CF REGISTER 5 */
+#define PCM990_CF_REG5_BVD1    0x0001  /* R CF /BVD1 */
+#define PCM990_CF_REG5_BVD2    0x0002  /* R CF /BVD2 */
+#define PCM990_CF_REG5_VS1     0x0004  /* R CF /VS1 */
+#define PCM990_CF_REG5_VS2     0x0008  /* R CF /VS2 */
+
+#define PCM990_CF_PLD_REG6     0x100C  /* OFFSET CF REGISTER 6 */
+#define PCM990_CF_REG6_CD1     0x0001  /* R CF Card_Detect1 */
+#define PCM990_CF_REG6_CD2     0x0002  /* R CF Card_Detect2 */
+
+#ifndef __ASSEMBLY__
+#  define  __PCM990_CF_PLD_REG(x) \
+       (*((volatile unsigned char *)PCM990_CF_PLD_P2V(x)))
+#else
+#  define  __PCM990_CF_PLD_REG(x)      PCM990_CF_PLD_P2V(x)
+#endif
+
+#define PCM990_CF0 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG0)
+#define PCM990_CF1 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG1)
+#define PCM990_CF2 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG2)
+#define PCM990_CF3 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG3)
+#define PCM990_CF4 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG4)
+#define PCM990_CF5 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG5)
+#define PCM990_CF6 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG6)
+
+/*
+ * Wolfson AC97 Touch
+ */
+#define PCM990_AC97_IRQ_GPIO   10
+#define PCM990_AC97_IRQ                IRQ_GPIO(PCM990_AC97_IRQ_GPIO)
+#define PCM990_AC97_IRQ_EDGE   IRQT_RISING
+
+/*
+ * MMC phyCORE
+ */
+#define PCM990_MMC0_IRQ_GPIO   9
+#define PCM990_MMC0_IRQ                IRQ_GPIO(PCM990_MMC0_IRQ_GPIO)
+#define PCM990_MMC0_IRQ_EDGE   IRQT_FALLING
+
+/*
+ * USB phyCore
+ */
+#define PCM990_USB_OVERCURRENT (88 | GPIO_ALT_FN_1_IN)
+#define PCM990_USB_PWR_EN (89 | GPIO_ALT_FN_2_OUT)