summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Weber <rjohnweber@gmail.com>2013-06-27 22:07:16 -0500
committerJohn Weber <rjohnweber@gmail.com>2013-07-17 14:22:36 -0500
commit9102bd30ccab67abe7d864dc78ed81f43d73ca2e (patch)
tree8bdab37f865b4e4f5d6420fddff3ec430cdeb8f4
parent3383d801188adc582b849c6fd1fe1c53be7dbaa9 (diff)
downloadlinux-9102bd30ccab67abe7d864dc78ed81f43d73ca2e.tar.gz
wandboard: Add board support
-rw-r--r--arch/arm/configs/wandboard_defconfig224
-rw-r--r--arch/arm/mach-mx6/Kconfig36
-rw-r--r--arch/arm/mach-mx6/Makefile2
-rw-r--r--arch/arm/mach-mx6/baseboard-wand.c137
-rw-r--r--arch/arm/mach-mx6/board-wand.c1059
-rw-r--r--arch/arm/tools/mach-types2
6 files changed, 1459 insertions, 1 deletions
diff --git a/arch/arm/configs/wandboard_defconfig b/arch/arm/configs/wandboard_defconfig
new file mode 100644
index 000000000000..c6e46b4ebfbb
--- /dev/null
+++ b/arch/arm/configs/wandboard_defconfig
@@ -0,0 +1,224 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+CONFIG_DEFAULT_HOSTNAME="wandboard"
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_BUG is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MXC=y
+CONFIG_ARCH_MX6=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_MACH_WANDBOARD=y
+CONFIG_IMX_PCIE=y
+CONFIG_USB_EHCI_ARC_H1=y
+CONFIG_USB_FSL_ARC_OTG=y
+CONFIG_DMA_ZONE_SIZE=96
+CONFIG_ARM_THUMBEE=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_753970=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_COMPACTION=y
+CONFIG_KSM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_IMX=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_PM_RUNTIME=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_DEFAULT_PS is not set
+# CONFIG_WIRELESS_EXT_SYSFS is not set
+CONFIG_RFKILL_REGULATOR=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_FEC_NAPI=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=720
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DUMMY=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_VIDEO_MXC_CAMERA is not set
+CONFIG_USB_VIDEO_CLASS=y
+# CONFIG_USB_GSPCA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_DRM=y
+CONFIG_DRM_VIVANTE=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_10x18=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_HIDRAW=y
+CONFIG_USB_HIDDEV=y
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_SONY=m
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=100
+CONFIG_USB_MASS_STORAGE=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_ULPI=y
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_SNVS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=y
+CONFIG_STAGING=y
+CONFIG_ZRAM=y
+CONFIG_MXC_IPU=y
+CONFIG_MXC_SSI=y
+# CONFIG_MXC_HMP4E is not set
+# CONFIG_MXC_HWEVENT is not set
+CONFIG_MXC_ASRC=y
+CONFIG_MXC_GPU_VIV=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_FRAME_WARN=4096
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index df954b40d8e8..cf783cfec072 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -282,6 +282,42 @@ config MACH_MX6Q_HDMIDONGLE
Include support for i.MX 6Quad HDMI Dongle 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_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 IMX_HAVE_PLATFORM_IMX_SSI if MXC_SSI
+ select IMX_HAVE_PLATFORM_IMX_ESAI if MXC_SSI
+ 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_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
+ select IMX_HAVE_PLATFORM_IMX_PCIE if IMX_PCIE
+ select ZONE_DMA if ION=n
+ select IMX_HAVE_PLATFORM_AHCI if SATA_AHCI_PLATFORM
+ 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 8c1d754f02a2..88404f3451b3 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -15,6 +15,8 @@ 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_MX6Q_HDMIDONGLE) += board-mx6q_hdmidongle.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 000000000000..e9e9378d44f4
--- /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 000000000000..e7ce54cf1128
--- /dev/null
+++ b/arch/arm/mach-mx6/board-wand.c
@@ -0,0 +1,1059 @@
+/*
+ Wandboard board file. Copyright (C) 2013 Tapani Utriainen
+ Authors: Tapani Utriainen, Edward Lin
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#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/i2c.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/phy.h>
+
+#include <mach/ahci_sata.h>
+#include <mach/common.h>
+//#include <mach/devices-common.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx6dl.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/iomux-v3.h>
+#include <mach/mx6.h>
+
+#include "crm_regs.h"
+#include "devices-imx6q.h"
+#include "usb.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_PCIE_NRST IMX_GPIO_NR(3, 31)
+
+#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 IMX6_SETUP_PAD(p) \
+ if (cpu_is_mx6q()) \
+ mxc_iomux_v3_setup_pad(MX6Q_PAD_##p);\
+ else \
+ mxc_iomux_v3_setup_pad(MX6DL_PAD_##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
+ *
+ ****************************************************************************/
+
+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,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_CONTROLLER,
+ }, {
+ .cd_gpio =-EINVAL,
+ .wp_gpio =-EINVAL,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 0,
+ .delay_line = 0,
+ .always_present = 1,
+ .cd_type = ESDHC_CD_PERMANENT,
+ }, {
+ .cd_gpio = WAND_SD3_CD,
+ .wp_gpio = WAND_SD3_WP,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 0,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_CONTROLLER,
+ }
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void wand_init_sd(void) {
+ int i;
+
+ IMX6_SETUP_PAD( SD1_CLK__USDHC1_CLK_50MHZ_40OHM );
+ IMX6_SETUP_PAD( SD1_CMD__USDHC1_CMD_50MHZ_40OHM );
+ IMX6_SETUP_PAD( SD1_DAT0__USDHC1_DAT0_50MHZ_40OHM );
+ IMX6_SETUP_PAD( SD1_DAT1__USDHC1_DAT1_50MHZ_40OHM );
+ IMX6_SETUP_PAD( SD1_DAT2__USDHC1_DAT2_50MHZ_40OHM );
+ IMX6_SETUP_PAD( SD1_DAT3__USDHC1_DAT3_50MHZ_40OHM );
+
+ IMX6_SETUP_PAD( SD2_CLK__USDHC2_CLK );
+ IMX6_SETUP_PAD( SD2_CMD__USDHC2_CMD );
+ IMX6_SETUP_PAD( SD2_DAT0__USDHC2_DAT0 );
+ IMX6_SETUP_PAD( SD2_DAT1__USDHC2_DAT1 );
+ IMX6_SETUP_PAD( SD2_DAT2__USDHC2_DAT2 );
+ IMX6_SETUP_PAD( SD2_DAT3__USDHC2_DAT3 );
+
+ IMX6_SETUP_PAD( SD3_CLK__USDHC3_CLK_50MHZ );
+ IMX6_SETUP_PAD( SD3_CMD__USDHC3_CMD_50MHZ );
+ IMX6_SETUP_PAD( SD3_DAT0__USDHC3_DAT0_50MHZ );
+ IMX6_SETUP_PAD( SD3_DAT1__USDHC3_DAT1_50MHZ );
+ IMX6_SETUP_PAD( SD3_DAT2__USDHC3_DAT2_50MHZ );
+ IMX6_SETUP_PAD( SD3_DAT3__USDHC3_DAT3_50MHZ );
+
+ /* Card Detect for SD1 & SD3, respectively */
+ IMX6_SETUP_PAD( GPIO_2__GPIO_1_2 );
+ IMX6_SETUP_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--) {
+ imx6q_add_sdhci_usdhc_imx(i, &wand_sd_data[i]);
+ }
+}
+
+
+/****************************************************************************
+ *
+ * I2C
+ *
+ ****************************************************************************/
+
+static struct imxi2c_platform_data wand_i2c_data[] = {
+ { .bitrate = 400000, },
+ { .bitrate = 400000, },
+ { .bitrate = 400000, },
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void __init wand_init_i2c(void) {
+ int i;
+
+ IMX6_SETUP_PAD( EIM_D21__I2C1_SCL );
+ IMX6_SETUP_PAD( EIM_D28__I2C1_SDA );
+
+ IMX6_SETUP_PAD( KEY_COL3__I2C2_SCL );
+ IMX6_SETUP_PAD( KEY_ROW3__I2C2_SDA );
+
+ IMX6_SETUP_PAD( GPIO_5__I2C3_SCL );
+ IMX6_SETUP_PAD( GPIO_16__I2C3_SDA );
+
+ for (i=0; i<3; i++) {
+ imx6q_add_imx_i2c(i, &wand_i2c_data[i]);
+ }
+}
+
+
+/****************************************************************************
+ *
+ * Initialize debug console (UART1)
+ *
+ ****************************************************************************/
+
+static __init void wand_init_uart(void) {
+ IMX6_SETUP_PAD( CSI0_DAT10__UART1_TXD );
+ IMX6_SETUP_PAD( CSI0_DAT11__UART1_RXD );
+ IMX6_SETUP_PAD( EIM_D19__UART1_CTS );
+ IMX6_SETUP_PAD( EIM_D20__UART1_RTS );
+
+ imx6q_add_imx_uart(0, NULL);
+}
+
+
+/****************************************************************************
+ *
+ * Initialize sound (SSI, ASRC, AUD3 channel and S/PDIF)
+ *
+ ****************************************************************************/
+
+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) {
+ IMX6_SETUP_PAD( CSI0_DAT4__AUDMUX_AUD3_TXC );
+ IMX6_SETUP_PAD( CSI0_DAT5__AUDMUX_AUD3_TXD );
+ IMX6_SETUP_PAD( CSI0_DAT6__AUDMUX_AUD3_TXFS );
+ IMX6_SETUP_PAD( CSI0_DAT7__AUDMUX_AUD3_RXD );
+ IMX6_SETUP_PAD( GPIO_0__CCM_CLKO );
+
+ /* 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 */
+
+ IMX6_SETUP_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 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 = {
+ .init = wand_fec_phy_init,
+ .power_hibernate = wand_fec_power_hibernate,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_ethernet(void) {
+ IMX6_SETUP_PAD( ENET_MDIO__ENET_MDIO );
+ IMX6_SETUP_PAD( ENET_MDC__ENET_MDC );
+ IMX6_SETUP_PAD( ENET_REF_CLK__ENET_TX_CLK );
+ IMX6_SETUP_PAD( RGMII_TXC__ENET_RGMII_TXC );
+ IMX6_SETUP_PAD( RGMII_TD0__ENET_RGMII_TD0 );
+ IMX6_SETUP_PAD( RGMII_TD1__ENET_RGMII_TD1 );
+ IMX6_SETUP_PAD( RGMII_TD2__ENET_RGMII_TD2 );
+ IMX6_SETUP_PAD( RGMII_TD3__ENET_RGMII_TD3 );
+ IMX6_SETUP_PAD( RGMII_TX_CTL__ENET_RGMII_TX_CTL );
+ IMX6_SETUP_PAD( RGMII_RXC__ENET_RGMII_RXC );
+ IMX6_SETUP_PAD( RGMII_RD0__ENET_RGMII_RD0 );
+ IMX6_SETUP_PAD( RGMII_RD1__ENET_RGMII_RD1 );
+ IMX6_SETUP_PAD( RGMII_RD2__ENET_RGMII_RD2 );
+ IMX6_SETUP_PAD( RGMII_RD3__ENET_RGMII_RD3 );
+ IMX6_SETUP_PAD( RGMII_RX_CTL__ENET_RGMII_RX_CTL );
+ IMX6_SETUP_PAD( ENET_TX_EN__GPIO_1_28 );
+ IMX6_SETUP_PAD( EIM_D29__GPIO_3_29 );
+
+ 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 void wand_usbotg_vbus(bool on) {
+ gpio_set_value_cansleep(WAND_USB_OTG_PWR, !on);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static __init void wand_init_usb(void) {
+ IMX6_SETUP_PAD( GPIO_9__GPIO_1_9 );
+ IMX6_SETUP_PAD( GPIO_1__USBOTG_ID );
+ IMX6_SETUP_PAD( EIM_D22__GPIO_3_22 );
+ IMX6_SETUP_PAD( EIM_D30__GPIO_3_30 );
+
+ 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);
+}
+
+
+/****************************************************************************
+ *
+ * LCD/LVDS/TTL
+ *
+ ****************************************************************************/
+
+static struct fsl_mxc_lcd_platform_data wand_lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB24
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct fsl_mxc_ldb_platform_data wand_ldb_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .ext_ref = 1,
+ .mode = LDB_SIN0,
+ .sec_ipu_id = 0,
+ .sec_disp_id = 0,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct ipuv3_fb_platform_data wand_lvds_fb[] = {
+ {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "LDB-WVGA",
+ .default_bpp = 24,
+ .int_clk = false,
+ },
+};
+
+/* ------------------------------------------------------------------------ */
+
+
+static void __init wand_init_lcd(void) {
+ /* TTL */
+ IMX6_SETUP_PAD( DI0_DISP_CLK__IPU1_DI0_DISP_CLK );
+ IMX6_SETUP_PAD( DI0_PIN2__IPU1_DI0_PIN2 ); /* HSync */
+ IMX6_SETUP_PAD( DI0_PIN3__IPU1_DI0_PIN3 ); /* VSync */
+ IMX6_SETUP_PAD( DI0_PIN4__IPU1_DI0_PIN4 ); /* Contrast */
+ IMX6_SETUP_PAD( DI0_PIN15__IPU1_DI0_PIN15 ); /* DISP0_DRDY */
+ IMX6_SETUP_PAD( DISP0_DAT0__IPU1_DISP0_DAT_0 );
+ IMX6_SETUP_PAD( DISP0_DAT1__IPU1_DISP0_DAT_1 );
+ IMX6_SETUP_PAD( DISP0_DAT2__IPU1_DISP0_DAT_2 );
+ IMX6_SETUP_PAD( DISP0_DAT3__IPU1_DISP0_DAT_3 );
+ IMX6_SETUP_PAD( DISP0_DAT4__IPU1_DISP0_DAT_4 );
+ IMX6_SETUP_PAD( DISP0_DAT5__IPU1_DISP0_DAT_5 );
+ IMX6_SETUP_PAD( DISP0_DAT6__IPU1_DISP0_DAT_6 );
+ IMX6_SETUP_PAD( DISP0_DAT7__IPU1_DISP0_DAT_7 );
+ IMX6_SETUP_PAD( DISP0_DAT8__IPU1_DISP0_DAT_8 );
+ IMX6_SETUP_PAD( DISP0_DAT9__IPU1_DISP0_DAT_9 );
+ IMX6_SETUP_PAD( DISP0_DAT10__IPU1_DISP0_DAT_10 );
+ IMX6_SETUP_PAD( DISP0_DAT11__IPU1_DISP0_DAT_11 );
+ IMX6_SETUP_PAD( DISP0_DAT12__IPU1_DISP0_DAT_12 );
+ IMX6_SETUP_PAD( DISP0_DAT13__IPU1_DISP0_DAT_13 );
+ IMX6_SETUP_PAD( DISP0_DAT14__IPU1_DISP0_DAT_14 );
+ IMX6_SETUP_PAD( DISP0_DAT15__IPU1_DISP0_DAT_15 );
+ IMX6_SETUP_PAD( DISP0_DAT16__IPU1_DISP0_DAT_16 );
+ IMX6_SETUP_PAD( DISP0_DAT17__IPU1_DISP0_DAT_17 );
+ IMX6_SETUP_PAD( DISP0_DAT18__IPU1_DISP0_DAT_18 );
+ IMX6_SETUP_PAD( DISP0_DAT19__IPU1_DISP0_DAT_19 );
+ IMX6_SETUP_PAD( DISP0_DAT20__IPU1_DISP0_DAT_20 );
+ IMX6_SETUP_PAD( DISP0_DAT21__IPU1_DISP0_DAT_21 );
+ IMX6_SETUP_PAD( DISP0_DAT22__IPU1_DISP0_DAT_22 );
+ IMX6_SETUP_PAD( DISP0_DAT23__IPU1_DISP0_DAT_23 );
+
+ /* LVDS */
+ IMX6_SETUP_PAD( SD4_DAT0__GPIO_2_8 );
+ IMX6_SETUP_PAD( SD4_DAT1__GPIO_2_9 );
+ IMX6_SETUP_PAD( SD4_DAT2__GPIO_2_10 );
+ IMX6_SETUP_PAD( SD4_DAT3__GPIO_2_11 );
+
+ IMX6_SETUP_PAD( LVDS0_CLK_P__LDB_LVDS0_CLK );
+ IMX6_SETUP_PAD( LVDS0_TX0_P__LDB_LVDS0_TX0 );
+ IMX6_SETUP_PAD( LVDS0_TX1_P__LDB_LVDS0_TX1 );
+ IMX6_SETUP_PAD( LVDS0_TX2_P__LDB_LVDS0_TX2 );
+ IMX6_SETUP_PAD( LVDS0_TX3_P__LDB_LVDS0_TX3 );
+
+ gpio_request(IMX_GPIO_NR(2, 8), "lvds0_en");
+ gpio_direction_output(IMX_GPIO_NR(2, 8), 1);
+
+ gpio_request(IMX_GPIO_NR(2, 9), "lvds0_blt_ctrl");
+ gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
+
+ gpio_request(IMX_GPIO_NR(2, 10), "disp0_bklen");
+ gpio_direction_output(IMX_GPIO_NR(2, 10), 1);
+
+ gpio_request(IMX_GPIO_NR(2, 11), "disp0_vdden");
+ gpio_direction_output(IMX_GPIO_NR(2, 11), 1);
+
+ imx6q_add_vdoa();
+
+ imx6q_add_ldb(&wand_ldb_data);
+ imx6q_add_lcdif(&wand_lcdif_data);
+
+ imx6q_add_ipuv3fb(1, &wand_lvds_fb[0]);
+}
+
+
+/****************************************************************************
+ *
+ * WiFi
+ *
+ ****************************************************************************/
+
+/* assumes SD/MMC pins are set; call after wand_init_sd() */
+static __init void wand_init_wifi(void) {
+ /* ref_on, enable 32k clock */
+ IMX6_SETUP_PAD( EIM_EB1__GPIO_2_29 );
+ /* Wifi reset (resets when low!) */
+ IMX6_SETUP_PAD( EIM_A25__GPIO_5_2 );
+ /* reg on, signal to FDC6331L */
+ IMX6_SETUP_PAD( ENET_RXD1__GPIO_1_26 );
+ /* host wake */
+ IMX6_SETUP_PAD( ENET_TXD1__GPIO_1_29 );
+ /* wl wake - nc */
+ IMX6_SETUP_PAD( ENET_TXD0__GPIO_1_30 );
+
+ 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 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) {
+ /* BT_ON, BT_WAKE and BT_HOST_WAKE */
+ IMX6_SETUP_PAD( EIM_DA13__GPIO_3_13 );
+ IMX6_SETUP_PAD( EIM_DA14__GPIO_3_14 );
+ IMX6_SETUP_PAD( EIM_DA15__GPIO_3_15 );
+
+ /* AUD5 channel goes to BT */
+ IMX6_SETUP_PAD( KEY_COL0__AUDMUX_AUD5_TXC );
+ IMX6_SETUP_PAD( KEY_ROW0__AUDMUX_AUD5_TXD );
+ IMX6_SETUP_PAD( KEY_COL1__AUDMUX_AUD5_TXFS );
+ IMX6_SETUP_PAD( KEY_ROW1__AUDMUX_AUD5_RXD );
+
+ /* Bluetooth is on UART3*/
+ IMX6_SETUP_PAD( EIM_D23__UART3_CTS );
+ IMX6_SETUP_PAD( EIM_D24__UART3_TXD );
+ IMX6_SETUP_PAD( EIM_D25__UART3_RXD );
+ IMX6_SETUP_PAD( EIM_EB3__UART3_RTS );
+
+ 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 __init void wand_init_external_gpios(void) {
+ IMX6_SETUP_PAD( EIM_DA11__GPIO_3_11 );
+ IMX6_SETUP_PAD( EIM_D27__GPIO_3_27 );
+ IMX6_SETUP_PAD( EIM_BCLK__GPIO_6_31 );
+ IMX6_SETUP_PAD( ENET_RX_ER__GPIO_1_24 );
+ IMX6_SETUP_PAD( SD3_RST__GPIO_7_8 );
+ IMX6_SETUP_PAD( EIM_D26__GPIO_3_26 );
+ IMX6_SETUP_PAD( EIM_DA8__GPIO_3_8 );
+ IMX6_SETUP_PAD( GPIO_19__GPIO_4_5 );
+
+ 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 const int wand_spi1_chipselect[] = { IMX_GPIO_NR(2, 30) };
+
+/* platform device */
+static const struct spi_imx_master wand_spi1_data = {
+ .chipselect = (int *)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 = (int *)wand_spi2_chipselect,
+ .num_chipselect = ARRAY_SIZE(wand_spi2_chipselect),
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void __init wand_init_spi(void) {
+ IMX6_SETUP_PAD( EIM_D16__ECSPI1_SCLK );
+ IMX6_SETUP_PAD( EIM_D17__ECSPI1_MISO );
+ IMX6_SETUP_PAD( EIM_D18__ECSPI1_MOSI );
+ IMX6_SETUP_PAD( EIM_EB2__GPIO_2_30 );
+
+ IMX6_SETUP_PAD( EIM_CS0__ECSPI2_SCLK );
+ IMX6_SETUP_PAD( EIM_CS1__ECSPI2_MOSI );
+ IMX6_SETUP_PAD( EIM_OE__ECSPI2_MISO );
+/* The choice of using gpios for chipselect is deliberate,
+ there can be issues using the dedicated mux modes for cs.*/
+ IMX6_SETUP_PAD( EIM_RW__GPIO_2_26 );
+ IMX6_SETUP_PAD( EIM_LBA__GPIO_2_27 );
+
+ 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);
+}
+
+
+/*****************************************************************************
+ *
+ * PCI Express (not present on default baseboard, but is routed to connector)
+ *
+ *****************************************************************************/
+
+static const struct imx_pcie_platform_data wand_pcie_data = {
+ .pcie_pwr_en = -EINVAL,
+ .pcie_rst = WAND_PCIE_NRST,
+ .pcie_wake_up = -EINVAL,
+ .pcie_dis = -EINVAL,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void __init wand_init_pcie(void) {
+ IMX6_SETUP_PAD( EIM_D31__GPIO_3_31);
+ imx6q_add_pcie(&wand_pcie_data);
+}
+
+
+/****************************************************************************
+ *
+ * AHCI - SATA
+ *
+ ****************************************************************************/
+
+static struct clk *wand_sata_clk;
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int wand_sata_init(struct device *dev, void __iomem *addr) {
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ wand_sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(wand_sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(wand_sata_clk);
+ }
+ ret = clk_enable(wand_sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ /* Set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write is 0x07FFFFFD,
+ * and the other one write for setting the mpll_clk_off_b
+ *.rx_eq_val_0(iomuxc_gpr13[26:24]),
+ *.los_lvl(iomuxc_gpr13[23:19]),
+ *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
+ *.sata_speed(iomuxc_gpr13[15]),
+ *.mpll_ss_en(iomuxc_gpr13[14]),
+ *.tx_atten_0(iomuxc_gpr13[13:11]),
+ *.tx_boost_0(iomuxc_gpr13[10:7]),
+ *.tx_lvl(iomuxc_gpr13[6:2]),
+ *.mpll_ck_off(iomuxc_gpr13[1]),
+ *.tx_edgerate_0(iomuxc_gpr13[0]),
+ */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);
+
+ /* enable SATA_PHY PLL */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+
+release_sata_clk:
+ clk_disable(wand_sata_clk);
+put_sata_clk:
+ clk_put(wand_sata_clk);
+
+ return ret;
+}
+
+static void wand_sata_exit(struct device *dev) {
+ clk_disable(wand_sata_clk);
+ clk_put(wand_sata_clk);
+}
+
+static struct ahci_platform_data wand_sata_data = {
+ .init = wand_sata_init,
+ .exit = wand_sata_exit,
+};
+
+
+static __init void wand_init_sata(void) {
+ imx6q_add_ahci(0, &wand_sata_data);
+}
+
+
+/*****************************************************************************
+ *
+ * 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();
+ wand_init_hdmi();
+ wand_init_lcd();
+ wand_init_wifi();
+ wand_init_bluetooth();
+ wand_init_pm();
+ wand_init_external_gpios();
+ wand_init_spi();
+ wand_init_gpu();
+ wand_init_pcie();
+ if (cpu_is_mx6q())
+ wand_init_sata();
+}
+
+/* ------------------------------------------------------------------------ */
+
+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 f6b5c0efc3e8..9856082230a7 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1120,4 +1120,4 @@ mx6q_arm2 MACH_MX6Q_ARM2 MX6Q_ARM2 3837
mx6sl_arm2 MACH_MX6SL_ARM2 MX6SL_ARM2 4091
mx6q_hdmidongle MACH_MX6Q_HDMIDONGLE MX6Q_HDMIDONGLE 4284
mx6sl_evk MACH_MX6SL_EVK MX6SL_EVK 4307
-
+wandboard MACH_WANDBOARD WANDBOARD 4412