diff options
Diffstat (limited to 'arch/arm/mach-mx3')
-rw-r--r-- | arch/arm/mach-mx3/Kconfig | 11 | ||||
-rw-r--r-- | arch/arm/mach-mx3/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-mx3/armadillo5x0.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-mx3/clock-imx35.c | 46 | ||||
-rw-r--r-- | arch/arm/mach-mx3/clock.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-mx3/cpu.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-mx3/devices.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-mx3/devices.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx3/kzmarm11.c | 268 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31lilly-db.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31lilly.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31lite-db.c | 198 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31lite.c | 175 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard-devboard.c | 86 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard-marxbot.c | 192 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard.c | 249 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx35pdk.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-mx3/pcm043.c | 7 |
18 files changed, 1441 insertions, 44 deletions
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 851f2458bf65..ea8ed109a7c2 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -2,11 +2,13 @@ if ARCH_MX3 config ARCH_MX31 select ARCH_HAS_RNGA + select ARCH_MXC_AUDMUX_V2 bool config ARCH_MX35 bool select ARCH_MXC_IOMUX_V3 + select ARCH_MXC_AUDMUX_V2 comment "MX3 platforms:" @@ -61,6 +63,7 @@ config MACH_MX31_3DS config MACH_MX31MOBOARD bool "Support mx31moboard platforms (EPFL Mobots group)" select ARCH_MX31 + select MXC_ULPI help Include support for mx31moboard platform. This includes specific configurations for the board and its peripherals. @@ -100,4 +103,12 @@ config MACH_MX35_3DS help Include support for MX35PDK platform. This includes specific configurations for the board and its peripherals. + +config MACH_KZM_ARM11_01 + bool "Support KZM-ARM11-01(Kyoto Microcomputer)" + select ARCH_MX31 + help + Include support for KZM-ARM11-01. This includes specific + configurations for the board and its peripherals. + endif diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 6b9775471be6..93c7b296be6a 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,12 +4,12 @@ # Object file lists. -obj-y := mm.o devices.o +obj-y := mm.o devices.o cpu.o obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o obj-$(CONFIG_ARCH_MX35) += clock-imx35.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o -obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o +obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o mx31lite-db.o obj-$(CONFIG_MACH_PCM037) += pcm037.o obj-$(CONFIG_MACH_PCM037_EET) += pcm037_eet.o obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o @@ -19,3 +19,4 @@ obj-$(CONFIG_MACH_QONG) += qong.o obj-$(CONFIG_MACH_PCM043) += pcm043.o obj-$(CONFIG_MACH_ARMADILLO5X0) += armadillo5x0.o obj-$(CONFIG_MACH_MX35_3DS) += mx35pdk.o +obj-$(CONFIG_MACH_KZM_ARM11_01) += kzmarm11.o diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c index 776c0ee1b3cd..54aab401dbdf 100644 --- a/arch/arm/mach-mx3/armadillo5x0.c +++ b/arch/arm/mach-mx3/armadillo5x0.c @@ -33,6 +33,9 @@ #include <linux/irq.h> #include <linux/mtd/physmap.h> #include <linux/io.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> +#include <linux/i2c.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -97,6 +100,47 @@ static int armadillo5x0_pins[] = { MX31_PIN_FPSHIFT__FPSHIFT, MX31_PIN_DRDY0__DRDY0, IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/ + /* I2C2 */ + MX31_PIN_CSPI2_MOSI__SCL, + MX31_PIN_CSPI2_MISO__SDA, +}; + +/* RTC over I2C*/ +#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) + +static struct i2c_board_info armadillo5x0_i2c_rtc = { + I2C_BOARD_INFO("s35390a", 0x30), +}; + +/* GPIO BUTTONS */ +static struct gpio_keys_button armadillo5x0_buttons[] = { + { + .code = KEY_ENTER, /*28*/ + .gpio = IOMUX_TO_GPIO(MX31_PIN_SCLK0), + .active_low = 1, + .desc = "menu", + .wakeup = 1, + }, { + .code = KEY_BACK, /*158*/ + .gpio = IOMUX_TO_GPIO(MX31_PIN_SRST0), + .active_low = 1, + .desc = "back", + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data armadillo5x0_button_data = { + .buttons = armadillo5x0_buttons, + .nbuttons = ARRAY_SIZE(armadillo5x0_buttons), +}; + +static struct platform_device armadillo5x0_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &armadillo5x0_button_data, + } }; /* @@ -278,7 +322,7 @@ static struct resource armadillo5x0_smc911x_resources[] = { }; static struct smsc911x_platform_config smsc911x_info = { - .flags = SMSC911X_USE_32BIT, + .flags = SMSC911X_USE_16BIT, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, }; @@ -300,6 +344,8 @@ static struct imxuart_platform_data uart_pdata = { static struct platform_device *devices[] __initdata = { &armadillo5x0_smc911x_device, + &mxc_i2c_device1, + &armadillo5x0_button_device, }; /* @@ -335,6 +381,18 @@ static void __init armadillo5x0_init(void) /* set NAND page size to 2k if not configured via boot mode pins */ __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR); + + /* RTC */ + /* Get RTC IRQ and register the chip */ + if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) { + if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0) + armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO); + else + gpio_free(ARMADILLO5X0_RTC_GPIO); + } + if (armadillo5x0_i2c_rtc.irq == 0) + pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); + i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); } static void __init armadillo5x0_timer_init(void) diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index c595260ec1f9..7584b4c6c556 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c @@ -335,7 +335,7 @@ static void clk_cgr_disable(struct clk *clk) DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL); DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL); -DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); +/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); */ DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL); DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL); DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL); @@ -381,12 +381,43 @@ DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL); DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); -DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL); +DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL); DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL); DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL); DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); +DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL); + +static int clk_dummy_enable(struct clk *clk) +{ + return 0; +} + +static void clk_dummy_disable(struct clk *clk) +{ +} + +static unsigned long get_rate_nfc(struct clk *clk) +{ + unsigned long div1; + + div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1; + + return get_rate_ahb(NULL) / div1; +} + +/* NAND Controller: It seems it can't be disabled */ +static struct clk nfc_clk = { + .id = 0, + .enable_reg = 0, + .enable_shift = 0, + .get_rate = get_rate_nfc, + .set_rate = NULL, /* set_rate_nfc, */ + .enable = clk_dummy_enable, + .disable = clk_dummy_disable +}; + #define _REGISTER_CLOCK(d, n, c) \ { \ .dev_id = d, \ @@ -397,7 +428,6 @@ DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "asrc", asrc_clk) _REGISTER_CLOCK(NULL, "ata", ata_clk) - _REGISTER_CLOCK(NULL, "audmux", audmux_clk) _REGISTER_CLOCK(NULL, "can", can1_clk) _REGISTER_CLOCK(NULL, "can", can2_clk) _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) @@ -434,8 +464,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "sdma", sdma_clk) _REGISTER_CLOCK(NULL, "spba", spba_clk) _REGISTER_CLOCK(NULL, "spdif", spdif_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) + _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) + _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) @@ -443,12 +473,14 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) + _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk) _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk) _REGISTER_CLOCK(NULL, "max", max_clk) - _REGISTER_CLOCK(NULL, "admux", admux_clk) + _REGISTER_CLOCK(NULL, "audmux", audmux_clk) _REGISTER_CLOCK(NULL, "csi", csi_clk) _REGISTER_CLOCK(NULL, "iim", iim_clk) _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) + _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) }; int __init mx35_clocks_init() @@ -456,7 +488,7 @@ int __init mx35_clocks_init() int i; unsigned int ll = 0; -#ifdef CONFIG_DEBUG_LL_CONSOLE +#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) ll = (3 << 16); #endif diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index b2a3bcf8266e..27a318af0d20 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -558,8 +558,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) + _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) + _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) _REGISTER_CLOCK(NULL, "firi", firi_clk) _REGISTER_CLOCK(NULL, "ata", ata_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) @@ -616,6 +616,8 @@ int __init mx31_clocks_init(unsigned long fref) clk_enable(&serial_pll_clk); + mx31_read_cpu_rev(); + if (mx31_revision() >= CHIP_REV_2_0) { reg = __raw_readl(MXC_CCM_PMCR1); /* No PLL restart on DVFS switch; enable auto EMI handshake */ diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c new file mode 100644 index 000000000000..db828809c675 --- /dev/null +++ b/arch/arm/mach-mx3/cpu.c @@ -0,0 +1,57 @@ +/* + * MX3 CPU type detection + * + * Copyright (c) 2009 Daniel Mack <daniel@caiaq.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. + */ + +#include <linux/module.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/iim.h> + +unsigned int mx31_cpu_rev; +EXPORT_SYMBOL(mx31_cpu_rev); + +struct mx3_cpu_type { + u8 srev; + const char *name; + const char *v; + unsigned int rev; +}; + +static struct mx3_cpu_type mx31_cpu_type[] __initdata = { + { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = CHIP_REV_1_0 }, + { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = CHIP_REV_1_1 }, + { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = CHIP_REV_1_1 }, + { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = CHIP_REV_1_1 }, + { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = CHIP_REV_1_1 }, + { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = CHIP_REV_1_2 }, + { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = CHIP_REV_1_2 }, + { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = CHIP_REV_2_0 }, + { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = CHIP_REV_2_0 }, +}; + +void __init mx31_read_cpu_rev(void) +{ + u32 i, srev; + + /* read SREV register from IIM module */ + srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR) + MXC_IIMSREV); + + for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) + if (srev == mx31_cpu_type[i].srev) { + printk(KERN_INFO + "CPU identified as %s, silicon rev %s\n", + mx31_cpu_type[i].name, mx31_cpu_type[i].v); + + mx31_cpu_rev = mx31_cpu_type[i].rev; + return; + } + + printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev); +} diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index e6abe181b967..6adb586515ea 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -537,6 +537,44 @@ struct platform_device mxc_fec_device = { }; #endif +static struct resource imx_ssi_resources0[] = { + { + .start = SSI1_BASE_ADDR, + .end = SSI1_BASE_ADDR + 0xfff, + .flags = IORESOURCE_MEM, + }, { + .start = MX31_INT_SSI1, + .end = MX31_INT_SSI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource imx_ssi_resources1[] = { + { + .start = SSI2_BASE_ADDR, + .end = SSI2_BASE_ADDR + 0xfff, + .flags = IORESOURCE_MEM + }, { + .start = MX31_INT_SSI2, + .end = MX31_INT_SSI2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device imx_ssi_device0 = { + .name = "imx-ssi", + .id = 0, + .num_resources = ARRAY_SIZE(imx_ssi_resources0), + .resource = imx_ssi_resources0, +}; + +struct platform_device imx_ssi_device1 = { + .name = "imx-ssi", + .id = 1, + .num_resources = ARRAY_SIZE(imx_ssi_resources1), + .resource = imx_ssi_resources1, +}; + static int mx3_devices_init(void) { if (cpu_is_mx31()) { @@ -546,7 +584,7 @@ static int mx3_devices_init(void) } if (cpu_is_mx35()) { mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; - mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff; + mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0x1fff; otg_resources[0].start = MX35_OTG_BASE_ADDR; otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff; otg_resources[1].start = MXC_INT_USBOTG; @@ -555,6 +593,10 @@ static int mx3_devices_init(void) mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff; mxc_usbh1_resources[1].start = MXC_INT_USBHS; mxc_usbh1_resources[1].end = MXC_INT_USBHS; + imx_ssi_resources0[1].start = MX35_INT_SSI1; + imx_ssi_resources0[1].end = MX35_INT_SSI1; + imx_ssi_resources1[1].start = MX35_INT_SSI2; + imx_ssi_resources1[1].end = MX35_INT_SSI2; } return 0; diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index ab87419dc9a0..42cf175eac6b 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h @@ -23,4 +23,6 @@ extern struct platform_device mxc_rnga_device; extern struct platform_device mxc_spi_device0; extern struct platform_device mxc_spi_device1; extern struct platform_device mxc_spi_device2; +extern struct platform_device imx_ssi_device0; +extern struct platform_device imx_ssi_device1; diff --git a/arch/arm/mach-mx3/kzmarm11.c b/arch/arm/mach-mx3/kzmarm11.c new file mode 100644 index 000000000000..6fa99ce3008a --- /dev/null +++ b/arch/arm/mach-mx3/kzmarm11.c @@ -0,0 +1,268 @@ +/* + * KZM-ARM11-01 support + * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.org> + * + * based on code for MX31ADS, + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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 <linux/gpio.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/smsc911x.h> +#include <linux/types.h> + +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/setup.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> +#include <asm/mach/time.h> + +#include <mach/board-kzmarm11.h> +#include <mach/clock.h> +#include <mach/common.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx3.h> +#include <mach/memory.h> + +#include "devices.h" + +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) +/* + * KZM-ARM11-01 has an external UART on FPGA + */ +static struct plat_serial8250_port serial_platform_data[] = { + { + .membase = IO_ADDRESS(KZM_ARM11_16550), + .mapbase = KZM_ARM11_16550, + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), + .irqflags = IRQ_TYPE_EDGE_RISING, + .uartclk = 14745600, + .regshift = 0, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_BUGGY_UART, + }, + {}, +}; + +static struct resource serial8250_resources[] = { + { + .start = KZM_ARM11_16550, + .end = KZM_ARM11_16550 + 0x10, + .flags = IORESOURCE_MEM, + }, + { + .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), + .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_platform_data, + }, + .num_resources = ARRAY_SIZE(serial8250_resources), + .resource = serial8250_resources, +}; + +static int __init kzm_init_ext_uart(void) +{ + u8 tmp; + + /* + * GPIO 1-1: external UART interrupt line + */ + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO)); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); + + /* + * Unmask UART interrupt + */ + tmp = __raw_readb(IO_ADDRESS(KZM_ARM11_CTL1)); + tmp |= 0x2; + __raw_writeb(tmp, IO_ADDRESS(KZM_ARM11_CTL1)); + + return platform_device_register(&serial_device); +} +#else +static inline int kzm_init_ext_uart(void) +{ + return 0; +} +#endif + +/* + * SMSC LAN9118 + */ +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +static struct smsc911x_platform_config kzm_smsc9118_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, +}; + +static struct resource kzm_smsc9118_resources[] = { + { + .start = CS5_BASE_ADDR, + .end = CS5_BASE_ADDR + SZ_128K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), + .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, +}; + +static struct platform_device kzm_smsc9118_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(kzm_smsc9118_resources), + .resource = kzm_smsc9118_resources, + .dev = { + .platform_data = &kzm_smsc9118_config, + }, +}; + +static int __init kzm_init_smsc9118(void) +{ + /* + * GPIO 1-2: SMSC9118 interrupt line + */ + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO)); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); + + return platform_device_register(&kzm_smsc9118_device); +} +#else +static inline int kzm_init_smsc9118(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static void __init kzm_init_imx_uart(void) +{ + mxc_register_device(&mxc_uart_device0, &uart_pdata); + + mxc_register_device(&mxc_uart_device1, &uart_pdata); +} +#else +static inline void kzm_init_imx_uart(void) +{ +} +#endif + +static int kzm_pins[] __initdata = { + MX31_PIN_CTS1__CTS1, + MX31_PIN_RTS1__RTS1, + MX31_PIN_TXD1__TXD1, + MX31_PIN_RXD1__RXD1, + MX31_PIN_DCD_DCE1__DCD_DCE1, + MX31_PIN_RI_DCE1__RI_DCE1, + MX31_PIN_DSR_DCE1__DSR_DCE1, + MX31_PIN_DTR_DCE1__DTR_DCE1, + MX31_PIN_CTS2__CTS2, + MX31_PIN_RTS2__RTS2, + MX31_PIN_TXD2__TXD2, + MX31_PIN_RXD2__RXD2, + MX31_PIN_DCD_DTE1__DCD_DTE2, + MX31_PIN_RI_DTE1__RI_DTE2, + MX31_PIN_DSR_DTE1__DSR_DTE2, + MX31_PIN_DTR_DTE1__DTR_DTE2, +}; + +/* + * Board specific initialization. + */ +static void __init kzm_board_init(void) +{ + mxc_iomux_setup_multiple_pins(kzm_pins, + ARRAY_SIZE(kzm_pins), "kzm"); + kzm_init_ext_uart(); + kzm_init_smsc9118(); + kzm_init_imx_uart(); + + pr_info("Clock input source is 26MHz\n"); +} + +/* + * This structure defines static mappings for the kzm-arm11-01 board. + */ +static struct map_desc kzm_io_desc[] __initdata = { + { + .virtual = CS4_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(CS4_BASE_ADDR), + .length = CS4_SIZE, + .type = MT_DEVICE + }, + { + .virtual = CS5_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(CS5_BASE_ADDR), + .length = CS5_SIZE, + .type = MT_DEVICE + }, +}; + +/* + * Set up static virtual mappings. + */ +static void __init kzm_map_io(void) +{ + mx31_map_io(); + iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc)); +} + +static void __init kzm_timer_init(void) +{ + mx31_clocks_init(26000000); +} + +static struct sys_timer kzm_timer = { + .init = kzm_timer_init, +}; + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_KZM_ARM11_01 data structure. + */ +MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01") + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = kzm_map_io, + .init_irq = mx31_init_irq, + .init_machine = kzm_board_init, + .timer = &kzm_timer, +MACHINE_END diff --git a/arch/arm/mach-mx3/mx31lilly-db.c b/arch/arm/mach-mx3/mx31lilly-db.c index 3b3a78f49c23..7aebd74a12e8 100644 --- a/arch/arm/mach-mx3/mx31lilly-db.c +++ b/arch/arm/mach-mx3/mx31lilly-db.c @@ -109,6 +109,9 @@ static int mxc_mmc1_get_ro(struct device *dev) static int gpio_det, gpio_wp; +#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + static int mxc_mmc1_init(struct device *dev, irq_handler_t detect_irq, void *data) { @@ -117,6 +120,13 @@ static int mxc_mmc1_init(struct device *dev, gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1); gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG); + ret = gpio_request(gpio_det, "MMC detect"); if (ret) return ret; diff --git a/arch/arm/mach-mx3/mx31lilly.c b/arch/arm/mach-mx3/mx31lilly.c index 423025150f6f..9ce029f554b9 100644 --- a/arch/arm/mach-mx3/mx31lilly.c +++ b/arch/arm/mach-mx3/mx31lilly.c @@ -31,6 +31,8 @@ #include <linux/interrupt.h> #include <linux/smsc911x.h> #include <linux/mtd/physmap.h> +#include <linux/spi/spi.h> +#include <linux/mfd/mc13783.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -41,6 +43,7 @@ #include <mach/common.h> #include <mach/iomux-mx3.h> #include <mach/board-mx31lilly.h> +#include <mach/spi.h> #include "devices.h" @@ -108,7 +111,36 @@ static struct platform_device physmap_flash_device = { static struct platform_device *devices[] __initdata = { &smsc91x_device, &physmap_flash_device, - &mxc_i2c_device1, +}; + +/* SPI */ + +static int spi_internal_chipselect[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(1), + MXC_SPI_CS(2), +}; + +static struct spi_imx_master spi0_pdata = { + .chipselect = spi_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), +}; + +static struct spi_imx_master spi1_pdata = { + .chipselect = spi_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), +}; + +static struct mc13783_platform_data mc13783_pdata __initdata = { + .flags = MC13783_USE_RTC | MC13783_USE_TOUCHSCREEN, +}; + +static struct spi_board_info mc13783_dev __initdata = { + .modalias = "mc13783", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 0, + .platform_data = &mc13783_pdata, }; static int mx31lilly_baseboard; @@ -128,8 +160,27 @@ static void __init mx31lilly_board_init(void) } mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__SCL, "I2C SCL"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__SDA, "I2C SDA"); + + /* SPI */ + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2"); + + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1"); + mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2"); + + mxc_register_device(&mxc_spi_device0, &spi0_pdata); + mxc_register_device(&mxc_spi_device1, &spi1_pdata); + spi_register_board_info(&mc13783_dev, 1); platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c new file mode 100644 index 000000000000..694611d6b057 --- /dev/null +++ b/arch/arm/mach-mx3/mx31lite-db.c @@ -0,0 +1,198 @@ +/* + * LogicPD i.MX31 SOM-LV development board support + * + * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> + * + * based on code for other MX31 boards, + * + * Copyright 2005-2007 Freescale Semiconductor + * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> + * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group + * + * 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 <linux/kernel.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/leds.h> +#include <linux/platform_device.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/common.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx3.h> +#include <mach/board-mx31lite.h> +#include <mach/mmc.h> +#include <mach/spi.h> + +#include "devices.h" + +/* + * This file contains board-specific initialization routines for the + * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'. + * If you design an own baseboard for the module, use this file as base + * for support code. + */ + +static unsigned int litekit_db_board_pins[] __initdata = { + /* UART1 */ + MX31_PIN_CTS1__CTS1, + MX31_PIN_RTS1__RTS1, + MX31_PIN_TXD1__TXD1, + MX31_PIN_RXD1__RXD1, + /* SPI 0 */ + MX31_PIN_CSPI1_SCLK__SCLK, + MX31_PIN_CSPI1_MOSI__MOSI, + MX31_PIN_CSPI1_MISO__MISO, + MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI1_SS0__SS0, + MX31_PIN_CSPI1_SS1__SS1, + MX31_PIN_CSPI1_SS2__SS2, +}; + +/* UART */ +static struct imxuart_platform_data uart_pdata __initdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +/* MMC */ + +static int gpio_det, gpio_wp; + +#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + +static int mxc_mmc1_get_ro(struct device *dev) +{ + return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0)); +} + +static int mxc_mmc1_init(struct device *dev, + irq_handler_t detect_irq, void *data) +{ + int ret; + + gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1); + gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6); + + mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG); + + ret = gpio_request(gpio_det, "MMC detect"); + if (ret) + return ret; + + ret = gpio_request(gpio_wp, "MMC w/p"); + if (ret) + goto exit_free_det; + + gpio_direction_input(gpio_det); + gpio_direction_input(gpio_wp); + + ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq, + IRQF_DISABLED | IRQF_TRIGGER_FALLING, + "MMC detect", data); + if (ret) + goto exit_free_wp; + + return 0; + +exit_free_wp: + gpio_free(gpio_wp); + +exit_free_det: + gpio_free(gpio_det); + + return ret; +} + +static void mxc_mmc1_exit(struct device *dev, void *data) +{ + gpio_free(gpio_det); + gpio_free(gpio_wp); + free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data); +} + +static struct imxmmc_platform_data mmc_pdata = { + .get_ro = mxc_mmc1_get_ro, + .init = mxc_mmc1_init, + .exit = mxc_mmc1_exit, +}; + +/* SPI */ + +static int spi_internal_chipselect[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(1), + MXC_SPI_CS(2), +}; + +static struct spi_imx_master spi0_pdata = { + .chipselect = spi_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), +}; + +/* GPIO LEDs */ + +static struct gpio_led litekit_leds[] = { + { + .name = "GPIO0", + .gpio = IOMUX_TO_GPIO(MX31_PIN_COMPARE), + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "GPIO1", + .gpio = IOMUX_TO_GPIO(MX31_PIN_CAPTURE), + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + } +}; + +static struct gpio_led_platform_data litekit_led_platform_data = { + .leds = litekit_leds, + .num_leds = ARRAY_SIZE(litekit_leds), +}; + +static struct platform_device litekit_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &litekit_led_platform_data, + }, +}; + +void __init mx31lite_db_init(void) +{ + mxc_iomux_setup_multiple_pins(litekit_db_board_pins, + ARRAY_SIZE(litekit_db_board_pins), + "development board pins"); + mxc_register_device(&mxc_uart_device0, &uart_pdata); + mxc_register_device(&mxcsdhc_device0, &mmc_pdata); + mxc_register_device(&mxc_spi_device0, &spi0_pdata); + platform_device_register(&litekit_led_device); +} + diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index a8d57decdfdb..def6b6736594 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c @@ -2,6 +2,7 @@ * Copyright (C) 2000 Deep Blue Solutions Ltd * Copyright (C) 2002 Shane Nay (shane@minirl.com) * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2009 Daniel Mack <daniel@caiaq.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 @@ -25,38 +26,47 @@ #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/smsc911x.h> +#include <linux/mfd/mc13783.h> +#include <linux/spi/spi.h> +#include <linux/usb/otg.h> +#include <linux/usb/ulpi.h> +#include <linux/mtd/physmap.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach/map.h> -#include <mach/common.h> #include <asm/page.h> #include <asm/setup.h> + +#include <mach/hardware.h> +#include <mach/common.h> #include <mach/board-mx31lite.h> #include <mach/imx-uart.h> #include <mach/iomux-mx3.h> #include <mach/irqs.h> #include <mach/mxc_nand.h> +#include <mach/spi.h> +#include <mach/mxc_ehci.h> +#include <mach/ulpi.h> + #include "devices.h" /* - * This file contains the board-specific initialization routines. + * This file contains the module-specific initialization routines. */ static unsigned int mx31lite_pins[] = { - /* UART1 */ - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, /* LAN9117 IRQ pin */ IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), -}; - -static struct imxuart_platform_data uart_pdata = { - .flags = IMXUART_HAVE_RTSCTS, + /* SPI 1 */ + MX31_PIN_CSPI2_SCLK__SCLK, + MX31_PIN_CSPI2_MOSI__MOSI, + MX31_PIN_CSPI2_MISO__MISO, + MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI2_SS0__SS0, + MX31_PIN_CSPI2_SS1__SS1, + MX31_PIN_CSPI2_SS2__SS2, }; static struct mxc_nand_platform_data mx31lite_nand_board_info = { @@ -93,6 +103,111 @@ static struct platform_device smsc911x_device = { }; /* + * SPI + * + * The MC13783 is the only hard-wired SPI device on the module. + */ + +static int spi_internal_chipselect[] = { + MXC_SPI_CS(0), +}; + +static struct spi_imx_master spi1_pdata = { + .chipselect = spi_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), +}; + +static struct mc13783_platform_data mc13783_pdata __initdata = { + .flags = MC13783_USE_RTC | + MC13783_USE_REGULATOR, +}; + +static struct spi_board_info mc13783_spi_dev __initdata = { + .modalias = "mc13783", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 0, + .platform_data = &mc13783_pdata, + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), +}; + +/* + * USB + */ + +#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + +static int usbh2_init(struct platform_device *pdev) +{ + int pins[] = { + MX31_PIN_USBH2_DATA0__USBH2_DATA0, + MX31_PIN_USBH2_DATA1__USBH2_DATA1, + MX31_PIN_USBH2_CLK__USBH2_CLK, + MX31_PIN_USBH2_DIR__USBH2_DIR, + MX31_PIN_USBH2_NXT__USBH2_NXT, + MX31_PIN_USBH2_STP__USBH2_STP, + }; + + mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2"); + + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); + + mxc_iomux_set_gpr(MUX_PGP_UH2, true); + + /* chip select */ + mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO), + "USBH2_CS"); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0); + + return 0; +} + +static struct mxc_usbh_platform_data usbh2_pdata = { + .init = usbh2_init, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED, +}; + +/* + * NOR flash + */ + +static struct physmap_flash_data nor_flash_data = { + .width = 2, +}; + +static struct resource nor_flash_resource = { + .start = 0xa0000000, + .end = 0xa1ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device physmap_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &nor_flash_data, + }, + .resource = &nor_flash_resource, + .num_resources = 1, +}; + + + +/* * This structure defines the MX31 memory map. */ static struct map_desc mx31lite_io_desc[] __initdata = { @@ -118,19 +233,40 @@ void __init mx31lite_map_io(void) iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc)); } -/* - * Board specific initialization. - */ +static int mx31lite_baseboard; +core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444); + static void __init mxc_board_init(void) { int ret; + switch (mx31lite_baseboard) { + case MX31LITE_NOBOARD: + break; + case MX31LITE_DB: + mx31lite_db_init(); + break; + default: + printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n", + mx31lite_baseboard); + } + mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins), "mx31lite"); - mxc_register_device(&mxc_uart_device0, &uart_pdata); + /* NOR and NAND flash */ + platform_device_register(&physmap_flash_device); mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info); + mxc_register_device(&mxc_spi_device1, &spi1_pdata); + spi_register_board_info(&mc13783_spi_dev, 1); + + /* USB */ + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_usbh2, &usbh2_pdata); + /* SMSC9117 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); if (ret) @@ -150,12 +286,7 @@ struct sys_timer mx31lite_timer = { .init = mx31lite_timer_init, }; -/* - * The following uses standard kernel macros defined in arch.h in order to - * initialize __mach_desc_MX31LITE data structure. - */ - -MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT") +MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM") /* Maintainer: Freescale Semiconductor, Inc. */ .phys_io = AIPS1_BASE_ADDR, .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index 5592cdb8d0ad..8fc624f141cb 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c @@ -22,11 +22,15 @@ #include <linux/platform_device.h> #include <linux/types.h> +#include <linux/usb/otg.h> + #include <mach/common.h> #include <mach/imx-uart.h> #include <mach/iomux-mx3.h> #include <mach/hardware.h> #include <mach/mmc.h> +#include <mach/mxc_ehci.h> +#include <mach/ulpi.h> #include "devices.h" @@ -39,6 +43,12 @@ static unsigned int devboard_pins[] = { MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, + /* USB H1 */ + MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM, + MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP, + MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB, + MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND, + MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12, }; static struct imxuart_platform_data uart_pdata = { @@ -98,6 +108,80 @@ static struct imxmmc_platform_data sdhc2_pdata = { .exit = devboard_sdhc2_exit, }; +#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + +static int devboard_usbh1_hw_init(struct platform_device *pdev) +{ + mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG); + + return 0; +} + +#define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B) +#define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE) + +static int devboard_isp1105_init(struct otg_transceiver *otg) +{ + int ret = gpio_request(USBH1_MODE, "usbh1-mode"); + if (ret) + return ret; + /* single ended */ + gpio_direction_output(USBH1_MODE, 0); + + ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen"); + if (ret) { + gpio_free(USBH1_MODE); + return ret; + } + gpio_direction_output(USBH1_VBUSEN_B, 1); + + return 0; +} + + +static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on) +{ + if (on) + gpio_set_value(USBH1_VBUSEN_B, 0); + else + gpio_set_value(USBH1_VBUSEN_B, 1); + + return 0; +} + +static struct mxc_usbh_platform_data usbh1_pdata = { + .init = devboard_usbh1_hw_init, + .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, + .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI, +}; + +static int __init devboard_usbh1_init(void) +{ + struct otg_transceiver *otg; + + otg = kzalloc(sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + otg->label = "ISP1105"; + otg->init = devboard_isp1105_init; + otg->set_vbus = devboard_isp1105_set_vbus; + + usbh1_pdata.otg = otg; + + return mxc_register_device(&mx31_usbh1, &usbh1_pdata); +} + /* * system init for baseboard usage. Will be called by mx31moboard init. */ @@ -111,4 +195,6 @@ void __init mx31moboard_devboard_init(void) mxc_register_device(&mxc_uart_device1, &uart_pdata); mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); + + devboard_usbh1_init(); } diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 2bfaffb344f0..85184a35e674 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c @@ -16,17 +16,26 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/delay.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/i2c.h> +#include <linux/spi/spi.h> #include <linux/platform_device.h> #include <linux/types.h> +#include <linux/usb/otg.h> + #include <mach/common.h> #include <mach/hardware.h> #include <mach/imx-uart.h> #include <mach/iomux-mx3.h> #include <mach/mmc.h> +#include <mach/mxc_ehci.h> +#include <mach/ulpi.h> + +#include <media/soc_camera.h> #include "devices.h" @@ -37,7 +46,6 @@ static unsigned int marxbot_pins[] = { MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, /* CSI */ - MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5, MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7, MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9, MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11, @@ -45,10 +53,19 @@ static unsigned int marxbot_pins[] = { MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15, MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK, MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, + MX31_PIN_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5, MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, MX31_PIN_TXD2__GPIO1_28, /* dsPIC resets */ MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22, + /*battery detection */ + MX31_PIN_LCS0__GPIO3_23, + /* USB H1 */ + MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM, + MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP, + MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB, + MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND, + MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12, }; #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) @@ -120,6 +137,166 @@ static void dspics_resets_init(void) } } +static struct spi_board_info marxbot_spi_board_info[] __initdata = { + { + .modalias = "spidev", + .max_speed_hz = 300000, + .bus_num = 1, + .chip_select = 1, /* according spi1_cs[] ! */ + }, +}; + +#define TURRETCAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1) +#define BASECAM_POWER IOMUX_TO_GPIO(MX31_PIN_CSI_D5) +#define TURRETCAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0) +#define BASECAM_RST_B IOMUX_TO_GPIO(MX31_PIN_CSI_D4) +#define CAM_CHOICE IOMUX_TO_GPIO(MX31_PIN_TXD2) + +static int marxbot_basecam_power(struct device *dev, int on) +{ + gpio_set_value(BASECAM_POWER, !on); + return 0; +} + +static int marxbot_basecam_reset(struct device *dev) +{ + gpio_set_value(BASECAM_RST_B, 0); + udelay(100); + gpio_set_value(BASECAM_RST_B, 1); + return 0; +} + +static struct i2c_board_info marxbot_i2c_devices[] = { + { + I2C_BOARD_INFO("mt9t031", 0x5d), + }, +}; + +static struct soc_camera_link base_iclink = { + .bus_id = 0, /* Must match with the camera ID */ + .power = marxbot_basecam_power, + .reset = marxbot_basecam_reset, + .board_info = &marxbot_i2c_devices[0], + .i2c_adapter_id = 0, + .module_name = "mt9t031", +}; + +static struct platform_device marxbot_camera[] = { + { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &base_iclink, + }, + }, +}; + +static struct platform_device *marxbot_cameras[] __initdata = { + &marxbot_camera[0], +}; + +static int __init marxbot_cam_init(void) +{ + int ret = gpio_request(CAM_CHOICE, "cam-choice"); + if (ret) + return ret; + gpio_direction_output(CAM_CHOICE, 1); + + ret = gpio_request(BASECAM_RST_B, "basecam-reset"); + if (ret) + return ret; + gpio_direction_output(BASECAM_RST_B, 1); + ret = gpio_request(BASECAM_POWER, "basecam-standby"); + if (ret) + return ret; + gpio_direction_output(BASECAM_POWER, 0); + + ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset"); + if (ret) + return ret; + gpio_direction_output(TURRETCAM_RST_B, 1); + ret = gpio_request(TURRETCAM_POWER, "turretcam-standby"); + if (ret) + return ret; + gpio_direction_output(TURRETCAM_POWER, 0); + + return 0; +} + +#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + +static int marxbot_usbh1_hw_init(struct platform_device *pdev) +{ + mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG); + + return 0; +} + +#define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B) +#define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE) + +static int marxbot_isp1105_init(struct otg_transceiver *otg) +{ + int ret = gpio_request(USBH1_MODE, "usbh1-mode"); + if (ret) + return ret; + /* single ended */ + gpio_direction_output(USBH1_MODE, 0); + + ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen"); + if (ret) { + gpio_free(USBH1_MODE); + return ret; + } + gpio_direction_output(USBH1_VBUSEN_B, 1); + + return 0; +} + + +static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on) +{ + if (on) + gpio_set_value(USBH1_VBUSEN_B, 0); + else + gpio_set_value(USBH1_VBUSEN_B, 1); + + return 0; +} + +static struct mxc_usbh_platform_data usbh1_pdata = { + .init = marxbot_usbh1_hw_init, + .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, + .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI, +}; + +static int __init marxbot_usbh1_init(void) +{ + struct otg_transceiver *otg; + + otg = kzalloc(sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + otg->label = "ISP1105"; + otg->init = marxbot_isp1105_init; + otg->set_vbus = marxbot_isp1105_set_vbus; + + usbh1_pdata.otg = otg; + + return mxc_register_device(&mx31_usbh1, &usbh1_pdata); +} + /* * system init for baseboard usage. Will be called by mx31moboard init. */ @@ -133,4 +310,17 @@ void __init mx31moboard_marxbot_init(void) dspics_resets_init(); mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); + + spi_register_board_info(marxbot_spi_board_info, + ARRAY_SIZE(marxbot_spi_board_info)); + + marxbot_cam_init(); + platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras)); + + /* battery present pin */ + gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0)); + gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false); + + marxbot_usbh1_init(); } diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index 9243de54041a..b70529145936 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c @@ -17,6 +17,7 @@ */ #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/fsl_devices.h> #include <linux/gpio.h> #include <linux/init.h> @@ -26,8 +27,14 @@ #include <linux/mtd/physmap.h> #include <linux/mtd/partitions.h> #include <linux/platform_device.h> +#include <linux/regulator/machine.h> +#include <linux/mfd/mc13783.h> +#include <linux/spi/spi.h> #include <linux/types.h> +#include <linux/usb/otg.h> +#include <linux/usb/ulpi.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> @@ -37,16 +44,20 @@ #include <mach/hardware.h> #include <mach/imx-uart.h> #include <mach/iomux-mx3.h> +#include <mach/ipu.h> #include <mach/i2c.h> #include <mach/mmc.h> -#include <mach/mx31.h> +#include <mach/mxc_ehci.h> +#include <mach/mx3_camera.h> +#include <mach/spi.h> +#include <mach/ulpi.h> #include "devices.h" static unsigned int moboard_pins[] = { /* UART0 */ - MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1, MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, + MX31_PIN_CTS1__GPIO2_7, /* UART4 */ MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5, MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5, @@ -73,12 +84,31 @@ static unsigned int moboard_pins[] = { MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR, MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP, MX31_PIN_USB_OC__GPIO1_30, + /* USB H2 */ + MX31_PIN_USBH2_DATA0__USBH2_DATA0, + MX31_PIN_USBH2_DATA1__USBH2_DATA1, + MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3, + MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5, + MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7, + MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR, + MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP, + MX31_PIN_SCK6__GPIO1_25, /* LEDs */ MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1, MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3, /* SEL */ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, + /* SPI1 */ + MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO, + MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2, + /* Atlas IRQ */ + MX31_PIN_GPIO1_3__GPIO1_3, + /* SPI2 */ + MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO, + MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI2_SS1__CSPI3_SS1, }; static struct physmap_flash_data mx31moboard_flash_data = { @@ -101,7 +131,18 @@ static struct platform_device mx31moboard_flash = { .num_resources = 1, }; -static struct imxuart_platform_data uart_pdata = { +static int moboard_uart0_init(struct platform_device *pdev) +{ + gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); + return 0; +} + +static struct imxuart_platform_data uart0_pdata = { + .init = moboard_uart0_init, +}; + +static struct imxuart_platform_data uart4_pdata = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -113,6 +154,103 @@ static struct imxi2c_platform_data moboard_i2c1_pdata = { .bitrate = 100000, }; +static int moboard_spi1_cs[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(2), +}; + +static struct spi_imx_master moboard_spi1_master = { + .chipselect = moboard_spi1_cs, + .num_chipselect = ARRAY_SIZE(moboard_spi1_cs), +}; + +static struct regulator_consumer_supply sdhc_consumers[] = { + { + .dev = &mxcsdhc_device0.dev, + .supply = "sdhc0_vcc", + }, + { + .dev = &mxcsdhc_device1.dev, + .supply = "sdhc1_vcc", + }, +}; + +static struct regulator_init_data sdhc_vreg_data = { + .constraints = { + .min_uV = 2700000, + .max_uV = 3000000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_FAST, + .always_on = 0, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(sdhc_consumers), + .consumer_supplies = sdhc_consumers, +}; + +static struct regulator_consumer_supply cam_consumers[] = { + { + .dev = &mx3_camera.dev, + .supply = "cam_vcc", + }, +}; + +static struct regulator_init_data cam_vreg_data = { + .constraints = { + .min_uV = 2700000, + .max_uV = 3000000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, + .valid_modes_mask = REGULATOR_MODE_NORMAL | + REGULATOR_MODE_FAST, + .always_on = 0, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(cam_consumers), + .consumer_supplies = cam_consumers, +}; + +static struct mc13783_regulator_init_data moboard_regulators[] = { + { + .id = MC13783_REGU_VMMC1, + .init_data = &sdhc_vreg_data, + }, + { + .id = MC13783_REGU_VCAM, + .init_data = &cam_vreg_data, + }, +}; + +static struct mc13783_platform_data moboard_pmic = { + .regulators = moboard_regulators, + .num_regulators = ARRAY_SIZE(moboard_regulators), + .flags = MC13783_USE_REGULATOR | MC13783_USE_RTC | + MC13783_USE_ADC, +}; + +static struct spi_board_info moboard_spi_board_info[] __initdata = { + { + .modalias = "mc13783", + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + .max_speed_hz = 300000, + .bus_num = 1, + .chip_select = 0, + .platform_data = &moboard_pmic, + .mode = SPI_CS_HIGH, + }, +}; + +static int moboard_spi2_cs[] = { + MXC_SPI_CS(1), +}; + +static struct spi_imx_master moboard_spi2_master = { + .chipselect = moboard_spi2_cs, + .num_chipselect = ARRAY_SIZE(moboard_spi2_cs), +}; + #define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0) #define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1) @@ -208,6 +346,56 @@ static struct fsl_usb2_platform_data usb_pdata = { .phy_mode = FSL_USB2_PHY_ULPI, }; +#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6) + +static int moboard_usbh2_hw_init(struct platform_device *pdev) +{ + int ret = gpio_request(USBH2_EN_B, "usbh2-en"); + if (ret) + return ret; + + mxc_iomux_set_gpr(MUX_PGP_UH2, true); + + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); + + gpio_direction_output(USBH2_EN_B, 0); + + return 0; +} + +static int moboard_usbh2_hw_exit(struct platform_device *pdev) +{ + gpio_free(USBH2_EN_B); + return 0; +} + +static struct mxc_usbh_platform_data usbh2_pdata = { + .init = moboard_usbh2_hw_init, + .exit = moboard_usbh2_hw_exit, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED, +}; + +static int __init moboard_usbh2_init(void) +{ + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + return mxc_register_device(&mx31_usbh2, &usbh2_pdata); +} + + static struct gpio_led mx31moboard_leds[] = { { .name = "coreboard-led-0:red:running", @@ -266,11 +454,48 @@ static void mx31moboard_init_sel_gpios(void) } } +static struct ipu_platform_data mx3_ipu_data = { + .irq_base = MXC_IPU_IRQ_START, +}; + static struct platform_device *devices[] __initdata = { &mx31moboard_flash, &mx31moboard_leds_device, }; +static struct mx3_camera_pdata camera_pdata = { + .dma_dev = &mx3_ipu.dev, + .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, + .mclk_10khz = 4800, +}; + +#define CAMERA_BUF_SIZE (4*1024*1024) + +static int __init mx31moboard_cam_alloc_dma(const size_t buf_size) +{ + dma_addr_t dma_handle; + void *buf; + int dma; + + if (buf_size < 2 * 1024 * 1024) + return -EINVAL; + + buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL); + if (!buf) { + pr_err("%s: cannot allocate camera buffer-memory\n", __func__); + return -ENOMEM; + } + + memset(buf, 0, buf_size); + + dma = dma_declare_coherent_memory(&mx3_camera.dev, + dma_handle, dma_handle, buf_size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); + + /* The way we call dma_declare_coherent_memory only a malloc can fail */ + return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM; +} + static int mx31moboard_baseboard; core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); @@ -284,20 +509,34 @@ static void __init mxc_board_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); - mxc_register_device(&mxc_uart_device0, &uart_pdata); - mxc_register_device(&mxc_uart_device4, &uart_pdata); + mxc_register_device(&mxc_uart_device0, &uart0_pdata); + + mxc_register_device(&mxc_uart_device4, &uart4_pdata); mx31moboard_init_sel_gpios(); mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata); mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata); + mxc_register_device(&mxc_spi_device1, &moboard_spi1_master); + mxc_register_device(&mxc_spi_device2, &moboard_spi2_master); + + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); + spi_register_board_info(moboard_spi_board_info, + ARRAY_SIZE(moboard_spi_board_info)); + mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata); + mxc_register_device(&mx3_ipu, &mx3_ipu_data); + if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE)) + mxc_register_device(&mx3_camera, &camera_pdata); + usb_xcvr_reset(); moboard_usbotg_init(); mxc_register_device(&mxc_otg_udc_device, &usb_pdata); + moboard_usbh2_init(); switch (mx31moboard_baseboard) { case MX31NOBOARD: diff --git a/arch/arm/mach-mx3/mx35pdk.c b/arch/arm/mach-mx3/mx35pdk.c index 6ff186e46ceb..0bbc65ea23c8 100644 --- a/arch/arm/mach-mx3/mx35pdk.c +++ b/arch/arm/mach-mx3/mx35pdk.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/memory.h> #include <linux/gpio.h> +#include <linux/fsl_devices.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -69,6 +70,15 @@ static struct pad_desc mx35pdk_pads[] = { MX35_PAD_FEC_TDATA2__FEC_TDATA_2, MX35_PAD_FEC_RDATA3__FEC_RDATA_3, MX35_PAD_FEC_TDATA3__FEC_TDATA_3, + /* USBOTG */ + MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, + MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, +}; + +/* OTG config */ +static struct fsl_usb2_platform_data usb_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI_WIDE, }; /* @@ -81,6 +91,8 @@ static void __init mxc_board_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); mxc_register_device(&mxc_uart_device0, &uart_pdata); + + mxc_register_device(&mxc_otg_udc_device, &usb_pdata); } static void __init mx35pdk_timer_init(void) diff --git a/arch/arm/mach-mx3/pcm043.c b/arch/arm/mach-mx3/pcm043.c index e18a224671fa..e3aa829be586 100644 --- a/arch/arm/mach-mx3/pcm043.c +++ b/arch/arm/mach-mx3/pcm043.c @@ -43,6 +43,7 @@ #include <mach/iomux-mx35.h> #include <mach/ipu.h> #include <mach/mx3fb.h> +#include <mach/mxc_nand.h> #include "devices.h" @@ -206,6 +207,11 @@ static struct pad_desc pcm043_pads[] = { MX35_PAD_ATA_CS0__GPIO2_6, }; +static struct mxc_nand_platform_data pcm037_nand_board_info = { + .width = 1, + .hw_ecc = 1, +}; + /* * Board specific initialization. */ @@ -216,6 +222,7 @@ static void __init mxc_board_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); mxc_register_device(&mxc_uart_device0, &uart_pdata); + mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); mxc_register_device(&mxc_uart_device1, &uart_pdata); |