diff options
Diffstat (limited to 'arch/arm/mach-mx5')
-rw-r--r-- | arch/arm/mach-mx5/Kconfig | 27 | ||||
-rw-r--r-- | arch/arm/mach-mx5/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-mx5/board-cpuimx51.c | 293 | ||||
-rw-r--r-- | arch/arm/mach-mx5/board-mx51_3ds.c | 164 | ||||
-rw-r--r-- | arch/arm/mach-mx5/board-mx51_babbage.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-mx5/clock-mx51.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-mx5/devices.c | 83 | ||||
-rw-r--r-- | arch/arm/mach-mx5/devices.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c | 200 | ||||
-rw-r--r-- | arch/arm/mach-mx5/mm.c | 3 |
10 files changed, 819 insertions, 3 deletions
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 1576d51e676..0848db5dd36 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -15,4 +15,31 @@ config MACH_MX51_BABBAGE u-boot. This includes specific configurations for the board and its peripherals. +config MACH_MX51_3DS + bool "Support MX51PDK (3DS)" + select MXC_DEBUG_BOARD + help + Include support for MX51PDK (3DS) platform. This includes specific + configurations for the board and its peripherals. + +config MACH_EUKREA_CPUIMX51 + bool "Support Eukrea CPUIMX51 module" + help + Include support for Eukrea CPUIMX51 platform. This includes + specific configurations for the module and its peripherals. + +choice + prompt "Baseboard" + depends on MACH_EUKREA_CPUIMX51 + default MACH_EUKREA_MBIMX51_BASEBOARD + +config MACH_EUKREA_MBIMX51_BASEBOARD + prompt "Eukrea MBIMX51 development board" + bool + help + This adds board specific devices that can be found on Eukrea's + MBIMX51 evaluation board. + +endchoice + endif diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index bf23f869ef5..86c66e7f52f 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -6,4 +6,6 @@ obj-y := cpu.o mm.o clock-mx51.o devices.o obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o - +obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o +obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o +obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c new file mode 100644 index 00000000000..623607a20f5 --- /dev/null +++ b/arch/arm/mach-mx5/board-cpuimx51.c @@ -0,0 +1,293 @@ +/* + * + * Copyright (C) 2010 Eric Bénard <eric@eukrea.com> + * + * based on board-mx51_babbage.c which is + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/fsl_devices.h> + +#include <mach/eukrea-baseboards.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx51.h> +#include <mach/i2c.h> +#include <mach/mxc_ehci.h> + +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "devices.h" + +#define CPUIMX51_USBH1_STP (0*32 + 27) +#define CPUIMX51_QUARTA_GPIO (2*32 + 28) +#define CPUIMX51_QUARTB_GPIO (2*32 + 25) +#define CPUIMX51_QUARTC_GPIO (2*32 + 26) +#define CPUIMX51_QUARTD_GPIO (2*32 + 27) +#define CPUIMX51_QUARTA_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTA_GPIO) +#define CPUIMX51_QUARTB_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTB_GPIO) +#define CPUIMX51_QUARTC_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTC_GPIO) +#define CPUIMX51_QUARTD_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTD_GPIO) +#define CPUIMX51_QUART_XTAL 14745600 +#define CPUIMX51_QUART_REGSHIFT 17 + +/* USB_CTRL_1 */ +#define MX51_USB_CTRL_1_OFFSET 0x10 +#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25) + +#define MX51_USB_PLLDIV_12_MHZ 0x00 +#define MX51_USB_PLL_DIV_19_2_MHZ 0x01 +#define MX51_USB_PLL_DIV_24_MHZ 0x02 + +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x400000), + .irq = CPUIMX51_QUARTA_IRQ, + .irqflags = IRQF_TRIGGER_HIGH, + .uartclk = CPUIMX51_QUART_XTAL, + .regshift = CPUIMX51_QUART_REGSHIFT, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x800000), + .irq = CPUIMX51_QUARTB_IRQ, + .irqflags = IRQF_TRIGGER_HIGH, + .uartclk = CPUIMX51_QUART_XTAL, + .regshift = CPUIMX51_QUART_REGSHIFT, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x1000000), + .irq = CPUIMX51_QUARTC_IRQ, + .irqflags = IRQF_TRIGGER_HIGH, + .uartclk = CPUIMX51_QUART_XTAL, + .regshift = CPUIMX51_QUART_REGSHIFT, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + }, { + .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x2000000), + .irq = CPUIMX51_QUARTD_IRQ, + .irqflags = IRQF_TRIGGER_HIGH, + .uartclk = CPUIMX51_QUART_XTAL, + .regshift = CPUIMX51_QUART_REGSHIFT, + .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 struct platform_device *devices[] __initdata = { + &mxc_fec_device, +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) + &serial_device, +#endif +}; + +static struct pad_desc eukrea_cpuimx51_pads[] = { + /* UART1 */ + MX51_PAD_UART1_RXD__UART1_RXD, + MX51_PAD_UART1_TXD__UART1_TXD, + MX51_PAD_UART1_RTS__UART1_RTS, + MX51_PAD_UART1_CTS__UART1_CTS, + + /* I2C2 */ + MX51_PAD_GPIO_1_2__I2C2_SCL, + MX51_PAD_GPIO_1_3__I2C2_SDA, + MX51_PAD_NANDF_D10__GPIO_3_30, + + /* QUART IRQ */ + MX51_PAD_NANDF_D15__GPIO_3_25, + MX51_PAD_NANDF_D14__GPIO_3_26, + MX51_PAD_NANDF_D13__GPIO_3_27, + MX51_PAD_NANDF_D12__GPIO_3_28, + + /* USB HOST1 */ + MX51_PAD_USBH1_CLK__USBH1_CLK, + MX51_PAD_USBH1_DIR__USBH1_DIR, + MX51_PAD_USBH1_NXT__USBH1_NXT, + MX51_PAD_USBH1_DATA0__USBH1_DATA0, + MX51_PAD_USBH1_DATA1__USBH1_DATA1, + MX51_PAD_USBH1_DATA2__USBH1_DATA2, + MX51_PAD_USBH1_DATA3__USBH1_DATA3, + MX51_PAD_USBH1_DATA4__USBH1_DATA4, + MX51_PAD_USBH1_DATA5__USBH1_DATA5, + MX51_PAD_USBH1_DATA6__USBH1_DATA6, + MX51_PAD_USBH1_DATA7__USBH1_DATA7, + MX51_PAD_USBH1_STP__USBH1_STP, +}; + +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static struct imxi2c_platform_data eukrea_cpuimx51_i2c_data = { + .bitrate = 100000, +}; + +static struct i2c_board_info eukrea_cpuimx51_i2c_devices[] = { + { + I2C_BOARD_INFO("pcf8563", 0x51), + }, +}; + +/* This function is board specific as the bit mask for the plldiv will also +be different for other Freescale SoCs, thus a common bitmask is not +possible and cannot get place in /plat-mxc/ehci.c.*/ +static int initialize_otg_port(struct platform_device *pdev) +{ + u32 v; + void __iomem *usb_base; + void __iomem *usbother_base; + + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; + + /* Set the PHY clock to 19.2MHz */ + v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET); + v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK; + v |= MX51_USB_PLL_DIV_19_2_MHZ; + __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET); + iounmap(usb_base); + return 0; +} + +static int initialize_usbh1_port(struct platform_device *pdev) +{ + u32 v; + void __iomem *usb_base; + void __iomem *usbother_base; + + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; + + /* The clock for the USBH1 ULPI port will come externally from the PHY. */ + v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET); + __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + MX51_USB_CTRL_1_OFFSET); + iounmap(usb_base); + return 0; +} + +static struct mxc_usbh_platform_data dr_utmi_config = { + .init = initialize_otg_port, + .portsc = MXC_EHCI_UTMI_16BIT, + .flags = MXC_EHCI_INTERNAL_PHY, +}; + +static struct fsl_usb2_platform_data usb_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI_WIDE, +}; + +static struct mxc_usbh_platform_data usbh1_config = { + .init = initialize_usbh1_port, + .portsc = MXC_EHCI_MODE_ULPI, + .flags = (MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_ITC_NO_THRESHOLD), +}; + +static int otg_mode_host; + +static int __init eukrea_cpuimx51_otg_mode(char *options) +{ + if (!strcmp(options, "host")) + otg_mode_host = 1; + else if (!strcmp(options, "device")) + otg_mode_host = 0; + else + pr_info("otg_mode neither \"host\" nor \"device\". " + "Defaulting to device\n"); + return 0; +} +__setup("otg_mode=", eukrea_cpuimx51_otg_mode); + +/* + * Board specific initialization. + */ +static void __init eukrea_cpuimx51_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads, + ARRAY_SIZE(eukrea_cpuimx51_pads)); + + mxc_register_device(&mxc_uart_device0, &uart_pdata); + gpio_request(CPUIMX51_QUARTA_GPIO, "quarta_irq"); + gpio_direction_input(CPUIMX51_QUARTA_GPIO); + gpio_free(CPUIMX51_QUARTA_GPIO); + gpio_request(CPUIMX51_QUARTB_GPIO, "quartb_irq"); + gpio_direction_input(CPUIMX51_QUARTB_GPIO); + gpio_free(CPUIMX51_QUARTB_GPIO); + gpio_request(CPUIMX51_QUARTC_GPIO, "quartc_irq"); + gpio_direction_input(CPUIMX51_QUARTC_GPIO); + gpio_free(CPUIMX51_QUARTC_GPIO); + gpio_request(CPUIMX51_QUARTD_GPIO, "quartd_irq"); + gpio_direction_input(CPUIMX51_QUARTD_GPIO); + gpio_free(CPUIMX51_QUARTD_GPIO); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + mxc_register_device(&mxc_i2c_device1, &eukrea_cpuimx51_i2c_data); + i2c_register_board_info(1, eukrea_cpuimx51_i2c_devices, + ARRAY_SIZE(eukrea_cpuimx51_i2c_devices)); + + if (otg_mode_host) + mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + else { + initialize_otg_port(NULL); + mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata); + } + mxc_register_device(&mxc_usbh1_device, &usbh1_config); + +#ifdef CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD + eukrea_mbimx51_baseboard_init(); +#endif +} + +static void __init eukrea_cpuimx51_timer_init(void) +{ + mx51_clocks_init(32768, 24000000, 22579200, 0); +} + +static struct sys_timer mxc_timer = { + .init = eukrea_cpuimx51_timer_init, +}; + +MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module") + /* Maintainer: Eric Bénard <eric@eukrea.com> */ + .phys_io = MX51_AIPS1_BASE_ADDR, + .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx51_map_io, + .init_irq = mx51_init_irq, + .init_machine = eukrea_cpuimx51_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c new file mode 100644 index 00000000000..f95c2fd9466 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx51_3ds.c @@ -0,0 +1,164 @@ +/* + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/input/matrix_keypad.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include <mach/hardware.h> +#include <mach/common.h> +#include <mach/iomux-mx51.h> +#include <mach/imx-uart.h> +#include <mach/3ds_debugboard.h> + +#include "devices.h" + +#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6) + +static struct pad_desc mx51_3ds_pads[] = { + /* UART1 */ + MX51_PAD_UART1_RXD__UART1_RXD, + MX51_PAD_UART1_TXD__UART1_TXD, + MX51_PAD_UART1_RTS__UART1_RTS, + MX51_PAD_UART1_CTS__UART1_CTS, + + /* UART2 */ + MX51_PAD_UART2_RXD__UART2_RXD, + MX51_PAD_UART2_TXD__UART2_TXD, + MX51_PAD_EIM_D25__UART2_CTS, + MX51_PAD_EIM_D26__UART2_RTS, + + /* UART3 */ + MX51_PAD_UART3_RXD__UART3_RXD, + MX51_PAD_UART3_TXD__UART3_TXD, + MX51_PAD_EIM_D24__UART3_CTS, + MX51_PAD_EIM_D27__UART3_RTS, + + /* CPLD PARENT IRQ PIN */ + MX51_PAD_GPIO_1_6__GPIO_1_6, + + /* KPP */ + MX51_PAD_KEY_ROW0__KEY_ROW0, + MX51_PAD_KEY_ROW1__KEY_ROW1, + MX51_PAD_KEY_ROW2__KEY_ROW2, + MX51_PAD_KEY_ROW3__KEY_ROW3, + MX51_PAD_KEY_COL0__KEY_COL0, + MX51_PAD_KEY_COL1__KEY_COL1, + MX51_PAD_KEY_COL2__KEY_COL2, + MX51_PAD_KEY_COL3__KEY_COL3, + MX51_PAD_KEY_COL4__KEY_COL4, + MX51_PAD_KEY_COL5__KEY_COL5, +}; + +/* Serial ports */ +#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static inline void mxc_init_imx_uart(void) +{ + mxc_register_device(&mxc_uart_device0, &uart_pdata); + mxc_register_device(&mxc_uart_device1, &uart_pdata); + mxc_register_device(&mxc_uart_device2, &uart_pdata); +} +#else /* !SERIAL_IMX */ +static inline void mxc_init_imx_uart(void) +{ +} +#endif /* SERIAL_IMX */ + +#if defined(CONFIG_KEYBOARD_IMX) || defined(CONFIG_KEYBOARD_IMX_MODULE) +static int mx51_3ds_board_keymap[] = { + KEY(0, 0, KEY_1), + KEY(0, 1, KEY_2), + KEY(0, 2, KEY_3), + KEY(0, 3, KEY_F1), + KEY(0, 4, KEY_UP), + KEY(0, 5, KEY_F2), + + KEY(1, 0, KEY_4), + KEY(1, 1, KEY_5), + KEY(1, 2, KEY_6), + KEY(1, 3, KEY_LEFT), + KEY(1, 4, KEY_SELECT), + KEY(1, 5, KEY_RIGHT), + + KEY(2, 0, KEY_7), + KEY(2, 1, KEY_8), + KEY(2, 2, KEY_9), + KEY(2, 3, KEY_F3), + KEY(2, 4, KEY_DOWN), + KEY(2, 5, KEY_F4), + + KEY(3, 0, KEY_0), + KEY(3, 1, KEY_OK), + KEY(3, 2, KEY_ESC), + KEY(3, 3, KEY_ENTER), + KEY(3, 4, KEY_MENU), + KEY(3, 5, KEY_BACK) +}; + +static struct matrix_keymap_data mx51_3ds_map_data = { + .keymap = mx51_3ds_board_keymap, + .keymap_size = ARRAY_SIZE(mx51_3ds_board_keymap), +}; + +static void mxc_init_keypad(void) +{ + mxc_register_device(&mxc_keypad_device, &mx51_3ds_map_data); +} +#else +static inline void mxc_init_keypad(void) +{ +} +#endif + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads, + ARRAY_SIZE(mx51_3ds_pads)); + mxc_init_imx_uart(); + + if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT)) + printk(KERN_WARNING "Init of the debugboard failed, all " + "devices on the board are unusable.\n"); + + mxc_init_keypad(); +} + +static void __init mx51_3ds_timer_init(void) +{ + mx51_clocks_init(32768, 24000000, 22579200, 0); +} + +static struct sys_timer mxc_timer = { + .init = mx51_3ds_timer_init, +}; + +MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board") + /* Maintainer: Freescale Semiconductor, Inc. */ + .phys_io = MX51_AIPS1_BASE_ADDR, + .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx51_map_io, + .init_irq = mx51_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index ed885f9d7b7..6e384d92e62 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/i2c.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/io.h> @@ -21,6 +22,7 @@ #include <mach/hardware.h> #include <mach/imx-uart.h> #include <mach/iomux-mx51.h> +#include <mach/i2c.h> #include <mach/mxc_ehci.h> #include <asm/irq.h> @@ -64,6 +66,18 @@ static struct pad_desc mx51babbage_pads[] = { MX51_PAD_EIM_D27__UART3_RTS, MX51_PAD_EIM_D24__UART3_CTS, + /* I2C1 */ + MX51_PAD_EIM_D16__I2C1_SDA, + MX51_PAD_EIM_D19__I2C1_SCL, + + /* I2C2 */ + MX51_PAD_KEY_COL4__I2C2_SCL, + MX51_PAD_KEY_COL5__I2C2_SDA, + + /* HSI2C */ + MX51_PAD_I2C1_CLK__HSI2C_CLK, + MX51_PAD_I2C1_DAT__HSI2C_DAT, + /* USB HOST1 */ MX51_PAD_USBH1_CLK__USBH1_CLK, MX51_PAD_USBH1_DIR__USBH1_DIR, @@ -78,7 +92,7 @@ static struct pad_desc mx51babbage_pads[] = { MX51_PAD_USBH1_DATA7__USBH1_DATA7, /* USB HUB reset line*/ - MX51_PAD_GPIO_1_7__GPIO1_7, + MX51_PAD_GPIO_1_7__GPIO_1_7, }; /* Serial ports */ @@ -99,6 +113,14 @@ static inline void mxc_init_imx_uart(void) } #endif /* SERIAL_IMX */ +static struct imxi2c_platform_data babbage_i2c_data = { + .bitrate = 100000, +}; + +static struct imxi2c_platform_data babbage_hsi2c_data = { + .bitrate = 400000, +}; + static int gpio_usbh1_active(void) { struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27; @@ -230,6 +252,10 @@ static void __init mxc_board_init(void) mxc_init_imx_uart(); platform_add_devices(devices, ARRAY_SIZE(devices)); + mxc_register_device(&mxc_i2c_device0, &babbage_i2c_data); + mxc_register_device(&mxc_i2c_device1, &babbage_i2c_data); + mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data); + if (otg_mode_host) mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); else { diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index d9f612d3370..6af69def357 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -758,6 +758,10 @@ static struct clk gpt_32k_clk = { .parent = &ckil_clk, }; +static struct clk kpp_clk = { + .id = 0, +}; + #define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \ static struct clk name = { \ .id = i, \ @@ -798,6 +802,14 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); +/* I2C */ +DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, + NULL, NULL, &ipg_clk, NULL); + /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -815,12 +827,16 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) + _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) + _REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk) }; static void clk_tree_init(void) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 7130449aacd..1920ff4963b 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -93,6 +93,64 @@ struct platform_device mxc_fec_device = { .resource = mxc_fec_resources, }; +static struct resource mxc_i2c0_resources[] = { + { + .start = MX51_I2C1_BASE_ADDR, + .end = MX51_I2C1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MX51_MXC_INT_I2C1, + .end = MX51_MXC_INT_I2C1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_i2c_device0 = { + .name = "imx-i2c", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_i2c0_resources), + .resource = mxc_i2c0_resources, +}; + +static struct resource mxc_i2c1_resources[] = { + { + .start = MX51_I2C2_BASE_ADDR, + .end = MX51_I2C2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MX51_MXC_INT_I2C2, + .end = MX51_MXC_INT_I2C2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_i2c_device1 = { + .name = "imx-i2c", + .id = 1, + .num_resources = ARRAY_SIZE(mxc_i2c1_resources), + .resource = mxc_i2c1_resources, +}; + +static struct resource mxc_hsi2c_resources[] = { + { + .start = MX51_HSI2C_DMA_BASE_ADDR, + .end = MX51_HSI2C_DMA_BASE_ADDR + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MX51_MXC_INT_HS_I2C, + .end = MX51_MXC_INT_HS_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_hsi2c_device = { + .name = "imx-i2c", + .id = 2, + .num_resources = ARRAY_SIZE(mxc_hsi2c_resources), + .resource = mxc_hsi2c_resources +}; + static u64 usb_dma_mask = DMA_BIT_MASK(32); static struct resource usbotg_resources[] = { @@ -168,34 +226,57 @@ struct platform_device mxc_wdt = { .resource = mxc_wdt_resources, }; +static struct resource mxc_kpp_resources[] = { + { + .start = MX51_MXC_INT_KPP, + .end = MX51_MXC_INT_KPP, + .flags = IORESOURCE_IRQ, + } , { + .start = MX51_KPP_BASE_ADDR, + .end = MX51_KPP_BASE_ADDR + 0x8 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device mxc_keypad_device = { + .name = "imx-keypad", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_kpp_resources), + .resource = mxc_kpp_resources, +}; + static struct mxc_gpio_port mxc_gpio_ports[] = { { .chip.label = "gpio-0", .base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR), .irq = MX51_MXC_INT_GPIO1_LOW, + .irq_high = MX51_MXC_INT_GPIO1_HIGH, .virtual_irq_start = MXC_GPIO_IRQ_START }, { .chip.label = "gpio-1", .base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR), .irq = MX51_MXC_INT_GPIO2_LOW, + .irq_high = MX51_MXC_INT_GPIO2_HIGH, .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1 }, { .chip.label = "gpio-2", .base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR), .irq = MX51_MXC_INT_GPIO3_LOW, + .irq_high = MX51_MXC_INT_GPIO3_HIGH, .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2 }, { .chip.label = "gpio-3", .base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR), .irq = MX51_MXC_INT_GPIO4_LOW, + .irq_high = MX51_MXC_INT_GPIO4_HIGH, .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3 }, }; -int __init mxc_register_gpios(void) +int __init imx51_register_gpios(void) { return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports)); } diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index c879ae71cd5..e509cfaad1d 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -6,3 +6,7 @@ extern struct platform_device mxc_usbdr_host_device; extern struct platform_device mxc_usbh1_device; extern struct platform_device mxc_usbdr_udc_device; extern struct platform_device mxc_wdt; +extern struct platform_device mxc_i2c_device0; +extern struct platform_device mxc_i2c_device1; +extern struct platform_device mxc_hsi2c_device; +extern struct platform_device mxc_keypad_device; diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c new file mode 100644 index 00000000000..ffa93d1d6ef --- /dev/null +++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c @@ -0,0 +1,200 @@ +/* + * + * Copyright (C) 2010 Eric Bénard <eric@eukrea.com> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/fsl_devices.h> +#include <linux/i2c/tsc2007.h> +#include <linux/leds.h> +#include <linux/input/matrix_keypad.h> + +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx51.h> + +#include <asm/mach/arch.h> + +#include "devices.h" + +#define MBIMX51_TSC2007_GPIO (2*32 + 30) +#define MBIMX51_TSC2007_IRQ (MXC_INTERNAL_IRQS + MBIMX51_TSC2007_GPIO) +#define MBIMX51_LED0 (2*32 + 5) +#define MBIMX51_LED1 (2*32 + 6) +#define MBIMX51_LED2 (2*32 + 7) +#define MBIMX51_LED3 (2*32 + 8) + +static struct gpio_led mbimx51_leds[] = { + { + .name = "led0", + .default_trigger = "heartbeat", + .active_low = 1, + .gpio = MBIMX51_LED0, + }, + { + .name = "led1", + .default_trigger = "nand-disk", + .active_low = 1, + .gpio = MBIMX51_LED1, + }, + { + .name = "led2", + .default_trigger = "mmc0", + .active_low = 1, + .gpio = MBIMX51_LED2, + }, + { + .name = "led3", + .default_trigger = "default-on", + .active_low = 1, + .gpio = MBIMX51_LED3, + }, +}; + +static struct gpio_led_platform_data mbimx51_leds_info = { + .leds = mbimx51_leds, + .num_leds = ARRAY_SIZE(mbimx51_leds), +}; + +static struct platform_device mbimx51_leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &mbimx51_leds_info, + }, +}; + +static struct platform_device *devices[] __initdata = { + &mbimx51_leds_gpio, +}; + +static struct pad_desc mbimx51_pads[] = { + /* UART2 */ + MX51_PAD_UART2_RXD__UART2_RXD, + MX51_PAD_UART2_TXD__UART2_TXD, + + /* UART3 */ + MX51_PAD_UART3_RXD__UART3_RXD, + MX51_PAD_UART3_TXD__UART3_TXD, + MX51_PAD_KEY_COL4__UART3_RTS, + MX51_PAD_KEY_COL5__UART3_CTS, + + /* TSC2007 IRQ */ + MX51_PAD_NANDF_D10__GPIO_3_30, + + /* LEDS */ + MX51_PAD_DISPB2_SER_DIN__GPIO_3_5, + MX51_PAD_DISPB2_SER_DIO__GPIO_3_6, + MX51_PAD_DISPB2_SER_CLK__GPIO_3_7, + MX51_PAD_DISPB2_SER_RS__GPIO_3_8, + + /* KPP */ + MX51_PAD_KEY_ROW0__KEY_ROW0, + MX51_PAD_KEY_ROW1__KEY_ROW1, + MX51_PAD_KEY_ROW2__KEY_ROW2, + MX51_PAD_KEY_ROW3__KEY_ROW3, + MX51_PAD_KEY_COL0__KEY_COL0, + MX51_PAD_KEY_COL1__KEY_COL1, + MX51_PAD_KEY_COL2__KEY_COL2, + MX51_PAD_KEY_COL3__KEY_COL3, +}; + +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static int mbimx51_keymap[] = { + KEY(0, 0, KEY_1), + KEY(0, 1, KEY_2), + KEY(0, 2, KEY_3), + KEY(0, 3, KEY_UP), + + KEY(1, 0, KEY_4), + KEY(1, 1, KEY_5), + KEY(1, 2, KEY_6), + KEY(1, 3, KEY_LEFT), + + KEY(2, 0, KEY_7), + KEY(2, 1, KEY_8), + KEY(2, 2, KEY_9), + KEY(2, 3, KEY_RIGHT), + + KEY(3, 0, KEY_0), + KEY(3, 1, KEY_DOWN), + KEY(3, 2, KEY_ESC), + KEY(3, 3, KEY_ENTER), +}; + +static struct matrix_keymap_data mbimx51_map_data = { + .keymap = mbimx51_keymap, + .keymap_size = ARRAY_SIZE(mbimx51_keymap), +}; + +static int tsc2007_get_pendown_state(void) +{ + return !gpio_get_value(MBIMX51_TSC2007_GPIO); +} + +struct tsc2007_platform_data tsc2007_data = { + .model = 2007, + .x_plate_ohms = 180, + .get_pendown_state = tsc2007_get_pendown_state, +}; + +static struct i2c_board_info mbimx51_i2c_devices[] = { + { + I2C_BOARD_INFO("tsc2007", 0x48), + .irq = MBIMX51_TSC2007_IRQ, + .platform_data = &tsc2007_data, + }, +}; + +/* + * baseboard initialization. + */ +void __init eukrea_mbimx51_baseboard_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mbimx51_pads, + ARRAY_SIZE(mbimx51_pads)); + + mxc_register_device(&mxc_uart_device1, NULL); + mxc_register_device(&mxc_uart_device2, &uart_pdata); + + gpio_request(MBIMX51_LED0, "LED0"); + gpio_direction_output(MBIMX51_LED0, 1); + gpio_free(MBIMX51_LED0); + gpio_request(MBIMX51_LED1, "LED1"); + gpio_direction_output(MBIMX51_LED1, 1); + gpio_free(MBIMX51_LED1); + gpio_request(MBIMX51_LED2, "LED2"); + gpio_direction_output(MBIMX51_LED2, 1); + gpio_free(MBIMX51_LED2); + gpio_request(MBIMX51_LED3, "LED3"); + gpio_direction_output(MBIMX51_LED3, 1); + gpio_free(MBIMX51_LED3); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + mxc_register_device(&mxc_keypad_device, &mbimx51_map_data); + + gpio_request(MBIMX51_TSC2007_GPIO, "tsc2007_irq"); + gpio_direction_input(MBIMX51_TSC2007_GPIO); + set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING); + i2c_register_board_info(1, mbimx51_i2c_devices, + ARRAY_SIZE(mbimx51_i2c_devices)); +} diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index b7677ef80cc..bc3f30db8d9 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -65,6 +65,8 @@ void __init mx51_map_io(void) iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); } +int imx51_register_gpios(void); + void __init mx51_init_irq(void) { unsigned long tzic_addr; @@ -80,4 +82,5 @@ void __init mx51_init_irq(void) panic("unable to map TZIC interrupt controller\n"); tzic_init_irq(tzic_virt); + imx51_register_gpios(); } |