Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e927b76 authored by Robert Schwebel's avatar Robert Schwebel Committed by Russell King
Browse files

[ARM] 4747/1: pcm027: support for pcm990 baseboard for phyCORE-PXA270



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: default avatarJuergen Beisert <j.beisert@pengutronix.de>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 4f15a980
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+330 −0
Original line number Diff line number Diff line
/*
 *  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");
}
+275 −0
Original line number Diff line number Diff line
/*
 * 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)