diff options
Diffstat (limited to 'arch/arm/mach-mx2')
-rw-r--r-- | arch/arm/mach-mx2/Kconfig | 35 | ||||
-rw-r--r-- | arch/arm/mach-mx2/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-mx2/clock_imx21.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx2/clock_imx27.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-mx2/devices.c | 332 | ||||
-rw-r--r-- | arch/arm/mach-mx2/devices.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-mx2/eukrea_cpuimx27.c | 234 | ||||
-rw-r--r-- | arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c | 249 | ||||
-rw-r--r-- | arch/arm/mach-mx2/generic.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-mx2/mx21ads.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-mx2/mx27ads.c | 38 | ||||
-rw-r--r-- | arch/arm/mach-mx2/mx27lite.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx2/mx27pdk.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx2/pca100.c | 244 | ||||
-rw-r--r-- | arch/arm/mach-mx2/pcm038.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-mx2/pcm970-baseboard.c | 112 |
16 files changed, 1164 insertions, 182 deletions
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index c77da586b71..c8a2eac4d13 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -53,6 +53,34 @@ config MACH_PCM970_BASEBOARD endchoice +config MACH_EUKREA_CPUIMX27 + bool "Eukrea CPUIMX27 module" + depends on MACH_MX27 + help + Include support for Eukrea CPUIMX27 platform. This includes + specific configurations for the module and its peripherals. + +config MACH_EUKREA_CPUIMX27_USESDHC2 + bool "CPUIMX27 integrates SDHC2 module" + depends on MACH_EUKREA_CPUIMX27 + help + This adds support for the internal SDHC2 used on CPUIMX27 used + for wifi or eMMC. + +choice + prompt "Baseboard" + depends on MACH_EUKREA_CPUIMX27 + default MACH_EUKREA_MBIMX27_BASEBOARD + +config MACH_EUKREA_MBIMX27_BASEBOARD + prompt "Eukrea MBIMX27 development board" + bool + help + This adds board specific devices that can be found on Eukrea's + MBIMX27 evaluation board. + +endchoice + config MACH_MX27_3DS bool "MX27PDK platform" depends on MACH_MX27 @@ -67,4 +95,11 @@ config MACH_MX27LITE Include support for MX27 LITEKIT platform. This includes specific configurations for the board and its peripherals. +config MACH_PCA100 + bool "Phytec phyCARD-s (pca100)" + depends on MACH_MX27 + help + Include support for phyCARD-s (aka pca100) platform. This + includes specific configurations for the module and its peripherals. + endif diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index b9b1cca4e9b..19560f04563 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -17,4 +17,7 @@ obj-$(CONFIG_MACH_PCM038) += pcm038.o obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o +obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o +obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o +obj-$(CONFIG_MACH_PCA100) += pca100.o diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c index 0850fb88ec1..eede79855f4 100644 --- a/arch/arm/mach-mx2/clock_imx21.c +++ b/arch/arm/mach-mx2/clock_imx21.c @@ -1004,6 +1004,6 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) clk_enable(&uart_clk[0]); #endif - mxc_timer_init(&gpt_clk[0]); + mxc_timer_init(&gpt_clk[0], IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1); return 0; } diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index 2c971442f3f..4089951acb4 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -643,7 +643,14 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk) _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) _REGISTER_CLOCK(NULL, "csi", csi_clk) - _REGISTER_CLOCK(NULL, "usb", usb_clk) + _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk) + _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1) + _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk) + _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1) + _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk) + _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1) + _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk) + _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1) _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk) _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk) _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) @@ -748,7 +755,7 @@ int __init mx27_clocks_init(unsigned long fref) clk_enable(&uart1_clk); #endif - mxc_timer_init(&gpt1_clk); + mxc_timer_init(&gpt1_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1); return 0; } diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index a0f1b367432..50199aff014 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c @@ -40,45 +40,87 @@ #include "devices.h" /* - * Resource definition for the MXC IrDA + * SPI master controller + * + * - i.MX1: 2 channel (slighly different register setting) + * - i.MX21: 2 channel + * - i.MX27: 3 channel */ -static struct resource mxc_irda_resources[] = { - [0] = { - .start = UART3_BASE_ADDR, - .end = UART3_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, +static struct resource mxc_spi_resources0[] = { + { + .start = CSPI1_BASE_ADDR, + .end = CSPI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_CSPI1, + .end = MXC_INT_CSPI1, + .flags = IORESOURCE_IRQ, }, - [1] = { - .start = MXC_INT_UART3, - .end = MXC_INT_UART3, - .flags = IORESOURCE_IRQ, +}; + +static struct resource mxc_spi_resources1[] = { + { + .start = CSPI2_BASE_ADDR, + .end = CSPI2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_CSPI2, + .end = MXC_INT_CSPI2, + .flags = IORESOURCE_IRQ, }, }; -/* Platform Data for MXC IrDA */ -struct platform_device mxc_irda_device = { - .name = "mxc_irda", +#ifdef CONFIG_MACH_MX27 +static struct resource mxc_spi_resources2[] = { + { + .start = CSPI3_BASE_ADDR, + .end = CSPI3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_CSPI3, + .end = MXC_INT_CSPI3, + .flags = IORESOURCE_IRQ, + }, +}; +#endif + +struct platform_device mxc_spi_device0 = { + .name = "spi_imx", .id = 0, - .num_resources = ARRAY_SIZE(mxc_irda_resources), - .resource = mxc_irda_resources, + .num_resources = ARRAY_SIZE(mxc_spi_resources0), + .resource = mxc_spi_resources0, +}; + +struct platform_device mxc_spi_device1 = { + .name = "spi_imx", + .id = 1, + .num_resources = ARRAY_SIZE(mxc_spi_resources1), + .resource = mxc_spi_resources1, +}; + +#ifdef CONFIG_MACH_MX27 +struct platform_device mxc_spi_device2 = { + .name = "spi_imx", + .id = 2, + .num_resources = ARRAY_SIZE(mxc_spi_resources2), + .resource = mxc_spi_resources2, }; +#endif /* * General Purpose Timer - * - i.MX1: 2 timer (slighly different register handling) - * - i.MX21: 3 timer - * - i.MX27: 6 timer + * - i.MX21: 3 timers + * - i.MX27: 6 timers */ /* We use gpt0 as system timer, so do not add a device for this one */ static struct resource timer1_resources[] = { - [0] = { + { .start = GPT2_BASE_ADDR, .end = GPT2_BASE_ADDR + 0x17, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_GPT2, .end = MXC_INT_GPT2, .flags = IORESOURCE_IRQ, @@ -89,16 +131,15 @@ struct platform_device mxc_gpt1 = { .name = "imx_gpt", .id = 1, .num_resources = ARRAY_SIZE(timer1_resources), - .resource = timer1_resources + .resource = timer1_resources, }; static struct resource timer2_resources[] = { - [0] = { + { .start = GPT3_BASE_ADDR, .end = GPT3_BASE_ADDR + 0x17, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_GPT3, .end = MXC_INT_GPT3, .flags = IORESOURCE_IRQ, @@ -109,17 +150,16 @@ struct platform_device mxc_gpt2 = { .name = "imx_gpt", .id = 2, .num_resources = ARRAY_SIZE(timer2_resources), - .resource = timer2_resources + .resource = timer2_resources, }; #ifdef CONFIG_MACH_MX27 static struct resource timer3_resources[] = { - [0] = { + { .start = GPT4_BASE_ADDR, .end = GPT4_BASE_ADDR + 0x17, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_GPT4, .end = MXC_INT_GPT4, .flags = IORESOURCE_IRQ, @@ -130,16 +170,15 @@ struct platform_device mxc_gpt3 = { .name = "imx_gpt", .id = 3, .num_resources = ARRAY_SIZE(timer3_resources), - .resource = timer3_resources + .resource = timer3_resources, }; static struct resource timer4_resources[] = { - [0] = { + { .start = GPT5_BASE_ADDR, .end = GPT5_BASE_ADDR + 0x17, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_GPT5, .end = MXC_INT_GPT5, .flags = IORESOURCE_IRQ, @@ -150,16 +189,15 @@ struct platform_device mxc_gpt4 = { .name = "imx_gpt", .id = 4, .num_resources = ARRAY_SIZE(timer4_resources), - .resource = timer4_resources + .resource = timer4_resources, }; static struct resource timer5_resources[] = { - [0] = { + { .start = GPT6_BASE_ADDR, .end = GPT6_BASE_ADDR + 0x17, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_GPT6, .end = MXC_INT_GPT6, .flags = IORESOURCE_IRQ, @@ -170,7 +208,7 @@ struct platform_device mxc_gpt5 = { .name = "imx_gpt", .id = 5, .num_resources = ARRAY_SIZE(timer5_resources), - .resource = timer5_resources + .resource = timer5_resources, }; #endif @@ -214,11 +252,11 @@ static struct resource mxc_nand_resources[] = { { .start = NFC_BASE_ADDR, .end = NFC_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_MEM, }, { .start = MXC_INT_NANDFC, .end = MXC_INT_NANDFC, - .flags = IORESOURCE_IRQ + .flags = IORESOURCE_IRQ, }, }; @@ -240,8 +278,7 @@ static struct resource mxc_fb[] = { .start = LCDC_BASE_ADDR, .end = LCDC_BASE_ADDR + 0xFFF, .flags = IORESOURCE_MEM, - }, - { + }, { .start = MXC_INT_LCDC, .end = MXC_INT_LCDC, .flags = IORESOURCE_IRQ, @@ -264,11 +301,11 @@ static struct resource mxc_fec_resources[] = { { .start = FEC_BASE_ADDR, .end = FEC_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_MEM, }, { .start = MXC_INT_FEC, .end = MXC_INT_FEC, - .flags = IORESOURCE_IRQ + .flags = IORESOURCE_IRQ, }, }; @@ -281,15 +318,14 @@ struct platform_device mxc_fec_device = { #endif static struct resource mxc_i2c_1_resources[] = { - [0] = { + { .start = I2C_BASE_ADDR, .end = I2C_BASE_ADDR + 0x0fff, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_I2C, .end = MXC_INT_I2C, - .flags = IORESOURCE_IRQ + .flags = IORESOURCE_IRQ, } }; @@ -297,20 +333,19 @@ struct platform_device mxc_i2c_device0 = { .name = "imx-i2c", .id = 0, .num_resources = ARRAY_SIZE(mxc_i2c_1_resources), - .resource = mxc_i2c_1_resources + .resource = mxc_i2c_1_resources, }; #ifdef CONFIG_MACH_MX27 static struct resource mxc_i2c_2_resources[] = { - [0] = { + { .start = I2C2_BASE_ADDR, .end = I2C2_BASE_ADDR + 0x0fff, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_I2C2, .end = MXC_INT_I2C2, - .flags = IORESOURCE_IRQ + .flags = IORESOURCE_IRQ, } }; @@ -318,17 +353,16 @@ struct platform_device mxc_i2c_device1 = { .name = "imx-i2c", .id = 1, .num_resources = ARRAY_SIZE(mxc_i2c_2_resources), - .resource = mxc_i2c_2_resources + .resource = mxc_i2c_2_resources, }; #endif static struct resource mxc_pwm_resources[] = { - [0] = { + { .start = PWM_BASE_ADDR, .end = PWM_BASE_ADDR + 0x0fff, - .flags = IORESOURCE_MEM - }, - [1] = { + .flags = IORESOURCE_MEM, + }, { .start = MXC_INT_PWM, .end = MXC_INT_PWM, .flags = IORESOURCE_IRQ, @@ -339,28 +373,26 @@ struct platform_device mxc_pwm_device = { .name = "mxc_pwm", .id = 0, .num_resources = ARRAY_SIZE(mxc_pwm_resources), - .resource = mxc_pwm_resources + .resource = mxc_pwm_resources, }; /* * Resource definition for the MXC SDHC */ static struct resource mxc_sdhc1_resources[] = { - [0] = { - .start = SDHC1_BASE_ADDR, - .end = SDHC1_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = MXC_INT_SDHC1, - .end = MXC_INT_SDHC1, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = DMA_REQ_SDHC1, - .end = DMA_REQ_SDHC1, - .flags = IORESOURCE_DMA - }, + { + .start = SDHC1_BASE_ADDR, + .end = SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_SDHC1, + .end = MXC_INT_SDHC1, + .flags = IORESOURCE_IRQ, + }, { + .start = DMA_REQ_SDHC1, + .end = DMA_REQ_SDHC1, + .flags = IORESOURCE_DMA, + }, }; static u64 mxc_sdhc1_dmamask = 0xffffffffUL; @@ -377,21 +409,19 @@ struct platform_device mxc_sdhc_device0 = { }; static struct resource mxc_sdhc2_resources[] = { - [0] = { - .start = SDHC2_BASE_ADDR, - .end = SDHC2_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = MXC_INT_SDHC2, - .end = MXC_INT_SDHC2, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = DMA_REQ_SDHC2, - .end = DMA_REQ_SDHC2, - .flags = IORESOURCE_DMA - }, + { + .start = SDHC2_BASE_ADDR, + .end = SDHC2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_SDHC2, + .end = MXC_INT_SDHC2, + .flags = IORESOURCE_IRQ, + }, { + .start = DMA_REQ_SDHC2, + .end = DMA_REQ_SDHC2, + .flags = IORESOURCE_DMA, + }, }; static u64 mxc_sdhc2_dmamask = 0xffffffffUL; @@ -407,35 +437,123 @@ struct platform_device mxc_sdhc_device1 = { .resource = mxc_sdhc2_resources, }; +#ifdef CONFIG_MACH_MX27 +static struct resource otg_resources[] = { + { + .start = OTG_BASE_ADDR, + .end = OTG_BASE_ADDR + 0x1ff, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_USB3, + .end = MXC_INT_USB3, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 otg_dmamask = 0xffffffffUL; + +/* OTG gadget device */ +struct platform_device mxc_otg_udc_device = { + .name = "fsl-usb2-udc", + .id = -1, + .dev = { + .dma_mask = &otg_dmamask, + .coherent_dma_mask = 0xffffffffUL, + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; + +/* OTG host */ +struct platform_device mxc_otg_host = { + .name = "mxc-ehci", + .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + .dma_mask = &otg_dmamask, + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; + +/* USB host 1 */ + +static u64 usbh1_dmamask = 0xffffffffUL; + +static struct resource mxc_usbh1_resources[] = { + { + .start = OTG_BASE_ADDR + 0x200, + .end = OTG_BASE_ADDR + 0x3ff, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_USB1, + .end = MXC_INT_USB1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_usbh1 = { + .name = "mxc-ehci", + .id = 1, + .dev = { + .coherent_dma_mask = 0xffffffff, + .dma_mask = &usbh1_dmamask, + }, + .resource = mxc_usbh1_resources, + .num_resources = ARRAY_SIZE(mxc_usbh1_resources), +}; + +/* USB host 2 */ +static u64 usbh2_dmamask = 0xffffffffUL; + +static struct resource mxc_usbh2_resources[] = { + { + .start = OTG_BASE_ADDR + 0x400, + .end = OTG_BASE_ADDR + 0x5ff, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_USB2, + .end = MXC_INT_USB2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_usbh2 = { + .name = "mxc-ehci", + .id = 2, + .dev = { + .coherent_dma_mask = 0xffffffff, + .dma_mask = &usbh2_dmamask, + }, + .resource = mxc_usbh2_resources, + .num_resources = ARRAY_SIZE(mxc_usbh2_resources), +}; +#endif + /* GPIO port description */ static struct mxc_gpio_port imx_gpio_ports[] = { - [0] = { + { .chip.label = "gpio-0", .irq = MXC_INT_GPIO, .base = IO_ADDRESS(GPIO_BASE_ADDR), .virtual_irq_start = MXC_GPIO_IRQ_START, - }, - [1] = { + }, { .chip.label = "gpio-1", .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100), .virtual_irq_start = MXC_GPIO_IRQ_START + 32, - }, - [2] = { + }, { .chip.label = "gpio-2", .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200), .virtual_irq_start = MXC_GPIO_IRQ_START + 64, - }, - [3] = { + }, { .chip.label = "gpio-3", .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300), .virtual_irq_start = MXC_GPIO_IRQ_START + 96, - }, - [4] = { + }, { .chip.label = "gpio-4", .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400), .virtual_irq_start = MXC_GPIO_IRQ_START + 128, - }, - [5] = { + }, { .chip.label = "gpio-5", .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500), .virtual_irq_start = MXC_GPIO_IRQ_START + 160, diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h index 049005bb6aa..d315406d672 100644 --- a/arch/arm/mach-mx2/devices.h +++ b/arch/arm/mach-mx2/devices.h @@ -4,7 +4,6 @@ extern struct platform_device mxc_gpt3; extern struct platform_device mxc_gpt4; extern struct platform_device mxc_gpt5; extern struct platform_device mxc_wdt; -extern struct platform_device mxc_irda_device; extern struct platform_device mxc_uart_device0; extern struct platform_device mxc_uart_device1; extern struct platform_device mxc_uart_device2; @@ -20,3 +19,11 @@ extern struct platform_device mxc_i2c_device0; extern struct platform_device mxc_i2c_device1; extern struct platform_device mxc_sdhc_device0; extern struct platform_device mxc_sdhc_device1; +extern struct platform_device mxc_otg_udc_device; +extern struct platform_device mxc_otg_host; +extern struct platform_device mxc_usbh1; +extern struct platform_device mxc_usbh2; +extern struct platform_device mxc_spi_device0; +extern struct platform_device mxc_spi_device1; +extern struct platform_device mxc_spi_device2; + diff --git a/arch/arm/mach-mx2/eukrea_cpuimx27.c b/arch/arm/mach-mx2/eukrea_cpuimx27.c new file mode 100644 index 00000000000..7b187606682 --- /dev/null +++ b/arch/arm/mach-mx2/eukrea_cpuimx27.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2009 Eric Benard - eric@eukrea.com + * + * Based on pcm038.c which is : + * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix + * Copyright (C) 2008 Juergen Beisert (kernel@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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include <linux/i2c.h> +#include <linux/io.h> +#include <linux/mtd/plat-ram.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/mach/map.h> + +#include <mach/board-eukrea_cpuimx27.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/i2c.h> +#include <mach/iomux.h> +#include <mach/imx-uart.h> +#include <mach/mxc_nand.h> + +#include "devices.h" + +static int eukrea_cpuimx27_pins[] = { + /* UART1 */ + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS, + /* UART4 */ + PB26_AF_UART4_RTS, + PB28_AF_UART4_TXD, + PB29_AF_UART4_CTS, + PB31_AF_UART4_RXD, + /* FEC */ + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_RX_CLK, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN, + /* I2C1 */ + PD17_PF_I2C_DATA, + PD18_PF_I2C_CLK, + /* SDHC2 */ + PB4_PF_SD2_D0, + PB5_PF_SD2_D1, + PB6_PF_SD2_D2, + PB7_PF_SD2_D3, + PB8_PF_SD2_CMD, + PB9_PF_SD2_CLK, +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) + /* Quad UART's IRQ */ + GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN, + GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN, + GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN, + GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN, +#endif +}; + +static struct physmap_flash_data eukrea_cpuimx27_flash_data = { + .width = 2, +}; + +static struct resource eukrea_cpuimx27_flash_resource = { + .start = 0xc0000000, + .end = 0xc3ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device eukrea_cpuimx27_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &eukrea_cpuimx27_flash_data, + }, + .num_resources = 1, + .resource = &eukrea_cpuimx27_flash_resource, +}; + +static struct imxuart_platform_data uart_pdata[] = { + { + .flags = IMXUART_HAVE_RTSCTS, + }, { + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = { + .width = 1, + .hw_ecc = 1, +}; + +static struct platform_device *platform_devices[] __initdata = { + &eukrea_cpuimx27_nor_mtd_device, + &mxc_fec_device, +}; + +static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = { + .bitrate = 100000, +}; + +static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = { + { + I2C_BOARD_INFO("pcf8563", 0x51), + }, +}; + +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x200000), + .irq = IRQ_GPIOB(23), + .uartclk = 14745600, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x400000), + .irq = IRQ_GPIOB(22), + .uartclk = 14745600, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x800000), + .irq = IRQ_GPIOB(27), + .uartclk = 14745600, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x1000000), + .irq = IRQ_GPIOB(30), + .uartclk = 14745600, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + } +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; +#endif + +static void __init eukrea_cpuimx27_init(void) +{ + mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins, + ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27"); + + mxc_register_device(&mxc_uart_device0, &uart_pdata[0]); + + mxc_register_device(&mxc_nand_device, &eukrea_cpuimx27_nand_board_info); + + i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices, + ARRAY_SIZE(eukrea_cpuimx27_i2c_devices)); + + mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + +#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2) + /* SDHC2 can be used for Wifi */ + mxc_register_device(&mxc_sdhc_device1, NULL); + /* in which case UART4 is also used for Bluetooth */ + mxc_register_device(&mxc_uart_device3, &uart_pdata[1]); +#endif + +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) + platform_device_register(&serial_device); +#endif + +#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD + eukrea_mbimx27_baseboard_init(); +#endif +} + +static void __init eukrea_cpuimx27_timer_init(void) +{ + mx27_clocks_init(26000000); +} + +static struct sys_timer eukrea_cpuimx27_timer = { + .init = eukrea_cpuimx27_timer_init, +}; + +MACHINE_START(CPUIMX27, "EUKREA CPUIMX27") + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx27_map_io, + .init_irq = mx27_init_irq, + .init_machine = eukrea_cpuimx27_init, + .timer = &eukrea_cpuimx27_timer, +MACHINE_END diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c new file mode 100644 index 00000000000..7382b6d27ee --- /dev/null +++ b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2009 Eric Benard - eric@eukrea.com + * + * Based on pcm970-baseboard.c which is : + * Copyright (C) 2008 Juergen Beisert (kernel@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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include <linux/gpio.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> + +#include <asm/mach/arch.h> + +#include <mach/common.h> +#include <mach/iomux.h> +#include <mach/imxfb.h> +#include <mach/hardware.h> +#include <mach/mmc.h> +#include <mach/imx-uart.h> + +#include "devices.h" + +static int eukrea_mbimx27_pins[] = { + /* UART2 */ + PE3_PF_UART2_CTS, + PE4_PF_UART2_RTS, + PE6_PF_UART2_TXD, + PE7_PF_UART2_RXD, + /* UART3 */ + PE8_PF_UART3_TXD, + PE9_PF_UART3_RXD, + PE10_PF_UART3_CTS, + PE11_PF_UART3_RTS, + /* UART4 */ + PB26_AF_UART4_RTS, + PB28_AF_UART4_TXD, + PB29_AF_UART4_CTS, + PB31_AF_UART4_RXD, + /* SDHC1*/ + PE18_PF_SD1_D0, + PE19_PF_SD1_D1, + PE20_PF_SD1_D2, + PE21_PF_SD1_D3, + PE22_PF_SD1_CMD, + PE23_PF_SD1_CLK, + /* display */ + PA5_PF_LSCLK, + PA6_PF_LD0, + PA7_PF_LD1, + PA8_PF_LD2, + PA9_PF_LD3, + PA10_PF_LD4, + PA11_PF_LD5, + PA12_PF_LD6, + PA13_PF_LD7, + PA14_PF_LD8, + PA15_PF_LD9, + PA16_PF_LD10, + PA17_PF_LD11, + PA18_PF_LD12, + PA19_PF_LD13, + PA20_PF_LD14, + PA21_PF_LD15, + PA22_PF_LD16, + PA23_PF_LD17, + PA28_PF_HSYNC, + PA29_PF_VSYNC, + PA30_PF_CONTRAST, + PA31_PF_OE_ACD, + /* SPI1 */ + PD28_PF_CSPI1_SS0, + PD29_PF_CSPI1_SCLK, + PD30_PF_CSPI1_MISO, + PD31_PF_CSPI1_MOSI, +}; + +static struct gpio_led gpio_leds[] = { + { + .name = "led1", + .default_trigger = "heartbeat", + .active_low = 1, + .gpio = GPIO_PORTF | 16, + }, + { + .name = "led2", + .default_trigger = "none", + .active_low = 1, + .gpio = GPIO_PORTF | 19, + }, + { + .name = "backlight", + .default_trigger = "backlight", + .active_low = 0, + .gpio = GPIO_PORTE | 5, + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +static struct imx_fb_videomode eukrea_mbimx27_modes[] = { + { + .mode = { + .name = "CMO-QGVA", + .refresh = 60, + .xres = 320, + .yres = 240, + .pixclock = 156000, + .hsync_len = 30, + .left_margin = 38, + .right_margin = 20, + .vsync_len = 3, + .upper_margin = 15, + .lower_margin = 4, + }, + .pcr = 0xFAD08B80, + .bpp = 16, + }, +}; + +static struct imx_fb_platform_data eukrea_mbimx27_fb_data = { + .mode = eukrea_mbimx27_modes, + .num_modes = ARRAY_SIZE(eukrea_mbimx27_modes), + + .pwmr = 0x00A903FF, + .lscr1 = 0x00120300, + .dmacr = 0x00040060, +}; + +static struct imxuart_platform_data uart_pdata[] = { + { + .flags = IMXUART_HAVE_RTSCTS, + }, + { + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +#if defined(CONFIG_TOUCHSCREEN_ADS7846) + || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + +#define ADS7846_PENDOWN (GPIO_PORTD | 25) + +static void ads7846_dev_init(void) +{ + if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) { + printk(KERN_ERR "can't get ads746 pen down GPIO\n"); + return; + } + + gpio_direction_input(ADS7846_PENDOWN); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(ADS7846_PENDOWN); +} + +static struct ads7846_platform_data ads7846_config __initdata = { + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, +}; + +static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = { + [0] = { + .modalias = "ads7846", + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 1500000, + .irq = IRQ_GPIOD(25), + .platform_data = &ads7846_config, + .mode = SPI_MODE_2, + }, +}; + +static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28}; + +static struct spi_imx_master eukrea_mbimx27_spi_0_data = { + .chipselect = eukrea_mbimx27_spi_cs, + .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs), +}; +#endif + +static struct platform_device *platform_devices[] __initdata = { + &leds_gpio, +}; + +/* + * system init for baseboard usage. Will be called by cpuimx27 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 eukrea_mbimx27_baseboard_init(void) +{ + mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins, + ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27"); + + mxc_register_device(&mxc_uart_device1, &uart_pdata[0]); + mxc_register_device(&mxc_uart_device2, &uart_pdata[1]); + + mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data); + mxc_register_device(&mxc_sdhc_device0, NULL); + +#if defined(CONFIG_TOUCHSCREEN_ADS7846) + || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + /* SPI and ADS7846 Touchscreen controler init */ + mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); + mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN); + mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data); + spi_register_board_info(eukrea_mbimx27_spi_board_info, + ARRAY_SIZE(eukrea_mbimx27_spi_board_info)); + ads7846_dev_init(); +#endif + + /* Leds configuration */ + mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT); + mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT); + /* Backlight */ + mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c index 169372f69d8..ae8f759134d 100644 --- a/arch/arm/mach-mx2/generic.c +++ b/arch/arm/mach-mx2/generic.c @@ -72,6 +72,7 @@ static struct map_desc mxc_io_desc[] __initdata = { void __init mx21_map_io(void) { mxc_set_cpu_type(MXC_CPU_MX21); + mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR)); iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); } @@ -79,7 +80,18 @@ void __init mx21_map_io(void) void __init mx27_map_io(void) { mxc_set_cpu_type(MXC_CPU_MX27); + mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR)); iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); } +void __init mx27_init_irq(void) +{ + mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR)); +} + +void __init mx21_init_irq(void) +{ + mx27_init_irq(); +} + diff --git a/arch/arm/mach-mx2/mx21ads.c b/arch/arm/mach-mx2/mx21ads.c index a5ee461cb40..cf5f77cbc2f 100644 --- a/arch/arm/mach-mx2/mx21ads.c +++ b/arch/arm/mach-mx2/mx21ads.c @@ -164,25 +164,33 @@ static void mx21ads_fb_exit(struct platform_device *pdev) * Connected is a portrait Sharp-QVGA display * of type: LQ035Q7DB02 */ -static struct imx_fb_platform_data mx21ads_fb_data = { - .pixclock = 188679, /* in ps */ - .xres = 240, - .yres = 320, - - .bpp = 16, - .hsync_len = 2, - .left_margin = 6, - .right_margin = 16, +static struct imx_fb_videomode mx21ads_modes[] = { + { + .mode = { + .name = "Sharp-LQ035Q7", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 188679, /* in ps (5.3MHz) */ + .hsync_len = 2, + .left_margin = 6, + .right_margin = 16, + .vsync_len = 1, + .upper_margin = 8, + .lower_margin = 10, + }, + .pcr = 0xfb108bc7, + .bpp = 16, + }, +}; - .vsync_len = 1, - .upper_margin = 8, - .lower_margin = 10, - .fixed_screen_cpu = 0, +static struct imx_fb_platform_data mx21ads_fb_data = { + .mode = mx21ads_modes, + .num_modes = ARRAY_SIZE(mx21ads_modes), - .pcr = 0xFB108BC7, - .pwmr = 0x00A901ff, - .lscr1 = 0x00120300, - .dmacr = 0x00020008, + .pwmr = 0x00a903ff, + .lscr1 = 0x00120300, + .dmacr = 0x00020008, .init = mx21ads_fb_init, .exit = mx21ads_fb_exit, @@ -280,7 +288,7 @@ MACHINE_START(MX21ADS, "Freescale i.MX21ADS") .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x100, .map_io = mx21ads_map_io, - .init_irq = mxc_init_irq, + .init_irq = mx21_init_irq, .init_machine = mx21ads_board_init, .timer = &mx21ads_timer, MACHINE_END diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c index 02daddac699..83e412b713e 100644 --- a/arch/arm/mach-mx2/mx27ads.c +++ b/arch/arm/mach-mx2/mx27ads.c @@ -183,20 +183,29 @@ void lcd_power(int on) __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); } -static struct imx_fb_platform_data mx27ads_fb_data = { - .pixclock = 188679, - .xres = 240, - .yres = 320, - - .bpp = 16, - .hsync_len = 1, - .left_margin = 9, - .right_margin = 16, +static struct imx_fb_videomode mx27ads_modes[] = { + { + .mode = { + .name = "Sharp-LQ035Q7", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 188679, /* in ps (5.3MHz) */ + .hsync_len = 1, + .left_margin = 9, + .right_margin = 16, + .vsync_len = 1, + .upper_margin = 7, + .lower_margin = 9, + }, + .bpp = 16, + .pcr = 0xFB008BC0, + }, +}; - .vsync_len = 1, - .upper_margin = 7, - .lower_margin = 9, - .fixed_screen_cpu = 0, +static struct imx_fb_platform_data mx27ads_fb_data = { + .mode = mx27ads_modes, + .num_modes = ARRAY_SIZE(mx27ads_modes), /* * - HSYNC active high @@ -207,7 +216,6 @@ static struct imx_fb_platform_data mx27ads_fb_data = { * - data enable low active * - enable sharp mode */ - .pcr = 0xFB008BC0, .pwmr = 0x00A903FF, .lscr1 = 0x00120300, .dmacr = 0x00020010, @@ -330,7 +338,7 @@ MACHINE_START(MX27ADS, "Freescale i.MX27ADS") .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x100, .map_io = mx27ads_map_io, - .init_irq = mxc_init_irq, + .init_irq = mx27_init_irq, .init_machine = mx27ads_board_init, .timer = &mx27ads_timer, MACHINE_END diff --git a/arch/arm/mach-mx2/mx27lite.c b/arch/arm/mach-mx2/mx27lite.c index 3ae11cb8c04..82ea227ea0c 100644 --- a/arch/arm/mach-mx2/mx27lite.c +++ b/arch/arm/mach-mx2/mx27lite.c @@ -89,7 +89,7 @@ MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE") .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x100, .map_io = mx27_map_io, - .init_irq = mxc_init_irq, + .init_irq = mx27_init_irq, .init_machine = mx27lite_init, .timer = &mx27lite_timer, MACHINE_END diff --git a/arch/arm/mach-mx2/mx27pdk.c b/arch/arm/mach-mx2/mx27pdk.c index 1d9238c7a6c..6761d1b79e4 100644 --- a/arch/arm/mach-mx2/mx27pdk.c +++ b/arch/arm/mach-mx2/mx27pdk.c @@ -89,7 +89,7 @@ MACHINE_START(MX27_3DS, "Freescale MX27PDK") .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x100, .map_io = mx27_map_io, - .init_irq = mxc_init_irq, + .init_irq = mx27_init_irq, .init_machine = mx27pdk_init, .timer = &mx27pdk_timer, MACHINE_END diff --git a/arch/arm/mach-mx2/pca100.c b/arch/arm/mach-mx2/pca100.c new file mode 100644 index 00000000000..fe5b165b88c --- /dev/null +++ b/arch/arm/mach-mx2/pca100.c @@ -0,0 +1,244 @@ +/* + * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix + * Copyright (C) 2009 Sascha Hauer (kernel@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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/i2c.h> +#include <linux/i2c/at24.h> +#include <linux/dma-mapping.h> +#include <linux/spi/spi.h> +#include <linux/spi/eeprom.h> +#include <linux/irq.h> +#include <linux/gpio.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/iomux.h> +#include <mach/i2c.h> +#include <asm/mach/time.h> +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) +#include <mach/spi.h> +#endif +#include <mach/imx-uart.h> +#include <mach/mxc_nand.h> +#include <mach/irqs.h> +#include <mach/mmc.h> + +#include "devices.h" + +static int pca100_pins[] = { + /* UART1 */ + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS, + /* SDHC */ + PB4_PF_SD2_D0, + PB5_PF_SD2_D1, + PB6_PF_SD2_D2, + PB7_PF_SD2_D3, + PB8_PF_SD2_CMD, + PB9_PF_SD2_CLK, + /* FEC */ + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_RX_CLK, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN, + /* SSI1 */ + PC20_PF_SSI1_FS, + PC21_PF_SSI1_RXD, + PC22_PF_SSI1_TXD, + PC23_PF_SSI1_CLK, + /* onboard I2C */ + PC5_PF_I2C2_SDA, + PC6_PF_I2C2_SCL, + /* external I2C */ + PD17_PF_I2C_DATA, + PD18_PF_I2C_CLK, + /* SPI1 */ + PD25_PF_CSPI1_RDY, + PD29_PF_CSPI1_SCLK, + PD30_PF_CSPI1_MISO, + PD31_PF_CSPI1_MOSI, +}; + +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static struct mxc_nand_platform_data pca100_nand_board_info = { + .width = 1, + .hw_ecc = 1, +}; + +static struct platform_device *platform_devices[] __initdata = { + &mxc_w1_master_device, + &mxc_fec_device, +}; + +static struct imxi2c_platform_data pca100_i2c_1_data = { + .bitrate = 100000, +}; + +static struct at24_platform_data board_eeprom = { + .byte_len = 4096, + .page_size = 32, + .flags = AT24_FLAG_ADDR16, +}; + +static struct i2c_board_info pca100_i2c_devices[] = { + { + I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ + .platform_data = &board_eeprom, + }, { + I2C_BOARD_INFO("rtc-pcf8563", 0x51), + .type = "pcf8563" + }, { + I2C_BOARD_INFO("lm75", 0x4a), + .type = "lm75" + } +}; + +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) +static struct spi_eeprom at25320 = { + .name = "at25320an", + .byte_len = 4096, + .page_size = 32, + .flags = EE_ADDR2, +}; + +static struct spi_board_info pca100_spi_board_info[] __initdata = { + { + .modalias = "at25", + .max_speed_hz = 30000, + .bus_num = 0, + .chip_select = 1, + .platform_data = &at25320, + }, +}; + +static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27}; + +static struct spi_imx_master pca100_spi_0_data = { + .chipselect = pca100_spi_cs, + .num_chipselect = ARRAY_SIZE(pca100_spi_cs), +}; +#endif + +static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq, + void *data) +{ + int ret; + + ret = request_irq(IRQ_GPIOC(29), detect_irq, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "imx-mmc-detect", data); + if (ret) + printk(KERN_ERR + "pca100: Failed to reuest irq for sd/mmc detection\n"); + + return ret; +} + +static void pca100_sdhc2_exit(struct device *dev, void *data) +{ + free_irq(IRQ_GPIOC(29), data); +} + +static struct imxmmc_platform_data sdhc_pdata = { + .init = pca100_sdhc2_init, + .exit = pca100_sdhc2_exit, +}; + +static void __init pca100_init(void) +{ + int ret; + + ret = mxc_gpio_setup_multiple_pins(pca100_pins, + ARRAY_SIZE(pca100_pins), "PCA100"); + if (ret) + printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret); + + mxc_register_device(&mxc_uart_device0, &uart_pdata); + + mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN); + mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata); + + mxc_register_device(&mxc_nand_device, &pca100_nand_board_info); + + /* only the i2c master 1 is used on this CPU card */ + i2c_register_board_info(1, pca100_i2c_devices, + ARRAY_SIZE(pca100_i2c_devices)); + + mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data); + + mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); + mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT); + + /* GPIO0_IRQ */ + mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN); + /* GPIO1_IRQ */ + mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN); + /* GPIO2_IRQ */ + mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN); + +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) + spi_register_board_info(pca100_spi_board_info, + ARRAY_SIZE(pca100_spi_board_info)); + mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data); +#endif + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +static void __init pca100_timer_init(void) +{ + mx27_clocks_init(26000000); +} + +static struct sys_timer pca100_timer = { + .init = pca100_timer_init, +}; + +MACHINE_START(PCA100, "phyCARD-i.MX27") + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx27_map_io, + .init_irq = mxc_init_irq, + .init_machine = pca100_init, + .timer = &pca100_timer, +MACHINE_END + diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index a4628d00434..ee65dda584c 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -186,17 +186,13 @@ static struct at24_platform_data board_eeprom = { }; static struct i2c_board_info pcm038_i2c_devices[] = { - [0] = { + { I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ .platform_data = &board_eeprom, - }, - [1] = { - I2C_BOARD_INFO("rtc-pcf8563", 0x51), - .type = "pcf8563" - }, - [2] = { + }, { + I2C_BOARD_INFO("pcf8563", 0x51), + }, { I2C_BOARD_INFO("lm75", 0x4a), - .type = "lm75" } }; @@ -220,6 +216,9 @@ static void __init pcm038_init(void) mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data); + /* PE18 for user-LED D40 */ + mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT); + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); #ifdef CONFIG_MACH_PCM970_BASEBOARD @@ -241,7 +240,7 @@ MACHINE_START(PCM038, "phyCORE-i.MX27") .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x100, .map_io = mx27_map_io, - .init_irq = mxc_init_irq, + .init_irq = mx27_init_irq, .init_machine = pcm038_init, .timer = &pcm038_timer, MACHINE_END diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c index 6a3acaf57dd..c261f59b0b4 100644 --- a/arch/arm/mach-mx2/pcm970-baseboard.c +++ b/arch/arm/mach-mx2/pcm970-baseboard.c @@ -19,6 +19,7 @@ #include <linux/gpio.h> #include <linux/irq.h> #include <linux/platform_device.h> +#include <linux/can/platform/sja1000.h> #include <asm/mach/arch.h> @@ -125,40 +126,96 @@ static struct imxmmc_platform_data sdhc_pdata = { .exit = pcm970_sdhc2_exit, }; -/* - * Connected is a portrait Sharp-QVGA display - * of type: LQ035Q7DH06 - */ -static struct imx_fb_platform_data pcm038_fb_data = { - .pixclock = 188679, /* in ps (5.3MHz) */ - .xres = 240, - .yres = 320, - - .bpp = 16, - .hsync_len = 7, - .left_margin = 5, - .right_margin = 16, +static struct imx_fb_videomode pcm970_modes[] = { + { + .mode = { + .name = "Sharp-LQ035Q7", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 188679, /* in ps (5.3MHz) */ + .hsync_len = 7, + .left_margin = 5, + .right_margin = 16, + .vsync_len = 1, + .upper_margin = 7, + .lower_margin = 9, + }, + /* + * - HSYNC active high + * - VSYNC active high + * - clk notenabled while idle + * - clock not inverted + * - data not inverted + * - data enable low active + * - enable sharp mode + */ + .pcr = 0xF00080C0, + .bpp = 16, + }, { + .mode = { + .name = "TX090", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 38255, + .left_margin = 144, + .right_margin = 0, + .upper_margin = 7, + .lower_margin = 40, + .hsync_len = 96, + .vsync_len = 1, + }, + /* + * - HSYNC active low (1 << 22) + * - VSYNC active low (1 << 23) + * - clk notenabled while idle + * - clock not inverted + * - data not inverted + * - data enable low active + * - enable sharp mode + */ + .pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19), + .bpp = 32, + }, +}; - .vsync_len = 1, - .upper_margin = 7, - .lower_margin = 9, - .fixed_screen_cpu = 0, +static struct imx_fb_platform_data pcm038_fb_data = { + .mode = pcm970_modes, + .num_modes = ARRAY_SIZE(pcm970_modes), - /* - * - HSYNC active high - * - VSYNC active high - * - clk notenabled while idle - * - clock not inverted - * - data not inverted - * - data enable low active - * - enable sharp mode - */ - .pcr = 0xFA0080C0, .pwmr = 0x00A903FF, .lscr1 = 0x00120300, .dmacr = 0x00020010, }; +static struct resource pcm970_sja1000_resources[] = { + { + .start = CS4_BASE_ADDR, + .end = CS4_BASE_ADDR + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_GPIOE(19), + .end = IRQ_GPIOE(19), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, +}; + +struct sja1000_platform_data pcm970_sja1000_platform_data = { + .clock = 16000000 / 2, + .ocr = 0x40 | 0x18, + .cdr = 0x40, +}; + +static struct platform_device pcm970_sja1000 = { + .name = "sja1000_platform", + .dev = { + .platform_data = &pcm970_sja1000_platform_data, + }, + .resource = pcm970_sja1000_resources, + .num_resources = ARRAY_SIZE(pcm970_sja1000_resources), +}; + /* * system init for baseboard usage. Will be called by pcm038 init. * @@ -172,4 +229,5 @@ void __init pcm970_baseboard_init(void) mxc_register_device(&mxc_fb_device, &pcm038_fb_data); mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata); + platform_device_register(&pcm970_sja1000); } |