meta-freescale-3rdparty/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0001-Linux-3.0.35-Add-wandboard-dual-support.patch
John Weber b057708fab linux (3.0.35): Add support for Wandboard-Dual
Signed-off-by: John Weber <rjohnweber@gmail.com>
2013-02-27 09:35:06 -03:00

1217 lines
40 KiB
Diff

From 73031b2da070693a3a75a3ec3e0f45c0e610bee4 Mon Sep 17 00:00:00 2001
From: John Weber <rjohnweber@gmail.com>
Date: Tue, 26 Feb 2013 15:00:48 -0600
Subject: [PATCH] Linux (3.0.35): Add wandboard-dual support
Upstream-Status: Pending
Signed-off-by: John Weber <rjohnweber@gmail.com>
---
arch/arm/mach-mx6/Kconfig | 41 ++
arch/arm/mach-mx6/Makefile | 2 +
arch/arm/mach-mx6/baseboard-wand.c | 137 +++++
arch/arm/mach-mx6/board-wand.c | 972 ++++++++++++++++++++++++++++++++++++
arch/arm/tools/mach-types | 1 +
5 files changed, 1153 insertions(+)
create mode 100644 arch/arm/mach-mx6/baseboard-wand.c
create mode 100644 arch/arm/mach-mx6/board-wand.c
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 2ffd90d..e49c56f 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -251,6 +251,47 @@ config MACH_MX6Q_SABREAUTO
Include support for i.MX 6Quad SABRE Auto platform. This includes specific
configurations for the board and its peripherals.
+config MACH_WANDBOARD
+ bool "Support for the WandBoard"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_DMA if IMX_SDMA
+ select IMX_HAVE_PLATFORM_IMX_UART if SERIAL_IMX
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX if MMC_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C if I2C_IMX
+ select IMX_HAVE_PLATFORM_IMX_ASRC if SND_IMX_SOC
+ select ARCH_MXC_AUDMUX_V2 if SND_IMX_SOC
+ select IMX_HAVE_PLATFORM_IMX_SSI if MXC_SSI
+ select IMX_HAVE_PLATFORM_IMX_ESAI if MXC_SSI
+ select IMX_HAVE_PLATFORM_IMX_SPDIF if SND_SOC_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_FEC if NETDEVICES
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC if USB
+ select IMX_HAVE_PLATFORM_MXC_EHCI if USB
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP if USB
+ select IMX_HAVE_PLATFORM_FSL_OTG if USB_OTG
+ select IMX_HAVE_PLATFORM_MXC_HDMI if FB_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_IPUV3 if MXC_IPU_V3
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL if ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_IMX_PM if PM
+ select IMX_HAVE_PLATFORM_IMX_DVFS if CPU_FREQ_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX if SPI
+ select IMX_HAVE_PLATFORM_VIV_GPU if MXC_GPU_VIV
+ select IMX_HAVE_PLATFORM_IMX_VPU if MXC_VPU
+ select IMX_HAVE_PLATFORM_IMX_MIPI_DSI if VIDEO_MXC_IPU_OUTPUT
+ help
+ Include support for the WandBoard SoM.
+
+
+config WANDBOARD_BASE
+ tristate "Support for Wand baseboard"
+ depends on MACH_WANDBOARD
+ default y
+ help
+ Include support for the devices on the default wand baseboard.
+
+ If you have a standard Wandboard, say Y.
+
+
comment "MX6 Options:"
config IMX_PCIE
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
index 5cac9bc..3f43098 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o
obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o
obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze100.o
obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o
+obj-$(CONFIG_MACH_WANDBOARD) += board-wand.o
+obj-$(CONFIG_WANDBOARD_BASE) += baseboard-wand.o
obj-$(CONFIG_SMP) += plat_hotplug.o platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
obj-$(CONFIG_IMX_PCIE) += pcie.o
diff --git a/arch/arm/mach-mx6/baseboard-wand.c b/arch/arm/mach-mx6/baseboard-wand.c
new file mode 100644
index 0000000..e9e9378
--- /dev/null
+++ b/arch/arm/mach-mx6/baseboard-wand.c
@@ -0,0 +1,137 @@
+
+#include <asm/mach/arch.h>
+
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+
+#include <mach/common.h>
+#include <mach/devices-common.h>
+
+
+/****************************************************************************
+ *
+ * SGTL5000 Audio Codec
+ *
+ ****************************************************************************/
+
+static struct regulator_consumer_supply wandbase_sgtl5000_consumer_vdda = {
+ .supply = "VDDA",
+ .dev_name = "0-000a", /* Modified load time */
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct regulator_consumer_supply wandbase_sgtl5000_consumer_vddio = {
+ .supply = "VDDIO",
+ .dev_name = "0-000a", /* Modified load time */
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct regulator_init_data wandbase_sgtl5000_vdda_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wandbase_sgtl5000_consumer_vdda,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct regulator_init_data wandbase_sgtl5000_vddio_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wandbase_sgtl5000_consumer_vddio,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct fixed_voltage_config wandbase_sgtl5000_vdda_reg_config = {
+ .supply_name = "VDDA",
+ .microvolts = 2500000,
+ .gpio = -1,
+ .init_data = &wandbase_sgtl5000_vdda_reg_initdata,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct fixed_voltage_config wandbase_sgtl5000_vddio_reg_config = {
+ .supply_name = "VDDIO",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &wandbase_sgtl5000_vddio_reg_initdata,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct platform_device wandbase_sgtl5000_vdda_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wandbase_sgtl5000_vdda_reg_config,
+ },
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct platform_device wandbase_sgtl5000_vddio_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wandbase_sgtl5000_vddio_reg_config,
+ },
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct platform_device wandbase_audio_device = {
+ .name = "imx-sgtl5000",
+};
+
+/* ------------------------------------------------------------------------ */
+
+static const struct i2c_board_info wandbase_sgtl5000_i2c_data __initdata = {
+ I2C_BOARD_INFO("sgtl5000", 0x0a)
+};
+
+/* ------------------------------------------------------------------------ */
+
+static char wandbase_sgtl5000_dev_name[8] = "0-000a";
+
+extern struct mxc_audio_platform_data wand_audio_channel_data;
+
+static __init int wandbase_init_sgtl5000(void) {
+ int i2c_bus = 1; /* TODO: get this from the module. */
+
+ wandbase_sgtl5000_dev_name[0] = '0' + i2c_bus;
+ wandbase_sgtl5000_consumer_vdda.dev_name = wandbase_sgtl5000_dev_name;
+ wandbase_sgtl5000_consumer_vddio.dev_name = wandbase_sgtl5000_dev_name;
+
+ wandbase_audio_device.dev.platform_data = &wand_audio_channel_data;
+ platform_device_register(&wandbase_audio_device);
+
+ i2c_register_board_info(i2c_bus, &wandbase_sgtl5000_i2c_data, 1);
+ platform_device_register(&wandbase_sgtl5000_vdda_reg_devices);
+ platform_device_register(&wandbase_sgtl5000_vddio_reg_devices);
+ return 0;
+}
+
+
+/****************************************************************************
+ *
+ * main-function for wand baseboard
+ *
+ ****************************************************************************/
+
+static __init int wandbase_init(void) {
+ return wandbase_init_sgtl5000();
+}
+subsys_initcall(wandbase_init);
+
+static __exit void wandbase_exit(void) {
+ /* Actually, this cannot be unloaded. Or loaded as a module..? */
+}
+module_exit(wandbase_exit);
+
+MODULE_DESCRIPTION("Wand baseboard driver");
+MODULE_AUTHOR("Tapani <tapani@vmail.me>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx6/board-wand.c b/arch/arm/mach-mx6/board-wand.c
new file mode 100644
index 0000000..7f972eb
--- /dev/null
+++ b/arch/arm/mach-mx6/board-wand.c
@@ -0,0 +1,972 @@
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fec.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/phy.h>
+
+#include <mach/common.h>
+//#include <mach/devices-common.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx6dl.h>
+#include <mach/iomux-v3.h>
+#include <mach/mx6.h>
+
+#include "crm_regs.h"
+#include "devices-imx6q.h"
+#include "usb.h"
+//#include "cpu_op-mx6.h"
+
+#define WAND_BT_ON IMX_GPIO_NR(3, 13)
+#define WAND_BT_WAKE IMX_GPIO_NR(3, 14)
+#define WAND_BT_HOST_WAKE IMX_GPIO_NR(3, 15)
+
+#define WAND_RGMII_INT IMX_GPIO_NR(1, 28)
+#define WAND_RGMII_RST IMX_GPIO_NR(3, 29)
+
+#define WAND_SD1_CD IMX_GPIO_NR(1, 2)
+#define WAND_SD3_CD IMX_GPIO_NR(3, 9)
+#define WAND_SD3_WP IMX_GPIO_NR(1, 10)
+
+#define WAND_USB_OTG_OC IMX_GPIO_NR(1, 9)
+#define WAND_USB_OTG_PWR IMX_GPIO_NR(3, 22)
+#define WAND_USB_H1_OC IMX_GPIO_NR(3, 30)
+
+#define WAND_WL_REF_ON IMX_GPIO_NR(2, 29)
+#define WAND_WL_RST_N IMX_GPIO_NR(5, 2)
+#define WAND_WL_REG_ON IMX_GPIO_NR(1, 26)
+#define WAND_WL_HOST_WAKE IMX_GPIO_NR(1, 29)
+#define WAND_WL_WAKE IMX_GPIO_NR(1, 30)
+
+/* Syntactic sugar for pad configuration */
+#define WAND_SETUP_PADS(p) \
+ mxc_iomux_v3_setup_multiple_pads((p), ARRAY_SIZE(p))
+
+/* See arch/arm/plat-mxc/include/mach/iomux-mx6dl.h for definitions */
+
+/****************************************************************************
+ *
+ * DMA controller init
+ *
+ ****************************************************************************/
+
+static __init void wand_init_dma(void) {
+ imx6q_add_dma();
+}
+
+
+/****************************************************************************
+ *
+ * SD init
+ *
+ * SD1 is routed to EDM connector (external SD on wand baseboard)
+ * SD2 is WiFi
+ * SD3 is boot SD on the module
+ *
+ ****************************************************************************/
+
+/* For some reason, iomux_mx6dl.h does not define multiple speeds for
+ SD1 and SD2, so these don't have any speed switching. */
+static iomux_v3_cfg_t mx6dl_sd1_pads[] = {
+ MX6DL_PAD_SD1_CLK__USDHC1_CLK_50MHZ_40OHM,
+ MX6DL_PAD_SD1_CMD__USDHC1_CMD_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ_40OHM,
+};
+
+static iomux_v3_cfg_t mx6dl_sd2_pads[] = {
+ MX6DL_PAD_SD2_CLK__USDHC2_CLK,
+ MX6DL_PAD_SD2_CMD__USDHC2_CMD,
+ MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
+};
+
+
+#define MX6DL_USDHC_PAD_SETTING(id, speed) \
+mx6dl_sd##id##_##speed##mhz[] = { \
+ MX6DL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+}
+
+/* 50,100, and 200 MHz are supported for SD3 in iomux_mx6dl.h */
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 200);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 0:
+ sd_pads_50mhz = mx6dl_sd1_pads;
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd1_pads);
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz, sd_pads_50mhz_cnt);
+ break;
+ case 1:
+ sd_pads_50mhz = mx6dl_sd2_pads;
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd2_pads);
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz, sd_pads_50mhz_cnt);
+ break;
+ case 2:
+ sd_pads_200mhz = mx6dl_sd3_200mhz;
+ sd_pads_100mhz = mx6dl_sd3_100mhz;
+ sd_pads_50mhz = mx6dl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
+ break;
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+static const struct esdhc_platform_data wand_sd_data[3] = {
+ {
+ .cd_gpio = WAND_SD1_CD,
+ .wp_gpio =-EINVAL,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 0,
+ .platform_pad_change = plt_sd_pad_change,
+ }, {
+ .cd_gpio =-EINVAL,
+ .wp_gpio =-EINVAL,
+ .keep_power_at_suspend = 1,
+ .platform_pad_change = plt_sd_pad_change,
+ }, {
+ .cd_gpio = WAND_SD3_CD,
+ .wp_gpio = WAND_SD3_WP,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 0,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+ }
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_init_sd(void) {
+ //int i;
+ /* Card Detect for SD1 & SD3, respectively */
+ mxc_iomux_v3_setup_pad(MX6DL_PAD_GPIO_2__GPIO_1_2);
+ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA9__GPIO_3_9);
+
+ /* Add mmc devices in reverse order, so mmc0 always is boot sd (SD3) */
+/* for (i=2; i>=0; i--) {
+ WAND_SETUP_PADS(wand_sd_pads[i][0]);
+ imx6q_add_sdhci_usdhc_imx(i, &wand_sd_data[i]);
+ } */
+
+ /* SD3 is first, speed is set to lowest to start */
+ WAND_SETUP_PADS(mx6dl_sd3_50mhz);
+ imx6q_add_sdhci_usdhc_imx(2, &wand_sd_data[2]);
+
+ WAND_SETUP_PADS(mx6dl_sd2_pads);
+ imx6q_add_sdhci_usdhc_imx(1, &wand_sd_data[1]);
+
+ WAND_SETUP_PADS(mx6dl_sd1_pads);
+ imx6q_add_sdhci_usdhc_imx(0, &wand_sd_data[0]);
+}
+
+
+/****************************************************************************
+ *
+ * I2C
+ *
+ ****************************************************************************/
+
+static iomux_v3_cfg_t wand_i2c_pads[3][2] __initdata = {
+ {
+ MX6DL_PAD_EIM_D21__I2C1_SCL,
+ MX6DL_PAD_EIM_D28__I2C1_SDA,
+ }, {
+ MX6DL_PAD_KEY_COL3__I2C2_SCL,
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA,
+ }, {
+ MX6DL_PAD_GPIO_5__I2C3_SCL,
+ MX6DL_PAD_GPIO_16__I2C3_SDA
+ }
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct imxi2c_platform_data wand_i2c_data[] = {
+ { .bitrate = 100000, },
+ { .bitrate = 400000, },
+ { .bitrate = 400000, },
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void __init wand_init_i2c(void) {
+ int i;
+ for (i=0; i<3; i++) {
+ WAND_SETUP_PADS(wand_i2c_pads[i]);
+ imx6q_add_imx_i2c(i, &wand_i2c_data[i]);
+ }
+}
+
+
+/****************************************************************************
+ *
+ * Initialize debug console (UART1)
+ *
+ ****************************************************************************/
+
+static __initdata iomux_v3_cfg_t wand_uart_pads[] = {
+ /* UART1 (debug console) */
+ MX6DL_PAD_CSI0_DAT10__UART1_TXD,
+ MX6DL_PAD_CSI0_DAT11__UART1_RXD,
+ MX6DL_PAD_EIM_D19__UART1_CTS,
+ MX6DL_PAD_EIM_D20__UART1_RTS,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_uart(void) {
+ WAND_SETUP_PADS(wand_uart_pads);
+
+ imx6q_add_imx_uart(0, NULL);
+}
+
+
+/****************************************************************************
+ *
+ * Initialize sound (SSI, ASRC, AUD3 channel and S/PDIF)
+ *
+ ****************************************************************************/
+
+static iomux_v3_cfg_t wand_audio_pads[] = {
+ MX6DL_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6DL_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6DL_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6DL_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+};
+
+/* ------------------------------------------------------------------------ */
+
+extern struct mxc_audio_platform_data wand_audio_channel_data;
+
+/* This function is called as a callback from the audio channel data struct */
+static int wand_audio_clock_enable(void) {
+ struct clk *clko;
+ struct clk *new_parent;
+ int rate;
+
+ clko = clk_get(NULL, "clko_clk");
+ if (IS_ERR(clko)) return PTR_ERR(clko);
+
+ new_parent = clk_get(NULL, "ahb");
+ if (!IS_ERR(new_parent)) {
+ clk_set_parent(clko, new_parent);
+ clk_put(new_parent);
+ }
+
+ rate = clk_round_rate(clko, 16000000);
+ if (rate < 8000000 || rate > 27000000) {
+ pr_err("SGTL5000: mclk freq %d out of range!\n", rate);
+ clk_put(clko);
+ return -1;
+ }
+
+ wand_audio_channel_data.sysclk = rate;
+ clk_set_rate(clko, rate);
+ clk_enable(clko);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* This struct is added by the baseboard when initializing the codec */
+struct mxc_audio_platform_data wand_audio_channel_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3, /* audio channel: 3=AUD3. TODO: EDM */
+ .init = wand_audio_clock_enable,
+ .hp_gpio = -1,
+};
+EXPORT_SYMBOL_GPL(wand_audio_channel_data); /* TODO: edm naming? */
+
+/* ------------------------------------------------------------------------ */
+
+static int wand_set_spdif_clk_rate(struct clk *clk, unsigned long rate) {
+ unsigned long rate_actual;
+ rate_actual = clk_round_rate(clk, rate);
+ clk_set_rate(clk, rate_actual);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct mxc_spdif_platform_data wand_spdif = {
+ .spdif_tx = 1, /* enable tx */
+ .spdif_rx = 1, /* enable rx */
+ .spdif_clk_44100 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_clk_48000 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_div_44100 = 23,
+ .spdif_div_48000 = 37,
+ .spdif_div_32000 = 37,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk_set_rate = wand_set_spdif_clk_rate,
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct imx_ssi_platform_data wand_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct imx_asrc_platform_data wand_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
+/* ------------------------------------------------------------------------ */
+
+void __init wand_init_audio(void) {
+ WAND_SETUP_PADS(wand_audio_pads);
+
+ /* Sample rate converter is added together with audio */
+ wand_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ wand_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&wand_asrc_data);
+
+ imx6q_add_imx_ssi(1, &wand_ssi_pdata);
+ /* Enable SPDIF */
+
+ mxc_iomux_v3_setup_pad(MX6DL_PAD_ENET_RXD0__SPDIF_OUT1);
+
+ wand_spdif.spdif_core_clk = clk_get_sys("mxc_spdif.0", NULL);
+ clk_put(wand_spdif.spdif_core_clk);
+ imx6q_add_spdif(&wand_spdif);
+ imx6q_add_spdif_dai();
+ imx6q_add_spdif_audio_device();
+}
+
+
+/*****************************************************************************
+ *
+ * Init FEC and AR8031 PHY
+ *
+ *****************************************************************************/
+
+static iomux_v3_cfg_t wand_fec_pads[] = {
+ MX6DL_PAD_ENET_MDIO__ENET_MDIO,
+ MX6DL_PAD_ENET_MDC__ENET_MDC,
+ MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+ MX6DL_PAD_ENET_TX_EN__GPIO_1_28,
+ MX6DL_PAD_EIM_D29__GPIO_3_29,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int wand_fec_phy_init(struct phy_device *phydev) {
+ unsigned short val;
+
+ /* Enable AR8031 125MHz clk */
+ phy_write(phydev, 0x0d, 0x0007); /* Set device address to 7*/
+ phy_write(phydev, 0x00, 0x8000); /* Apply by soft reset */
+ udelay(500);
+
+ phy_write(phydev, 0x0e, 0x8016); /* set mmd reg */
+ phy_write(phydev, 0x0d, 0x4007); /* apply */
+
+ val = phy_read(phydev, 0xe);
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(phydev, 0xe, val);
+ phy_write(phydev, 0x0d, 0x4007); /* Post data */
+
+ /* Introduce random tx clock delay. Why is this needed? */
+ phy_write(phydev, 0x1d, 0x5);
+ val = phy_read(phydev, 0x1e);
+ val |= 0x0100;
+ phy_write(phydev, 0x1e, val);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int wand_fec_power_hibernate(struct phy_device *phydev) { return 0; }
+
+/* ------------------------------------------------------------------------ */
+
+static struct fec_platform_data wand_fec_data __initdata = {
+ .init = wand_fec_phy_init,
+ .power_hibernate = wand_fec_power_hibernate,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_ethernet(void) {
+ WAND_SETUP_PADS(wand_fec_pads);
+
+ gpio_request(WAND_RGMII_RST, "rgmii reset");
+ gpio_direction_output(WAND_RGMII_RST, 0);
+#ifdef CONFIG_FEC_1588
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+ msleep(10);
+ gpio_set_value(WAND_RGMII_RST, 1);
+ imx6_init_fec(wand_fec_data);
+}
+
+
+/****************************************************************************
+ *
+ * USB
+ *
+ ****************************************************************************/
+
+static __initdata iomux_v3_cfg_t wand_usb_pads[] = {
+ MX6DL_PAD_GPIO_9__GPIO_1_9,
+ MX6DL_PAD_GPIO_1__USBOTG_ID,
+ MX6DL_PAD_EIM_D22__GPIO_3_22,
+ MX6DL_PAD_EIM_D30__GPIO_3_30
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_usbotg_vbus(bool on) {
+ gpio_set_value_cansleep(WAND_USB_OTG_PWR, !on);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_usb(void) {
+ WAND_SETUP_PADS(wand_usb_pads);
+
+ gpio_request(WAND_USB_OTG_OC, "otg oc");
+ gpio_direction_input(WAND_USB_OTG_OC);
+
+ gpio_request(WAND_USB_OTG_PWR, "otg pwr");
+ gpio_direction_output(WAND_USB_OTG_PWR, 0);
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+ mxc_iomux_set_gpr_register(1, 13, 1, 1);
+
+ mx6_set_otghost_vbus_func(wand_usbotg_vbus);
+
+ gpio_request(WAND_USB_H1_OC, "usbh1 oc");
+ gpio_direction_input(WAND_USB_H1_OC);
+}
+
+
+/****************************************************************************
+ *
+ * IPU
+ *
+ ****************************************************************************/
+
+static struct imx_ipuv3_platform_data wand_ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
+ },
+};
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_ipu(void) {
+ imx6q_add_ipuv3(0, &wand_ipu_data[0]);
+}
+
+
+/****************************************************************************
+ *
+ * HDMI
+ *
+ ****************************************************************************/
+
+static struct ipuv3_fb_platform_data wand_hdmi_fb[] = {
+ { /* hdmi framebuffer */
+ .disp_dev = "hdmi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB32,
+ .mode_str = "1920x1080@60",
+ .default_bpp = 32,
+ .int_clk = false,
+ }
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_hdmi_init(int ipu_id, int disp_id) {
+ if ((unsigned)ipu_id > 1) ipu_id = 0;
+ if ((unsigned)disp_id > 1) disp_id = 0;
+
+ mxc_iomux_set_gpr_register(3, 2, 2, 2*ipu_id + disp_id);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct fsl_mxc_hdmi_platform_data wand_hdmi_data = {
+ .init = wand_hdmi_init,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct fsl_mxc_hdmi_core_platform_data wand_hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 1,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static const struct i2c_board_info wand_hdmi_i2c_info = {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_init_hdmi(void) {
+ i2c_register_board_info(0, &wand_hdmi_i2c_info, 1);
+ imx6q_add_mxc_hdmi_core(&wand_hdmi_core_data);
+ imx6q_add_mxc_hdmi(&wand_hdmi_data);
+ imx6q_add_ipuv3fb(0, wand_hdmi_fb);
+
+ /* Enable HDMI audio */
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
+}
+
+
+/****************************************************************************
+ *
+ * WiFi
+ *
+ ****************************************************************************/
+
+static __initdata iomux_v3_cfg_t wand_wifi_pads[] = {
+ /* ref_on, enable 32k clock */
+ MX6DL_PAD_EIM_EB1__GPIO_2_29,
+ /* Wifi reset (resets when low!) */
+ MX6DL_PAD_EIM_A25__GPIO_5_2,
+ /* reg on, signal to FDC6331L */
+ MX6DL_PAD_ENET_RXD1__GPIO_1_26,
+ /* host wake */
+ MX6DL_PAD_ENET_TXD1__GPIO_1_29,
+ /* wl wake - nc */
+ MX6DL_PAD_ENET_TXD0__GPIO_1_30,
+};
+
+/* ------------------------------------------------------------------------ */
+
+/* assumes SD/MMC pins are set; call after wand_init_sd() */
+static __init void wand_init_wifi(void) {
+ WAND_SETUP_PADS(wand_wifi_pads);
+
+ gpio_request(WAND_WL_RST_N, "wl_rst_n");
+ gpio_direction_output(WAND_WL_RST_N, 0);
+ msleep(11);
+ gpio_set_value(WAND_WL_RST_N, 1);
+
+ gpio_request(WAND_WL_REF_ON, "wl_ref_on");
+ gpio_direction_output(WAND_WL_REF_ON, 1);
+
+ gpio_request(WAND_WL_REG_ON, "wl_reg_on");
+ gpio_direction_output(WAND_WL_REG_ON, 1);
+
+ gpio_request(WAND_WL_WAKE, "wl_wake");
+ gpio_direction_output(WAND_WL_WAKE, 1);
+
+ gpio_request(WAND_WL_HOST_WAKE, "wl_host_wake");
+ gpio_direction_input(WAND_WL_HOST_WAKE);
+}
+
+
+/****************************************************************************
+ *
+ * Bluetooth
+ *
+ ****************************************************************************/
+
+static __initdata iomux_v3_cfg_t wand_bt_pads[] = {
+ /* BT_ON, BT_WAKE and BT_HOST_WAKE */
+ MX6DL_PAD_EIM_DA13__GPIO_3_13,
+ MX6DL_PAD_EIM_DA14__GPIO_3_14,
+ MX6DL_PAD_EIM_DA15__GPIO_3_15,
+
+ /* AUD5 channel goes to BT */
+ MX6DL_PAD_KEY_COL0__AUDMUX_AUD5_TXC,
+ MX6DL_PAD_KEY_ROW0__AUDMUX_AUD5_TXD,
+ MX6DL_PAD_KEY_COL1__AUDMUX_AUD5_TXFS,
+ MX6DL_PAD_KEY_ROW1__AUDMUX_AUD5_RXD,
+
+ /* Bluetooth is on UART3*/
+ MX6DL_PAD_EIM_D23__UART3_CTS,
+ MX6DL_PAD_EIM_D24__UART3_TXD,
+ MX6DL_PAD_EIM_D25__UART3_RXD,
+ MX6DL_PAD_EIM_EB3__UART3_RTS,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static const struct imxuart_platform_data wand_bt_uart_data = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_SDMA,
+ .dma_req_tx = MX6Q_DMA_REQ_UART3_TX,
+ .dma_req_rx = MX6Q_DMA_REQ_UART3_RX,
+};
+
+/* ------------------------------------------------------------------------ */
+
+/* This assumes wifi is initialized (chip has power) */
+static __init void wand_init_bluetooth(void) {
+ WAND_SETUP_PADS(wand_bt_pads);
+
+ imx6q_add_imx_uart(2, &wand_bt_uart_data);
+
+ gpio_request(WAND_BT_ON, "bt_on");
+ gpio_direction_output(WAND_BT_ON, 0);
+ msleep(11);
+ gpio_set_value(WAND_BT_ON, 1);
+
+ gpio_request(WAND_BT_WAKE, "bt_wake");
+ gpio_direction_output(WAND_BT_WAKE, 1);
+
+ gpio_request(WAND_BT_HOST_WAKE, "bt_host_wake");
+ gpio_direction_input(WAND_BT_WAKE);
+}
+
+
+/****************************************************************************
+ *
+ * Power and thermal management
+ *
+ ****************************************************************************/
+
+extern bool enable_wait_mode;
+
+static const struct anatop_thermal_platform_data wand_thermal = {
+ .name = "anatop_thermal",
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_suspend_enter(void) {
+ gpio_set_value(WAND_WL_WAKE, 0);
+ gpio_set_value(WAND_BT_WAKE, 0);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_suspend_exit(void) {
+ gpio_set_value(WAND_WL_WAKE, 1);
+ gpio_set_value(WAND_BT_WAKE, 1);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static const struct pm_platform_data wand_pm_data = {
+ .name = "imx_pm",
+ .suspend_enter = wand_suspend_enter,
+ .suspend_exit = wand_suspend_exit,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static const struct mxc_dvfs_platform_data wand_dvfscore_data = {
+ .reg_id = "cpu_vddgp",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_pm(void) {
+ enable_wait_mode = false;
+ imx6q_add_anatop_thermal_imx(1, &wand_thermal);
+ imx6q_add_pm_imx(0, &wand_pm_data);
+ imx6q_add_dvfs_core(&wand_dvfscore_data);
+ imx6q_add_busfreq();
+}
+
+
+/****************************************************************************
+ *
+ * Expansion pin header GPIOs
+ *
+ ****************************************************************************/
+
+static __initdata iomux_v3_cfg_t wand_external_gpio_pads[] = {
+ MX6DL_PAD_EIM_DA11__GPIO_3_11,
+ MX6DL_PAD_EIM_D27__GPIO_3_27,
+ MX6DL_PAD_EIM_BCLK__GPIO_6_31,
+ MX6DL_PAD_ENET_RX_ER__GPIO_1_24,
+ MX6DL_PAD_SD3_RST__GPIO_7_8,
+ MX6DL_PAD_EIM_D26__GPIO_3_26,
+ MX6DL_PAD_EIM_DA8__GPIO_3_8,
+ MX6DL_PAD_GPIO_19__GPIO_4_5,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_external_gpios(void) {
+ WAND_SETUP_PADS(wand_external_gpio_pads);
+
+ gpio_request(IMX_GPIO_NR(3, 11), "external_gpio_0");
+ gpio_export(IMX_GPIO_NR(3, 11), true);
+ gpio_request(IMX_GPIO_NR(3, 27), "external_gpio_1");
+ gpio_export(IMX_GPIO_NR(3, 27), true);
+ gpio_request(IMX_GPIO_NR(6, 31), "external_gpio_2");
+ gpio_export(IMX_GPIO_NR(6, 31), true);
+ gpio_request(IMX_GPIO_NR(1, 24), "external_gpio_3");
+ gpio_export(IMX_GPIO_NR(1, 24), true);
+ gpio_request(IMX_GPIO_NR(7, 8), "external_gpio_4");
+ gpio_export(IMX_GPIO_NR(7, 8), true);
+ gpio_request(IMX_GPIO_NR(3, 26), "external_gpio_5");
+ gpio_export(IMX_GPIO_NR(3, 26), true);
+ gpio_request(IMX_GPIO_NR(3, 8), "external_gpio_6");
+ gpio_export(IMX_GPIO_NR(3, 8), true);
+ gpio_request(IMX_GPIO_NR(4, 5), "external_gpio_7");
+ gpio_export(IMX_GPIO_NR(4, 5), true);
+}
+
+
+/****************************************************************************
+ *
+ * SPI - while not used on the Wandboard, the pins are routed out
+ *
+ ****************************************************************************/
+
+static __initdata iomux_v3_cfg_t wand_spi_pads[] = {
+ MX6DL_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6DL_PAD_EIM_D17__ECSPI1_MISO,
+ MX6DL_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6DL_PAD_EIM_EB2__GPIO_2_30,
+
+ MX6DL_PAD_EIM_CS0__ECSPI2_SCLK,
+ MX6DL_PAD_EIM_CS1__ECSPI2_MOSI,
+ MX6DL_PAD_EIM_OE__ECSPI2_MISO,
+ MX6DL_PAD_EIM_RW__GPIO_2_26,
+ MX6DL_PAD_EIM_LBA__GPIO_2_27,
+};
+/* The choice of using gpios for chipselect is deliberate,
+ there can be issues using the dedicated mux modes for cs.
+*/
+
+/* ------------------------------------------------------------------------ */
+
+static const int wand_spi1_chipselect[] = { IMX_GPIO_NR(2, 30) };
+
+/* platform device */
+static const struct spi_imx_master wand_spi1_data = {
+ .chipselect = wand_spi1_chipselect,
+ .num_chipselect = ARRAY_SIZE(wand_spi1_chipselect),
+};
+
+/* ------------------------------------------------------------------------ */
+
+static const int wand_spi2_chipselect[] = { IMX_GPIO_NR(2, 26), IMX_GPIO_NR(2, 27) };
+
+static const struct spi_imx_master wand_spi2_data = {
+ .chipselect = wand_spi2_chipselect,
+ .num_chipselect = ARRAY_SIZE(wand_spi2_chipselect),
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void __init wand_init_spi(void) {
+ WAND_SETUP_PADS(wand_spi_pads);
+
+ imx6q_add_ecspi(0, &wand_spi1_data);
+ imx6q_add_ecspi(1, &wand_spi2_data);
+}
+
+
+/****************************************************************************
+ *
+ * Vivante GPU/VPU
+ *
+ ****************************************************************************/
+
+static const __initconst struct imx_viv_gpu_data wand_gpu_data = {
+ .phys_baseaddr = 0,
+ .iobase_3d = GPU_3D_ARB_BASE_ADDR,
+ .irq_3d = MXC_INT_GPU3D_IRQ,
+ .iobase_2d = GPU_2D_ARB_BASE_ADDR,
+ .irq_2d = MXC_INT_GPU2D_IRQ,
+ .iobase_vg = OPENVG_ARB_BASE_ADDR,
+ .irq_vg = MXC_INT_OPENVG_XAQ2,
+};
+
+static struct viv_gpu_platform_data wand_gpu_pdata = {
+ .reserved_mem_size = SZ_128M + SZ_64M - SZ_16M,
+};
+
+static __init void wand_init_gpu(void) {
+ imx_add_viv_gpu(&wand_gpu_data, &wand_gpu_pdata);
+ imx6q_add_vpu();
+ imx6q_add_v4l2_output(0);
+}
+
+/*****************************************************************************
+ *
+ * Init clocks and early boot console
+ *
+ *****************************************************************************/
+
+extern void __iomem *twd_base;
+
+static void __init wand_init_timer(void) {
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART1_BASE_ADDR, uart_clk);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct sys_timer wand_timer = {
+ .init = wand_init_timer,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void __init wand_reserve(void) {
+ phys_addr_t phys;
+
+ if (wand_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(wand_gpu_pdata.reserved_mem_size, SZ_4K, SZ_512M);
+ memblock_remove(phys, wand_gpu_pdata.reserved_mem_size);
+ wand_gpu_pdata.reserved_mem_base = phys;
+ }
+}
+
+/*****************************************************************************
+ *
+ * BOARD INIT
+ *
+ *****************************************************************************/
+
+static void __init wand_board_init(void) {
+ wand_init_dma();
+ wand_init_uart();
+ wand_init_sd();
+ wand_init_i2c();
+ wand_init_audio();
+ wand_init_ethernet();
+ wand_init_usb();
+ wand_init_ipu();
+ imx6q_add_imx_snvs_rtc();
+ wand_init_hdmi();
+ wand_init_wifi();
+ wand_init_bluetooth();
+ wand_init_pm();
+ wand_init_external_gpios();
+ wand_init_spi();
+ wand_init_gpu();
+}
+
+/* ------------------------------------------------------------------------ */
+
+MACHINE_START(WANDBOARD, "Wandboard")
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = wand_board_init,
+ .timer = &wand_timer,
+ .reserve = wand_reserve,
+MACHINE_END
+
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 88210d9..5b4c1be 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1119,4 +1119,5 @@ mx6q_sabresd MACH_MX6Q_SABRESD MX6Q_SABRESD 3980
mx6q_arm2 MACH_MX6Q_ARM2 MX6Q_ARM2 3837
mx6sl_arm2 MACH_MX6SL_ARM2 MX6SL_ARM2 4091
mx6sl_evk MACH_MX6SL_EVK MX6SL_EVK 4307
+wandboard MACH_WANDBOARD WANDBOARD 4412
--
1.7.9.5