define Package/imx-bootlets
SECTION:=boot
CATEGORY:=Boot Loaders
- TITLE:=i.MX23 bootlets
- DEPENDS:=@TARGET_imx23
+ TITLE:=i.MX23/i.MX28 bootlets
+ DEPENDS:=@TARGET_mxs
endef
define Package/imx-bootlets/description
- i.MX23 bootlets (for oLinuxino)
+ i.MX23/i.MX28 bootlets (for oLinuxino)
endef
define Build/Compile
define Package/uboot-imx23-$(1)
SECTION:=boot
CATEGORY:=Boot Loaders
- DEPENDS:=@TARGET_imx23
+ DEPENDS:=@TARGET_mxs
TITLE:=$(2)
URL:=http://www.denx.de/wiki/U-Boot
VARIANT:=$(1)
+++ /dev/null
-#
-# Copyright (C) 2013 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-ARCH:=arm
-BOARD:=imx23
-BOARDNAME:=Freescale i.MX23 series
-FEATURES:=ext4 rtc usb gpio
-CPU_TYPE:=arm926ej-s
-
-MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
-LINUX_VERSION:=3.10.15
-KERNELNAME:="zImage dtbs"
-
-define Target/Description
- Support for Freescale i.MX233-based boards
-endef
-
-include $(INCLUDE_DIR)/target.mk
-
-DEFAULT_PACKAGES += kmod-wdt-stmp3xxx
-
-$(eval $(call BuildTarget))
+++ /dev/null
-::sysinit:/etc/init.d/rcS S boot
-::shutdown:/etc/init.d/rcS K shutdown
-ttyAMA0::askfirst:/bin/ash --login
+++ /dev/null
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_AMBA_PL08X is not set
-# CONFIG_APM_EMULATION is not set
-CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_CPU_AUTO=y
-# CONFIG_ARCH_MULTI_V4 is not set
-# CONFIG_ARCH_MULTI_V4T is not set
-CONFIG_ARCH_MULTI_V4_V5=y
-CONFIG_ARCH_MULTI_V5=y
-# CONFIG_ARCH_MULTI_V6 is not set
-# CONFIG_ARCH_MULTI_V7 is not set
-CONFIG_ARCH_MXS=y
-# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
-# CONFIG_ARCH_WM8505 is not set
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_APPENDED_DTB=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_L1_CACHE_SHIFT=5
-CONFIG_ARM_NR_BANKS=8
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_SP805_WATCHDOG is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLKSRC_OF=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="console=ttyAMA0,115200 root=/dev/mmcblk0p2 rw rootwait"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_COMMON_CLK=y
-CONFIG_COREDUMP=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_ARM926T=y
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_PABRT_LEGACY=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_USE_DOMAINS=y
-CONFIG_CRC16=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-# CONFIG_DEBUG_PINCTRL is not set
-# CONFIG_DEBUG_USER is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DTC=y
-CONFIG_EXT4_FS=y
-CONFIG_FEC=y
-CONFIG_FRAME_POINTER=y
-CONFIG_FS_MBCACHE=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_DEVRES=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_MXS=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-CONFIG_HAVE_AOUT=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_PFN_VALID=y
-CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
-CONFIG_HAVE_BPF_JIT=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CLK_PREPARE=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_HAVE_PWM=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_UID16=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_ALGOPCA=y
-CONFIG_I2C_ALGOPCF=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_DEBUG_ALGO=y
-CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CORE=y
-CONFIG_I2C_MUX=y
-# CONFIG_I2C_MUX_GPIO is not set
-# CONFIG_I2C_MUX_PCA9541 is not set
-# CONFIG_I2C_MUX_PCA954x is not set
-CONFIG_I2C_MUX_PINCTRL=y
-CONFIG_I2C_MXS=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-# CONFIG_IIO_BUFFER_CB is not set
-CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
-CONFIG_IIO_GPIO_TRIGGER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_PERIODIC_RTC_TRIGGER=y
-# CONFIG_IIO_SIMPLE_DUMMY is not set
-# CONFIG_IIO_ST_ACCEL_3AXIS is not set
-# CONFIG_IIO_ST_GYRO_3AXIS is not set
-# CONFIG_IIO_ST_MAGN_3AXIS is not set
-CONFIG_IIO_SYSFS_TRIGGER=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISDN is not set
-CONFIG_JBD2=y
-CONFIG_KTIME_SCALAR=y
-# CONFIG_LEDS_REGULATOR is not set
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BOARDINFO=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_MXS=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_OF_PARTS=y
-# CONFIG_MTD_PHYSMAP_OF is not set
-CONFIG_MULTI_IRQ_HANDLER=y
-CONFIG_MXS_DMA=y
-# CONFIG_MXS_LRADC is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-# CONFIG_NET_DMA is not set
-CONFIG_NLS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DEVICE=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_I2C=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_MTD=y
-CONFIG_OF_NET=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_PAGE_OFFSET=0xC0000000
-# CONFIG_PCI_SYSCALL is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PHYLIB=y
-CONFIG_PINCONF=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_IMX23=y
-CONFIG_PINCTRL_IMX28=y
-CONFIG_PINCTRL_MXS=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINMUX=y
-# CONFIG_PL330_DMA is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_PPS=y
-# CONFIG_PREEMPT_RCU is not set
-CONFIG_PTP_1588_CLOCK=y
-# CONFIG_RCU_STALL_COMMON is not set
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_SPI=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_DEBUG=y
-# CONFIG_REGULATOR_DUMMY is not set
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_RFKILL_REGULATOR is not set
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_STMP is not set
-# CONFIG_SAMSUNG_USB2PHY is not set
-# CONFIG_SAMSUNG_USB3PHY is not set
-# CONFIG_SAMSUNG_USBPHY is not set
-CONFIG_SCHED_HRTICK=y
-# CONFIG_SCSI_DMA is not set
-CONFIG_SERIAL_AMBA_PL010=y
-CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_MXS_AUART=y
-CONFIG_SERIAL_MXS_AUART_CONSOLE=y
-CONFIG_SMSC_PHY=y
-CONFIG_SOC_IMX23=y
-CONFIG_SOC_IMX28=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-# CONFIG_SPI_MXS is not set
-CONFIG_SPLIT_PTLOCK_CPUS=999999
-CONFIG_STMP_DEVICE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_TEGRA_HOST1X is not set
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_UID16=y
-CONFIG_UIDGID_CONVERTED=y
-# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_USB=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_XHCI is not set
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-# CONFIG_USB_MXS_PHY is not set
-CONFIG_USB_OTG=y
-CONFIG_USB_PHY=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_VECTORS_BASE=0xffff0000
-# CONFIG_VFP is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZONE_DMA_FLAG=0
+++ /dev/null
-#
-# Copyright (C) 2013 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/image.mk
-
-define Image/BuildKernel/olinuxino-bootlet
- cat $(LINUX_DIR)/arch/arm/boot/zImage $(LINUX_DIR)/arch/arm/boot/dts/imx23-olinuxino.dtb > $(STAGING_DIR)/zImage_dtb
- (cd $(STAGING_DIR); \
- $(STAGING_DIR)/../host/bin/elftosb -z -c ./linux_prebuilt.db -o linux.sb; \
- dd if=/dev/zero of=sd_mmc_bootstream.raw bs=512 count=4; \
- dd if=linux.sb of=$(BIN_DIR)/openwrt-imx23-sbImage ibs=512 seek=4; \
- )
-endef
-
-define Image/BuildKernel/olinuxino-uboot
- mkimage -A arm -O linux -T kernel -C none \
- -a 0x42000000 -e 0x42000000 \
- -n 'ARM OpenWrt Linux-$(LINUX_VERSION)' \
- -d $(KDIR)/vmlinux $(KDIR)/uImage
- cp $(KDIR)/uImage $(BIN_DIR)/$(IMG_PREFIX)-uImage
-endef
-
-define Image/BuildKernel
-
- ifeq ($(CONFIG_PACKAGE_imx-bootlets),y)
- $(call Image/BuildKernel/olinuxino-bootlet)
- endif
-
- ifeq ($(CONFIG_PACKAGE_uboot-imx23-mx23_olinuxino),y)
- $(call Image/BuildKernel/olinuxino-uboot)
- endif
-endef
-
-define Image/Build
- $(call Image/Build/$(1))
- dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
-endef
-
-$(eval $(call BuildImage))
-
+++ /dev/null
-#
-# Copyright (C) 2013 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-
-define KernelPackage/rtc-stmp3xxx
- SUBMENU:=$(OTHER_MENU)
- TITLE:=STMP3xxx SoC built-in RTC support
- DEPENDS:=@TARGET_imx23
- $(call AddDepends/rtc)
- KCONFIG:=\
- CONFIG_RTC_CLASS=y \
- CONFIG_RTC_DRV_STMP=m
- FILES:=$(LINUX_DIR)/drivers/rtc/rtc-stmp3xxx.ko
- AUTOLOAD:=$(call AutoLoad,50,rtc-stmp3xxx)
-endef
-
-$(eval $(call KernelPackage,rtc-stmp3xxx))
-
-define KernelPackage/wdt-stmp3xxx
- SUBMENU:=$(OTHER_MENU)
- TITLE:=STMP3xxx Watchdog timer
- DEPENDS:=kmod-rtc-stmp3xxx
- KCONFIG:=CONFIG_STMP3XXX_RTC_WATCHDOG
- FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/stmp3xxx_rtc_wdt.ko
- AUTOLOAD:=$(call AutoLoad,51,stmp3xxx_rtc_wdt)
-endef
-
-define KernelPackage/wdt-stmp3xxx/description
- Kernel module for STMP3xxx watchdog timer.
-endef
-
-$(eval $(call KernelPackage,wdt-stmp3xxx))
-
-define KernelPackage/usb-chipidea-imx
- TITLE:=Support for ChipIdea controllers on i.MX
- DEPENDS:=+kmod-usb-chipidea @TARGET_imx23
- FILES:=\
- $(LINUX_DIR)/drivers/usb/chipidea/ci13xxx_imx.ko
- AUTOLOAD:=$(call AutoLoad,52,ci13xxx_imx,1)
- $(call AddDepends/usb)
-endef
-
-define KernelPackage/usb-chipidea-imx/description
- Kernel support for USB ChipIdea controllers on i.MX
-endef
-
-$(eval $(call KernelPackage,usb-chipidea-imx,1))
-
-define KernelPackage/usb-mxs-phy
- TITLE:=Support for Freescale MXS USB PHY controllers
- DEPENDS:=+kmod-usb-chipidea-imx
- KCONFIG:= \
- CONFIG_USB_MXS_PHY
- FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-mxs-usb.ko
- AUTOLOAD:=$(call AutoLoad,50,phy-mxs-usb,1)
- $(call AddDepends/usb)
-endef
-
-define KernelPackage/usb-mxs-phy/description
- Kernel support for Freescale MXS USB PHY controllers
-endef
-
-$(eval $(call KernelPackage,usb-mxs-phy,1))
-
-define KernelPackage/usb-net-smsc95xx
- TITLE:=SMSC95xx USB/2.0 Ethernet driver
- DEPENDS:=@TARGET_imx23
- KCONFIG:=CONFIG_USB_NET_SMSC95XX
- FILES:=$(LINUX_DIR)/drivers/net/usb/smsc95xx.ko
- AUTOLOAD:=$(call AutoLoad,64,smsc95xx)
- $(call AddDepends/usb-net)
-endef
-
-define KernelPackage/usb-net-smsc95xx/description
- Kernel support for SMSC95xx USB/2.0 Ethernet driver
-endef
-
-$(eval $(call KernelPackage,usb-net-smsc95xx))
-
-define KernelPackage/sound-soc-imx23
- TITLE:=Freescale i.MX233 built-in SoC sound support
- KCONFIG:= \
- CONFIG_SND_SOC_MXS_BUILTIN_CODEC \
- CONFIG_SND_MXS_SOC_BUILTIN
- FILES:= \
- $(LINUX_DIR)/sound/soc/mxs/snd-soc-mxs-builtin-audio.ko \
- $(LINUX_DIR)/sound/soc/mxs/snd-soc-mxs-builtin-dai.ko \
- $(LINUX_DIR)/sound/soc/mxs/snd-soc-mxs-builtin-pcm.ko \
- $(LINUX_DIR)/sound/soc/codecs/snd-soc-mxs-builtin-codec.ko
- AUTOLOAD:=$(call AutoLoad,65,snd-soc-mxs-builtin-pcm snd-soc-mxs-builtin-dai snd-soc-mxs-builtin-codec snd-soc-mxs-builtin-audio)
- DEPENDS:=@TARGET_imx23 +kmod-sound-soc-core
- $(call AddDepends/sound)
-endef
-
-define KernelPackage/sound-soc-imx23/description
- Kernel support for i.MX233 built-in SoC audio
-endef
-
-$(eval $(call KernelPackage,sound-soc-imx23))
-
-define KernelPackage/iio-mxs-lradc
- SUBMENU:=$(OTHER_MENU)
- TITLE:=LRADC driver for i.MX23/28
- DEPENDS:=@TARGET_imx23
- KCONFIG:=CONFIG_MXS_LRADC
- FILES:=$(LINUX_DIR)/drivers/staging/iio/adc/mxs-lradc.ko \
- $(LINUX_DIR)/drivers/iio/industrialio-triggered-buffer.ko
- AUTOLOAD:=$(call AutoLoad,70,industrialio-triggered-buffer mxs-lradc)
-endef
-
-define KernelPackage/iio-mxs-lradc/description
- Kernel module for i.MX23/28 LRADC driver
-endef
-
-$(eval $(call KernelPackage,iio-mxs-lradc))
-
-define KernelPackage/crypto-hw-dcp
- TITLE:=i.MX23/28 DCP hardware crypto module
- DEPENDS:=@TARGET_imx23
- KCONFIG:=CONFIG_CRYPTO_DEV_DCP
- FILES:=$(LINUX_DIR)/drivers/crypto/dcp.ko
- AUTOLOAD:=$(call AutoLoad,90,dcp)
- $(call AddDepends/crypto,+kmod-crypto-authenc +kmod-crypto-des)
-endef
-
-define KernelPackage/crypto-hw-dcp/description
- Kernel support for the i.MX23/28 DCP crypto engine
-endef
-
-$(eval $(call KernelPackage,crypto-hw-dcp))
+++ /dev/null
---- a/sound/soc/codecs/Kconfig
-+++ b/sound/soc/codecs/Kconfig
-@@ -125,6 +125,7 @@ config SND_SOC_ALL_CODECS
- select SND_SOC_WM9705 if SND_SOC_AC97_BUS
- select SND_SOC_WM9712 if SND_SOC_AC97_BUS
- select SND_SOC_WM9713 if SND_SOC_AC97_BUS
-+ select SND_SOC_MXS_BUILTIN_CODEC
- help
- Normally ASoC codec drivers are only built if a machine driver which
- uses them is also built since they are only usable with a machine
-@@ -507,6 +508,9 @@ config SND_SOC_WM9712
- config SND_SOC_WM9713
- tristate
-
-+config SND_SOC_MXS_BUILTIN_CODEC
-+ tristate
-+
- # Amp
- config SND_SOC_LM4857
- tristate
---- a/sound/soc/codecs/Makefile
-+++ b/sound/soc/codecs/Makefile
-@@ -118,6 +118,7 @@ snd-soc-wm9705-objs := wm9705.o
- snd-soc-wm9712-objs := wm9712.o
- snd-soc-wm9713-objs := wm9713.o
- snd-soc-wm-hubs-objs := wm_hubs.o
-+snd-soc-mxs-builtin-codec-objs := mxs-builtin-codec.o
-
- # Amp
- snd-soc-max9877-objs := max9877.o
-@@ -242,6 +243,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-
- obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
- obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
- obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
-+obj-$(CONFIG_SND_SOC_MXS_BUILTIN_CODEC) += snd-soc-mxs-builtin-codec.o
-
- # Amp
- obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
---- /dev/null
-+++ b/sound/soc/codecs/mxs-builtin-codec.c
-@@ -0,0 +1,1128 @@
-+/*
-+ * mxs-builtin-codec.c -- i.MX233 built-in codec ALSA Soc Audio driver
-+ *
-+ * Author: Michal Ulianko <michal.ulianko@gmail.com>
-+ *
-+ * Based on sound/soc/codecs/mxs-adc-codec.c for kernel 2.6.35
-+ * by Vladislav Buzov <vbuzov@embeddedalley.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <sound/pcm.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+
-+#include "mxs-builtin-codec.h"
-+
-+#ifndef BF
-+#define BF(value, field) (((value) << BP_##field) & BM_##field)
-+#endif
-+
-+/* TODO Delete this and use BM_RTC_PERSISTENT0_RELEASE_GND from header file
-+ * if it works. */
-+#define BP_RTC_PERSISTENT0_SPARE_ANALOG 18
-+#define BM_RTC_PERSISTENT0_SPARE_ANALOG 0xFFFC0000
-+#define BM_RTC_PERSISTENT0_RELEASE_GND BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG)
-+
-+/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */
-+
-+struct mxs_adc_priv {
-+ void __iomem *ain_base;
-+ void __iomem *aout_base;
-+ void __iomem *rtc_base;
-+ struct clk *clk;
-+};
-+
-+static unsigned int mxs_regmap[] = {
-+ HW_AUDIOOUT_CTRL,
-+ HW_AUDIOOUT_STAT,
-+ HW_AUDIOOUT_DACSRR,
-+ HW_AUDIOOUT_DACVOLUME,
-+ HW_AUDIOOUT_DACDEBUG,
-+ HW_AUDIOOUT_HPVOL,
-+ HW_AUDIOOUT_PWRDN,
-+ HW_AUDIOOUT_REFCTRL,
-+ HW_AUDIOOUT_ANACTRL,
-+ HW_AUDIOOUT_TEST,
-+ HW_AUDIOOUT_BISTCTRL,
-+ HW_AUDIOOUT_BISTSTAT0,
-+ HW_AUDIOOUT_BISTSTAT1,
-+ HW_AUDIOOUT_ANACLKCTRL,
-+ HW_AUDIOOUT_DATA,
-+ HW_AUDIOOUT_SPEAKERCTRL,
-+ HW_AUDIOOUT_VERSION,
-+ HW_AUDIOIN_CTRL,
-+ HW_AUDIOIN_STAT,
-+ HW_AUDIOIN_ADCSRR,
-+ HW_AUDIOIN_ADCVOLUME,
-+ HW_AUDIOIN_ADCDEBUG,
-+ HW_AUDIOIN_ADCVOL,
-+ HW_AUDIOIN_MICLINE,
-+ HW_AUDIOIN_ANACLKCTRL,
-+ HW_AUDIOIN_DATA,
-+};
-+
-+static void __iomem *mxs_getreg(struct mxs_adc_priv *mxs_adc, int i)
-+{
-+ if (i <= 16)
-+ return mxs_adc->aout_base + mxs_regmap[i];
-+ else if (i < ADC_REGNUM)
-+ return mxs_adc->ain_base + mxs_regmap[i];
-+ else
-+ return NULL;
-+}
-+
-+static u8 dac_volumn_control_word[] = {
-+ 0x37, 0x5e, 0x7e, 0x8e,
-+ 0x9e, 0xae, 0xb6, 0xbe,
-+ 0xc6, 0xce, 0xd6, 0xde,
-+ 0xe6, 0xee, 0xf6, 0xfe,
-+};
-+
-+struct dac_srr {
-+ u32 rate;
-+ u32 basemult;
-+ u32 src_hold;
-+ u32 src_int;
-+ u32 src_frac;
-+};
-+
-+static struct dac_srr srr_values[] = {
-+ {192000, 0x4, 0x0, 0x0F, 0x13FF},
-+ {176400, 0x4, 0x0, 0x11, 0x0037},
-+ {128000, 0x4, 0x0, 0x17, 0x0E00},
-+ {96000, 0x2, 0x0, 0x0F, 0x13FF},
-+ {88200, 0x2, 0x0, 0x11, 0x0037},
-+ {64000, 0x2, 0x0, 0x17, 0x0E00},
-+ {48000, 0x1, 0x0, 0x0F, 0x13FF},
-+ {44100, 0x1, 0x0, 0x11, 0x0037},
-+ {32000, 0x1, 0x0, 0x17, 0x0E00},
-+ {24000, 0x1, 0x1, 0x0F, 0x13FF},
-+ {22050, 0x1, 0x1, 0x11, 0x0037},
-+ {16000, 0x1, 0x1, 0x17, 0x0E00},
-+ {12000, 0x1, 0x3, 0x0F, 0x13FF},
-+ {11025, 0x1, 0x3, 0x11, 0x0037},
-+ {8000, 0x1, 0x3, 0x17, 0x0E00}
-+};
-+
-+static inline int get_srr_values(int rate)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(srr_values); i++)
-+ if (srr_values[i].rate == rate)
-+ return i;
-+
-+ return -1;
-+}
-+
-+/* SoC IO functions */
-+static void mxs_codec_write_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
-+{
-+ u16 *cache = codec->reg_cache;
-+ if (reg < ADC_REGNUM)
-+ cache[reg] = value;
-+}
-+
-+static int mxs_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+ unsigned int reg_val;
-+ unsigned int mask = 0xffff;
-+
-+ if (reg >= ADC_REGNUM)
-+ return -EIO;
-+
-+ mxs_codec_write_cache(codec, reg, value);
-+
-+ if (reg & 0x1) {
-+ mask <<= 16;
-+ value <<= 16;
-+ }
-+
-+ reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1));
-+ reg_val = (reg_val & ~mask) | value;
-+ __raw_writel(reg_val, mxs_getreg(mxs_adc, reg >> 1));
-+
-+ return 0;
-+}
-+
-+static unsigned int mxs_codec_read(struct snd_soc_codec *codec, unsigned int reg)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+ unsigned int reg_val;
-+
-+ if (reg >= ADC_REGNUM)
-+ return -1;
-+
-+ reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1));
-+ if (reg & 1)
-+ reg_val >>= 16;
-+
-+ return reg_val & 0xffff;
-+}
-+
-+// static unsigned int mxs_codec_read_cache(struct snd_soc_codec *codec, unsigned int reg)
-+// {
-+// u16 *cache = codec->reg_cache;
-+// if (reg >= ADC_REGNUM)
-+// return -EINVAL;
-+// return cache[reg];
-+// }
-+
-+static void mxs_codec_sync_reg_cache(struct snd_soc_codec *codec)
-+{
-+ int reg;
-+ for (reg = 0; reg < ADC_REGNUM; reg += 1)
-+ mxs_codec_write_cache(codec, reg,
-+ mxs_codec_read(codec, reg));
-+}
-+
-+// static int mxs_codec_restore_reg(struct snd_soc_codec *codec, unsigned int reg)
-+// {
-+// unsigned int cached_val, hw_val;
-+//
-+// cached_val = mxs_codec_read_cache(codec, reg);
-+// hw_val = mxs_codec_read(codec, reg);
-+//
-+// if (hw_val != cached_val)
-+// return mxs_codec_write(codec, reg, cached_val);
-+//
-+// return 0;
-+// }
-+/* END SoC IO functions */
-+
-+/* Codec routines */
-+#define VAG_BASE_VALUE ((1400/2 - 625)/25)
-+
-+static void mxs_codec_dac_set_vag(struct mxs_adc_priv *mxs_adc)
-+{
-+ u32 refctrl_val = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL);
-+
-+ refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VAG_VAL);
-+ refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VBG_ADJ);
-+ refctrl_val |= BF(VAG_BASE_VALUE, AUDIOOUT_REFCTRL_VAG_VAL) |
-+ BM_AUDIOOUT_REFCTRL_ADJ_VAG |
-+ BF(0xF, AUDIOOUT_REFCTRL_ADC_REFVAL) |
-+ BM_AUDIOOUT_REFCTRL_ADJ_ADC |
-+ BF(0x3, AUDIOOUT_REFCTRL_VBG_ADJ) | BM_AUDIOOUT_REFCTRL_RAISE_REF;
-+
-+ __raw_writel(refctrl_val, mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL);
-+}
-+
-+static bool mxs_codec_dac_is_capless(struct mxs_adc_priv *mxs_adc)
-+{
-+ if ((__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_PWRDN)
-+ & BM_AUDIOOUT_PWRDN_CAPLESS) == 0)
-+ return false;
-+ else
-+ return true;
-+}
-+
-+static void mxs_codec_dac_arm_short_cm(struct mxs_adc_priv *mxs_adc, bool bShort)
-+{
-+ __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_CM),
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_CM_STS,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ if (bShort)
-+ __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_CM),
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
-+}
-+
-+static void mxs_codec_dac_arm_short_lr(struct mxs_adc_priv *mxs_adc, bool bShort)
-+{
-+ __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_LR),
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ if (bShort)
-+ __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_LR),
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
-+}
-+
-+static void mxs_codec_dac_set_short_trip_level(struct mxs_adc_priv *mxs_adc, u8 u8level)
-+{
-+ __raw_writel(__raw_readl(mxs_adc->aout_base +
-+ HW_AUDIOOUT_ANACTRL)
-+ & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL)
-+ & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR)
-+ | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJL)
-+ | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJR),
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL);
-+}
-+
-+static void mxs_codec_dac_arm_short(struct mxs_adc_priv *mxs_adc, bool bLatchCM, bool bLatchLR)
-+{
-+ if (bLatchCM) {
-+ if (mxs_codec_dac_is_capless(mxs_adc))
-+ mxs_codec_dac_arm_short_cm(mxs_adc, true);
-+ } else
-+ mxs_codec_dac_arm_short_cm(mxs_adc, false);
-+
-+ if (bLatchLR)
-+ mxs_codec_dac_arm_short_lr(mxs_adc, true);
-+ else
-+ mxs_codec_dac_arm_short_lr(mxs_adc, false);
-+}
-+
-+static void
-+mxs_codec_dac_power_on(struct mxs_adc_priv *mxs_adc)
-+{
-+ /* Ungate DAC clocks */
-+ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
-+ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_CLR);
-+
-+ /* 16 bit word length */
-+ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
-+
-+ /* Arm headphone LR short protect */
-+ mxs_codec_dac_set_short_trip_level(mxs_adc, 0);
-+ mxs_codec_dac_arm_short(mxs_adc, false, true);
-+
-+ /* Update DAC volume over zero crossings */
-+ __raw_writel(BM_AUDIOOUT_DACVOLUME_EN_ZCD,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
-+ /* Mute DAC */
-+ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
-+ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
-+
-+ /* Update HP volume over zero crossings */
-+ __raw_writel(BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD,
-+ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
-+
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
-+
-+ /* Mute HP output */
-+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
-+ /* Mute speaker amp */
-+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
-+ /* Enable the audioout */
-+ __raw_writel(BM_AUDIOOUT_CTRL_RUN,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
-+}
-+
-+static void
-+mxs_codec_dac_power_down(struct mxs_adc_priv *mxs_adc)
-+{
-+ /* Disable the audioout */
-+ __raw_writel(BM_AUDIOOUT_CTRL_RUN,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
-+ /* Disable class AB */
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+
-+ /* Set hold to ground */
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
-+
-+ /* Mute HP output */
-+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
-+ /* Power down HP output */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
-+
-+ /* Mute speaker amp */
-+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
-+ /* Power down speaker amp */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_SPEAKER,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
-+
-+ /* Mute DAC */
-+ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
-+ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
-+ /* Power down DAC */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_DAC,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
-+
-+ /* Gate DAC clocks */
-+ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_SET);
-+ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
-+}
-+
-+static void
-+mxs_codec_adc_power_on(struct mxs_adc_priv *mxs_adc)
-+{
-+ u32 reg;
-+
-+ /* Ungate ADC clocks */
-+ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
-+ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
-+ mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_CLR);
-+
-+ /* 16 bit word length */
-+ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
-+
-+ /* Unmute ADC channels */
-+ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
-+
-+ /*
-+ * The MUTE_LEFT and MUTE_RIGHT fields need to be cleared.
-+ * They aren't presented in the datasheet, so this is hardcode.
-+ */
-+ __raw_writel(0x01000100, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME_CLR);
-+
-+ /* Set the Input channel gain 3dB */
-+ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_LEFT,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
-+ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_RIGHT,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
-+ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_LEFT),
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
-+ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_RIGHT),
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
-+
-+ /* Select default input - Microphone */
-+ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_LEFT,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
-+ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_RIGHT,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
-+ __raw_writel(BF
-+ (BV_AUDIOIN_ADCVOL_SELECT__MIC,
-+ AUDIOIN_ADCVOL_SELECT_LEFT),
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
-+ __raw_writel(BF
-+ (BV_AUDIOIN_ADCVOL_SELECT__MIC,
-+ AUDIOIN_ADCVOL_SELECT_RIGHT),
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
-+
-+ /* Supply bias voltage to microphone */
-+ __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_RESISTOR),
-+ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
-+ __raw_writel(BM_AUDIOIN_MICLINE_MIC_SELECT,
-+ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
-+ __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_GAIN),
-+ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
-+ __raw_writel(BF(7, AUDIOIN_MICLINE_MIC_BIAS),
-+ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
-+
-+ /* Set max ADC volume */
-+ reg = __raw_readl(mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME);
-+ reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
-+ reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
-+ reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_LEFT);
-+ reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_RIGHT);
-+ __raw_writel(reg, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME);
-+}
-+
-+static void
-+mxs_codec_adc_power_down(struct mxs_adc_priv *mxs_adc)
-+{
-+ /* Mute ADC channels */
-+ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
-+
-+ /* Power Down ADC */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_ADC | BM_AUDIOOUT_PWRDN_RIGHT_ADC,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
-+
-+ /* Gate ADC clocks */
-+ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
-+ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
-+ mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_SET);
-+
-+ /* Disable bias voltage to microphone */
-+ __raw_writel(BF(0, AUDIOIN_MICLINE_MIC_RESISTOR),
-+ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
-+}
-+
-+static void mxs_codec_dac_enable(struct mxs_adc_priv *mxs_adc)
-+{
-+ /* Move DAC codec out of reset */
-+ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
-+
-+ /* Reduce analog power */
-+ __raw_writel(BM_AUDIOOUT_TEST_HP_I1_ADJ,
-+ mxs_adc->aout_base + HW_AUDIOOUT_TEST_CLR);
-+ __raw_writel(BF(0x1, AUDIOOUT_TEST_HP_I1_ADJ),
-+ mxs_adc->aout_base + HW_AUDIOOUT_TEST_SET);
-+ __raw_writel(BM_AUDIOOUT_REFCTRL_LOW_PWR,
-+ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET);
-+ __raw_writel(BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS,
-+ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET);
-+ __raw_writel(BM_AUDIOOUT_REFCTRL_BIAS_CTRL,
-+ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR);
-+ __raw_writel(BF(0x1, AUDIOOUT_REFCTRL_BIAS_CTRL),
-+ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR);
-+
-+ /* Set Vag value */
-+ mxs_codec_dac_set_vag(mxs_adc);
-+
-+ /* Power on DAC codec */
-+ mxs_codec_dac_power_on(mxs_adc);
-+}
-+
-+static void mxs_codec_dac_disable(struct mxs_adc_priv *mxs_adc)
-+{
-+ mxs_codec_dac_power_down(mxs_adc);
-+}
-+
-+static void mxs_codec_adc_enable(struct mxs_adc_priv *mxs_adc)
-+{
-+ /* Move ADC codec out of reset */
-+ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
-+
-+ /* Power on ADC codec */
-+ mxs_codec_adc_power_on(mxs_adc);
-+}
-+
-+static void mxs_codec_adc_disable(struct mxs_adc_priv *mxs_adc)
-+{
-+ mxs_codec_adc_power_down(mxs_adc);
-+}
-+
-+static void mxs_codec_startup(struct snd_soc_codec *codec)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+
-+ /* Soft reset DAC block */
-+ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
-+ while (!(__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_CTRL)
-+ & BM_AUDIOOUT_CTRL_CLKGATE)){
-+ }
-+
-+ /* Soft reset ADC block */
-+ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
-+ while (!(__raw_readl(mxs_adc->ain_base + HW_AUDIOIN_CTRL)
-+ & BM_AUDIOIN_CTRL_CLKGATE)){
-+ }
-+
-+ mxs_codec_dac_enable(mxs_adc);
-+ mxs_codec_adc_enable(mxs_adc);
-+
-+ /* Sync regs and cache */
-+ mxs_codec_sync_reg_cache(codec);
-+}
-+
-+static void mxs_codec_stop(struct snd_soc_codec *codec)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+
-+ mxs_codec_dac_disable(mxs_adc);
-+ mxs_codec_adc_disable(mxs_adc);
-+}
-+/* END Codec routines */
-+
-+/* kcontrol */
-+static int dac_info_volsw(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_info *uinfo)
-+{
-+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-+ uinfo->count = 2;
-+ uinfo->value.integer.min = 0;
-+ uinfo->value.integer.max = 0xf;
-+ return 0;
-+}
-+
-+static int dac_get_volsw(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+ int reg, l, r;
-+ int i;
-+
-+ reg = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
-+
-+ l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >>
-+ BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
-+ r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >>
-+ BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
-+ /*Left channel */
-+ i = 0;
-+ while (i < 16) {
-+ if (l == dac_volumn_control_word[i]) {
-+ ucontrol->value.integer.value[0] = i;
-+ break;
-+ }
-+ i++;
-+ }
-+ if (i == 16)
-+ ucontrol->value.integer.value[0] = i;
-+ /*Right channel */
-+ i = 0;
-+ while (i < 16) {
-+ if (r == dac_volumn_control_word[i]) {
-+ ucontrol->value.integer.value[1] = i;
-+ break;
-+ }
-+ i++;
-+ }
-+ if (i == 16)
-+ ucontrol->value.integer.value[1] = i;
-+
-+ return 0;
-+}
-+
-+static int dac_put_volsw(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+ int reg, l, r;
-+ int i;
-+
-+ i = ucontrol->value.integer.value[0];
-+ l = dac_volumn_control_word[i];
-+ /*Get dac volume for left channel */
-+ reg = BF(l, AUDIOOUT_DACVOLUME_VOLUME_LEFT);
-+
-+ i = ucontrol->value.integer.value[1];
-+ r = dac_volumn_control_word[i];
-+ /*Get dac volume for right channel */
-+ reg = reg | BF(r, AUDIOOUT_DACVOLUME_VOLUME_RIGHT);
-+
-+ /*Clear left/right dac volume */
-+ __raw_writel(BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT |
-+ BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR);
-+ __raw_writel(reg, mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
-+
-+ return 0;
-+}
-+
-+static const char *mxs_codec_adc_input_sel[] = {
-+ "Mic", "Line In 1", "Head Phone", "Line In 2" };
-+
-+static const char *mxs_codec_hp_output_sel[] = { "DAC Out", "Line In 1" };
-+
-+static const char *mxs_codec_adc_3d_sel[] = {
-+ "Off", "Low", "Medium", "High" };
-+
-+static const struct soc_enum mxs_codec_enum[] = {
-+ SOC_ENUM_SINGLE(ADC_ADCVOL_L, 12, 4, mxs_codec_adc_input_sel),
-+ SOC_ENUM_SINGLE(ADC_ADCVOL_L, 4, 4, mxs_codec_adc_input_sel),
-+ SOC_ENUM_SINGLE(DAC_HPVOL_H, 0, 2, mxs_codec_hp_output_sel),
-+ SOC_ENUM_SINGLE(DAC_CTRL_L, 8, 4, mxs_codec_adc_3d_sel),
-+};
-+
-+static const struct snd_kcontrol_new mxs_snd_controls[] = {
-+ /* Playback Volume */
-+ {
-+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-+ .name = "DAC Playback Volume",
-+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
-+ .info = dac_info_volsw,
-+ .get = dac_get_volsw,
-+ .put = dac_put_volsw,
-+ },
-+
-+ SOC_DOUBLE_R("DAC Playback Switch",
-+ DAC_VOLUME_H, DAC_VOLUME_L, 8, 0x01, 1),
-+ SOC_DOUBLE("HP Playback Volume", DAC_HPVOL_L, 8, 0, 0x7F, 1),
-+
-+ /* Capture Volume */
-+ SOC_DOUBLE_R("ADC Capture Volume",
-+ ADC_VOLUME_H, ADC_VOLUME_L, 0, 0xFF, 0),
-+ SOC_DOUBLE("ADC PGA Capture Volume", ADC_ADCVOL_L, 8, 0, 0x0F, 0),
-+ SOC_SINGLE("ADC PGA Capture Switch", ADC_ADCVOL_H, 8, 0x1, 1),
-+ SOC_SINGLE("Mic PGA Capture Volume", ADC_MICLINE_L, 0, 0x03, 0),
-+
-+ /* Virtual 3D effect */
-+ SOC_ENUM("3D effect", mxs_codec_enum[3]),
-+};
-+/* END kcontrol */
-+
-+/* DAPM */
-+static int pga_event(struct snd_soc_dapm_widget *w,
-+ struct snd_kcontrol *kcontrol, int event)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec);
-+
-+ switch (event) {
-+ case SND_SOC_DAPM_PRE_PMU:
-+ /* Prepare powering up HP and SPEAKER output */
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
-+ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
-+ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET);
-+ msleep(100);
-+ break;
-+ case SND_SOC_DAPM_POST_PMU:
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
-+ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ break;
-+ case SND_SOC_DAPM_POST_PMD:
-+ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
-+ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int adc_event(struct snd_soc_dapm_widget *w,
-+ struct snd_kcontrol *kcontrol, int event)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec);
-+
-+ switch (event) {
-+ case SND_SOC_DAPM_PRE_PMU:
-+ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
-+ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET);
-+ msleep(100);
-+ break;
-+ case SND_SOC_DAPM_POST_PMD:
-+ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
-+ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/* Left ADC Mux */
-+static const struct snd_kcontrol_new mxs_left_adc_controls =
-+SOC_DAPM_ENUM("Route", mxs_codec_enum[0]);
-+
-+/* Right ADC Mux */
-+static const struct snd_kcontrol_new mxs_right_adc_controls =
-+SOC_DAPM_ENUM("Route", mxs_codec_enum[1]);
-+
-+/* Head Phone Mux */
-+static const struct snd_kcontrol_new mxs_hp_controls =
-+SOC_DAPM_ENUM("Route", mxs_codec_enum[2]);
-+
-+static const struct snd_soc_dapm_widget mxs_dapm_widgets[] = {
-+ SND_SOC_DAPM_ADC_E("ADC", "Capture", DAC_PWRDN_L, 8, 1, adc_event,
-+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-+
-+ SND_SOC_DAPM_DAC("DAC", "Playback", DAC_PWRDN_L, 12, 1),
-+
-+ SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
-+ &mxs_left_adc_controls),
-+ SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
-+ &mxs_right_adc_controls),
-+ SND_SOC_DAPM_MUX("HP Mux", SND_SOC_NOPM, 0, 0,
-+ &mxs_hp_controls),
-+ SND_SOC_DAPM_PGA_E("HP AMP", DAC_PWRDN_L, 0, 1, NULL, 0, pga_event,
-+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
-+ SND_SOC_DAPM_POST_PMD),
-+ SND_SOC_DAPM_PGA("SPEAKER AMP", DAC_PWRDN_H, 8, 1, NULL, 0),
-+ SND_SOC_DAPM_INPUT("LINE1L"),
-+ SND_SOC_DAPM_INPUT("LINE1R"),
-+ SND_SOC_DAPM_INPUT("LINE2L"),
-+ SND_SOC_DAPM_INPUT("LINE2R"),
-+ SND_SOC_DAPM_INPUT("MIC"),
-+
-+ SND_SOC_DAPM_OUTPUT("SPEAKER"),
-+ SND_SOC_DAPM_OUTPUT("HPL"),
-+ SND_SOC_DAPM_OUTPUT("HPR"),
-+};
-+
-+/* routes for sgtl5000 */
-+static const struct snd_soc_dapm_route mxs_dapm_routes[] = {
-+ /* Left ADC Mux */
-+ {"Left ADC Mux", "Mic", "MIC"},
-+ {"Left ADC Mux", "Line In 1", "LINE1L"},
-+ {"Left ADC Mux", "Line In 2", "LINE2L"},
-+ {"Left ADC Mux", "Head Phone", "HPL"},
-+
-+ /* Right ADC Mux */
-+ {"Right ADC Mux", "Mic", "MIC"},
-+ {"Right ADC Mux", "Line In 1", "LINE1R"},
-+ {"Right ADC Mux", "Line In 2", "LINE2R"},
-+ {"Right ADC Mux", "Head Phone", "HPR"},
-+
-+ /* ADC */
-+ {"ADC", NULL, "Left ADC Mux"},
-+ {"ADC", NULL, "Right ADC Mux"},
-+
-+ /* HP Mux */
-+ {"HP Mux", "DAC Out", "DAC"},
-+ {"HP Mux", "Line In 1", "LINE1L"},
-+ {"HP Mux", "Line In 1", "LINE1R"},
-+
-+ /* HP amp */
-+ {"HP AMP", NULL, "HP Mux"},
-+ /* HP output */
-+ {"HPR", NULL, "HP AMP"},
-+ {"HPL", NULL, "HP AMP"},
-+
-+ /* Speaker amp */
-+ {"SPEAKER AMP", NULL, "DAC"},
-+ {"SPEAKER", NULL, "SPEAKER AMP"},
-+};
-+/* END DAPM */
-+
-+static int mxs_set_bias_level(struct snd_soc_codec *codec,
-+ enum snd_soc_bias_level level)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+
-+ pr_debug("dapm level %d\n", level);
-+ switch (level) {
-+ case SND_SOC_BIAS_ON: /* full On */
-+ if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
-+ break;
-+ break;
-+
-+ case SND_SOC_BIAS_PREPARE: /* partial On */
-+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
-+ break;
-+ /* Set Capless mode */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_CLR);
-+ break;
-+
-+ case SND_SOC_BIAS_STANDBY: /* Off, with power */
-+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
-+ break;
-+ /* Unset Capless mode */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
-+ break;
-+
-+ case SND_SOC_BIAS_OFF: /* Off, without power */
-+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
-+ break;
-+ /* Unset Capless mode */
-+ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
-+ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
-+ break;
-+ }
-+
-+ codec->dapm.bias_level = level;
-+ return 0;
-+}
-+
-+/* MXS-ADC Codec DAI driver */
-+static int mxs_pcm_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params,
-+ struct snd_soc_dai *dai)
-+{
-+ struct snd_soc_codec *codec = dai->codec;
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
-+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
-+ int i;
-+ u32 srr_value = 0;
-+ u32 src_hold = 0;
-+
-+ i = get_srr_values(params_rate(params));
-+ if (i < 0)
-+ dev_warn(codec->dev, "%s doesn't support rate %d\n",
-+ codec->name, params_rate(params));
-+ else {
-+ src_hold = srr_values[i].src_hold;
-+
-+ srr_value =
-+ BF(srr_values[i].basemult, AUDIOOUT_DACSRR_BASEMULT) |
-+ BF(srr_values[i].src_int, AUDIOOUT_DACSRR_SRC_INT) |
-+ BF(srr_values[i].src_frac, AUDIOOUT_DACSRR_SRC_FRAC) |
-+ BF(src_hold, AUDIOOUT_DACSRR_SRC_HOLD);
-+
-+ if (playback)
-+ __raw_writel(srr_value,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACSRR);
-+ else
-+ __raw_writel(srr_value,
-+ mxs_adc->ain_base + HW_AUDIOIN_ADCSRR);
-+ }
-+
-+ switch (params_format(params)) {
-+ case SNDRV_PCM_FORMAT_S16_LE:
-+ if (playback)
-+ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
-+ else
-+ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
-+
-+ break;
-+
-+ case SNDRV_PCM_FORMAT_S32_LE:
-+ if (playback)
-+ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
-+ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
-+ else
-+ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
-+ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
-+
-+ break;
-+
-+ default:
-+ dev_warn(codec->dev, "%s doesn't support format %d\n",
-+ codec->name, params_format(params));
-+
-+ }
-+
-+ return 0;
-+}
-+
-+/* mute the codec used by alsa core */
-+static int mxs_codec_dig_mute(struct snd_soc_dai *codec_dai, int mute)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec_dai->codec);
-+ int l, r;
-+ int ll, rr;
-+ u32 reg, reg1, reg2;
-+ u32 dac_mask = BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
-+ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT;
-+
-+ if (mute) {
-+ reg = __raw_readl(mxs_adc->aout_base + \
-+ HW_AUDIOOUT_DACVOLUME);
-+
-+ reg1 = reg & ~BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
-+ reg1 = reg1 & ~BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
-+
-+ l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >>
-+ BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
-+ r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >>
-+ BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
-+
-+ /* fade out dac vol */
-+ while ((l > DAC_VOLUME_MIN) || (r > DAC_VOLUME_MIN)) {
-+ l -= 0x8;
-+ r -= 0x8;
-+ ll = l > DAC_VOLUME_MIN ? l : DAC_VOLUME_MIN;
-+ rr = r > DAC_VOLUME_MIN ? r : DAC_VOLUME_MIN;
-+ reg2 = reg1 | BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(ll)
-+ | BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(rr);
-+ __raw_writel(reg2,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
-+ msleep(1);
-+ }
-+
-+ __raw_writel(dac_mask,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
-+ reg = reg | dac_mask;
-+ __raw_writel(reg,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
-+ } else
-+ __raw_writel(dac_mask,
-+ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR);
-+
-+ return 0;
-+}
-+
-+#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
-+#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-+
-+static const struct snd_soc_dai_ops mxs_codec_dai_ops = {
-+ .hw_params = mxs_pcm_hw_params,
-+ .digital_mute = mxs_codec_dig_mute,
-+};
-+
-+static struct snd_soc_dai_driver mxs_codec_dai_driver = {
-+ .name = "mxs-builtin-codec-dai",
-+ .playback = {
-+ .stream_name = "Playback",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rates = MXS_ADC_RATES,
-+ .formats = MXS_ADC_FORMATS,
-+ },
-+ .capture = {
-+ .stream_name = "Capture",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rates = MXS_ADC_RATES,
-+ .formats = MXS_ADC_FORMATS,
-+ },
-+ .ops = &mxs_codec_dai_ops,
-+};
-+/* END MXS-ADC Codec DAI driver */
-+
-+/* MXS-ADC Codec driver */
-+static int mxs_codec_driver_probe(struct snd_soc_codec *codec)
-+{
-+ int ret = 0;
-+ /* We don't use snd_soc_codec_set_cache_io because we are using
-+ * our own IO functions: write, read. */
-+
-+ mxs_codec_startup(codec);
-+
-+ /* leading to standby state */
-+ ret = mxs_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-+ if (ret)
-+ goto err;
-+
-+ return 0;
-+
-+err:
-+ mxs_codec_stop(codec);
-+
-+ return ret;
-+}
-+
-+static int mxs_codec_driver_remove(struct snd_soc_codec *codec)
-+{
-+ mxs_codec_stop(codec);
-+
-+ return 0;
-+}
-+
-+// static int mxs_codec_driver_suspend(struct snd_soc_codec *codec)
-+// {
-+// /* TODO Enable power management. */
-+// return 0;
-+// }
-+
-+// static int mxs_codec_driver_resume(struct snd_soc_codec *codec)
-+// {
-+// /* TODO Enable power management. */
-+// return 0;
-+// }
-+
-+static struct snd_soc_codec_driver mxs_codec_driver = {
-+ .probe = mxs_codec_driver_probe,
-+ .remove = mxs_codec_driver_remove,
-+// .suspend = mxs_codec_driver_suspend,
-+// .resume = mxs_codec_driver_resume,
-+ .set_bias_level = mxs_set_bias_level,
-+ .reg_cache_size = ADC_REGNUM,
-+ .reg_word_size = sizeof(u16),
-+ .reg_cache_step = 1,
-+// .reg_cache_default = mxsadc_regs,
-+// .volatile_register = sgtl5000_volatile_register,
-+ .controls = mxs_snd_controls,
-+ .num_controls = ARRAY_SIZE(mxs_snd_controls),
-+ .dapm_widgets = mxs_dapm_widgets,
-+ .num_dapm_widgets = ARRAY_SIZE(mxs_dapm_widgets),
-+ .dapm_routes = mxs_dapm_routes,
-+ .num_dapm_routes = ARRAY_SIZE(mxs_dapm_routes),
-+ .write = mxs_codec_write,
-+ .read = mxs_codec_read,
-+};
-+/* END MXS-ADC Codec driver */
-+
-+/* Underlying platform device that registers codec */
-+static int mxs_adc_probe(struct platform_device *pdev)
-+{
-+ struct mxs_adc_priv *mxs_adc;
-+ struct resource *r;
-+ int ret;
-+
-+ mxs_adc = devm_kzalloc(&pdev->dev, sizeof(struct mxs_adc_priv), GFP_KERNEL);
-+ if (!mxs_adc)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, mxs_adc);
-+
-+ /* audio-in IO memory */
-+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioin");
-+ if (IS_ERR(r)) {
-+ dev_err(&pdev->dev, "failed to get resource\n");
-+ return PTR_ERR(r);
-+ }
-+
-+ mxs_adc->ain_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-+ if (IS_ERR(mxs_adc->ain_base)) {
-+ dev_err(&pdev->dev, "ioremap failed\n");
-+ return PTR_ERR(mxs_adc->ain_base);
-+ }
-+
-+ /* audio-out IO memory */
-+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioout");
-+ if (IS_ERR(r)) {
-+ dev_err(&pdev->dev, "failed to get resource\n");
-+ return PTR_ERR(r);
-+ }
-+
-+ mxs_adc->aout_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-+ if (IS_ERR(mxs_adc->aout_base)) {
-+ dev_err(&pdev->dev, "ioremap failed\n");
-+ return PTR_ERR(mxs_adc->aout_base);
-+ }
-+
-+ /* rtc IO memory */
-+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
-+ if (IS_ERR(r)) {
-+ dev_err(&pdev->dev, "failed to get resource\n");
-+ return PTR_ERR(r);
-+ }
-+
-+ mxs_adc->rtc_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
-+ if (IS_ERR(mxs_adc->rtc_base)) {
-+ dev_err(&pdev->dev, "ioremap failed\n");
-+ return PTR_ERR(mxs_adc->rtc_base);
-+ }
-+
-+ /* Get audio clock */
-+ mxs_adc->clk = devm_clk_get(&pdev->dev, "filt");
-+ if (IS_ERR(mxs_adc->clk)) {
-+ ret = PTR_ERR(mxs_adc->clk);
-+ dev_err(&pdev->dev, "%s: Clock initialization failed\n", __func__);
-+ return ret;
-+ }
-+
-+ /* Turn on audio clock */
-+ ret = clk_prepare_enable(mxs_adc->clk);
-+ if (unlikely(ret != 0)) {
-+ dev_err(&pdev->dev, "%s: Clock prepare or enable failed\n", __func__);
-+ return ret;
-+ }
-+
-+ ret = snd_soc_register_codec(&pdev->dev,
-+ &mxs_codec_driver,&mxs_codec_dai_driver, 1);
-+ if (unlikely(ret != 0)) {
-+ dev_err(&pdev->dev, "Codec registration failed\n");
-+ goto disable_clk;
-+ }
-+
-+ return 0;
-+
-+disable_clk:
-+ clk_disable_unprepare(mxs_adc->clk);
-+ return ret;
-+}
-+
-+static int mxs_adc_remove(struct platform_device *pdev)
-+{
-+ struct mxs_adc_priv *mxs_adc = platform_get_drvdata(pdev);
-+
-+ clk_disable_unprepare(mxs_adc->clk);
-+ snd_soc_unregister_codec(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mxs_adc_dt_ids[] = {
-+ { .compatible = "fsl,mxs-builtin-codec", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mxs_adc_dt_ids);
-+
-+static struct platform_driver mxs_adc_driver = {
-+ .driver = {
-+ .name = "mxs-builtin-codec",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mxs_adc_dt_ids,
-+ },
-+ .probe = mxs_adc_probe,
-+ .remove = mxs_adc_remove,
-+};
-+
-+module_platform_driver(mxs_adc_driver);
-+/* END Underlying platform device that registers codec */
-+
-+MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec Driver");
-+MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/sound/soc/codecs/mxs-builtin-codec.h
-@@ -0,0 +1,825 @@
-+#ifndef __MXS_ADC_CODEC_H
-+
-+#include <linux/io.h>
-+
-+/* MXS ADC/DAC registers */
-+#define DAC_CTRL_L 0
-+#define DAC_CTRL_H 1
-+#define DAC_STAT_L 2
-+#define DAC_STAT_H 3
-+#define DAC_SRR_L 4
-+#define DAC_VOLUME_L 6
-+#define DAC_VOLUME_H 7
-+#define DAC_DEBUG_L 8
-+#define DAC_DEBUG_H 9
-+#define DAC_HPVOL_L 10
-+#define DAC_HPVOL_H 11
-+#define DAC_PWRDN_L 12
-+#define DAC_PWRDN_H 13
-+#define DAC_REFCTRL_L 14
-+#define DAC_REFCTRL_H 15
-+#define DAC_ANACTRL_L 16
-+#define DAC_ANACTRL_H 17
-+#define DAC_TEST_L 18
-+#define DAC_TEST_H 19
-+#define DAC_BISTCTRL_L 20
-+#define DAC_BISTCTRL_H 21
-+#define DAC_BISTSTAT0_L 22
-+#define DAC_BISTSTAT0_H 23
-+#define DAC_BISTSTAT1_L 24
-+#define DAC_BISTSTAT1_H 25
-+#define DAC_ANACLKCTRL_L 26
-+#define DAC_ANACLKCTRL_H 27
-+#define DAC_DATA_L 28
-+#define DAC_DATA_H 29
-+#define DAC_SPEAKERCTRL_L 30
-+#define DAC_SPEAKERCTRL_H 31
-+#define DAC_VERSION_L 32
-+#define DAC_VERSION_H 33
-+#define ADC_CTRL_L 34
-+#define ADC_CTRL_H 35
-+#define ADC_STAT_L 36
-+#define ADC_STAT_H 37
-+#define ADC_SRR_L 38
-+#define ADC_SRR_H 39
-+#define ADC_VOLUME_L 40
-+#define ADC_VOLUME_H 41
-+#define ADC_DEBUG_L 42
-+#define ADC_DEBUG_H 43
-+#define ADC_ADCVOL_L 44
-+#define ADC_ADCVOL_H 45
-+#define ADC_MICLINE_L 46
-+#define ADC_MICLINE_H 47
-+#define ADC_ANACLKCTRL_L 48
-+#define ADC_ANACLKCTRL_H 49
-+#define ADC_DATA_L 50
-+#define ADC_DATA_H 51
-+
-+#define ADC_REGNUM 52
-+
-+#define DAC_VOLUME_MIN 0x37
-+#define DAC_VOLUME_MAX 0xFE
-+#define ADC_VOLUME_MIN 0x37
-+#define ADC_VOLUME_MAX 0xFE
-+#define HP_VOLUME_MAX 0x0
-+#define HP_VOLUME_MIN 0x7F
-+#define LO_VOLUME_MAX 0x0
-+#define LO_VOLUME_MIN 0x1F
-+
-+/* RTC */
-+#define HW_RTC_PERSISTENT0 (0x00000060)
-+#define HW_RTC_PERSISTENT0_SET (0x00000064)
-+#define HW_RTC_PERSISTENT0_CLR (0x00000068)
-+#define HW_RTC_PERSISTENT0_TOG (0x0000006c)
-+
-+// TODO
-+//#define BM_RTC_PERSISTENT0_RELEASE_GND 0x00080000
-+
-+/* AUDIOOUT */
-+#define HW_AUDIOOUT_CTRL (0x00000000)
-+#define HW_AUDIOOUT_CTRL_SET (0x00000004)
-+#define HW_AUDIOOUT_CTRL_CLR (0x00000008)
-+#define HW_AUDIOOUT_CTRL_TOG (0x0000000c)
-+
-+#define BM_AUDIOOUT_CTRL_SFTRST 0x80000000
-+#define BM_AUDIOOUT_CTRL_CLKGATE 0x40000000
-+#define BP_AUDIOOUT_CTRL_RSRVD4 21
-+#define BM_AUDIOOUT_CTRL_RSRVD4 0x3FE00000
-+#define BF_AUDIOOUT_CTRL_RSRVD4(v) \
-+ (((v) << 21) & BM_AUDIOOUT_CTRL_RSRVD4)
-+#define BP_AUDIOOUT_CTRL_DMAWAIT_COUNT 16
-+#define BM_AUDIOOUT_CTRL_DMAWAIT_COUNT 0x001F0000
-+#define BF_AUDIOOUT_CTRL_DMAWAIT_COUNT(v) \
-+ (((v) << 16) & BM_AUDIOOUT_CTRL_DMAWAIT_COUNT)
-+#define BM_AUDIOOUT_CTRL_RSRVD3 0x00008000
-+#define BM_AUDIOOUT_CTRL_LR_SWAP 0x00004000
-+#define BM_AUDIOOUT_CTRL_EDGE_SYNC 0x00002000
-+#define BM_AUDIOOUT_CTRL_INVERT_1BIT 0x00001000
-+#define BP_AUDIOOUT_CTRL_RSRVD2 10
-+#define BM_AUDIOOUT_CTRL_RSRVD2 0x00000C00
-+#define BF_AUDIOOUT_CTRL_RSRVD2(v) \
-+ (((v) << 10) & BM_AUDIOOUT_CTRL_RSRVD2)
-+#define BP_AUDIOOUT_CTRL_SS3D_EFFECT 8
-+#define BM_AUDIOOUT_CTRL_SS3D_EFFECT 0x00000300
-+#define BF_AUDIOOUT_CTRL_SS3D_EFFECT(v) \
-+ (((v) << 8) & BM_AUDIOOUT_CTRL_SS3D_EFFECT)
-+#define BM_AUDIOOUT_CTRL_RSRVD1 0x00000080
-+#define BM_AUDIOOUT_CTRL_WORD_LENGTH 0x00000040
-+#define BM_AUDIOOUT_CTRL_DAC_ZERO_ENABLE 0x00000020
-+#define BM_AUDIOOUT_CTRL_LOOPBACK 0x00000010
-+#define BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008
-+#define BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ 0x00000004
-+#define BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN 0x00000002
-+#define BM_AUDIOOUT_CTRL_RUN 0x00000001
-+
-+#define HW_AUDIOOUT_STAT (0x00000010)
-+#define HW_AUDIOOUT_STAT_SET (0x00000014)
-+#define HW_AUDIOOUT_STAT_CLR (0x00000018)
-+#define HW_AUDIOOUT_STAT_TOG (0x0000001c)
-+
-+#define BM_AUDIOOUT_STAT_DAC_PRESENT 0x80000000
-+#define BP_AUDIOOUT_STAT_RSRVD1 0
-+#define BM_AUDIOOUT_STAT_RSRVD1 0x7FFFFFFF
-+#define BF_AUDIOOUT_STAT_RSRVD1(v) \
-+ (((v) << 0) & BM_AUDIOOUT_STAT_RSRVD1)
-+
-+#define HW_AUDIOOUT_DACSRR (0x00000020)
-+#define HW_AUDIOOUT_DACSRR_SET (0x00000024)
-+#define HW_AUDIOOUT_DACSRR_CLR (0x00000028)
-+#define HW_AUDIOOUT_DACSRR_TOG (0x0000002c)
-+
-+#define BM_AUDIOOUT_DACSRR_OSR 0x80000000
-+#define BV_AUDIOOUT_DACSRR_OSR__OSR6 0x0
-+#define BV_AUDIOOUT_DACSRR_OSR__OSR12 0x1
-+#define BP_AUDIOOUT_DACSRR_BASEMULT 28
-+#define BM_AUDIOOUT_DACSRR_BASEMULT 0x70000000
-+#define BF_AUDIOOUT_DACSRR_BASEMULT(v) \
-+ (((v) << 28) & BM_AUDIOOUT_DACSRR_BASEMULT)
-+#define BV_AUDIOOUT_DACSRR_BASEMULT__SINGLE_RATE 0x1
-+#define BV_AUDIOOUT_DACSRR_BASEMULT__DOUBLE_RATE 0x2
-+#define BV_AUDIOOUT_DACSRR_BASEMULT__QUAD_RATE 0x4
-+#define BM_AUDIOOUT_DACSRR_RSRVD2 0x08000000
-+#define BP_AUDIOOUT_DACSRR_SRC_HOLD 24
-+#define BM_AUDIOOUT_DACSRR_SRC_HOLD 0x07000000
-+#define BF_AUDIOOUT_DACSRR_SRC_HOLD(v) \
-+ (((v) << 24) & BM_AUDIOOUT_DACSRR_SRC_HOLD)
-+#define BP_AUDIOOUT_DACSRR_RSRVD1 21
-+#define BM_AUDIOOUT_DACSRR_RSRVD1 0x00E00000
-+#define BF_AUDIOOUT_DACSRR_RSRVD1(v) \
-+ (((v) << 21) & BM_AUDIOOUT_DACSRR_RSRVD1)
-+#define BP_AUDIOOUT_DACSRR_SRC_INT 16
-+#define BM_AUDIOOUT_DACSRR_SRC_INT 0x001F0000
-+#define BF_AUDIOOUT_DACSRR_SRC_INT(v) \
-+ (((v) << 16) & BM_AUDIOOUT_DACSRR_SRC_INT)
-+#define BP_AUDIOOUT_DACSRR_RSRVD0 13
-+#define BM_AUDIOOUT_DACSRR_RSRVD0 0x0000E000
-+#define BF_AUDIOOUT_DACSRR_RSRVD0(v) \
-+ (((v) << 13) & BM_AUDIOOUT_DACSRR_RSRVD0)
-+#define BP_AUDIOOUT_DACSRR_SRC_FRAC 0
-+#define BM_AUDIOOUT_DACSRR_SRC_FRAC 0x00001FFF
-+#define BF_AUDIOOUT_DACSRR_SRC_FRAC(v) \
-+ (((v) << 0) & BM_AUDIOOUT_DACSRR_SRC_FRAC)
-+
-+#define HW_AUDIOOUT_DACVOLUME (0x00000030)
-+#define HW_AUDIOOUT_DACVOLUME_SET (0x00000034)
-+#define HW_AUDIOOUT_DACVOLUME_CLR (0x00000038)
-+#define HW_AUDIOOUT_DACVOLUME_TOG (0x0000003c)
-+
-+#define BP_AUDIOOUT_DACVOLUME_RSRVD4 29
-+#define BM_AUDIOOUT_DACVOLUME_RSRVD4 0xE0000000
-+#define BF_AUDIOOUT_DACVOLUME_RSRVD4(v) \
-+ (((v) << 29) & BM_AUDIOOUT_DACVOLUME_RSRVD4)
-+#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_LEFT 0x10000000
-+#define BP_AUDIOOUT_DACVOLUME_RSRVD3 26
-+#define BM_AUDIOOUT_DACVOLUME_RSRVD3 0x0C000000
-+#define BF_AUDIOOUT_DACVOLUME_RSRVD3(v) \
-+ (((v) << 26) & BM_AUDIOOUT_DACVOLUME_RSRVD3)
-+#define BM_AUDIOOUT_DACVOLUME_EN_ZCD 0x02000000
-+#define BM_AUDIOOUT_DACVOLUME_MUTE_LEFT 0x01000000
-+#define BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT 16
-+#define BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT 0x00FF0000
-+#define BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(v) \
-+ (((v) << 16) & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT)
-+#define BP_AUDIOOUT_DACVOLUME_RSRVD2 13
-+#define BM_AUDIOOUT_DACVOLUME_RSRVD2 0x0000E000
-+#define BF_AUDIOOUT_DACVOLUME_RSRVD2(v) \
-+ (((v) << 13) & BM_AUDIOOUT_DACVOLUME_RSRVD2)
-+#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_RIGHT 0x00001000
-+#define BP_AUDIOOUT_DACVOLUME_RSRVD1 9
-+#define BM_AUDIOOUT_DACVOLUME_RSRVD1 0x00000E00
-+#define BF_AUDIOOUT_DACVOLUME_RSRVD1(v) \
-+ (((v) << 9) & BM_AUDIOOUT_DACVOLUME_RSRVD1)
-+#define BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT 0x00000100
-+#define BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0
-+#define BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0x000000FF
-+#define BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(v) \
-+ (((v) << 0) & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT)
-+
-+#define HW_AUDIOOUT_DACDEBUG (0x00000040)
-+#define HW_AUDIOOUT_DACDEBUG_SET (0x00000044)
-+#define HW_AUDIOOUT_DACDEBUG_CLR (0x00000048)
-+#define HW_AUDIOOUT_DACDEBUG_TOG (0x0000004c)
-+
-+#define BM_AUDIOOUT_DACDEBUG_ENABLE_DACDMA 0x80000000
-+#define BP_AUDIOOUT_DACDEBUG_RSRVD2 12
-+#define BM_AUDIOOUT_DACDEBUG_RSRVD2 0x7FFFF000
-+#define BF_AUDIOOUT_DACDEBUG_RSRVD2(v) \
-+ (((v) << 12) & BM_AUDIOOUT_DACDEBUG_RSRVD2)
-+#define BP_AUDIOOUT_DACDEBUG_RAM_SS 8
-+#define BM_AUDIOOUT_DACDEBUG_RAM_SS 0x00000F00
-+#define BF_AUDIOOUT_DACDEBUG_RAM_SS(v) \
-+ (((v) << 8) & BM_AUDIOOUT_DACDEBUG_RAM_SS)
-+#define BP_AUDIOOUT_DACDEBUG_RSRVD1 6
-+#define BM_AUDIOOUT_DACDEBUG_RSRVD1 0x000000C0
-+#define BF_AUDIOOUT_DACDEBUG_RSRVD1(v) \
-+ (((v) << 6) & BM_AUDIOOUT_DACDEBUG_RSRVD1)
-+#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_CLK_CROSS 0x00000020
-+#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_CLK_CROSS 0x00000010
-+#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_HAND_SHAKE 0x00000008
-+#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_HAND_SHAKE 0x00000004
-+#define BM_AUDIOOUT_DACDEBUG_DMA_PREQ 0x00000002
-+#define BM_AUDIOOUT_DACDEBUG_FIFO_STATUS 0x00000001
-+
-+#define HW_AUDIOOUT_HPVOL (0x00000050)
-+#define HW_AUDIOOUT_HPVOL_SET (0x00000054)
-+#define HW_AUDIOOUT_HPVOL_CLR (0x00000058)
-+#define HW_AUDIOOUT_HPVOL_TOG (0x0000005c)
-+
-+#define BP_AUDIOOUT_HPVOL_RSRVD5 29
-+#define BM_AUDIOOUT_HPVOL_RSRVD5 0xE0000000
-+#define BF_AUDIOOUT_HPVOL_RSRVD5(v) \
-+ (((v) << 29) & BM_AUDIOOUT_HPVOL_RSRVD5)
-+#define BM_AUDIOOUT_HPVOL_VOLUME_UPDATE_PENDING 0x10000000
-+#define BP_AUDIOOUT_HPVOL_RSRVD4 26
-+#define BM_AUDIOOUT_HPVOL_RSRVD4 0x0C000000
-+#define BF_AUDIOOUT_HPVOL_RSRVD4(v) \
-+ (((v) << 26) & BM_AUDIOOUT_HPVOL_RSRVD4)
-+#define BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD 0x02000000
-+#define BM_AUDIOOUT_HPVOL_MUTE 0x01000000
-+#define BP_AUDIOOUT_HPVOL_RSRVD3 17
-+#define BM_AUDIOOUT_HPVOL_RSRVD3 0x00FE0000
-+#define BF_AUDIOOUT_HPVOL_RSRVD3(v) \
-+ (((v) << 17) & BM_AUDIOOUT_HPVOL_RSRVD3)
-+#define BM_AUDIOOUT_HPVOL_SELECT 0x00010000
-+#define BM_AUDIOOUT_HPVOL_RSRVD2 0x00008000
-+#define BP_AUDIOOUT_HPVOL_VOL_LEFT 8
-+#define BM_AUDIOOUT_HPVOL_VOL_LEFT 0x00007F00
-+#define BF_AUDIOOUT_HPVOL_VOL_LEFT(v) \
-+ (((v) << 8) & BM_AUDIOOUT_HPVOL_VOL_LEFT)
-+#define BM_AUDIOOUT_HPVOL_RSRVD1 0x00000080
-+#define BP_AUDIOOUT_HPVOL_VOL_RIGHT 0
-+#define BM_AUDIOOUT_HPVOL_VOL_RIGHT 0x0000007F
-+#define BF_AUDIOOUT_HPVOL_VOL_RIGHT(v) \
-+ (((v) << 0) & BM_AUDIOOUT_HPVOL_VOL_RIGHT)
-+
-+#define HW_AUDIOOUT_RESERVED (0x00000060)
-+#define HW_AUDIOOUT_RESERVED_SET (0x00000064)
-+#define HW_AUDIOOUT_RESERVED_CLR (0x00000068)
-+#define HW_AUDIOOUT_RESERVED_TOG (0x0000006c)
-+
-+#define BP_AUDIOOUT_RESERVED_RSRVD1 0
-+#define BM_AUDIOOUT_RESERVED_RSRVD1 0xFFFFFFFF
-+#define BF_AUDIOOUT_RESERVED_RSRVD1(v) (v)
-+
-+#define HW_AUDIOOUT_PWRDN (0x00000070)
-+#define HW_AUDIOOUT_PWRDN_SET (0x00000074)
-+#define HW_AUDIOOUT_PWRDN_CLR (0x00000078)
-+#define HW_AUDIOOUT_PWRDN_TOG (0x0000007c)
-+
-+#define BP_AUDIOOUT_PWRDN_RSRVD7 25
-+#define BM_AUDIOOUT_PWRDN_RSRVD7 0xFE000000
-+#define BF_AUDIOOUT_PWRDN_RSRVD7(v) \
-+ (((v) << 25) & BM_AUDIOOUT_PWRDN_RSRVD7)
-+#define BM_AUDIOOUT_PWRDN_SPEAKER 0x01000000
-+#define BP_AUDIOOUT_PWRDN_RSRVD6 21
-+#define BM_AUDIOOUT_PWRDN_RSRVD6 0x00E00000
-+#define BF_AUDIOOUT_PWRDN_RSRVD6(v) \
-+ (((v) << 21) & BM_AUDIOOUT_PWRDN_RSRVD6)
-+#define BM_AUDIOOUT_PWRDN_SELFBIAS 0x00100000
-+#define BP_AUDIOOUT_PWRDN_RSRVD5 17
-+#define BM_AUDIOOUT_PWRDN_RSRVD5 0x000E0000
-+#define BF_AUDIOOUT_PWRDN_RSRVD5(v) \
-+ (((v) << 17) & BM_AUDIOOUT_PWRDN_RSRVD5)
-+#define BM_AUDIOOUT_PWRDN_RIGHT_ADC 0x00010000
-+#define BP_AUDIOOUT_PWRDN_RSRVD4 13
-+#define BM_AUDIOOUT_PWRDN_RSRVD4 0x0000E000
-+#define BF_AUDIOOUT_PWRDN_RSRVD4(v) \
-+ (((v) << 13) & BM_AUDIOOUT_PWRDN_RSRVD4)
-+#define BM_AUDIOOUT_PWRDN_DAC 0x00001000
-+#define BP_AUDIOOUT_PWRDN_RSRVD3 9
-+#define BM_AUDIOOUT_PWRDN_RSRVD3 0x00000E00
-+#define BF_AUDIOOUT_PWRDN_RSRVD3(v) \
-+ (((v) << 9) & BM_AUDIOOUT_PWRDN_RSRVD3)
-+#define BM_AUDIOOUT_PWRDN_ADC 0x00000100
-+#define BP_AUDIOOUT_PWRDN_RSRVD2 5
-+#define BM_AUDIOOUT_PWRDN_RSRVD2 0x000000E0
-+#define BF_AUDIOOUT_PWRDN_RSRVD2(v) \
-+ (((v) << 5) & BM_AUDIOOUT_PWRDN_RSRVD2)
-+#define BM_AUDIOOUT_PWRDN_CAPLESS 0x00000010
-+#define BP_AUDIOOUT_PWRDN_RSRVD1 1
-+#define BM_AUDIOOUT_PWRDN_RSRVD1 0x0000000E
-+#define BF_AUDIOOUT_PWRDN_RSRVD1(v) \
-+ (((v) << 1) & BM_AUDIOOUT_PWRDN_RSRVD1)
-+#define BM_AUDIOOUT_PWRDN_HEADPHONE 0x00000001
-+
-+#define HW_AUDIOOUT_REFCTRL (0x00000080)
-+#define HW_AUDIOOUT_REFCTRL_SET (0x00000084)
-+#define HW_AUDIOOUT_REFCTRL_CLR (0x00000088)
-+#define HW_AUDIOOUT_REFCTRL_TOG (0x0000008c)
-+
-+#define BP_AUDIOOUT_REFCTRL_RSRVD4 27
-+#define BM_AUDIOOUT_REFCTRL_RSRVD4 0xF8000000
-+#define BF_AUDIOOUT_REFCTRL_RSRVD4(v) \
-+ (((v) << 27) & BM_AUDIOOUT_REFCTRL_RSRVD4)
-+#define BM_AUDIOOUT_REFCTRL_FASTSETTLING 0x04000000
-+#define BM_AUDIOOUT_REFCTRL_RAISE_REF 0x02000000
-+#define BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS 0x01000000
-+#define BM_AUDIOOUT_REFCTRL_RSRVD3 0x00800000
-+#define BP_AUDIOOUT_REFCTRL_VBG_ADJ 20
-+#define BM_AUDIOOUT_REFCTRL_VBG_ADJ 0x00700000
-+#define BF_AUDIOOUT_REFCTRL_VBG_ADJ(v) \
-+ (((v) << 20) & BM_AUDIOOUT_REFCTRL_VBG_ADJ)
-+#define BM_AUDIOOUT_REFCTRL_LOW_PWR 0x00080000
-+#define BM_AUDIOOUT_REFCTRL_LW_REF 0x00040000
-+#define BP_AUDIOOUT_REFCTRL_BIAS_CTRL 16
-+#define BM_AUDIOOUT_REFCTRL_BIAS_CTRL 0x00030000
-+#define BF_AUDIOOUT_REFCTRL_BIAS_CTRL(v) \
-+ (((v) << 16) & BM_AUDIOOUT_REFCTRL_BIAS_CTRL)
-+#define BM_AUDIOOUT_REFCTRL_RSRVD2 0x00008000
-+#define BM_AUDIOOUT_REFCTRL_VDDXTAL_TO_VDDD 0x00004000
-+#define BM_AUDIOOUT_REFCTRL_ADJ_ADC 0x00002000
-+#define BM_AUDIOOUT_REFCTRL_ADJ_VAG 0x00001000
-+#define BP_AUDIOOUT_REFCTRL_ADC_REFVAL 8
-+#define BM_AUDIOOUT_REFCTRL_ADC_REFVAL 0x00000F00
-+#define BF_AUDIOOUT_REFCTRL_ADC_REFVAL(v) \
-+ (((v) << 8) & BM_AUDIOOUT_REFCTRL_ADC_REFVAL)
-+#define BP_AUDIOOUT_REFCTRL_VAG_VAL 4
-+#define BM_AUDIOOUT_REFCTRL_VAG_VAL 0x000000F0
-+#define BF_AUDIOOUT_REFCTRL_VAG_VAL(v) \
-+ (((v) << 4) & BM_AUDIOOUT_REFCTRL_VAG_VAL)
-+#define BM_AUDIOOUT_REFCTRL_RSRVD1 0x00000008
-+#define BP_AUDIOOUT_REFCTRL_DAC_ADJ 0
-+#define BM_AUDIOOUT_REFCTRL_DAC_ADJ 0x00000007
-+#define BF_AUDIOOUT_REFCTRL_DAC_ADJ(v) \
-+ (((v) << 0) & BM_AUDIOOUT_REFCTRL_DAC_ADJ)
-+
-+#define HW_AUDIOOUT_ANACTRL (0x00000090)
-+#define HW_AUDIOOUT_ANACTRL_SET (0x00000094)
-+#define HW_AUDIOOUT_ANACTRL_CLR (0x00000098)
-+#define HW_AUDIOOUT_ANACTRL_TOG (0x0000009c)
-+
-+#define BP_AUDIOOUT_ANACTRL_RSRVD8 29
-+#define BM_AUDIOOUT_ANACTRL_RSRVD8 0xE0000000
-+#define BF_AUDIOOUT_ANACTRL_RSRVD8(v) \
-+ (((v) << 29) & BM_AUDIOOUT_ANACTRL_RSRVD8)
-+#define BM_AUDIOOUT_ANACTRL_SHORT_CM_STS 0x10000000
-+#define BP_AUDIOOUT_ANACTRL_RSRVD7 25
-+#define BM_AUDIOOUT_ANACTRL_RSRVD7 0x0E000000
-+#define BF_AUDIOOUT_ANACTRL_RSRVD7(v) \
-+ (((v) << 25) & BM_AUDIOOUT_ANACTRL_RSRVD7)
-+#define BM_AUDIOOUT_ANACTRL_SHORT_LR_STS 0x01000000
-+#define BP_AUDIOOUT_ANACTRL_RSRVD6 22
-+#define BM_AUDIOOUT_ANACTRL_RSRVD6 0x00C00000
-+#define BF_AUDIOOUT_ANACTRL_RSRVD6(v) \
-+ (((v) << 22) & BM_AUDIOOUT_ANACTRL_RSRVD6)
-+#define BP_AUDIOOUT_ANACTRL_SHORTMODE_CM 20
-+#define BM_AUDIOOUT_ANACTRL_SHORTMODE_CM 0x00300000
-+#define BF_AUDIOOUT_ANACTRL_SHORTMODE_CM(v) \
-+ (((v) << 20) & BM_AUDIOOUT_ANACTRL_SHORTMODE_CM)
-+#define BM_AUDIOOUT_ANACTRL_RSRVD5 0x00080000
-+#define BP_AUDIOOUT_ANACTRL_SHORTMODE_LR 17
-+#define BM_AUDIOOUT_ANACTRL_SHORTMODE_LR 0x00060000
-+#define BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(v) \
-+ (((v) << 17) & BM_AUDIOOUT_ANACTRL_SHORTMODE_LR)
-+#define BP_AUDIOOUT_ANACTRL_RSRVD4 15
-+#define BM_AUDIOOUT_ANACTRL_RSRVD4 0x00018000
-+#define BF_AUDIOOUT_ANACTRL_RSRVD4(v) \
-+ (((v) << 15) & BM_AUDIOOUT_ANACTRL_RSRVD4)
-+#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJL 12
-+#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL 0x00007000
-+#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJL(v) \
-+ (((v) << 12) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL)
-+#define BM_AUDIOOUT_ANACTRL_RSRVD3 0x00000800
-+#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJR 8
-+#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR 0x00000700
-+#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJR(v) \
-+ (((v) << 8) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR)
-+#define BP_AUDIOOUT_ANACTRL_RSRVD2 6
-+#define BM_AUDIOOUT_ANACTRL_RSRVD2 0x000000C0
-+#define BF_AUDIOOUT_ANACTRL_RSRVD2(v) \
-+ (((v) << 6) & BM_AUDIOOUT_ANACTRL_RSRVD2)
-+#define BM_AUDIOOUT_ANACTRL_HP_HOLD_GND 0x00000020
-+#define BM_AUDIOOUT_ANACTRL_HP_CLASSAB 0x00000010
-+#define BP_AUDIOOUT_ANACTRL_RSRVD1 0
-+#define BM_AUDIOOUT_ANACTRL_RSRVD1 0x0000000F
-+#define BF_AUDIOOUT_ANACTRL_RSRVD1(v) \
-+ (((v) << 0) & BM_AUDIOOUT_ANACTRL_RSRVD1)
-+
-+#define HW_AUDIOOUT_TEST (0x000000a0)
-+#define HW_AUDIOOUT_TEST_SET (0x000000a4)
-+#define HW_AUDIOOUT_TEST_CLR (0x000000a8)
-+#define HW_AUDIOOUT_TEST_TOG (0x000000ac)
-+
-+#define BM_AUDIOOUT_TEST_RSRVD4 0x80000000
-+#define BP_AUDIOOUT_TEST_HP_ANTIPOP 28
-+#define BM_AUDIOOUT_TEST_HP_ANTIPOP 0x70000000
-+#define BF_AUDIOOUT_TEST_HP_ANTIPOP(v) \
-+ (((v) << 28) & BM_AUDIOOUT_TEST_HP_ANTIPOP)
-+#define BM_AUDIOOUT_TEST_RSRVD3 0x08000000
-+#define BM_AUDIOOUT_TEST_TM_ADCIN_TOHP 0x04000000
-+#define BM_AUDIOOUT_TEST_TM_LOOP 0x02000000
-+#define BM_AUDIOOUT_TEST_TM_HPCOMMON 0x01000000
-+#define BP_AUDIOOUT_TEST_HP_I1_ADJ 22
-+#define BM_AUDIOOUT_TEST_HP_I1_ADJ 0x00C00000
-+#define BF_AUDIOOUT_TEST_HP_I1_ADJ(v) \
-+ (((v) << 22) & BM_AUDIOOUT_TEST_HP_I1_ADJ)
-+#define BP_AUDIOOUT_TEST_HP_IALL_ADJ 20
-+#define BM_AUDIOOUT_TEST_HP_IALL_ADJ 0x00300000
-+#define BF_AUDIOOUT_TEST_HP_IALL_ADJ(v) \
-+ (((v) << 20) & BM_AUDIOOUT_TEST_HP_IALL_ADJ)
-+#define BP_AUDIOOUT_TEST_RSRVD2 14
-+#define BM_AUDIOOUT_TEST_RSRVD2 0x000FC000
-+#define BF_AUDIOOUT_TEST_RSRVD2(v) \
-+ (((v) << 14) & BM_AUDIOOUT_TEST_RSRVD2)
-+#define BM_AUDIOOUT_TEST_VAG_CLASSA 0x00002000
-+#define BM_AUDIOOUT_TEST_VAG_DOUBLE_I 0x00001000
-+#define BP_AUDIOOUT_TEST_RSRVD1 4
-+#define BM_AUDIOOUT_TEST_RSRVD1 0x00000FF0
-+#define BF_AUDIOOUT_TEST_RSRVD1(v) \
-+ (((v) << 4) & BM_AUDIOOUT_TEST_RSRVD1)
-+#define BM_AUDIOOUT_TEST_ADCTODAC_LOOP 0x00000008
-+#define BM_AUDIOOUT_TEST_DAC_CLASSA 0x00000004
-+#define BM_AUDIOOUT_TEST_DAC_DOUBLE_I 0x00000002
-+#define BM_AUDIOOUT_TEST_DAC_DIS_RTZ 0x00000001
-+
-+#define HW_AUDIOOUT_BISTCTRL (0x000000b0)
-+#define HW_AUDIOOUT_BISTCTRL_SET (0x000000b4)
-+#define HW_AUDIOOUT_BISTCTRL_CLR (0x000000b8)
-+#define HW_AUDIOOUT_BISTCTRL_TOG (0x000000bc)
-+
-+#define BP_AUDIOOUT_BISTCTRL_RSVD0 4
-+#define BM_AUDIOOUT_BISTCTRL_RSVD0 0xFFFFFFF0
-+#define BF_AUDIOOUT_BISTCTRL_RSVD0(v) \
-+ (((v) << 4) & BM_AUDIOOUT_BISTCTRL_RSVD0)
-+#define BM_AUDIOOUT_BISTCTRL_FAIL 0x00000008
-+#define BM_AUDIOOUT_BISTCTRL_PASS 0x00000004
-+#define BM_AUDIOOUT_BISTCTRL_DONE 0x00000002
-+#define BM_AUDIOOUT_BISTCTRL_START 0x00000001
-+
-+#define HW_AUDIOOUT_BISTSTAT0 (0x000000c0)
-+#define HW_AUDIOOUT_BISTSTAT0_SET (0x000000c4)
-+#define HW_AUDIOOUT_BISTSTAT0_CLR (0x000000c8)
-+#define HW_AUDIOOUT_BISTSTAT0_TOG (0x000000cc)
-+
-+#define BP_AUDIOOUT_BISTSTAT0_RSVD0 24
-+#define BM_AUDIOOUT_BISTSTAT0_RSVD0 0xFF000000
-+#define BF_AUDIOOUT_BISTSTAT0_RSVD0(v) \
-+ (((v) << 24) & BM_AUDIOOUT_BISTSTAT0_RSVD0)
-+#define BP_AUDIOOUT_BISTSTAT0_DATA 0
-+#define BM_AUDIOOUT_BISTSTAT0_DATA 0x00FFFFFF
-+#define BF_AUDIOOUT_BISTSTAT0_DATA(v) \
-+ (((v) << 0) & BM_AUDIOOUT_BISTSTAT0_DATA)
-+
-+#define HW_AUDIOOUT_BISTSTAT1 (0x000000d0)
-+#define HW_AUDIOOUT_BISTSTAT1_SET (0x000000d4)
-+#define HW_AUDIOOUT_BISTSTAT1_CLR (0x000000d8)
-+#define HW_AUDIOOUT_BISTSTAT1_TOG (0x000000dc)
-+
-+#define BP_AUDIOOUT_BISTSTAT1_RSVD1 29
-+#define BM_AUDIOOUT_BISTSTAT1_RSVD1 0xE0000000
-+#define BF_AUDIOOUT_BISTSTAT1_RSVD1(v) \
-+ (((v) << 29) & BM_AUDIOOUT_BISTSTAT1_RSVD1)
-+#define BP_AUDIOOUT_BISTSTAT1_STATE 24
-+#define BM_AUDIOOUT_BISTSTAT1_STATE 0x1F000000
-+#define BF_AUDIOOUT_BISTSTAT1_STATE(v) \
-+ (((v) << 24) & BM_AUDIOOUT_BISTSTAT1_STATE)
-+#define BP_AUDIOOUT_BISTSTAT1_RSVD0 8
-+#define BM_AUDIOOUT_BISTSTAT1_RSVD0 0x00FFFF00
-+#define BF_AUDIOOUT_BISTSTAT1_RSVD0(v) \
-+ (((v) << 8) & BM_AUDIOOUT_BISTSTAT1_RSVD0)
-+#define BP_AUDIOOUT_BISTSTAT1_ADDR 0
-+#define BM_AUDIOOUT_BISTSTAT1_ADDR 0x000000FF
-+#define BF_AUDIOOUT_BISTSTAT1_ADDR(v) \
-+ (((v) << 0) & BM_AUDIOOUT_BISTSTAT1_ADDR)
-+
-+#define HW_AUDIOOUT_ANACLKCTRL (0x000000e0)
-+#define HW_AUDIOOUT_ANACLKCTRL_SET (0x000000e4)
-+#define HW_AUDIOOUT_ANACLKCTRL_CLR (0x000000e8)
-+#define HW_AUDIOOUT_ANACLKCTRL_TOG (0x000000ec)
-+
-+#define BM_AUDIOOUT_ANACLKCTRL_CLKGATE 0x80000000
-+#define BP_AUDIOOUT_ANACLKCTRL_RSRVD3 5
-+#define BM_AUDIOOUT_ANACLKCTRL_RSRVD3 0x7FFFFFE0
-+#define BF_AUDIOOUT_ANACLKCTRL_RSRVD3(v) \
-+ (((v) << 5) & BM_AUDIOOUT_ANACLKCTRL_RSRVD3)
-+#define BM_AUDIOOUT_ANACLKCTRL_INVERT_DACCLK 0x00000010
-+#define BM_AUDIOOUT_ANACLKCTRL_RSRVD2 0x00000008
-+#define BP_AUDIOOUT_ANACLKCTRL_DACDIV 0
-+#define BM_AUDIOOUT_ANACLKCTRL_DACDIV 0x00000007
-+#define BF_AUDIOOUT_ANACLKCTRL_DACDIV(v) \
-+ (((v) << 0) & BM_AUDIOOUT_ANACLKCTRL_DACDIV)
-+
-+#define HW_AUDIOOUT_DATA (0x000000f0)
-+#define HW_AUDIOOUT_DATA_SET (0x000000f4)
-+#define HW_AUDIOOUT_DATA_CLR (0x000000f8)
-+#define HW_AUDIOOUT_DATA_TOG (0x000000fc)
-+
-+#define BP_AUDIOOUT_DATA_HIGH 16
-+#define BM_AUDIOOUT_DATA_HIGH 0xFFFF0000
-+#define BF_AUDIOOUT_DATA_HIGH(v) \
-+ (((v) << 16) & BM_AUDIOOUT_DATA_HIGH)
-+#define BP_AUDIOOUT_DATA_LOW 0
-+#define BM_AUDIOOUT_DATA_LOW 0x0000FFFF
-+#define BF_AUDIOOUT_DATA_LOW(v) \
-+ (((v) << 0) & BM_AUDIOOUT_DATA_LOW)
-+
-+#define HW_AUDIOOUT_SPEAKERCTRL (0x00000100)
-+#define HW_AUDIOOUT_SPEAKERCTRL_SET (0x00000104)
-+#define HW_AUDIOOUT_SPEAKERCTRL_CLR (0x00000108)
-+#define HW_AUDIOOUT_SPEAKERCTRL_TOG (0x0000010c)
-+
-+#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD2 25
-+#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD2 0xFE000000
-+#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD2(v) \
-+ (((v) << 25) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD2)
-+#define BM_AUDIOOUT_SPEAKERCTRL_MUTE 0x01000000
-+#define BP_AUDIOOUT_SPEAKERCTRL_I1_ADJ 22
-+#define BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ 0x00C00000
-+#define BF_AUDIOOUT_SPEAKERCTRL_I1_ADJ(v) \
-+ (((v) << 22) & BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ)
-+#define BP_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 20
-+#define BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 0x00300000
-+#define BF_AUDIOOUT_SPEAKERCTRL_IALL_ADJ(v) \
-+ (((v) << 20) & BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ)
-+#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD1 16
-+#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD1 0x000F0000
-+#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD1(v) \
-+ (((v) << 16) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD1)
-+#define BP_AUDIOOUT_SPEAKERCTRL_POSDRIVER 14
-+#define BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER 0x0000C000
-+#define BF_AUDIOOUT_SPEAKERCTRL_POSDRIVER(v) \
-+ (((v) << 14) & BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER)
-+#define BP_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 12
-+#define BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 0x00003000
-+#define BF_AUDIOOUT_SPEAKERCTRL_NEGDRIVER(v) \
-+ (((v) << 12) & BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER)
-+#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD0 0
-+#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD0 0x00000FFF
-+#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD0(v) \
-+ (((v) << 0) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD0)
-+
-+#define HW_AUDIOOUT_VERSION (0x00000200)
-+
-+#define BP_AUDIOOUT_VERSION_MAJOR 24
-+#define BM_AUDIOOUT_VERSION_MAJOR 0xFF000000
-+#define BF_AUDIOOUT_VERSION_MAJOR(v) \
-+ (((v) << 24) & BM_AUDIOOUT_VERSION_MAJOR)
-+#define BP_AUDIOOUT_VERSION_MINOR 16
-+#define BM_AUDIOOUT_VERSION_MINOR 0x00FF0000
-+#define BF_AUDIOOUT_VERSION_MINOR(v) \
-+ (((v) << 16) & BM_AUDIOOUT_VERSION_MINOR)
-+#define BP_AUDIOOUT_VERSION_STEP 0
-+#define BM_AUDIOOUT_VERSION_STEP 0x0000FFFF
-+#define BF_AUDIOOUT_VERSION_STEP(v) \
-+ (((v) << 0) & BM_AUDIOOUT_VERSION_STEP)
-+
-+/* AUDIOIN */
-+#define HW_AUDIOIN_CTRL (0x00000000)
-+#define HW_AUDIOIN_CTRL_SET (0x00000004)
-+#define HW_AUDIOIN_CTRL_CLR (0x00000008)
-+#define HW_AUDIOIN_CTRL_TOG (0x0000000c)
-+
-+#define BM_AUDIOIN_CTRL_SFTRST 0x80000000
-+#define BM_AUDIOIN_CTRL_CLKGATE 0x40000000
-+#define BP_AUDIOIN_CTRL_RSRVD3 21
-+#define BM_AUDIOIN_CTRL_RSRVD3 0x3FE00000
-+#define BF_AUDIOIN_CTRL_RSRVD3(v) \
-+ (((v) << 21) & BM_AUDIOIN_CTRL_RSRVD3)
-+#define BP_AUDIOIN_CTRL_DMAWAIT_COUNT 16
-+#define BM_AUDIOIN_CTRL_DMAWAIT_COUNT 0x001F0000
-+#define BF_AUDIOIN_CTRL_DMAWAIT_COUNT(v) \
-+ (((v) << 16) & BM_AUDIOIN_CTRL_DMAWAIT_COUNT)
-+#define BP_AUDIOIN_CTRL_RSRVD1 11
-+#define BM_AUDIOIN_CTRL_RSRVD1 0x0000F800
-+#define BF_AUDIOIN_CTRL_RSRVD1(v) \
-+ (((v) << 11) & BM_AUDIOIN_CTRL_RSRVD1)
-+#define BM_AUDIOIN_CTRL_LR_SWAP 0x00000400
-+#define BM_AUDIOIN_CTRL_EDGE_SYNC 0x00000200
-+#define BM_AUDIOIN_CTRL_INVERT_1BIT 0x00000100
-+#define BM_AUDIOIN_CTRL_OFFSET_ENABLE 0x00000080
-+#define BM_AUDIOIN_CTRL_HPF_ENABLE 0x00000040
-+#define BM_AUDIOIN_CTRL_WORD_LENGTH 0x00000020
-+#define BM_AUDIOIN_CTRL_LOOPBACK 0x00000010
-+#define BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008
-+#define BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ 0x00000004
-+#define BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN 0x00000002
-+#define BM_AUDIOIN_CTRL_RUN 0x00000001
-+
-+#define HW_AUDIOIN_STAT (0x00000010)
-+#define HW_AUDIOIN_STAT_SET (0x00000014)
-+#define HW_AUDIOIN_STAT_CLR (0x00000018)
-+#define HW_AUDIOIN_STAT_TOG (0x0000001c)
-+
-+#define BM_AUDIOIN_STAT_ADC_PRESENT 0x80000000
-+#define BP_AUDIOIN_STAT_RSRVD3 0
-+#define BM_AUDIOIN_STAT_RSRVD3 0x7FFFFFFF
-+#define BF_AUDIOIN_STAT_RSRVD3(v) \
-+ (((v) << 0) & BM_AUDIOIN_STAT_RSRVD3)
-+
-+#define HW_AUDIOIN_ADCSRR (0x00000020)
-+#define HW_AUDIOIN_ADCSRR_SET (0x00000024)
-+#define HW_AUDIOIN_ADCSRR_CLR (0x00000028)
-+#define HW_AUDIOIN_ADCSRR_TOG (0x0000002c)
-+
-+#define BM_AUDIOIN_ADCSRR_OSR 0x80000000
-+#define BV_AUDIOIN_ADCSRR_OSR__OSR6 0x0
-+#define BV_AUDIOIN_ADCSRR_OSR__OSR12 0x1
-+#define BP_AUDIOIN_ADCSRR_BASEMULT 28
-+#define BM_AUDIOIN_ADCSRR_BASEMULT 0x70000000
-+#define BF_AUDIOIN_ADCSRR_BASEMULT(v) \
-+ (((v) << 28) & BM_AUDIOIN_ADCSRR_BASEMULT)
-+#define BV_AUDIOIN_ADCSRR_BASEMULT__SINGLE_RATE 0x1
-+#define BV_AUDIOIN_ADCSRR_BASEMULT__DOUBLE_RATE 0x2
-+#define BV_AUDIOIN_ADCSRR_BASEMULT__QUAD_RATE 0x4
-+#define BM_AUDIOIN_ADCSRR_RSRVD2 0x08000000
-+#define BP_AUDIOIN_ADCSRR_SRC_HOLD 24
-+#define BM_AUDIOIN_ADCSRR_SRC_HOLD 0x07000000
-+#define BF_AUDIOIN_ADCSRR_SRC_HOLD(v) \
-+ (((v) << 24) & BM_AUDIOIN_ADCSRR_SRC_HOLD)
-+#define BP_AUDIOIN_ADCSRR_RSRVD1 21
-+#define BM_AUDIOIN_ADCSRR_RSRVD1 0x00E00000
-+#define BF_AUDIOIN_ADCSRR_RSRVD1(v) \
-+ (((v) << 21) & BM_AUDIOIN_ADCSRR_RSRVD1)
-+#define BP_AUDIOIN_ADCSRR_SRC_INT 16
-+#define BM_AUDIOIN_ADCSRR_SRC_INT 0x001F0000
-+#define BF_AUDIOIN_ADCSRR_SRC_INT(v) \
-+ (((v) << 16) & BM_AUDIOIN_ADCSRR_SRC_INT)
-+#define BP_AUDIOIN_ADCSRR_RSRVD0 13
-+#define BM_AUDIOIN_ADCSRR_RSRVD0 0x0000E000
-+#define BF_AUDIOIN_ADCSRR_RSRVD0(v) \
-+ (((v) << 13) & BM_AUDIOIN_ADCSRR_RSRVD0)
-+#define BP_AUDIOIN_ADCSRR_SRC_FRAC 0
-+#define BM_AUDIOIN_ADCSRR_SRC_FRAC 0x00001FFF
-+#define BF_AUDIOIN_ADCSRR_SRC_FRAC(v) \
-+ (((v) << 0) & BM_AUDIOIN_ADCSRR_SRC_FRAC)
-+
-+#define HW_AUDIOIN_ADCVOLUME (0x00000030)
-+#define HW_AUDIOIN_ADCVOLUME_SET (0x00000034)
-+#define HW_AUDIOIN_ADCVOLUME_CLR (0x00000038)
-+#define HW_AUDIOIN_ADCVOLUME_TOG (0x0000003c)
-+
-+#define BP_AUDIOIN_ADCVOLUME_RSRVD5 29
-+#define BM_AUDIOIN_ADCVOLUME_RSRVD5 0xE0000000
-+#define BF_AUDIOIN_ADCVOLUME_RSRVD5(v) \
-+ (((v) << 29) & BM_AUDIOIN_ADCVOLUME_RSRVD5)
-+#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_LEFT 0x10000000
-+#define BP_AUDIOIN_ADCVOLUME_RSRVD4 26
-+#define BM_AUDIOIN_ADCVOLUME_RSRVD4 0x0C000000
-+#define BF_AUDIOIN_ADCVOLUME_RSRVD4(v) \
-+ (((v) << 26) & BM_AUDIOIN_ADCVOLUME_RSRVD4)
-+#define BM_AUDIOIN_ADCVOLUME_EN_ZCD 0x02000000
-+#define BM_AUDIOIN_ADCVOLUME_RSRVD3 0x01000000
-+#define BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT 16
-+#define BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT 0x00FF0000
-+#define BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(v) \
-+ (((v) << 16) & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT)
-+#define BP_AUDIOIN_ADCVOLUME_RSRVD2 13
-+#define BM_AUDIOIN_ADCVOLUME_RSRVD2 0x0000E000
-+#define BF_AUDIOIN_ADCVOLUME_RSRVD2(v) \
-+ (((v) << 13) & BM_AUDIOIN_ADCVOLUME_RSRVD2)
-+#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_RIGHT 0x00001000
-+#define BP_AUDIOIN_ADCVOLUME_RSRVD1 8
-+#define BM_AUDIOIN_ADCVOLUME_RSRVD1 0x00000F00
-+#define BF_AUDIOIN_ADCVOLUME_RSRVD1(v) \
-+ (((v) << 8) & BM_AUDIOIN_ADCVOLUME_RSRVD1)
-+#define BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0
-+#define BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0x000000FF
-+#define BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(v) \
-+ (((v) << 0) & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT)
-+
-+#define HW_AUDIOIN_ADCDEBUG (0x00000040)
-+#define HW_AUDIOIN_ADCDEBUG_SET (0x00000044)
-+#define HW_AUDIOIN_ADCDEBUG_CLR (0x00000048)
-+#define HW_AUDIOIN_ADCDEBUG_TOG (0x0000004c)
-+
-+#define BM_AUDIOIN_ADCDEBUG_ENABLE_ADCDMA 0x80000000
-+#define BP_AUDIOIN_ADCDEBUG_RSRVD1 4
-+#define BM_AUDIOIN_ADCDEBUG_RSRVD1 0x7FFFFFF0
-+#define BF_AUDIOIN_ADCDEBUG_RSRVD1(v) \
-+ (((v) << 4) & BM_AUDIOIN_ADCDEBUG_RSRVD1)
-+#define BM_AUDIOIN_ADCDEBUG_ADC_DMA_REQ_HAND_SHAKE_CLK_CROSS 0x00000008
-+#define BM_AUDIOIN_ADCDEBUG_SET_INTERRUPT3_HAND_SHAKE 0x00000004
-+#define BM_AUDIOIN_ADCDEBUG_DMA_PREQ 0x00000002
-+#define BM_AUDIOIN_ADCDEBUG_FIFO_STATUS 0x00000001
-+
-+#define HW_AUDIOIN_ADCVOL (0x00000050)
-+#define HW_AUDIOIN_ADCVOL_SET (0x00000054)
-+#define HW_AUDIOIN_ADCVOL_CLR (0x00000058)
-+#define HW_AUDIOIN_ADCVOL_TOG (0x0000005c)
-+
-+#define BP_AUDIOIN_ADCVOL_RSRVD4 29
-+#define BM_AUDIOIN_ADCVOL_RSRVD4 0xE0000000
-+#define BF_AUDIOIN_ADCVOL_RSRVD4(v) \
-+ (((v) << 29) & BM_AUDIOIN_ADCVOL_RSRVD4)
-+#define BM_AUDIOIN_ADCVOL_VOLUME_UPDATE_PENDING 0x10000000
-+#define BP_AUDIOIN_ADCVOL_RSRVD3 26
-+#define BM_AUDIOIN_ADCVOL_RSRVD3 0x0C000000
-+#define BF_AUDIOIN_ADCVOL_RSRVD3(v) \
-+ (((v) << 26) & BM_AUDIOIN_ADCVOL_RSRVD3)
-+#define BM_AUDIOIN_ADCVOL_EN_ADC_ZCD 0x02000000
-+#define BM_AUDIOIN_ADCVOL_MUTE 0x01000000
-+#define BP_AUDIOIN_ADCVOL_RSRVD2 14
-+#define BM_AUDIOIN_ADCVOL_RSRVD2 0x00FFC000
-+#define BF_AUDIOIN_ADCVOL_RSRVD2(v) \
-+ (((v) << 14) & BM_AUDIOIN_ADCVOL_RSRVD2)
-+#define BP_AUDIOIN_ADCVOL_SELECT_LEFT 12
-+#define BM_AUDIOIN_ADCVOL_SELECT_LEFT 0x00003000
-+#define BF_AUDIOIN_ADCVOL_SELECT_LEFT(v) \
-+ (((v) << 12) & BM_AUDIOIN_ADCVOL_SELECT_LEFT)
-+#define BP_AUDIOIN_ADCVOL_GAIN_LEFT 8
-+#define BM_AUDIOIN_ADCVOL_GAIN_LEFT 0x00000F00
-+#define BF_AUDIOIN_ADCVOL_GAIN_LEFT(v) \
-+ (((v) << 8) & BM_AUDIOIN_ADCVOL_GAIN_LEFT)
-+#define BP_AUDIOIN_ADCVOL_RSRVD1 6
-+#define BM_AUDIOIN_ADCVOL_RSRVD1 0x000000C0
-+#define BF_AUDIOIN_ADCVOL_RSRVD1(v) \
-+ (((v) << 6) & BM_AUDIOIN_ADCVOL_RSRVD1)
-+#define BP_AUDIOIN_ADCVOL_SELECT_RIGHT 4
-+#define BM_AUDIOIN_ADCVOL_SELECT_RIGHT 0x00000030
-+#define BF_AUDIOIN_ADCVOL_SELECT_RIGHT(v) \
-+ (((v) << 4) & BM_AUDIOIN_ADCVOL_SELECT_RIGHT)
-+#define BP_AUDIOIN_ADCVOL_GAIN_RIGHT 0
-+#define BM_AUDIOIN_ADCVOL_GAIN_RIGHT 0x0000000F
-+#define BF_AUDIOIN_ADCVOL_GAIN_RIGHT(v) \
-+ (((v) << 0) & BM_AUDIOIN_ADCVOL_GAIN_RIGHT)
-+
-+#define HW_AUDIOIN_MICLINE (0x00000060)
-+#define HW_AUDIOIN_MICLINE_SET (0x00000064)
-+#define HW_AUDIOIN_MICLINE_CLR (0x00000068)
-+#define HW_AUDIOIN_MICLINE_TOG (0x0000006c)
-+
-+#define BP_AUDIOIN_MICLINE_RSRVD6 30
-+#define BM_AUDIOIN_MICLINE_RSRVD6 0xC0000000
-+#define BF_AUDIOIN_MICLINE_RSRVD6(v) \
-+ (((v) << 30) & BM_AUDIOIN_MICLINE_RSRVD6)
-+#define BM_AUDIOIN_MICLINE_DIVIDE_LINE1 0x20000000
-+#define BM_AUDIOIN_MICLINE_DIVIDE_LINE2 0x10000000
-+#define BP_AUDIOIN_MICLINE_RSRVD5 25
-+#define BM_AUDIOIN_MICLINE_RSRVD5 0x0E000000
-+#define BF_AUDIOIN_MICLINE_RSRVD5(v) \
-+ (((v) << 25) & BM_AUDIOIN_MICLINE_RSRVD5)
-+#define BM_AUDIOIN_MICLINE_MIC_SELECT 0x01000000
-+#define BP_AUDIOIN_MICLINE_RSRVD4 22
-+#define BM_AUDIOIN_MICLINE_RSRVD4 0x00C00000
-+#define BF_AUDIOIN_MICLINE_RSRVD4(v) \
-+ (((v) << 22) & BM_AUDIOIN_MICLINE_RSRVD4)
-+#define BP_AUDIOIN_MICLINE_MIC_RESISTOR 20
-+#define BM_AUDIOIN_MICLINE_MIC_RESISTOR 0x00300000
-+#define BF_AUDIOIN_MICLINE_MIC_RESISTOR(v) \
-+ (((v) << 20) & BM_AUDIOIN_MICLINE_MIC_RESISTOR)
-+#define BM_AUDIOIN_MICLINE_RSRVD3 0x00080000
-+#define BP_AUDIOIN_MICLINE_MIC_BIAS 16
-+#define BM_AUDIOIN_MICLINE_MIC_BIAS 0x00070000
-+#define BF_AUDIOIN_MICLINE_MIC_BIAS(v) \
-+ (((v) << 16) & BM_AUDIOIN_MICLINE_MIC_BIAS)
-+#define BP_AUDIOIN_MICLINE_RSRVD2 6
-+#define BM_AUDIOIN_MICLINE_RSRVD2 0x0000FFC0
-+#define BF_AUDIOIN_MICLINE_RSRVD2(v) \
-+ (((v) << 6) & BM_AUDIOIN_MICLINE_RSRVD2)
-+#define BP_AUDIOIN_MICLINE_MIC_CHOPCLK 4
-+#define BM_AUDIOIN_MICLINE_MIC_CHOPCLK 0x00000030
-+#define BF_AUDIOIN_MICLINE_MIC_CHOPCLK(v) \
-+ (((v) << 4) & BM_AUDIOIN_MICLINE_MIC_CHOPCLK)
-+#define BP_AUDIOIN_MICLINE_RSRVD1 2
-+#define BM_AUDIOIN_MICLINE_RSRVD1 0x0000000C
-+#define BF_AUDIOIN_MICLINE_RSRVD1(v) \
-+ (((v) << 2) & BM_AUDIOIN_MICLINE_RSRVD1)
-+#define BP_AUDIOIN_MICLINE_MIC_GAIN 0
-+#define BM_AUDIOIN_MICLINE_MIC_GAIN 0x00000003
-+#define BF_AUDIOIN_MICLINE_MIC_GAIN(v) \
-+ (((v) << 0) & BM_AUDIOIN_MICLINE_MIC_GAIN)
-+
-+#define HW_AUDIOIN_ANACLKCTRL (0x00000070)
-+#define HW_AUDIOIN_ANACLKCTRL_SET (0x00000074)
-+#define HW_AUDIOIN_ANACLKCTRL_CLR (0x00000078)
-+#define HW_AUDIOIN_ANACLKCTRL_TOG (0x0000007c)
-+
-+#define BM_AUDIOIN_ANACLKCTRL_CLKGATE 0x80000000
-+#define BP_AUDIOIN_ANACLKCTRL_RSRVD4 11
-+#define BM_AUDIOIN_ANACLKCTRL_RSRVD4 0x7FFFF800
-+#define BF_AUDIOIN_ANACLKCTRL_RSRVD4(v) \
-+ (((v) << 11) & BM_AUDIOIN_ANACLKCTRL_RSRVD4)
-+#define BM_AUDIOIN_ANACLKCTRL_DITHER_OFF 0x00000400
-+#define BM_AUDIOIN_ANACLKCTRL_SLOW_DITHER 0x00000200
-+#define BM_AUDIOIN_ANACLKCTRL_INVERT_ADCCLK 0x00000100
-+#define BP_AUDIOIN_ANACLKCTRL_RSRVD3 6
-+#define BM_AUDIOIN_ANACLKCTRL_RSRVD3 0x000000C0
-+#define BF_AUDIOIN_ANACLKCTRL_RSRVD3(v) \
-+ (((v) << 6) & BM_AUDIOIN_ANACLKCTRL_RSRVD3)
-+#define BP_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 4
-+#define BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 0x00000030
-+#define BF_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT(v) \
-+ (((v) << 4) & BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT)
-+#define BM_AUDIOIN_ANACLKCTRL_RSRVD2 0x00000008
-+#define BP_AUDIOIN_ANACLKCTRL_ADCDIV 0
-+#define BM_AUDIOIN_ANACLKCTRL_ADCDIV 0x00000007
-+#define BF_AUDIOIN_ANACLKCTRL_ADCDIV(v) \
-+ (((v) << 0) & BM_AUDIOIN_ANACLKCTRL_ADCDIV)
-+
-+#define HW_AUDIOIN_DATA (0x00000080)
-+#define HW_AUDIOIN_DATA_SET (0x00000084)
-+#define HW_AUDIOIN_DATA_CLR (0x00000088)
-+#define HW_AUDIOIN_DATA_TOG (0x0000008c)
-+
-+#define BP_AUDIOIN_DATA_HIGH 16
-+#define BM_AUDIOIN_DATA_HIGH 0xFFFF0000
-+#define BF_AUDIOIN_DATA_HIGH(v) \
-+ (((v) << 16) & BM_AUDIOIN_DATA_HIGH)
-+#define BP_AUDIOIN_DATA_LOW 0
-+#define BM_AUDIOIN_DATA_LOW 0x0000FFFF
-+#define BF_AUDIOIN_DATA_LOW(v) \
-+ (((v) << 0) & BM_AUDIOIN_DATA_LOW)
-+
-+#define BV_AUDIOIN_ADCVOL_SELECT__MIC 0x00
-+
-+#endif /* __MXS_ADC_CODEC_H */
---- a/sound/soc/mxs/Kconfig
-+++ b/sound/soc/mxs/Kconfig
-@@ -18,3 +18,13 @@ config SND_SOC_MXS_SGTL5000
- a sgtl5000 codec.
-
- endif # SND_MXS_SOC
-+
-+
-+config SND_MXS_SOC_BUILTIN
-+ tristate "SoC Audio for Freescale i.MX23 built-in codec"
-+ depends on ARCH_MXS
-+ select SND_SOC_GENERIC_DMAENGINE_PCM
-+ select SND_SOC_MXS_BUILTIN_CODEC
-+ help
-+ Say Y or M if you want to add support for codecs attached to
-+ the MXS SAIF interface.
---- a/sound/soc/mxs/Makefile
-+++ b/sound/soc/mxs/Makefile
-@@ -8,3 +8,12 @@ obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs
- snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
-
- obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
-+
-+# i.MX23 built-in audio Machine and Platform support
-+snd-soc-mxs-builtin-pcm-objs := mxs-builtin-pcm.o
-+snd-soc-mxs-builtin-dai-objs := mxs-builtin-dai.o
-+snd-soc-mxs-builtin-audio-objs := mxs-builtin-audio.o
-+
-+obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-pcm.o
-+obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-dai.o
-+obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-audio.o
---- /dev/null
-+++ b/sound/soc/mxs/mxs-builtin-audio.c
-@@ -0,0 +1,120 @@
-+/*
-+ * mxs-builtin-audio.c -- i.MX233 built-in codec ALSA Soc Audio driver
-+ *
-+ * Author: Michal Ulianko <michal.ulianko@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <sound/core.h>
-+#include <sound/pcm.h>
-+#include <sound/soc.h>
-+#include <sound/jack.h>
-+#include <sound/soc-dapm.h>
-+#include <asm/mach-types.h>
-+
-+static struct snd_soc_dai_link mxs_adc_dai_link[] = {
-+ {
-+ .name = "MXS ADC/DAC",
-+ .stream_name = "MXS ADC/DAC",
-+ .codec_dai_name = "mxs-builtin-codec-dai",
-+// .codec_name = "mxs-builtin-codec",
-+// .cpu_dai_name = "mxs-builtin-cpu-dai",
-+// .platform_name = "mxs-builtin-cpu-dai",
-+// .ops = &mxs_sgtl5000_hifi_ops,
-+ },
-+};
-+
-+static struct snd_soc_card mxs_adc_audio = {
-+ .name = "mxs-builtin-audio",
-+ .owner = THIS_MODULE,
-+ .dai_link = mxs_adc_dai_link,
-+ .num_links = ARRAY_SIZE(mxs_adc_dai_link),
-+};
-+
-+static int mxsadc_audio_probe_dt(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device_node *cpu_dai_np, *codec_np;
-+ int ret = 0;
-+
-+ if (!np)
-+ return 1; /* no device tree */
-+
-+ cpu_dai_np = of_parse_phandle(np, "cpu-dai", 0);
-+ codec_np = of_parse_phandle(np, "audio-codec", 0);
-+ if (!cpu_dai_np || !codec_np) {
-+ dev_err(&pdev->dev, "phandle missing or invalid\n");
-+ return -EINVAL;
-+ }
-+
-+ mxs_adc_dai_link[0].codec_name = NULL;
-+ mxs_adc_dai_link[0].codec_of_node = codec_np;
-+ mxs_adc_dai_link[0].cpu_dai_name = NULL;
-+ mxs_adc_dai_link[0].cpu_of_node = cpu_dai_np;
-+ mxs_adc_dai_link[0].platform_name = NULL;
-+ mxs_adc_dai_link[0].platform_of_node = cpu_dai_np;
-+
-+// of_node_put(codec_np);
-+// of_node_put(cpu_dai_np);
-+
-+ return ret;
-+}
-+
-+static int mxsadc_audio_probe(struct platform_device *pdev)
-+{
-+ struct snd_soc_card *card = &mxs_adc_audio;
-+ int ret;
-+
-+ ret = mxsadc_audio_probe_dt(pdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ card->dev = &pdev->dev;
-+ platform_set_drvdata(pdev, card);
-+
-+ ret = snd_soc_register_card(card);
-+ if (ret) {
-+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mxsadc_audio_remove(struct platform_device *pdev)
-+{
-+ struct snd_soc_card *card = platform_get_drvdata(pdev);
-+
-+ snd_soc_unregister_card(card);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mxs_adc_audio_dt_ids[] = {
-+ { .compatible = "fsl,mxs-builtin-audio", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mxs_adc_audio_dt_ids);
-+
-+static struct platform_driver mxs_adc_audio_driver = {
-+ .driver = {
-+ .name = "mxs-builtin-audio",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mxs_adc_audio_dt_ids,
-+ },
-+ .probe = mxsadc_audio_probe,
-+ .remove = mxsadc_audio_remove,
-+};
-+
-+module_platform_driver(mxs_adc_audio_driver);
-+
-+MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Machine Driver");
-+MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/sound/soc/mxs/mxs-builtin-dai.c
-@@ -0,0 +1,588 @@
-+/*
-+ * mxs-builtin-dai.c -- i.MX233 built-in codec ALSA Soc Audio driver
-+ *
-+ * Author: Michal Ulianko <michal.ulianko@gmail.com>
-+ *
-+ * Based on sound/soc/mxs/mxs-adc.c for kernel 2.6.35
-+ * by Vladislav Buzov <vbuzov@embeddedalley.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/platform_device.h>
-+#include <sound/pcm.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+
-+#include "../codecs/mxs-builtin-codec.h"
-+#include "mxs-builtin-pcm.h"
-+
-+#define ADC_VOLUME_MIN 0x37
-+
-+/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */
-+
-+// TODO use container_of
-+struct mxs_irq_data {
-+ struct snd_pcm_substream *substream;
-+ struct mxs_adc_priv *mxs_adc;
-+};
-+
-+struct mxs_adc_priv {
-+ struct mxs_irq_data irq_data;
-+ int dma_adc_err_irq;
-+ int dma_dac_err_irq;
-+ int hp_short_irq;
-+ void __iomem *audioin_base;
-+ void __iomem *audioout_base;
-+ void __iomem *rtc_base;
-+};
-+
-+typedef struct {
-+ struct work_struct work;
-+ struct timer_list timer;
-+
-+ /* target workqueue and CPU ->timer uses to queue ->work */
-+ struct workqueue_struct *wq;
-+ int cpu;
-+
-+ struct mxs_adc_priv *mxs_adc;
-+} my_delayed_work_t;
-+
-+// static struct delayed_work work;
-+// static struct delayed_work adc_ramp_work;
-+// static struct delayed_work dac_ramp_work;
-+// static struct delayed_work test;
-+static my_delayed_work_t work;
-+static my_delayed_work_t adc_ramp_work;
-+static my_delayed_work_t dac_ramp_work;
-+static my_delayed_work_t test;
-+static bool adc_ramp_done = 1;
-+static bool dac_ramp_done = 1;
-+
-+static inline void mxs_adc_schedule_work(struct delayed_work *work)
-+{
-+ schedule_delayed_work(work, HZ / 10);
-+}
-+
-+static void mxs_adc_work(struct work_struct *work)
-+{
-+ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
-+ /* disable irq */
-+ disable_irq(mxs_adc->hp_short_irq);
-+
-+ while (true) {
-+ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR);
-+ msleep(10);
-+ if ((__raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL)
-+ & BM_AUDIOOUT_ANACTRL_SHORT_LR_STS) != 0) {
-+ /* rearm the short protection */
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1),
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
-+
-+ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET);
-+ printk(KERN_WARNING "WARNING : Headphone LR short!\r\n");
-+ } else {
-+ printk(KERN_WARNING "INFO : Headphone LR no longer short!\r\n");
-+ break;
-+ }
-+ msleep(1000);
-+ }
-+
-+ /* power up the HEADPHONE and un-mute the HPVOL */
-+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR);
-+ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR);
-+
-+ /* enable irq for next short detect*/
-+ enable_irq(mxs_adc->hp_short_irq);
-+}
-+
-+static void mxs_adc_schedule_ramp_work(struct delayed_work *work)
-+{
-+ schedule_delayed_work(work, msecs_to_jiffies(2));
-+ adc_ramp_done = 0;
-+}
-+
-+static void mxs_adc_ramp_work(struct work_struct *work)
-+{
-+ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
-+ u32 reg = 0;
-+ u32 reg1 = 0;
-+ u32 reg2 = 0;
-+ u32 l, r;
-+ u32 ll, rr;
-+ int i;
-+
-+ reg = __raw_readl(mxs_adc->audioin_base + \
-+ HW_AUDIOIN_ADCVOLUME);
-+
-+ reg1 = reg & ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
-+ reg1 = reg1 & ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
-+ /* minimize adc volume */
-+ reg2 = reg1 |
-+ BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ADC_VOLUME_MIN) |
-+ BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(ADC_VOLUME_MIN);
-+ __raw_writel(reg2,
-+ mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME);
-+ msleep(1);
-+
-+ l = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT) >>
-+ BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
-+ r = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT) >>
-+ BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
-+
-+ /* fade in adc vol */
-+ for (i = ADC_VOLUME_MIN; (i < l) || (i < r);) {
-+ i += 0x8;
-+ ll = i < l ? i : l;
-+ rr = i < r ? i : r;
-+ reg2 = reg1 |
-+ BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ll) |
-+ BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(rr);
-+ __raw_writel(reg2,
-+ mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME);
-+ msleep(1);
-+ }
-+ adc_ramp_done = 1;
-+}
-+
-+static void mxs_dac_schedule_ramp_work(struct delayed_work *work)
-+{
-+ schedule_delayed_work(work, msecs_to_jiffies(2));
-+ dac_ramp_done = 0;
-+}
-+
-+static void mxs_dac_ramp_work(struct work_struct *work)
-+{
-+ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
-+ u32 reg = 0;
-+ u32 reg1 = 0;
-+ u32 l, r;
-+ u32 ll, rr;
-+ int i;
-+
-+ /* unmute hp and speaker */
-+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR);
-+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_CLR);
-+
-+ reg = __raw_readl(mxs_adc->audioout_base + \
-+ HW_AUDIOOUT_HPVOL);
-+
-+ reg1 = reg & ~BM_AUDIOOUT_HPVOL_VOL_LEFT;
-+ reg1 = reg1 & ~BM_AUDIOOUT_HPVOL_VOL_RIGHT;
-+
-+ l = (reg & BM_AUDIOOUT_HPVOL_VOL_LEFT) >>
-+ BP_AUDIOOUT_HPVOL_VOL_LEFT;
-+ r = (reg & BM_AUDIOOUT_HPVOL_VOL_RIGHT) >>
-+ BP_AUDIOOUT_HPVOL_VOL_RIGHT;
-+ /* fade in hp vol */
-+ for (i = 0x7f; i > 0 ;) {
-+ i -= 0x8;
-+ ll = i > (int)l ? i : l;
-+ rr = i > (int)r ? i : r;
-+ reg = reg1 | BF_AUDIOOUT_HPVOL_VOL_LEFT(ll)
-+ | BF_AUDIOOUT_HPVOL_VOL_RIGHT(rr);
-+ __raw_writel(reg,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL);
-+ msleep(1);
-+ }
-+ dac_ramp_done = 1;
-+}
-+
-+/* IRQs */
-+static irqreturn_t mxs_short_irq(int irq, void *dev_id)
-+{
-+ struct mxs_adc_priv *mxs_adc = dev_id;
-+ //struct snd_pcm_substream *substream = mxs_adc->irq_data.substream;
-+
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
-+ __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1),
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
-+
-+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET);
-+ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET);
-+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
-+
-+ mxs_adc_schedule_work((struct delayed_work *) &work);
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t mxs_err_irq(int irq, void *dev_id)
-+{
-+ struct mxs_adc_priv *mxs_adc = dev_id;
-+ struct snd_pcm_substream *substream = mxs_adc->irq_data.substream;
-+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
-+ u32 ctrl_reg;
-+ u32 overflow_mask;
-+ u32 underflow_mask;
-+
-+ if (playback) {
-+ ctrl_reg = __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL);
-+ underflow_mask = BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ;
-+ overflow_mask = BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ;
-+ } else {
-+ ctrl_reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_CTRL);
-+ underflow_mask = BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ;
-+ overflow_mask = BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ;
-+ }
-+
-+ if (ctrl_reg & underflow_mask) {
-+ printk(KERN_DEBUG "%s underflow detected\n",
-+ playback ? "DAC" : "ADC");
-+
-+ if (playback)
-+ __raw_writel(
-+ BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
-+ else
-+ __raw_writel(
-+ BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
-+
-+ } else if (ctrl_reg & overflow_mask) {
-+ printk(KERN_DEBUG "%s overflow detected\n",
-+ playback ? "DAC" : "ADC");
-+
-+ if (playback)
-+ __raw_writel(
-+ BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
-+ else
-+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
-+ } else
-+ printk(KERN_WARNING "Unknown DAC error interrupt\n");
-+
-+ return IRQ_HANDLED;
-+}
-+/* END IRQs */
-+
-+static int mxs_trigger(struct snd_pcm_substream *substream,
-+ int cmd,
-+ struct snd_soc_dai *cpu_dai)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
-+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
-+ int ret = 0;
-+
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+
-+ if (playback) {
-+ /* enable the fifo error interrupt */
-+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_SET);
-+ /* write a data to data reg to trigger the transfer */
-+ __raw_writel(0x0,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_DATA);
-+ mxs_dac_schedule_ramp_work((struct delayed_work *) &dac_ramp_work);
-+ } else {
-+// mxs_dma_get_info(prtd->dma_ch, &dma_info);
-+// cur_bar1 = dma_info.buf_addr;
-+// xfer_count1 = dma_info.xfer_count;
-+
-+ __raw_writel(BM_AUDIOIN_CTRL_RUN,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET);
-+ udelay(100);
-+
-+// mxs_dma_get_info(prtd->dma_ch, &dma_info);
-+// cur_bar2 = dma_info.buf_addr;
-+// xfer_count2 = dma_info.xfer_count;
-+//
-+// /* check if DMA getting stuck */
-+// if ((xfer_count1 == xfer_count2) && (cur_bar1 == cur_bar2))
-+// /* read a data from data reg to trigger the receive */
-+// reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_DATA);
-+
-+ mxs_adc_schedule_ramp_work((struct delayed_work *) &adc_ramp_work);
-+ }
-+ break;
-+
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+
-+ if (playback) {
-+// printk(KERN_INFO "SNDRV_PCM_TRIGGER_START\n");
-+// printk(KERN_INFO "ctrl:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL));
-+// printk(KERN_INFO "stat:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_STAT));
-+// printk(KERN_INFO "srr:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACSRR));
-+// printk(KERN_INFO "vol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACVOLUME));
-+// printk(KERN_INFO "debug:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACDEBUG));
-+// printk(KERN_INFO "hpvol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL));
-+// printk(KERN_INFO "pwrdn:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN));
-+// printk(KERN_INFO "refc:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_REFCTRL));
-+// printk(KERN_INFO "anac:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL));
-+// printk(KERN_INFO "test:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_TEST));
-+// printk(KERN_INFO "bist:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_BISTCTRL));
-+// printk(KERN_INFO "anaclk:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACLKCTRL));
-+
-+ if (dac_ramp_done == 0) {
-+ cancel_delayed_work((struct delayed_work *) &dac_ramp_work);
-+ dac_ramp_done = 1;
-+ }
-+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET);
-+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
-+ /* disable the fifo error interrupt */
-+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
-+ mdelay(50);
-+ } else {
-+ if (adc_ramp_done == 0) {
-+ cancel_delayed_work((struct delayed_work *) &adc_ramp_work);
-+ adc_ramp_done = 1;
-+ }
-+ __raw_writel(BM_AUDIOIN_CTRL_RUN,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
-+ }
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "TRIGGER ERROR\n");
-+ ret = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static int mxs_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *cpu_dai)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
-+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
-+ mxs_adc->irq_data.mxs_adc = mxs_adc;
-+ mxs_adc->irq_data.substream = substream;
-+
-+ work.mxs_adc = mxs_adc;
-+ adc_ramp_work.mxs_adc = mxs_adc;
-+ dac_ramp_work.mxs_adc = mxs_adc;
-+ test.mxs_adc = mxs_adc;
-+ INIT_DELAYED_WORK(&work, mxs_adc_work);
-+ INIT_DELAYED_WORK(&adc_ramp_work, mxs_adc_ramp_work);
-+ INIT_DELAYED_WORK(&dac_ramp_work, mxs_dac_ramp_work);
-+
-+ /* Enable error interrupt */
-+ if (playback) {
-+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
-+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
-+ } else {
-+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
-+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
-+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET);
-+ }
-+
-+ return 0;
-+}
-+
-+static void mxs_shutdown(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *cpu_dai)
-+{
-+ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
-+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
-+
-+ /* Disable error interrupt */
-+ if (playback) {
-+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
-+ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
-+ } else {
-+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
-+ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
-+ }
-+}
-+
-+#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
-+#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-+
-+static const struct snd_soc_dai_ops mxs_adc_dai_ops = {
-+ .startup = mxs_startup,
-+ .trigger = mxs_trigger,
-+ .shutdown = mxs_shutdown,
-+};
-+
-+static int mxs_dai_probe(struct snd_soc_dai *dai)
-+{
-+ // TODO This does not make any sense.
-+ struct mxs_adc_priv *mxs_adc = dev_get_drvdata(dai->dev);
-+
-+ snd_soc_dai_set_drvdata(dai, mxs_adc);
-+
-+ return 0;
-+}
-+
-+static struct snd_soc_dai_driver mxs_adc_dai = {
-+ .name = "mxs-builtin-cpu-dai",
-+ .probe = mxs_dai_probe,
-+ .playback = {
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rates = MXS_ADC_RATES,
-+ .formats = MXS_ADC_FORMATS,
-+ },
-+ .capture = {
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rates = MXS_ADC_RATES,
-+ .formats = MXS_ADC_FORMATS,
-+ },
-+ .ops = &mxs_adc_dai_ops,
-+};
-+
-+static const struct snd_soc_component_driver mxs_adc_component = {
-+ .name = "mxs-xxx", //TODO change this name
-+};
-+
-+static int mxs_adc_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct mxs_adc_priv *mxs_adc;
-+ int ret = 0;
-+
-+ if (!np)
-+ return -EINVAL;
-+
-+ mxs_adc = devm_kzalloc(&pdev->dev, sizeof(*mxs_adc), GFP_KERNEL);
-+ if (!mxs_adc)
-+ return -ENOMEM;
-+
-+ mxs_adc->audioout_base = devm_ioremap(&pdev->dev, 0x80048000, 0x2000);
-+ if (IS_ERR(mxs_adc->audioout_base))
-+ return PTR_ERR(mxs_adc->audioout_base);
-+
-+ mxs_adc->audioin_base = devm_ioremap(&pdev->dev, 0x8004c000, 0x2000);
-+ if (IS_ERR(mxs_adc->audioin_base))
-+ return PTR_ERR(mxs_adc->audioin_base);
-+
-+ mxs_adc->rtc_base = devm_ioremap(&pdev->dev, 0x8005c000, 0x2000);
-+ if (IS_ERR(mxs_adc->rtc_base))
-+ return PTR_ERR(mxs_adc->rtc_base);
-+
-+ /* Get IRQ numbers */
-+ mxs_adc->dma_adc_err_irq = platform_get_irq(pdev, 0);
-+ if (mxs_adc->dma_adc_err_irq < 0) {
-+ ret = mxs_adc->dma_adc_err_irq;
-+ dev_err(&pdev->dev, "failed to get ADC DMA ERR irq resource: %d\n", ret);
-+ return ret;
-+ }
-+
-+ mxs_adc->dma_dac_err_irq = platform_get_irq(pdev, 1);
-+ if (mxs_adc->dma_dac_err_irq < 0) {
-+ ret = mxs_adc->dma_dac_err_irq;
-+ dev_err(&pdev->dev, "failed to get DAC DMA ERR irq resource: %d\n", ret);
-+ return ret;
-+ }
-+
-+ mxs_adc->hp_short_irq = platform_get_irq(pdev, 2);
-+ if (mxs_adc->hp_short_irq < 0) {
-+ ret = mxs_adc->hp_short_irq;
-+ dev_err(&pdev->dev, "failed to get HP_SHORT irq resource: %d\n", ret);
-+ return ret;
-+ }
-+
-+ /* Request IRQs */
-+ ret = devm_request_irq(&pdev->dev, mxs_adc->dma_adc_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error",
-+ mxs_adc);
-+ if (ret) {
-+ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
-+ __func__, mxs_adc->dma_adc_err_irq);
-+ return ret;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, mxs_adc->dma_dac_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error",
-+ mxs_adc);
-+ if (ret) {
-+ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
-+ __func__, mxs_adc->dma_dac_err_irq);
-+ return ret;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, mxs_adc->hp_short_irq, mxs_short_irq,
-+ IRQF_DISABLED | IRQF_SHARED, "MXS DAC and ADC HP SHORT", mxs_adc);
-+ if (ret) {
-+ printk(KERN_ERR "%s: Unable to request ADC/DAC HP SHORT irq %d\n",
-+ __func__, mxs_adc->hp_short_irq);
-+ return ret;
-+ }
-+
-+ platform_set_drvdata(pdev, mxs_adc);
-+
-+ ret = snd_soc_register_component(&pdev->dev, &mxs_adc_component, &mxs_adc_dai, 1);
-+ if (ret) {
-+ dev_err(&pdev->dev, "register DAI failed\n");
-+ return ret;
-+ }
-+
-+ ret = mxs_adc_pcm_platform_register(&pdev->dev);
-+ if (ret) {
-+ dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
-+ goto failed_pdev_alloc;
-+ }
-+
-+ return 0;
-+
-+failed_pdev_alloc:
-+ snd_soc_unregister_component(&pdev->dev);
-+
-+ return ret;
-+}
-+
-+static int mxs_adc_remove(struct platform_device *pdev)
-+{
-+ mxs_adc_pcm_platform_unregister(&pdev->dev);
-+ snd_soc_unregister_component(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mxs_adc_dai_dt_ids[] = {
-+ { .compatible = "fsl,mxs-builtin-cpu-dai", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mxs_adc_dai_dt_ids);
-+
-+static struct platform_driver mxs_adc_dai_driver = {
-+ .probe = mxs_adc_probe,
-+ .remove = mxs_adc_remove,
-+
-+ .driver = {
-+ .name = "mxs-builtin-cpu-dai",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mxs_adc_dai_dt_ids,
-+ },
-+};
-+
-+module_platform_driver(mxs_adc_dai_driver);
-+
-+MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec DAI Driver");
-+MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/sound/soc/mxs/mxs-builtin-pcm.c
-@@ -0,0 +1,69 @@
-+/*
-+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
-+ *
-+ * Based on sound/soc/imx/imx-pcm-dma-mx2.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+
-+#include <sound/core.h>
-+#include <sound/pcm.h>
-+#include <sound/soc.h>
-+#include <sound/dmaengine_pcm.h>
-+
-+#include "mxs-builtin-pcm.h"
-+
-+static const struct snd_pcm_hardware snd_mxs_hardware = {
-+ .info = SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_MMAP_VALID |
-+ SNDRV_PCM_INFO_PAUSE |
-+ SNDRV_PCM_INFO_RESUME |
-+ SNDRV_PCM_INFO_INTERLEAVED,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
-+ SNDRV_PCM_FMTBIT_S20_3LE |
-+ SNDRV_PCM_FMTBIT_S24_LE,
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .period_bytes_min = 32,
-+ .period_bytes_max = 8192,
-+ .periods_min = 1,
-+ .periods_max = 52,
-+ .buffer_bytes_max = 64 * 1024,
-+ .fifo_size = 32,
-+};
-+
-+static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
-+ .pcm_hardware = &snd_mxs_hardware,
-+ .prealloc_buffer_size = 64 * 1024,
-+};
-+
-+int mxs_adc_pcm_platform_register(struct device *dev)
-+{
-+ return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
-+ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
-+}
-+EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_register);
-+
-+void mxs_adc_pcm_platform_unregister(struct device *dev)
-+{
-+ snd_dmaengine_pcm_unregister(dev);
-+}
-+EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_unregister);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/sound/soc/mxs/mxs-builtin-pcm.h
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+ */
-+
-+#ifndef _MXS_PCM_H
-+#define _MXS_PCM_H
-+
-+int mxs_adc_pcm_platform_register(struct device *dev);
-+void mxs_adc_pcm_platform_unregister(struct device *dev);
-+
-+#endif
+++ /dev/null
---- a/arch/arm/boot/dts/imx23-olinuxino.dts
-+++ b/arch/arm/boot/dts/imx23-olinuxino.dts
-@@ -84,6 +84,25 @@
- usbphy0: usbphy@8007c000 {
- status = "okay";
- };
-+
-+ codec: mxs-builtin-codec {
-+ compatible = "fsl,mxs-builtin-codec";
-+ reg = <0x80048000 0x2000>, <0x8004c000 0x2000>,
-+ <0x8005c000 0x2000>;
-+ reg-names = "audioout", "audioin", "rtc";
-+ clocks = <&clks 31>;
-+ clock-names = "filt";
-+ };
-+
-+ platform_dai: mxs-builtin-cpu-dai {
-+ compatible = "fsl,mxs-builtin-cpu-dai";
-+ reg = <0x80048000 0x2000>, <0x8004c000 0x2000>,
-+ <0x8005c000 0x2000>;
-+ reg-names = "audioout", "audioin", "rtc";
-+ interrupts = <8 6 4>;
-+ dmas = <&dma_apbx 0>, <&dma_apbx 1>;
-+ dma-names = "rx", "tx";
-+ };
- };
- };
-
-@@ -118,4 +137,10 @@
- gpios = <&gpio2 1 1>;
- };
- };
-+
-+ mxs-builtin-audio {
-+ compatible = "fsl,mxs-builtin-audio";
-+ audio-codec = <&codec>;
-+ cpu-dai = <&platform_dai>;
-+ };
- };
+++ /dev/null
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -287,6 +287,16 @@ config CRYPTO_DEV_SAHARA
- This option enables support for the SAHARA HW crypto accelerator
- found in some Freescale i.MX chips.
-
-+config CRYPTO_DEV_DCP
-+ tristate "Support for the DCP engine"
-+ depends on ARCH_MXS && OF
-+ select CRYPTO_BLKCIPHER
-+ select CRYPTO_AES
-+ select CRYPTO_CBC
-+ help
-+ This options enables support for the hardware crypto-acceleration
-+ capabilities of the DCP co-processor
-+
- config CRYPTO_DEV_S5P
- tristate "Support for Samsung S5PV210 crypto accelerator"
- depends on ARCH_S5PV210
---- a/drivers/crypto/Makefile
-+++ b/drivers/crypto/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += om
- obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
- obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
- obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
-+obj-$(CONFIG_CRYPTO_DEV_DCP) += dcp.o
- obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
- obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o
- obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
---- /dev/null
-+++ b/drivers/crypto/dcp.c
-@@ -0,0 +1,925 @@
-+/*
-+ * Cryptographic API.
-+ *
-+ * Support for DCP cryptographic accelerator.
-+ *
-+ * Copyright (c) 2013
-+ * Author: Tobias Rauter <tobias.rau...@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ * Based on tegra-aes.c, dcp.c (from freescale SDK) and sahara.c
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/io.h>
-+#include <linux/mutex.h>
-+#include <linux/interrupt.h>
-+#include <linux/completion.h>
-+#include <linux/workqueue.h>
-+#include <linux/delay.h>
-+#include <linux/crypto.h>
-+#include <linux/miscdevice.h>
-+
-+#include <crypto/scatterwalk.h>
-+#include <crypto/aes.h>
-+
-+
-+/* IOCTL for DCP OTP Key AES - taken from Freescale's SDK*/
-+#define DBS_IOCTL_BASE 'd'
-+#define DBS_ENC _IOW(DBS_IOCTL_BASE, 0x00, uint8_t[16])
-+#define DBS_DEC _IOW(DBS_IOCTL_BASE, 0x01, uint8_t[16])
-+
-+/* DCP channel used for AES */
-+#define USED_CHANNEL 1
-+/* Ring Buffers' maximum size */
-+#define DCP_MAX_PKG 20
-+
-+/* Control Register */
-+#define DCP_REG_CTRL 0x000
-+#define DCP_CTRL_SFRST (1<<31)
-+#define DCP_CTRL_CLKGATE (1<<30)
-+#define DCP_CTRL_CRYPTO_PRESENT (1<<29)
-+#define DCP_CTRL_SHA_PRESENT (1<<28)
-+#define DCP_CTRL_GATHER_RES_WRITE (1<<23)
-+#define DCP_CTRL_ENABLE_CONTEXT_CACHE (1<<22)
-+#define DCP_CTRL_ENABLE_CONTEXT_SWITCH (1<<21)
-+#define DCP_CTRL_CH_IRQ_E_0 0x01
-+#define DCP_CTRL_CH_IRQ_E_1 0x02
-+#define DCP_CTRL_CH_IRQ_E_2 0x04
-+#define DCP_CTRL_CH_IRQ_E_3 0x08
-+
-+/* Status register */
-+#define DCP_REG_STAT 0x010
-+#define DCP_STAT_OTP_KEY_READY (1<<28)
-+#define DCP_STAT_CUR_CHANNEL(stat) ((stat>>24)&0x0F)
-+#define DCP_STAT_READY_CHANNEL(stat) ((stat>>16)&0x0F)
-+#define DCP_STAT_IRQ(stat) (stat&0x0F)
-+#define DCP_STAT_CHAN_0 (0x01)
-+#define DCP_STAT_CHAN_1 (0x02)
-+#define DCP_STAT_CHAN_2 (0x04)
-+#define DCP_STAT_CHAN_3 (0x08)
-+
-+/* Channel Control Register */
-+#define DCP_REG_CHAN_CTRL 0x020
-+#define DCP_CHAN_CTRL_CH0_IRQ_MERGED (1<<16)
-+#define DCP_CHAN_CTRL_HIGH_PRIO_0 (0x0100)
-+#define DCP_CHAN_CTRL_HIGH_PRIO_1 (0x0200)
-+#define DCP_CHAN_CTRL_HIGH_PRIO_2 (0x0400)
-+#define DCP_CHAN_CTRL_HIGH_PRIO_3 (0x0800)
-+#define DCP_CHAN_CTRL_ENABLE_0 (0x01)
-+#define DCP_CHAN_CTRL_ENABLE_1 (0x02)
-+#define DCP_CHAN_CTRL_ENABLE_2 (0x04)
-+#define DCP_CHAN_CTRL_ENABLE_3 (0x08)
-+
-+/*
-+ * Channel Registers:
-+ * The DCP has 4 channels. Each of this channels
-+ * has 4 registers (command pointer, semaphore, status and options).
-+ * The address of register REG of channel CHAN is obtained by
-+ * dcp_chan_reg(REG, CHAN)
-+ */
-+#define DCP_REG_CHAN_PTR 0x00000100
-+#define DCP_REG_CHAN_SEMA 0x00000110
-+#define DCP_REG_CHAN_STAT 0x00000120
-+#define DCP_REG_CHAN_OPT 0x00000130
-+
-+#define DCP_CHAN_STAT_NEXT_CHAIN_IS_0 0x010000
-+#define DCP_CHAN_STAT_NO_CHAIN 0x020000
-+#define DCP_CHAN_STAT_CONTEXT_ERROR 0x030000
-+#define DCP_CHAN_STAT_PAYLOAD_ERROR 0x040000
-+#define DCP_CHAN_STAT_INVALID_MODE 0x050000
-+#define DCP_CHAN_STAT_PAGEFAULT 0x40
-+#define DCP_CHAN_STAT_DST 0x20
-+#define DCP_CHAN_STAT_SRC 0x10
-+#define DCP_CHAN_STAT_PACKET 0x08
-+#define DCP_CHAN_STAT_SETUP 0x04
-+#define DCP_CHAN_STAT_MISMATCH 0x02
-+
-+/* hw packet control*/
-+
-+#define DCP_PKT_PAYLOAD_KEY (1<<11)
-+#define DCP_PKT_OTP_KEY (1<<10)
-+#define DCP_PKT_CIPHER_INIT (1<<9)
-+#define DCP_PKG_CIPHER_ENCRYPT (1<<8)
-+#define DCP_PKT_CIPHER_ENABLE (1<<5)
-+#define DCP_PKT_DECR_SEM (1<<1)
-+#define DCP_PKT_CHAIN (1<<2)
-+#define DCP_PKT_IRQ 1
-+
-+#define DCP_PKT_MODE_CBC (1<<4)
-+#define DCP_PKT_KEYSELECT_OTP (0xFF<<8)
-+
-+/* cipher flags */
-+#define DCP_ENC 0x0001
-+#define DCP_DEC 0x0002
-+#define DCP_ECB 0x0004
-+#define DCP_CBC 0x0008
-+#define DCP_CBC_INIT 0x0010
-+#define DCP_NEW_KEY 0x0040
-+#define DCP_OTP_KEY 0x0080
-+#define DCP_AES 0x1000
-+
-+/* DCP Flags */
-+#define DCP_FLAG_BUSY 0x01
-+#define DCP_FLAG_PRODUCING 0x02
-+
-+/* clock defines */
-+#define CLOCK_ON 1
-+#define CLOCK_OFF 0
-+
-+struct dcp_dev_req_ctx {
-+ int mode;
-+};
-+
-+struct dcp_op {
-+ unsigned int flags;
-+ u8 key[AES_KEYSIZE_128];
-+ int keylen;
-+
-+ struct ablkcipher_request *req;
-+ struct crypto_ablkcipher *fallback;
-+
-+ uint32_t stat;
-+ uint32_t pkt1;
-+ uint32_t pkt2;
-+ struct ablkcipher_walk walk;
-+};
-+
-+struct dcp_dev {
-+ struct device *dev;
-+ void __iomem *dcp_regs_base;
-+
-+ int dcp_vmi_irq;
-+ int dcp_irq;
-+
-+ spinlock_t queue_lock;
-+ struct crypto_queue queue;
-+
-+ uint32_t pkt_produced;
-+ uint32_t pkt_consumed;
-+
-+ struct dcp_hw_packet *hw_pkg[DCP_MAX_PKG];
-+ dma_addr_t hw_phys_pkg;
-+
-+ /* [KEY][IV] Both with 16 Bytes */
-+ u8 *payload_base;
-+ dma_addr_t payload_base_dma;
-+
-+
-+ struct tasklet_struct done_task;
-+ struct tasklet_struct queue_task;
-+ struct timer_list watchdog;
-+
-+ unsigned long flags;
-+
-+ struct dcp_op *ctx;
-+
-+ struct miscdevice dcp_bootstream_misc;
-+};
-+
-+struct dcp_hw_packet {
-+ uint32_t next;
-+ uint32_t pkt1;
-+ uint32_t pkt2;
-+ uint32_t src;
-+ uint32_t dst;
-+ uint32_t size;
-+ uint32_t payload;
-+ uint32_t stat;
-+};
-+
-+struct dcp_dev *global_dev;
-+
-+static inline u32 dcp_chan_reg(u32 reg, int chan)
-+{
-+ return reg + (chan) * 0x40;
-+}
-+
-+static inline void dcp_write(struct dcp_dev *dev, u32 data, u32 reg)
-+{
-+ writel(data, dev->dcp_regs_base + reg);
-+}
-+
-+static inline void dcp_set(struct dcp_dev *dev, u32 data, u32 reg)
-+{
-+ writel(data, dev->dcp_regs_base + (reg | 0x04));
-+}
-+
-+static inline void dcp_clear(struct dcp_dev *dev, u32 data, u32 reg)
-+{
-+ writel(data, dev->dcp_regs_base + (reg | 0x08));
-+}
-+
-+static inline void dcp_toggle(struct dcp_dev *dev, u32 data, u32 reg)
-+{
-+ writel(data, dev->dcp_regs_base + (reg | 0x0C));
-+}
-+
-+static inline unsigned int dcp_read(struct dcp_dev *dev, u32 reg)
-+{
-+ return readl(dev->dcp_regs_base + reg);
-+}
-+
-+void dcp_dma_unmap(struct dcp_dev *dev, struct dcp_hw_packet *pkt)
-+{
-+ dma_unmap_page(dev->dev, pkt->src, pkt->size, DMA_TO_DEVICE);
-+ dma_unmap_page(dev->dev, pkt->dst, pkt->size, DMA_FROM_DEVICE);
-+ dev_dbg(dev->dev, "unmap packet %x", (unsigned int) pkt);
-+}
-+
-+int dcp_dma_map(struct dcp_dev *dev,
-+ struct ablkcipher_walk *walk, struct dcp_hw_packet *pkt)
-+{
-+ dev_dbg(dev->dev, "map packet %x", (unsigned int) pkt);
-+ /* align to length = 16 */
-+ pkt->size = walk->nbytes - (walk->nbytes % 16);
-+
-+ pkt->src = dma_map_page(dev->dev, walk->src.page, walk->src.offset,
-+ pkt->size, DMA_TO_DEVICE);
-+
-+ if (pkt->src == 0) {
-+ dev_err(dev->dev, "Unable to map src");
-+ return -ENOMEM;
-+ }
-+
-+ pkt->dst = dma_map_page(dev->dev, walk->dst.page, walk->dst.offset,
-+ pkt->size, DMA_FROM_DEVICE);
-+
-+ if (pkt->dst == 0) {
-+ dev_err(dev->dev, "Unable to map dst");
-+ dma_unmap_page(dev->dev, pkt->src, pkt->size, DMA_TO_DEVICE);
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static void dcp_op_one(struct dcp_dev *dev, struct dcp_hw_packet *pkt,
-+ uint8_t last)
-+{
-+ struct dcp_op *ctx = dev->ctx;
-+ pkt->pkt1 = ctx->pkt1;
-+ pkt->pkt2 = ctx->pkt2;
-+
-+ pkt->payload = (u32) dev->payload_base_dma;
-+ pkt->stat = 0;
-+
-+ if (ctx->flags & DCP_CBC_INIT) {
-+ pkt->pkt1 |= DCP_PKT_CIPHER_INIT;
-+ ctx->flags &= ~DCP_CBC_INIT;
-+ }
-+
-+ mod_timer(&dev->watchdog, jiffies + msecs_to_jiffies(500));
-+ pkt->pkt1 |= DCP_PKT_IRQ;
-+ if (!last)
-+ pkt->pkt1 |= DCP_PKT_CHAIN;
-+
-+ dev->pkt_produced++;
-+
-+ dcp_write(dev, 1,
-+ dcp_chan_reg(DCP_REG_CHAN_SEMA, USED_CHANNEL));
-+}
-+
-+static void dcp_op_proceed(struct dcp_dev *dev)
-+{
-+ struct dcp_op *ctx = dev->ctx;
-+ struct dcp_hw_packet *pkt;
-+
-+ while (ctx->walk.nbytes) {
-+ int err = 0;
-+
-+ pkt = dev->hw_pkg[dev->pkt_produced % DCP_MAX_PKG];
-+ err = dcp_dma_map(dev, &ctx->walk, pkt);
-+ if (err) {
-+ dev->ctx->stat |= err;
-+ /* start timer to wait for already set up calls */
-+ mod_timer(&dev->watchdog,
-+ jiffies + msecs_to_jiffies(500));
-+ break;
-+ }
-+
-+
-+ err = ctx->walk.nbytes - pkt->size;
-+ ablkcipher_walk_done(dev->ctx->req, &dev->ctx->walk, err);
-+
-+ dcp_op_one(dev, pkt, ctx->walk.nbytes == 0);
-+ /* we have to wait if no space is left in buffer */
-+ if (dev->pkt_produced - dev->pkt_consumed == DCP_MAX_PKG)
-+ break;
-+ }
-+ clear_bit(DCP_FLAG_PRODUCING, &dev->flags);
-+}
-+
-+static void dcp_op_start(struct dcp_dev *dev, uint8_t use_walk)
-+{
-+ struct dcp_op *ctx = dev->ctx;
-+
-+ if (ctx->flags & DCP_NEW_KEY) {
-+ memcpy(dev->payload_base, ctx->key, ctx->keylen);
-+ ctx->flags &= ~DCP_NEW_KEY;
-+ }
-+
-+ ctx->pkt1 = 0;
-+ ctx->pkt1 |= DCP_PKT_CIPHER_ENABLE;
-+ ctx->pkt1 |= DCP_PKT_DECR_SEM;
-+
-+ if (ctx->flags & DCP_OTP_KEY)
-+ ctx->pkt1 |= DCP_PKT_OTP_KEY;
-+ else
-+ ctx->pkt1 |= DCP_PKT_PAYLOAD_KEY;
-+
-+ if (ctx->flags & DCP_ENC)
-+ ctx->pkt1 |= DCP_PKG_CIPHER_ENCRYPT;
-+
-+ ctx->pkt2 = 0;
-+ if (ctx->flags & DCP_CBC)
-+ ctx->pkt2 |= DCP_PKT_MODE_CBC;
-+
-+ dev->pkt_produced = 0;
-+ dev->pkt_consumed = 0;
-+
-+ ctx->stat = 0;
-+ dcp_clear(dev, -1, dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
-+ dcp_write(dev, (u32) dev->hw_phys_pkg,
-+ dcp_chan_reg(DCP_REG_CHAN_PTR, USED_CHANNEL));
-+
-+ set_bit(DCP_FLAG_PRODUCING, &dev->flags);
-+
-+ if (use_walk) {
-+ ablkcipher_walk_init(&ctx->walk, ctx->req->dst,
-+ ctx->req->src, ctx->req->nbytes);
-+ ablkcipher_walk_phys(ctx->req, &ctx->walk);
-+ dcp_op_proceed(dev);
-+ } else {
-+ dcp_op_one(dev, dev->hw_pkg[0], 1);
-+ clear_bit(DCP_FLAG_PRODUCING, &dev->flags);
-+ }
-+}
-+
-+static void dcp_done_task(unsigned long data)
-+{
-+ struct dcp_dev *dev = (struct dcp_dev *)data;
-+ struct dcp_hw_packet *last_packet;
-+ int fin;
-+ fin = 0;
-+
-+ for (last_packet = dev->hw_pkg[(dev->pkt_consumed) % DCP_MAX_PKG];
-+ last_packet->stat == 1;
-+ last_packet =
-+ dev->hw_pkg[++(dev->pkt_consumed) % DCP_MAX_PKG]) {
-+
-+ dcp_dma_unmap(dev, last_packet);
-+ last_packet->stat = 0;
-+ fin++;
-+ }
-+ /* the last call of this function already consumed this IRQ's packet */
-+ if (fin == 0)
-+ return;
-+
-+ dev_dbg(dev->dev,
-+ "Packet(s) done with status %x; finished: %d, produced:%d, complete consumed: %d",
-+ dev->ctx->stat, fin, dev->pkt_produced, dev->pkt_consumed);
-+
-+ last_packet = dev->hw_pkg[(dev->pkt_consumed - 1) % DCP_MAX_PKG];
-+ if (!dev->ctx->stat && last_packet->pkt1 & DCP_PKT_CHAIN) {
-+ if (!test_and_set_bit(DCP_FLAG_PRODUCING, &dev->flags))
-+ dcp_op_proceed(dev);
-+ return;
-+ }
-+
-+ while (unlikely(dev->pkt_consumed < dev->pkt_produced)) {
-+ dcp_dma_unmap(dev,
-+ dev->hw_pkg[dev->pkt_consumed++ % DCP_MAX_PKG]);
-+ }
-+
-+ if (dev->ctx->flags & DCP_OTP_KEY) {
-+ /* we used the miscdevice, no walk to finish */
-+ clear_bit(DCP_FLAG_BUSY, &dev->flags);
-+ return;
-+ }
-+
-+ ablkcipher_walk_complete(&dev->ctx->walk);
-+ dev->ctx->req->base.complete(&dev->ctx->req->base,
-+ dev->ctx->stat);
-+ dev->ctx->req = 0;
-+ /* in case there are other requests in the queue */
-+ tasklet_schedule(&dev->queue_task);
-+}
-+
-+void dcp_watchdog(unsigned long data)
-+{
-+ struct dcp_dev *dev = (struct dcp_dev *)data;
-+ dev->ctx->stat |= dcp_read(dev,
-+ dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
-+
-+ dev_err(dev->dev, "Timeout, Channel status: %x", dev->ctx->stat);
-+
-+ if (!dev->ctx->stat)
-+ dev->ctx->stat = -ETIMEDOUT;
-+
-+ dcp_done_task(data);
-+}
-+
-+
-+static irqreturn_t dcp_common_irq(int irq, void *context)
-+{
-+ u32 msk;
-+ struct dcp_dev *dev = (struct dcp_dev *) context;
-+
-+ del_timer(&dev->watchdog);
-+
-+ msk = DCP_STAT_IRQ(dcp_read(dev, DCP_REG_STAT));
-+ dcp_clear(dev, msk, DCP_REG_STAT);
-+ if (msk == 0)
-+ return IRQ_NONE;
-+
-+ dev->ctx->stat |= dcp_read(dev,
-+ dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
-+
-+ if (msk & DCP_STAT_CHAN_1)
-+ tasklet_schedule(&dev->done_task);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t dcp_vmi_irq(int irq, void *context)
-+{
-+ return dcp_common_irq(irq, context);
-+}
-+
-+static irqreturn_t dcp_irq(int irq, void *context)
-+{
-+ return dcp_common_irq(irq, context);
-+}
-+
-+static void dcp_crypt(struct dcp_dev *dev, struct dcp_op *ctx)
-+{
-+ dev->ctx = ctx;
-+
-+ if ((ctx->flags & DCP_CBC) && ctx->req->info) {
-+ ctx->flags |= DCP_CBC_INIT;
-+ memcpy(dev->payload_base + AES_KEYSIZE_128,
-+ ctx->req->info, AES_KEYSIZE_128);
-+ }
-+
-+ dcp_op_start(dev, 1);
-+}
-+
-+static void dcp_queue_task(unsigned long data)
-+{
-+ struct dcp_dev *dev = (struct dcp_dev *) data;
-+ struct crypto_async_request *async_req, *backlog;
-+ struct crypto_ablkcipher *tfm;
-+ struct dcp_op *ctx;
-+ struct dcp_dev_req_ctx *rctx;
-+ struct ablkcipher_request *req;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&dev->queue_lock, flags);
-+
-+ backlog = crypto_get_backlog(&dev->queue);
-+ async_req = crypto_dequeue_request(&dev->queue);
-+
-+ spin_unlock_irqrestore(&dev->queue_lock, flags);
-+
-+ if (!async_req)
-+ goto ret_nothing_done;
-+
-+ if (backlog)
-+ backlog->complete(backlog, -EINPROGRESS);
-+
-+ req = ablkcipher_request_cast(async_req);
-+ tfm = crypto_ablkcipher_reqtfm(req);
-+ rctx = ablkcipher_request_ctx(req);
-+ ctx = crypto_ablkcipher_ctx(tfm);
-+
-+ if (!req->src || !req->dst)
-+ goto ret_nothing_done;
-+
-+ ctx->flags |= rctx->mode;
-+ ctx->req = req;
-+
-+ dcp_crypt(dev, ctx);
-+
-+ return;
-+
-+ret_nothing_done:
-+ clear_bit(DCP_FLAG_BUSY, &dev->flags);
-+}
-+
-+
-+static int dcp_cra_init(struct crypto_tfm *tfm)
-+{
-+ const char *name = tfm->__crt_alg->cra_name;
-+ struct dcp_op *ctx = crypto_tfm_ctx(tfm);
-+
-+ tfm->crt_ablkcipher.reqsize = sizeof(struct dcp_dev_req_ctx);
-+
-+ ctx->fallback = crypto_alloc_ablkcipher(name, 0,
-+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
-+
-+ if (IS_ERR(ctx->fallback)) {
-+ dev_err(global_dev->dev, "Error allocating fallback algo %s\n",
-+ name);
-+ return PTR_ERR(ctx->fallback);
-+ }
-+
-+ return 0;
-+}
-+
-+static void dcp_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct dcp_op *ctx = crypto_tfm_ctx(tfm);
-+
-+ if (ctx->fallback)
-+ crypto_free_ablkcipher(ctx->fallback);
-+
-+ ctx->fallback = NULL;
-+}
-+
-+/* async interface */
-+static int dcp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct dcp_op *ctx = crypto_ablkcipher_ctx(tfm);
-+ unsigned int ret = 0;
-+ ctx->keylen = len;
-+ ctx->flags = 0;
-+ if (len == AES_KEYSIZE_128) {
-+ if (memcmp(ctx->key, key, AES_KEYSIZE_128)) {
-+ memcpy(ctx->key, key, len);
-+ ctx->flags |= DCP_NEW_KEY;
-+ }
-+ return 0;
-+ }
-+
-+ ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
-+ ctx->fallback->base.crt_flags |=
-+ (tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
-+
-+ ret = crypto_ablkcipher_setkey(ctx->fallback, key, len);
-+ if (ret) {
-+ struct crypto_tfm *tfm_aux = crypto_ablkcipher_tfm(tfm);
-+
-+ tfm_aux->crt_flags &= ~CRYPTO_TFM_RES_MASK;
-+ tfm_aux->crt_flags |=
-+ (ctx->fallback->base.crt_flags & CRYPTO_TFM_RES_MASK);
-+ }
-+ return ret;
-+}
-+
-+static int dcp_aes_cbc_crypt(struct ablkcipher_request *req, int mode)
-+{
-+ struct dcp_dev_req_ctx *rctx = ablkcipher_request_ctx(req);
-+ struct dcp_dev *dev = global_dev;
-+ unsigned long flags;
-+ int err = 0;
-+
-+ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
-+ return -EINVAL;
-+
-+ rctx->mode = mode;
-+
-+ spin_lock_irqsave(&dev->queue_lock, flags);
-+ err = ablkcipher_enqueue_request(&dev->queue, req);
-+ spin_unlock_irqrestore(&dev->queue_lock, flags);
-+
-+ flags = test_and_set_bit(DCP_FLAG_BUSY, &dev->flags);
-+
-+ if (!(flags & DCP_FLAG_BUSY))
-+ tasklet_schedule(&dev->queue_task);
-+
-+ return err;
-+}
-+
-+static int dcp_aes_cbc_encrypt(struct ablkcipher_request *req)
-+{
-+ struct crypto_tfm *tfm =
-+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
-+ struct dcp_op *ctx = crypto_ablkcipher_ctx(
-+ crypto_ablkcipher_reqtfm(req));
-+
-+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
-+ int err = 0;
-+ ablkcipher_request_set_tfm(req, ctx->fallback);
-+ err = crypto_ablkcipher_encrypt(req);
-+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
-+ return err;
-+ }
-+
-+ return dcp_aes_cbc_crypt(req, DCP_AES | DCP_ENC | DCP_CBC);
-+}
-+
-+static int dcp_aes_cbc_decrypt(struct ablkcipher_request *req)
-+{
-+ struct crypto_tfm *tfm =
-+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
-+ struct dcp_op *ctx = crypto_ablkcipher_ctx(
-+ crypto_ablkcipher_reqtfm(req));
-+
-+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
-+ int err = 0;
-+ ablkcipher_request_set_tfm(req, ctx->fallback);
-+ err = crypto_ablkcipher_decrypt(req);
-+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
-+ return err;
-+ }
-+ return dcp_aes_cbc_crypt(req, DCP_AES | DCP_DEC | DCP_CBC);
-+}
-+
-+static struct crypto_alg algs[] = {
-+ {
-+ .cra_name = "cbc(aes)",
-+ .cra_driver_name = "dcp-cbc-aes",
-+ .cra_alignmask = 3,
-+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK,
-+ .cra_blocksize = AES_KEYSIZE_128,
-+ .cra_type = &crypto_ablkcipher_type,
-+ .cra_priority = 300,
-+ .cra_u.ablkcipher = {
-+ .min_keysize = AES_KEYSIZE_128,
-+ .max_keysize = AES_KEYSIZE_128,
-+ .setkey = dcp_aes_setkey,
-+ .encrypt = dcp_aes_cbc_encrypt,
-+ .decrypt = dcp_aes_cbc_decrypt,
-+ .ivsize = AES_KEYSIZE_128,
-+ }
-+
-+ },
-+};
-+
-+/* DCP bootstream verification interface: uses OTP key for crypto */
-+static int dcp_bootstream_open(struct inode *inode, struct file *file)
-+{
-+ file->private_data = container_of((file->private_data),
-+ struct dcp_dev, dcp_bootstream_misc);
-+ return 0;
-+}
-+
-+static long dcp_bootstream_ioctl(struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct dcp_dev *dev = (struct dcp_dev *) file->private_data;
-+ void __user *argp = (void __user *)arg;
-+ int ret;
-+
-+ if (dev == NULL)
-+ return -EBADF;
-+
-+ if (cmd != DBS_ENC && cmd != DBS_DEC)
-+ return -EINVAL;
-+
-+ if (copy_from_user(dev->payload_base, argp, 16))
-+ return -EFAULT;
-+
-+ if (test_and_set_bit(DCP_FLAG_BUSY, &dev->flags))
-+ return -EAGAIN;
-+
-+ dev->ctx = kzalloc(sizeof(struct dcp_op), GFP_KERNEL);
-+ if (!dev->ctx) {
-+ dev_err(dev->dev,
-+ "cannot allocate context for OTP crypto");
-+ clear_bit(DCP_FLAG_BUSY, &dev->flags);
-+ return -ENOMEM;
-+ }
-+
-+ dev->ctx->flags = DCP_AES | DCP_ECB | DCP_OTP_KEY | DCP_CBC_INIT;
-+ dev->ctx->flags |= (cmd == DBS_ENC) ? DCP_ENC : DCP_DEC;
-+ dev->hw_pkg[0]->src = dev->payload_base_dma;
-+ dev->hw_pkg[0]->dst = dev->payload_base_dma;
-+ dev->hw_pkg[0]->size = 16;
-+
-+ dcp_op_start(dev, 0);
-+
-+ while (test_bit(DCP_FLAG_BUSY, &dev->flags))
-+ cpu_relax();
-+
-+ ret = dev->ctx->stat;
-+ if (!ret && copy_to_user(argp, dev->payload_base, 16))
-+ ret = -EFAULT;
-+
-+ kfree(dev->ctx);
-+
-+ return ret;
-+}
-+
-+static const struct file_operations dcp_bootstream_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = dcp_bootstream_ioctl,
-+ .open = dcp_bootstream_open,
-+};
-+
-+static int dcp_probe(struct platform_device *pdev)
-+{
-+ struct dcp_dev *dev = NULL;
-+ struct resource *r;
-+ int i, ret, j;
-+
-+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-+ if (dev == NULL) {
-+ dev_err(&pdev->dev, "Failed to allocate structure\n");
-+ ret = -ENOMEM;
-+ goto err;
-+ }
-+ global_dev = dev;
-+ dev->dev = &pdev->dev;
-+
-+ platform_set_drvdata(pdev, dev);
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!r) {
-+ dev_err(&pdev->dev, "failed to get IORESOURCE_MEM\n");
-+ ret = -ENXIO;
-+ goto err_dev;
-+ }
-+ dev->dcp_regs_base = ioremap(r->start, resource_size(r));
-+
-+
-+ dcp_set(dev, DCP_CTRL_SFRST, DCP_REG_CTRL);
-+ udelay(10);
-+ dcp_clear(dev, DCP_CTRL_SFRST | DCP_CTRL_CLKGATE, DCP_REG_CTRL);
-+
-+ dcp_write(dev, DCP_CTRL_GATHER_RES_WRITE |
-+ DCP_CTRL_ENABLE_CONTEXT_CACHE | DCP_CTRL_CH_IRQ_E_1,
-+ DCP_REG_CTRL);
-+
-+ dcp_write(dev, DCP_CHAN_CTRL_ENABLE_1, DCP_REG_CHAN_CTRL);
-+
-+ for (i = 0; i < 4; i++)
-+ dcp_clear(dev, -1, dcp_chan_reg(DCP_REG_CHAN_STAT, i));
-+
-+ dcp_clear(dev, -1, DCP_REG_STAT);
-+
-+
-+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-+ if (!r) {
-+ dev_err(&pdev->dev, "can't get IRQ resource (0)\n");
-+ ret = -EIO;
-+ goto err_unmap_mem;
-+ }
-+ dev->dcp_vmi_irq = r->start;
-+ ret = request_irq(dev->dcp_vmi_irq, dcp_vmi_irq, 0, "dcp", dev);
-+ if (ret != 0) {
-+ dev_err(&pdev->dev, "can't request_irq (0)\n");
-+ ret = -EIO;
-+ goto err_unmap_mem;
-+ }
-+
-+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-+ if (!r) {
-+ dev_err(&pdev->dev, "can't get IRQ resource (1)\n");
-+ ret = -EIO;
-+ goto err_free_irq0;
-+ }
-+ dev->dcp_irq = r->start;
-+ ret = request_irq(dev->dcp_irq, dcp_irq, 0, "dcp", dev);
-+ if (ret != 0) {
-+ dev_err(&pdev->dev, "can't request_irq (1)\n");
-+ ret = -EIO;
-+ goto err_free_irq0;
-+ }
-+
-+ dev->hw_pkg[0] = dma_alloc_coherent(&pdev->dev,
-+ DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
-+ &dev->hw_phys_pkg,
-+ GFP_KERNEL);
-+ if (!dev->hw_pkg[0]) {
-+ dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
-+ ret = -ENOMEM;
-+ goto err_free_irq1;
-+ }
-+
-+ for (i = 1; i < DCP_MAX_PKG; i++) {
-+ dev->hw_pkg[i - 1]->next = dev->hw_phys_pkg
-+ + i * sizeof(struct dcp_hw_packet);
-+ dev->hw_pkg[i] = dev->hw_pkg[i - 1] + 1;
-+ }
-+ dev->hw_pkg[i - 1]->next = dev->hw_phys_pkg;
-+
-+
-+ dev->payload_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
-+ &dev->payload_base_dma, GFP_KERNEL);
-+ if (!dev->payload_base) {
-+ dev_err(&pdev->dev, "Could not allocate memory for key\n");
-+ ret = -ENOMEM;
-+ goto err_free_hw_packet;
-+ }
-+ tasklet_init(&dev->queue_task, dcp_queue_task,
-+ (unsigned long) dev);
-+ tasklet_init(&dev->done_task, dcp_done_task,
-+ (unsigned long) dev);
-+ spin_lock_init(&dev->queue_lock);
-+
-+ crypto_init_queue(&dev->queue, 10);
-+
-+ init_timer(&dev->watchdog);
-+ dev->watchdog.function = &dcp_watchdog;
-+ dev->watchdog.data = (unsigned long)dev;
-+
-+ dev->dcp_bootstream_misc.minor = MISC_DYNAMIC_MINOR,
-+ dev->dcp_bootstream_misc.name = "dcpboot",
-+ dev->dcp_bootstream_misc.fops = &dcp_bootstream_fops,
-+ ret = misc_register(&dev->dcp_bootstream_misc);
-+ if (ret != 0) {
-+ dev_err(dev->dev, "Unable to register misc device\n");
-+ goto err_free_key_iv;
-+ }
-+
-+ for (i = 0; i < ARRAY_SIZE(algs); i++) {
-+ algs[i].cra_priority = 300;
-+ algs[i].cra_ctxsize = sizeof(struct dcp_op);
-+ algs[i].cra_module = THIS_MODULE;
-+ algs[i].cra_init = dcp_cra_init;
-+ algs[i].cra_exit = dcp_cra_exit;
-+ if (crypto_register_alg(&algs[i])) {
-+ dev_err(&pdev->dev, "register algorithm failed\n");
-+ ret = -ENOMEM;
-+ goto err_unregister;
-+ }
-+ }
-+ dev_notice(&pdev->dev, "DCP crypto enabled.!\n");
-+
-+ return 0;
-+
-+err_unregister:
-+ for (j = 0; j < i; j++)
-+ crypto_unregister_alg(&algs[j]);
-+err_free_key_iv:
-+ dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
-+ dev->payload_base_dma);
-+err_free_hw_packet:
-+ dma_free_coherent(&pdev->dev, DCP_MAX_PKG *
-+ sizeof(struct dcp_hw_packet), dev->hw_pkg[0],
-+ dev->hw_phys_pkg);
-+err_free_irq1:
-+ free_irq(dev->dcp_irq, dev);
-+err_free_irq0:
-+ free_irq(dev->dcp_vmi_irq, dev);
-+err_unmap_mem:
-+ iounmap((void *) dev->dcp_regs_base);
-+err_dev:
-+ kfree(dev);
-+err:
-+ return ret;
-+}
-+
-+static int dcp_remove(struct platform_device *pdev)
-+{
-+ struct dcp_dev *dev;
-+ int j;
-+ dev = platform_get_drvdata(pdev);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ dma_free_coherent(&pdev->dev,
-+ DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
-+ dev->hw_pkg[0], dev->hw_phys_pkg);
-+
-+ dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
-+ dev->payload_base_dma);
-+
-+ free_irq(dev->dcp_irq, dev);
-+ free_irq(dev->dcp_vmi_irq, dev);
-+
-+ tasklet_kill(&dev->done_task);
-+ tasklet_kill(&dev->queue_task);
-+
-+ iounmap((void *) dev->dcp_regs_base);
-+
-+ for (j = 0; j < ARRAY_SIZE(algs); j++)
-+ crypto_unregister_alg(&algs[j]);
-+
-+ misc_deregister(&dev->dcp_bootstream_misc);
-+
-+ kfree(dev);
-+ return 0;
-+}
-+
-+static struct of_device_id fs_dcp_of_match[] = {
-+ { .compatible = "fsl-dcp"},
-+ {},
-+};
-+
-+static struct platform_driver fs_dcp_driver = {
-+ .probe = dcp_probe,
-+ .remove = dcp_remove,
-+ .driver = {
-+ .name = "fsl-dcp",
-+ .owner = THIS_MODULE,
-+ .of_match_table = fs_dcp_of_match
-+ }
-+};
-+
-+module_platform_driver(fs_dcp_driver);
-+
-+
-+MODULE_AUTHOR("Tobias Rauter <tobias.rau...@gmail.com>");
-+MODULE_DESCRIPTION("Freescale DCP Crypto Driver");
-+MODULE_LICENSE("GPL");
+++ /dev/null
---- a/arch/arm/boot/dts/imx23.dtsi
-+++ b/arch/arm/boot/dts/imx23.dtsi
-@@ -337,6 +337,7 @@
-
- dcp@80028000 {
- reg = <0x80028000 0x2000>;
-+ interrupts = <52 53 54>;
- status = "disabled";
- };
-
---- a/arch/arm/boot/dts/imx23-olinuxino.dts
-+++ b/arch/arm/boot/dts/imx23-olinuxino.dts
-@@ -66,6 +66,12 @@
- pinctrl-0 = <&spi2_pins_a>;
- status = "okay";
- };
-+
-+ dcp@80028000 {
-+ status = "okay";
-+ compatible = "fsl-dcp";
-+ };
-+
- };
-
- apbx@80040000 {
+++ /dev/null
---- a/arch/arm/boot/dts/imx23-olinuxino.dts
-+++ b/arch/arm/boot/dts/imx23-olinuxino.dts
-@@ -109,6 +109,11 @@
- dmas = <&dma_apbx 0>, <&dma_apbx 1>;
- dma-names = "rx", "tx";
- };
-+
-+ lradc@80050000 {
-+ status = "okay";
-+ fsl,lradc-touchscreen-wires = <4>;
-+ };
- };
- };
-
+++ /dev/null
-#
-# Copyright (C) 2012 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-define Profile/olinuxino
- NAME:=Olimex Olinuxino boards
- PACKAGES += imx-bootlets kmod-usb-mxs-phy kmod-usb-net kmod-usb-net-smsc95xx \
- kmod-gpio-mcp23s08 kmod-leds-gpio kmod-ledtrig-heartbeat kmod-rtc-stmp3xxx \
- kmod-sound-core kmod-sound-soc-imx23 kmod-iio-mxs-lradc
-endef
-
-define Profile/olinuxino/Description
- Olimex Olinuxino boards
-endef
-$(eval $(call Profile,olinuxino))
-
--- /dev/null
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=arm
+BOARD:=mxs
+BOARDNAME:=Freescale i.MX23/i.MX28 series
+FEATURES:=ext4 rtc usb gpio
+CPU_TYPE:=arm926ej-s
+
+MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
+LINUX_VERSION:=3.10.15
+KERNELNAME:="zImage dtbs"
+
+define Target/Description
+ Support for Freescale i.MX23/i.MX28 boards
+endef
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += kmod-wdt-stmp3xxx
+
+$(eval $(call BuildTarget))
--- /dev/null
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K shutdown
+ttyAMA0::askfirst:/bin/ash --login
--- /dev/null
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_CPU_AUTO=y
+# CONFIG_ARCH_MULTI_V4 is not set
+# CONFIG_ARCH_MULTI_V4T is not set
+CONFIG_ARCH_MULTI_V4_V5=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V6 is not set
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_MXS=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+# CONFIG_ARCH_WM8505 is not set
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_APPENDED_DTB=y
+# CONFIG_ARM_ATAG_DTB_COMPAT is not set
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_NR_BANKS=8
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_SP805_WATCHDOG is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="console=ttyAMA0,115200 root=/dev/mmcblk0p2 rw rootwait"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_COMMON_CLK=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_ARM926T=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_USE_DOMAINS=y
+CONFIG_CRC16=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_DEBUG_USER is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DTC=y
+CONFIG_EXT4_FS=y
+CONFIG_FEC=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FS_MBCACHE=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_MXS=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_BPF_JIT=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_PWM=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCA=y
+CONFIG_I2C_ALGOPCF=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_MUX=y
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+# CONFIG_I2C_MUX_PCA954x is not set
+CONFIG_I2C_MUX_PINCTRL=y
+CONFIG_I2C_MXS=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+# CONFIG_IIO_BUFFER_CB is not set
+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+CONFIG_IIO_GPIO_TRIGGER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_PERIODIC_RTC_TRIGGER=y
+# CONFIG_IIO_SIMPLE_DUMMY is not set
+# CONFIG_IIO_ST_ACCEL_3AXIS is not set
+# CONFIG_IIO_ST_GYRO_3AXIS is not set
+# CONFIG_IIO_ST_MAGN_3AXIS is not set
+CONFIG_IIO_SYSFS_TRIGGER=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISDN is not set
+CONFIG_JBD2=y
+CONFIG_KTIME_SCALAR=y
+# CONFIG_LEDS_REGULATOR is not set
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_MXS=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_PHYSMAP_OF is not set
+CONFIG_MULTI_IRQ_HANDLER=y
+CONFIG_MXS_DMA=y
+# CONFIG_MXS_LRADC is not set
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_NET_DMA is not set
+CONFIG_NLS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PCI_SYSCALL is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_IMX23=y
+CONFIG_PINCTRL_IMX28=y
+CONFIG_PINCTRL_MXS=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PINMUX=y
+# CONFIG_PL330_DMA is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PPS=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_PTP_1588_CLOCK=y
+# CONFIG_RCU_STALL_COMMON is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_DUMMY is not set
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_RFKILL_REGULATOR is not set
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_STMP is not set
+# CONFIG_SAMSUNG_USB2PHY is not set
+# CONFIG_SAMSUNG_USB3PHY is not set
+# CONFIG_SAMSUNG_USBPHY is not set
+CONFIG_SCHED_HRTICK=y
+# CONFIG_SCSI_DMA is not set
+CONFIG_SERIAL_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_MXS_AUART=y
+CONFIG_SERIAL_MXS_AUART_CONSOLE=y
+CONFIG_SMSC_PHY=y
+CONFIG_SOC_IMX23=y
+CONFIG_SOC_IMX28=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+# CONFIG_SPI_MXS is not set
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_STMP_DEVICE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_TEGRA_HOST1X is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_UID16=y
+CONFIG_UIDGID_CONVERTED=y
+# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_USB=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_MXS_PHY is not set
+CONFIG_USB_OTG=y
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_VFP is not set
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZONE_DMA_FLAG=0
--- /dev/null
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+define Image/BuildKernel/olinuxino-bootlet
+ cat $(LINUX_DIR)/arch/arm/boot/zImage $(LINUX_DIR)/arch/arm/boot/dts/imx23-olinuxino.dtb > $(STAGING_DIR)/zImage_dtb
+ (cd $(STAGING_DIR); \
+ $(STAGING_DIR)/../host/bin/elftosb -z -c ./linux_prebuilt.db -o linux.sb; \
+ dd if=/dev/zero of=sd_mmc_bootstream.raw bs=512 count=4; \
+ dd if=linux.sb of=$(BIN_DIR)/openwrt-imx23-sbImage ibs=512 seek=4; \
+ )
+endef
+
+define Image/BuildKernel/olinuxino-uboot
+ mkimage -A arm -O linux -T kernel -C none \
+ -a 0x42000000 -e 0x42000000 \
+ -n 'ARM OpenWrt Linux-$(LINUX_VERSION)' \
+ -d $(KDIR)/vmlinux $(KDIR)/uImage
+ cp $(KDIR)/uImage $(BIN_DIR)/$(IMG_PREFIX)-uImage
+endef
+
+define Image/BuildKernel
+
+ ifeq ($(CONFIG_PACKAGE_imx-bootlets),y)
+ $(call Image/BuildKernel/olinuxino-bootlet)
+ endif
+
+ ifeq ($(CONFIG_PACKAGE_uboot-imx23-mx23_olinuxino),y)
+ $(call Image/BuildKernel/olinuxino-uboot)
+ endif
+endef
+
+define Image/Build
+ $(call Image/Build/$(1))
+ dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
+endef
+
+$(eval $(call BuildImage))
+
--- /dev/null
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+define KernelPackage/rtc-stmp3xxx
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=STMP3xxx SoC built-in RTC support
+ DEPENDS:=@TARGET_mxs
+ $(call AddDepends/rtc)
+ KCONFIG:= \
+ CONFIG_RTC_CLASS=y \
+ CONFIG_RTC_DRV_STMP=m
+ FILES:=$(LINUX_DIR)/drivers/rtc/rtc-stmp3xxx.ko
+ AUTOLOAD:=$(call AutoLoad,50,rtc-stmp3xxx)
+endef
+
+$(eval $(call KernelPackage,rtc-stmp3xxx))
+
+define KernelPackage/wdt-stmp3xxx
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=STMP3xxx Watchdog timer
+ DEPENDS:=kmod-rtc-stmp3xxx
+ KCONFIG:=CONFIG_STMP3XXX_RTC_WATCHDOG
+ FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/stmp3xxx_rtc_wdt.ko
+ AUTOLOAD:=$(call AutoLoad,51,stmp3xxx_rtc_wdt)
+endef
+
+define KernelPackage/wdt-stmp3xxx/description
+ Kernel module for STMP3xxx watchdog timer.
+endef
+
+$(eval $(call KernelPackage,wdt-stmp3xxx))
+
+define KernelPackage/usb-chipidea-imx
+ TITLE:=Support for ChipIdea controllers on Freescale i.MX SoCs
+ DEPENDS:=+kmod-usb-chipidea @TARGET_mxs
+ FILES:= \
+ $(LINUX_DIR)/drivers/usb/chipidea/ci13xxx_imx.ko
+ AUTOLOAD:=$(call AutoLoad,52,ci13xxx_imx,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-chipidea-imx/description
+ Kernel support for USB ChipIdea controllers on Freescale i.MX SoCs
+endef
+
+$(eval $(call KernelPackage,usb-chipidea-imx,1))
+
+define KernelPackage/usb-mxs-phy
+ TITLE:=Support for Freescale MXS USB PHY controllers
+ DEPENDS:=+kmod-usb-chipidea-imx
+ KCONFIG:= \
+ CONFIG_USB_MXS_PHY
+ FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-mxs-usb.ko
+ AUTOLOAD:=$(call AutoLoad,50,phy-mxs-usb,1)
+ $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-mxs-phy/description
+ Kernel support for Freescale MXS USB PHY controllers
+endef
+
+$(eval $(call KernelPackage,usb-mxs-phy,1))
+
+define KernelPackage/usb-net-smsc95xx
+ TITLE:=SMSC95xx USB/2.0 Ethernet driver
+ DEPENDS:=@TARGET_mxs
+ KCONFIG:=CONFIG_USB_NET_SMSC95XX
+ FILES:=$(LINUX_DIR)/drivers/net/usb/smsc95xx.ko
+ AUTOLOAD:=$(call AutoLoad,64,smsc95xx)
+ $(call AddDepends/usb-net)
+endef
+
+define KernelPackage/usb-net-smsc95xx/description
+ Kernel support for SMSC95xx USB/2.0 Ethernet driver
+endef
+
+$(eval $(call KernelPackage,usb-net-smsc95xx))
+
+define KernelPackage/sound-soc-mxs
+ TITLE:=Freescale i.MX23/i.MX28 built-in SoC sound support
+ KCONFIG:= \
+ CONFIG_SND_SOC_MXS_BUILTIN_CODEC \
+ CONFIG_SND_MXS_SOC_BUILTIN
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/mxs/snd-soc-mxs-builtin-audio.ko \
+ $(LINUX_DIR)/sound/soc/mxs/snd-soc-mxs-builtin-dai.ko \
+ $(LINUX_DIR)/sound/soc/mxs/snd-soc-mxs-builtin-pcm.ko \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-mxs-builtin-codec.ko
+ AUTOLOAD:=$(call AutoLoad,65,snd-soc-mxs-builtin-pcm snd-soc-mxs-builtin-dai snd-soc-mxs-builtin-codec snd-soc-mxs-builtin-audio)
+ DEPENDS:=@TARGET_mxs +kmod-sound-soc-core
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-mxs/description
+ Kernel support for Freescale i.MX23/i.MX28 built-in SoC audio
+endef
+
+$(eval $(call KernelPackage,sound-soc-mxs))
+
+define KernelPackage/iio-mxs-lradc
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=LRADC driver for i.MX23/28
+ DEPENDS:=@TARGET_mxs
+ KCONFIG:=CONFIG_MXS_LRADC
+ FILES:=$(LINUX_DIR)/drivers/staging/iio/adc/mxs-lradc.ko \
+ $(LINUX_DIR)/drivers/iio/industrialio-triggered-buffer.ko
+ AUTOLOAD:=$(call AutoLoad,70,industrialio-triggered-buffer mxs-lradc)
+endef
+
+define KernelPackage/iio-mxs-lradc/description
+ Kernel module for i.MX23/28 LRADC driver
+endef
+
+$(eval $(call KernelPackage,iio-mxs-lradc))
+
+define KernelPackage/crypto-hw-dcp
+ TITLE:=i.MX23/28 DCP hardware crypto module
+ DEPENDS:=@TARGET_mxs
+ KCONFIG:=CONFIG_CRYPTO_DEV_DCP
+ FILES:=$(LINUX_DIR)/drivers/crypto/dcp.ko
+ AUTOLOAD:=$(call AutoLoad,90,dcp)
+ $(call AddDepends/crypto,+kmod-crypto-authenc +kmod-crypto-des)
+endef
+
+define KernelPackage/crypto-hw-dcp/description
+ Kernel support for the i.MX23/28 DCP crypto engine
+endef
+
+$(eval $(call KernelPackage,crypto-hw-dcp))
--- /dev/null
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -125,6 +125,7 @@ config SND_SOC_ALL_CODECS
+ select SND_SOC_WM9705 if SND_SOC_AC97_BUS
+ select SND_SOC_WM9712 if SND_SOC_AC97_BUS
+ select SND_SOC_WM9713 if SND_SOC_AC97_BUS
++ select SND_SOC_MXS_BUILTIN_CODEC
+ help
+ Normally ASoC codec drivers are only built if a machine driver which
+ uses them is also built since they are only usable with a machine
+@@ -507,6 +508,9 @@ config SND_SOC_WM9712
+ config SND_SOC_WM9713
+ tristate
+
++config SND_SOC_MXS_BUILTIN_CODEC
++ tristate
++
+ # Amp
+ config SND_SOC_LM4857
+ tristate
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -118,6 +118,7 @@ snd-soc-wm9705-objs := wm9705.o
+ snd-soc-wm9712-objs := wm9712.o
+ snd-soc-wm9713-objs := wm9713.o
+ snd-soc-wm-hubs-objs := wm_hubs.o
++snd-soc-mxs-builtin-codec-objs := mxs-builtin-codec.o
+
+ # Amp
+ snd-soc-max9877-objs := max9877.o
+@@ -242,6 +243,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-
+ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
+ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
+ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
++obj-$(CONFIG_SND_SOC_MXS_BUILTIN_CODEC) += snd-soc-mxs-builtin-codec.o
+
+ # Amp
+ obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
+--- /dev/null
++++ b/sound/soc/codecs/mxs-builtin-codec.c
+@@ -0,0 +1,1128 @@
++/*
++ * mxs-builtin-codec.c -- i.MX233 built-in codec ALSA Soc Audio driver
++ *
++ * Author: Michal Ulianko <michal.ulianko@gmail.com>
++ *
++ * Based on sound/soc/codecs/mxs-adc-codec.c for kernel 2.6.35
++ * by Vladislav Buzov <vbuzov@embeddedalley.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++
++#include "mxs-builtin-codec.h"
++
++#ifndef BF
++#define BF(value, field) (((value) << BP_##field) & BM_##field)
++#endif
++
++/* TODO Delete this and use BM_RTC_PERSISTENT0_RELEASE_GND from header file
++ * if it works. */
++#define BP_RTC_PERSISTENT0_SPARE_ANALOG 18
++#define BM_RTC_PERSISTENT0_SPARE_ANALOG 0xFFFC0000
++#define BM_RTC_PERSISTENT0_RELEASE_GND BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG)
++
++/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */
++
++struct mxs_adc_priv {
++ void __iomem *ain_base;
++ void __iomem *aout_base;
++ void __iomem *rtc_base;
++ struct clk *clk;
++};
++
++static unsigned int mxs_regmap[] = {
++ HW_AUDIOOUT_CTRL,
++ HW_AUDIOOUT_STAT,
++ HW_AUDIOOUT_DACSRR,
++ HW_AUDIOOUT_DACVOLUME,
++ HW_AUDIOOUT_DACDEBUG,
++ HW_AUDIOOUT_HPVOL,
++ HW_AUDIOOUT_PWRDN,
++ HW_AUDIOOUT_REFCTRL,
++ HW_AUDIOOUT_ANACTRL,
++ HW_AUDIOOUT_TEST,
++ HW_AUDIOOUT_BISTCTRL,
++ HW_AUDIOOUT_BISTSTAT0,
++ HW_AUDIOOUT_BISTSTAT1,
++ HW_AUDIOOUT_ANACLKCTRL,
++ HW_AUDIOOUT_DATA,
++ HW_AUDIOOUT_SPEAKERCTRL,
++ HW_AUDIOOUT_VERSION,
++ HW_AUDIOIN_CTRL,
++ HW_AUDIOIN_STAT,
++ HW_AUDIOIN_ADCSRR,
++ HW_AUDIOIN_ADCVOLUME,
++ HW_AUDIOIN_ADCDEBUG,
++ HW_AUDIOIN_ADCVOL,
++ HW_AUDIOIN_MICLINE,
++ HW_AUDIOIN_ANACLKCTRL,
++ HW_AUDIOIN_DATA,
++};
++
++static void __iomem *mxs_getreg(struct mxs_adc_priv *mxs_adc, int i)
++{
++ if (i <= 16)
++ return mxs_adc->aout_base + mxs_regmap[i];
++ else if (i < ADC_REGNUM)
++ return mxs_adc->ain_base + mxs_regmap[i];
++ else
++ return NULL;
++}
++
++static u8 dac_volumn_control_word[] = {
++ 0x37, 0x5e, 0x7e, 0x8e,
++ 0x9e, 0xae, 0xb6, 0xbe,
++ 0xc6, 0xce, 0xd6, 0xde,
++ 0xe6, 0xee, 0xf6, 0xfe,
++};
++
++struct dac_srr {
++ u32 rate;
++ u32 basemult;
++ u32 src_hold;
++ u32 src_int;
++ u32 src_frac;
++};
++
++static struct dac_srr srr_values[] = {
++ {192000, 0x4, 0x0, 0x0F, 0x13FF},
++ {176400, 0x4, 0x0, 0x11, 0x0037},
++ {128000, 0x4, 0x0, 0x17, 0x0E00},
++ {96000, 0x2, 0x0, 0x0F, 0x13FF},
++ {88200, 0x2, 0x0, 0x11, 0x0037},
++ {64000, 0x2, 0x0, 0x17, 0x0E00},
++ {48000, 0x1, 0x0, 0x0F, 0x13FF},
++ {44100, 0x1, 0x0, 0x11, 0x0037},
++ {32000, 0x1, 0x0, 0x17, 0x0E00},
++ {24000, 0x1, 0x1, 0x0F, 0x13FF},
++ {22050, 0x1, 0x1, 0x11, 0x0037},
++ {16000, 0x1, 0x1, 0x17, 0x0E00},
++ {12000, 0x1, 0x3, 0x0F, 0x13FF},
++ {11025, 0x1, 0x3, 0x11, 0x0037},
++ {8000, 0x1, 0x3, 0x17, 0x0E00}
++};
++
++static inline int get_srr_values(int rate)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(srr_values); i++)
++ if (srr_values[i].rate == rate)
++ return i;
++
++ return -1;
++}
++
++/* SoC IO functions */
++static void mxs_codec_write_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
++{
++ u16 *cache = codec->reg_cache;
++ if (reg < ADC_REGNUM)
++ cache[reg] = value;
++}
++
++static int mxs_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++ unsigned int reg_val;
++ unsigned int mask = 0xffff;
++
++ if (reg >= ADC_REGNUM)
++ return -EIO;
++
++ mxs_codec_write_cache(codec, reg, value);
++
++ if (reg & 0x1) {
++ mask <<= 16;
++ value <<= 16;
++ }
++
++ reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1));
++ reg_val = (reg_val & ~mask) | value;
++ __raw_writel(reg_val, mxs_getreg(mxs_adc, reg >> 1));
++
++ return 0;
++}
++
++static unsigned int mxs_codec_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++ unsigned int reg_val;
++
++ if (reg >= ADC_REGNUM)
++ return -1;
++
++ reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1));
++ if (reg & 1)
++ reg_val >>= 16;
++
++ return reg_val & 0xffff;
++}
++
++// static unsigned int mxs_codec_read_cache(struct snd_soc_codec *codec, unsigned int reg)
++// {
++// u16 *cache = codec->reg_cache;
++// if (reg >= ADC_REGNUM)
++// return -EINVAL;
++// return cache[reg];
++// }
++
++static void mxs_codec_sync_reg_cache(struct snd_soc_codec *codec)
++{
++ int reg;
++ for (reg = 0; reg < ADC_REGNUM; reg += 1)
++ mxs_codec_write_cache(codec, reg,
++ mxs_codec_read(codec, reg));
++}
++
++// static int mxs_codec_restore_reg(struct snd_soc_codec *codec, unsigned int reg)
++// {
++// unsigned int cached_val, hw_val;
++//
++// cached_val = mxs_codec_read_cache(codec, reg);
++// hw_val = mxs_codec_read(codec, reg);
++//
++// if (hw_val != cached_val)
++// return mxs_codec_write(codec, reg, cached_val);
++//
++// return 0;
++// }
++/* END SoC IO functions */
++
++/* Codec routines */
++#define VAG_BASE_VALUE ((1400/2 - 625)/25)
++
++static void mxs_codec_dac_set_vag(struct mxs_adc_priv *mxs_adc)
++{
++ u32 refctrl_val = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL);
++
++ refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VAG_VAL);
++ refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VBG_ADJ);
++ refctrl_val |= BF(VAG_BASE_VALUE, AUDIOOUT_REFCTRL_VAG_VAL) |
++ BM_AUDIOOUT_REFCTRL_ADJ_VAG |
++ BF(0xF, AUDIOOUT_REFCTRL_ADC_REFVAL) |
++ BM_AUDIOOUT_REFCTRL_ADJ_ADC |
++ BF(0x3, AUDIOOUT_REFCTRL_VBG_ADJ) | BM_AUDIOOUT_REFCTRL_RAISE_REF;
++
++ __raw_writel(refctrl_val, mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL);
++}
++
++static bool mxs_codec_dac_is_capless(struct mxs_adc_priv *mxs_adc)
++{
++ if ((__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_PWRDN)
++ & BM_AUDIOOUT_PWRDN_CAPLESS) == 0)
++ return false;
++ else
++ return true;
++}
++
++static void mxs_codec_dac_arm_short_cm(struct mxs_adc_priv *mxs_adc, bool bShort)
++{
++ __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_CM),
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_CM_STS,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ if (bShort)
++ __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_CM),
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
++}
++
++static void mxs_codec_dac_arm_short_lr(struct mxs_adc_priv *mxs_adc, bool bShort)
++{
++ __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_LR),
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ if (bShort)
++ __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_LR),
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
++}
++
++static void mxs_codec_dac_set_short_trip_level(struct mxs_adc_priv *mxs_adc, u8 u8level)
++{
++ __raw_writel(__raw_readl(mxs_adc->aout_base +
++ HW_AUDIOOUT_ANACTRL)
++ & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL)
++ & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR)
++ | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJL)
++ | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJR),
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL);
++}
++
++static void mxs_codec_dac_arm_short(struct mxs_adc_priv *mxs_adc, bool bLatchCM, bool bLatchLR)
++{
++ if (bLatchCM) {
++ if (mxs_codec_dac_is_capless(mxs_adc))
++ mxs_codec_dac_arm_short_cm(mxs_adc, true);
++ } else
++ mxs_codec_dac_arm_short_cm(mxs_adc, false);
++
++ if (bLatchLR)
++ mxs_codec_dac_arm_short_lr(mxs_adc, true);
++ else
++ mxs_codec_dac_arm_short_lr(mxs_adc, false);
++}
++
++static void
++mxs_codec_dac_power_on(struct mxs_adc_priv *mxs_adc)
++{
++ /* Ungate DAC clocks */
++ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
++ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_CLR);
++
++ /* 16 bit word length */
++ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
++
++ /* Arm headphone LR short protect */
++ mxs_codec_dac_set_short_trip_level(mxs_adc, 0);
++ mxs_codec_dac_arm_short(mxs_adc, false, true);
++
++ /* Update DAC volume over zero crossings */
++ __raw_writel(BM_AUDIOOUT_DACVOLUME_EN_ZCD,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
++ /* Mute DAC */
++ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
++ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
++
++ /* Update HP volume over zero crossings */
++ __raw_writel(BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD,
++ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
++
++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
++
++ /* Mute HP output */
++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
++ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
++ /* Mute speaker amp */
++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
++ mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
++ /* Enable the audioout */
++ __raw_writel(BM_AUDIOOUT_CTRL_RUN,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
++}
++
++static void
++mxs_codec_dac_power_down(struct mxs_adc_priv *mxs_adc)
++{
++ /* Disable the audioout */
++ __raw_writel(BM_AUDIOOUT_CTRL_RUN,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
++ /* Disable class AB */
++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
++
++ /* Set hold to ground */
++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
++
++ /* Mute HP output */
++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
++ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET);
++ /* Power down HP output */
++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
++
++ /* Mute speaker amp */
++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
++ mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
++ /* Power down speaker amp */
++ __raw_writel(BM_AUDIOOUT_PWRDN_SPEAKER,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
++
++ /* Mute DAC */
++ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
++ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
++ /* Power down DAC */
++ __raw_writel(BM_AUDIOOUT_PWRDN_DAC,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
++
++ /* Gate DAC clocks */
++ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_SET);
++ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
++}
++
++static void
++mxs_codec_adc_power_on(struct mxs_adc_priv *mxs_adc)
++{
++ u32 reg;
++
++ /* Ungate ADC clocks */
++ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
++ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
++ mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_CLR);
++
++ /* 16 bit word length */
++ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
++
++ /* Unmute ADC channels */
++ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
++
++ /*
++ * The MUTE_LEFT and MUTE_RIGHT fields need to be cleared.
++ * They aren't presented in the datasheet, so this is hardcode.
++ */
++ __raw_writel(0x01000100, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME_CLR);
++
++ /* Set the Input channel gain 3dB */
++ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_LEFT,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
++ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_RIGHT,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
++ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_LEFT),
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
++ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_RIGHT),
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
++
++ /* Select default input - Microphone */
++ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_LEFT,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
++ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_RIGHT,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR);
++ __raw_writel(BF
++ (BV_AUDIOIN_ADCVOL_SELECT__MIC,
++ AUDIOIN_ADCVOL_SELECT_LEFT),
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
++ __raw_writel(BF
++ (BV_AUDIOIN_ADCVOL_SELECT__MIC,
++ AUDIOIN_ADCVOL_SELECT_RIGHT),
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
++
++ /* Supply bias voltage to microphone */
++ __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_RESISTOR),
++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
++ __raw_writel(BM_AUDIOIN_MICLINE_MIC_SELECT,
++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
++ __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_GAIN),
++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
++ __raw_writel(BF(7, AUDIOIN_MICLINE_MIC_BIAS),
++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
++
++ /* Set max ADC volume */
++ reg = __raw_readl(mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME);
++ reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
++ reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
++ reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_LEFT);
++ reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_RIGHT);
++ __raw_writel(reg, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME);
++}
++
++static void
++mxs_codec_adc_power_down(struct mxs_adc_priv *mxs_adc)
++{
++ /* Mute ADC channels */
++ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET);
++
++ /* Power Down ADC */
++ __raw_writel(BM_AUDIOOUT_PWRDN_ADC | BM_AUDIOOUT_PWRDN_RIGHT_ADC,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
++
++ /* Gate ADC clocks */
++ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
++ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
++ mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_SET);
++
++ /* Disable bias voltage to microphone */
++ __raw_writel(BF(0, AUDIOIN_MICLINE_MIC_RESISTOR),
++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET);
++}
++
++static void mxs_codec_dac_enable(struct mxs_adc_priv *mxs_adc)
++{
++ /* Move DAC codec out of reset */
++ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
++
++ /* Reduce analog power */
++ __raw_writel(BM_AUDIOOUT_TEST_HP_I1_ADJ,
++ mxs_adc->aout_base + HW_AUDIOOUT_TEST_CLR);
++ __raw_writel(BF(0x1, AUDIOOUT_TEST_HP_I1_ADJ),
++ mxs_adc->aout_base + HW_AUDIOOUT_TEST_SET);
++ __raw_writel(BM_AUDIOOUT_REFCTRL_LOW_PWR,
++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET);
++ __raw_writel(BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS,
++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET);
++ __raw_writel(BM_AUDIOOUT_REFCTRL_BIAS_CTRL,
++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR);
++ __raw_writel(BF(0x1, AUDIOOUT_REFCTRL_BIAS_CTRL),
++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR);
++
++ /* Set Vag value */
++ mxs_codec_dac_set_vag(mxs_adc);
++
++ /* Power on DAC codec */
++ mxs_codec_dac_power_on(mxs_adc);
++}
++
++static void mxs_codec_dac_disable(struct mxs_adc_priv *mxs_adc)
++{
++ mxs_codec_dac_power_down(mxs_adc);
++}
++
++static void mxs_codec_adc_enable(struct mxs_adc_priv *mxs_adc)
++{
++ /* Move ADC codec out of reset */
++ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
++
++ /* Power on ADC codec */
++ mxs_codec_adc_power_on(mxs_adc);
++}
++
++static void mxs_codec_adc_disable(struct mxs_adc_priv *mxs_adc)
++{
++ mxs_codec_adc_power_down(mxs_adc);
++}
++
++static void mxs_codec_startup(struct snd_soc_codec *codec)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++
++ /* Soft reset DAC block */
++ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
++ while (!(__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_CTRL)
++ & BM_AUDIOOUT_CTRL_CLKGATE)){
++ }
++
++ /* Soft reset ADC block */
++ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
++ while (!(__raw_readl(mxs_adc->ain_base + HW_AUDIOIN_CTRL)
++ & BM_AUDIOIN_CTRL_CLKGATE)){
++ }
++
++ mxs_codec_dac_enable(mxs_adc);
++ mxs_codec_adc_enable(mxs_adc);
++
++ /* Sync regs and cache */
++ mxs_codec_sync_reg_cache(codec);
++}
++
++static void mxs_codec_stop(struct snd_soc_codec *codec)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++
++ mxs_codec_dac_disable(mxs_adc);
++ mxs_codec_adc_disable(mxs_adc);
++}
++/* END Codec routines */
++
++/* kcontrol */
++static int dac_info_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_info *uinfo)
++{
++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
++ uinfo->count = 2;
++ uinfo->value.integer.min = 0;
++ uinfo->value.integer.max = 0xf;
++ return 0;
++}
++
++static int dac_get_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++ int reg, l, r;
++ int i;
++
++ reg = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
++
++ l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >>
++ BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
++ r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >>
++ BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
++ /*Left channel */
++ i = 0;
++ while (i < 16) {
++ if (l == dac_volumn_control_word[i]) {
++ ucontrol->value.integer.value[0] = i;
++ break;
++ }
++ i++;
++ }
++ if (i == 16)
++ ucontrol->value.integer.value[0] = i;
++ /*Right channel */
++ i = 0;
++ while (i < 16) {
++ if (r == dac_volumn_control_word[i]) {
++ ucontrol->value.integer.value[1] = i;
++ break;
++ }
++ i++;
++ }
++ if (i == 16)
++ ucontrol->value.integer.value[1] = i;
++
++ return 0;
++}
++
++static int dac_put_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++ int reg, l, r;
++ int i;
++
++ i = ucontrol->value.integer.value[0];
++ l = dac_volumn_control_word[i];
++ /*Get dac volume for left channel */
++ reg = BF(l, AUDIOOUT_DACVOLUME_VOLUME_LEFT);
++
++ i = ucontrol->value.integer.value[1];
++ r = dac_volumn_control_word[i];
++ /*Get dac volume for right channel */
++ reg = reg | BF(r, AUDIOOUT_DACVOLUME_VOLUME_RIGHT);
++
++ /*Clear left/right dac volume */
++ __raw_writel(BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT |
++ BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR);
++ __raw_writel(reg, mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
++
++ return 0;
++}
++
++static const char *mxs_codec_adc_input_sel[] = {
++ "Mic", "Line In 1", "Head Phone", "Line In 2" };
++
++static const char *mxs_codec_hp_output_sel[] = { "DAC Out", "Line In 1" };
++
++static const char *mxs_codec_adc_3d_sel[] = {
++ "Off", "Low", "Medium", "High" };
++
++static const struct soc_enum mxs_codec_enum[] = {
++ SOC_ENUM_SINGLE(ADC_ADCVOL_L, 12, 4, mxs_codec_adc_input_sel),
++ SOC_ENUM_SINGLE(ADC_ADCVOL_L, 4, 4, mxs_codec_adc_input_sel),
++ SOC_ENUM_SINGLE(DAC_HPVOL_H, 0, 2, mxs_codec_hp_output_sel),
++ SOC_ENUM_SINGLE(DAC_CTRL_L, 8, 4, mxs_codec_adc_3d_sel),
++};
++
++static const struct snd_kcontrol_new mxs_snd_controls[] = {
++ /* Playback Volume */
++ {
++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++ .name = "DAC Playback Volume",
++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
++ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
++ .info = dac_info_volsw,
++ .get = dac_get_volsw,
++ .put = dac_put_volsw,
++ },
++
++ SOC_DOUBLE_R("DAC Playback Switch",
++ DAC_VOLUME_H, DAC_VOLUME_L, 8, 0x01, 1),
++ SOC_DOUBLE("HP Playback Volume", DAC_HPVOL_L, 8, 0, 0x7F, 1),
++
++ /* Capture Volume */
++ SOC_DOUBLE_R("ADC Capture Volume",
++ ADC_VOLUME_H, ADC_VOLUME_L, 0, 0xFF, 0),
++ SOC_DOUBLE("ADC PGA Capture Volume", ADC_ADCVOL_L, 8, 0, 0x0F, 0),
++ SOC_SINGLE("ADC PGA Capture Switch", ADC_ADCVOL_H, 8, 0x1, 1),
++ SOC_SINGLE("Mic PGA Capture Volume", ADC_MICLINE_L, 0, 0x03, 0),
++
++ /* Virtual 3D effect */
++ SOC_ENUM("3D effect", mxs_codec_enum[3]),
++};
++/* END kcontrol */
++
++/* DAPM */
++static int pga_event(struct snd_soc_dapm_widget *w,
++ struct snd_kcontrol *kcontrol, int event)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec);
++
++ switch (event) {
++ case SND_SOC_DAPM_PRE_PMU:
++ /* Prepare powering up HP and SPEAKER output */
++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET);
++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET);
++ msleep(100);
++ break;
++ case SND_SOC_DAPM_POST_PMU:
++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ break;
++ case SND_SOC_DAPM_POST_PMD:
++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR);
++ break;
++ }
++ return 0;
++}
++
++static int adc_event(struct snd_soc_dapm_widget *w,
++ struct snd_kcontrol *kcontrol, int event)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec);
++
++ switch (event) {
++ case SND_SOC_DAPM_PRE_PMU:
++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET);
++ msleep(100);
++ break;
++ case SND_SOC_DAPM_POST_PMD:
++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND,
++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR);
++ break;
++ }
++ return 0;
++}
++
++/* Left ADC Mux */
++static const struct snd_kcontrol_new mxs_left_adc_controls =
++SOC_DAPM_ENUM("Route", mxs_codec_enum[0]);
++
++/* Right ADC Mux */
++static const struct snd_kcontrol_new mxs_right_adc_controls =
++SOC_DAPM_ENUM("Route", mxs_codec_enum[1]);
++
++/* Head Phone Mux */
++static const struct snd_kcontrol_new mxs_hp_controls =
++SOC_DAPM_ENUM("Route", mxs_codec_enum[2]);
++
++static const struct snd_soc_dapm_widget mxs_dapm_widgets[] = {
++ SND_SOC_DAPM_ADC_E("ADC", "Capture", DAC_PWRDN_L, 8, 1, adc_event,
++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
++
++ SND_SOC_DAPM_DAC("DAC", "Playback", DAC_PWRDN_L, 12, 1),
++
++ SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
++ &mxs_left_adc_controls),
++ SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
++ &mxs_right_adc_controls),
++ SND_SOC_DAPM_MUX("HP Mux", SND_SOC_NOPM, 0, 0,
++ &mxs_hp_controls),
++ SND_SOC_DAPM_PGA_E("HP AMP", DAC_PWRDN_L, 0, 1, NULL, 0, pga_event,
++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
++ SND_SOC_DAPM_POST_PMD),
++ SND_SOC_DAPM_PGA("SPEAKER AMP", DAC_PWRDN_H, 8, 1, NULL, 0),
++ SND_SOC_DAPM_INPUT("LINE1L"),
++ SND_SOC_DAPM_INPUT("LINE1R"),
++ SND_SOC_DAPM_INPUT("LINE2L"),
++ SND_SOC_DAPM_INPUT("LINE2R"),
++ SND_SOC_DAPM_INPUT("MIC"),
++
++ SND_SOC_DAPM_OUTPUT("SPEAKER"),
++ SND_SOC_DAPM_OUTPUT("HPL"),
++ SND_SOC_DAPM_OUTPUT("HPR"),
++};
++
++/* routes for sgtl5000 */
++static const struct snd_soc_dapm_route mxs_dapm_routes[] = {
++ /* Left ADC Mux */
++ {"Left ADC Mux", "Mic", "MIC"},
++ {"Left ADC Mux", "Line In 1", "LINE1L"},
++ {"Left ADC Mux", "Line In 2", "LINE2L"},
++ {"Left ADC Mux", "Head Phone", "HPL"},
++
++ /* Right ADC Mux */
++ {"Right ADC Mux", "Mic", "MIC"},
++ {"Right ADC Mux", "Line In 1", "LINE1R"},
++ {"Right ADC Mux", "Line In 2", "LINE2R"},
++ {"Right ADC Mux", "Head Phone", "HPR"},
++
++ /* ADC */
++ {"ADC", NULL, "Left ADC Mux"},
++ {"ADC", NULL, "Right ADC Mux"},
++
++ /* HP Mux */
++ {"HP Mux", "DAC Out", "DAC"},
++ {"HP Mux", "Line In 1", "LINE1L"},
++ {"HP Mux", "Line In 1", "LINE1R"},
++
++ /* HP amp */
++ {"HP AMP", NULL, "HP Mux"},
++ /* HP output */
++ {"HPR", NULL, "HP AMP"},
++ {"HPL", NULL, "HP AMP"},
++
++ /* Speaker amp */
++ {"SPEAKER AMP", NULL, "DAC"},
++ {"SPEAKER", NULL, "SPEAKER AMP"},
++};
++/* END DAPM */
++
++static int mxs_set_bias_level(struct snd_soc_codec *codec,
++ enum snd_soc_bias_level level)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++
++ pr_debug("dapm level %d\n", level);
++ switch (level) {
++ case SND_SOC_BIAS_ON: /* full On */
++ if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
++ break;
++ break;
++
++ case SND_SOC_BIAS_PREPARE: /* partial On */
++ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
++ break;
++ /* Set Capless mode */
++ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_CLR);
++ break;
++
++ case SND_SOC_BIAS_STANDBY: /* Off, with power */
++ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
++ break;
++ /* Unset Capless mode */
++ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
++ break;
++
++ case SND_SOC_BIAS_OFF: /* Off, without power */
++ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
++ break;
++ /* Unset Capless mode */
++ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS,
++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET);
++ break;
++ }
++
++ codec->dapm.bias_level = level;
++ return 0;
++}
++
++/* MXS-ADC Codec DAI driver */
++static int mxs_pcm_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec);
++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
++ int i;
++ u32 srr_value = 0;
++ u32 src_hold = 0;
++
++ i = get_srr_values(params_rate(params));
++ if (i < 0)
++ dev_warn(codec->dev, "%s doesn't support rate %d\n",
++ codec->name, params_rate(params));
++ else {
++ src_hold = srr_values[i].src_hold;
++
++ srr_value =
++ BF(srr_values[i].basemult, AUDIOOUT_DACSRR_BASEMULT) |
++ BF(srr_values[i].src_int, AUDIOOUT_DACSRR_SRC_INT) |
++ BF(srr_values[i].src_frac, AUDIOOUT_DACSRR_SRC_FRAC) |
++ BF(src_hold, AUDIOOUT_DACSRR_SRC_HOLD);
++
++ if (playback)
++ __raw_writel(srr_value,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACSRR);
++ else
++ __raw_writel(srr_value,
++ mxs_adc->ain_base + HW_AUDIOIN_ADCSRR);
++ }
++
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ if (playback)
++ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET);
++ else
++ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET);
++
++ break;
++
++ case SNDRV_PCM_FORMAT_S32_LE:
++ if (playback)
++ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR);
++ else
++ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR);
++
++ break;
++
++ default:
++ dev_warn(codec->dev, "%s doesn't support format %d\n",
++ codec->name, params_format(params));
++
++ }
++
++ return 0;
++}
++
++/* mute the codec used by alsa core */
++static int mxs_codec_dig_mute(struct snd_soc_dai *codec_dai, int mute)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec_dai->codec);
++ int l, r;
++ int ll, rr;
++ u32 reg, reg1, reg2;
++ u32 dac_mask = BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
++ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT;
++
++ if (mute) {
++ reg = __raw_readl(mxs_adc->aout_base + \
++ HW_AUDIOOUT_DACVOLUME);
++
++ reg1 = reg & ~BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
++ reg1 = reg1 & ~BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
++
++ l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >>
++ BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT;
++ r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >>
++ BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT;
++
++ /* fade out dac vol */
++ while ((l > DAC_VOLUME_MIN) || (r > DAC_VOLUME_MIN)) {
++ l -= 0x8;
++ r -= 0x8;
++ ll = l > DAC_VOLUME_MIN ? l : DAC_VOLUME_MIN;
++ rr = r > DAC_VOLUME_MIN ? r : DAC_VOLUME_MIN;
++ reg2 = reg1 | BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(ll)
++ | BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(rr);
++ __raw_writel(reg2,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
++ msleep(1);
++ }
++
++ __raw_writel(dac_mask,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET);
++ reg = reg | dac_mask;
++ __raw_writel(reg,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME);
++ } else
++ __raw_writel(dac_mask,
++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR);
++
++ return 0;
++}
++
++#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
++#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
++
++static const struct snd_soc_dai_ops mxs_codec_dai_ops = {
++ .hw_params = mxs_pcm_hw_params,
++ .digital_mute = mxs_codec_dig_mute,
++};
++
++static struct snd_soc_dai_driver mxs_codec_dai_driver = {
++ .name = "mxs-builtin-codec-dai",
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = MXS_ADC_RATES,
++ .formats = MXS_ADC_FORMATS,
++ },
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = MXS_ADC_RATES,
++ .formats = MXS_ADC_FORMATS,
++ },
++ .ops = &mxs_codec_dai_ops,
++};
++/* END MXS-ADC Codec DAI driver */
++
++/* MXS-ADC Codec driver */
++static int mxs_codec_driver_probe(struct snd_soc_codec *codec)
++{
++ int ret = 0;
++ /* We don't use snd_soc_codec_set_cache_io because we are using
++ * our own IO functions: write, read. */
++
++ mxs_codec_startup(codec);
++
++ /* leading to standby state */
++ ret = mxs_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++ if (ret)
++ goto err;
++
++ return 0;
++
++err:
++ mxs_codec_stop(codec);
++
++ return ret;
++}
++
++static int mxs_codec_driver_remove(struct snd_soc_codec *codec)
++{
++ mxs_codec_stop(codec);
++
++ return 0;
++}
++
++// static int mxs_codec_driver_suspend(struct snd_soc_codec *codec)
++// {
++// /* TODO Enable power management. */
++// return 0;
++// }
++
++// static int mxs_codec_driver_resume(struct snd_soc_codec *codec)
++// {
++// /* TODO Enable power management. */
++// return 0;
++// }
++
++static struct snd_soc_codec_driver mxs_codec_driver = {
++ .probe = mxs_codec_driver_probe,
++ .remove = mxs_codec_driver_remove,
++// .suspend = mxs_codec_driver_suspend,
++// .resume = mxs_codec_driver_resume,
++ .set_bias_level = mxs_set_bias_level,
++ .reg_cache_size = ADC_REGNUM,
++ .reg_word_size = sizeof(u16),
++ .reg_cache_step = 1,
++// .reg_cache_default = mxsadc_regs,
++// .volatile_register = sgtl5000_volatile_register,
++ .controls = mxs_snd_controls,
++ .num_controls = ARRAY_SIZE(mxs_snd_controls),
++ .dapm_widgets = mxs_dapm_widgets,
++ .num_dapm_widgets = ARRAY_SIZE(mxs_dapm_widgets),
++ .dapm_routes = mxs_dapm_routes,
++ .num_dapm_routes = ARRAY_SIZE(mxs_dapm_routes),
++ .write = mxs_codec_write,
++ .read = mxs_codec_read,
++};
++/* END MXS-ADC Codec driver */
++
++/* Underlying platform device that registers codec */
++static int mxs_adc_probe(struct platform_device *pdev)
++{
++ struct mxs_adc_priv *mxs_adc;
++ struct resource *r;
++ int ret;
++
++ mxs_adc = devm_kzalloc(&pdev->dev, sizeof(struct mxs_adc_priv), GFP_KERNEL);
++ if (!mxs_adc)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, mxs_adc);
++
++ /* audio-in IO memory */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioin");
++ if (IS_ERR(r)) {
++ dev_err(&pdev->dev, "failed to get resource\n");
++ return PTR_ERR(r);
++ }
++
++ mxs_adc->ain_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
++ if (IS_ERR(mxs_adc->ain_base)) {
++ dev_err(&pdev->dev, "ioremap failed\n");
++ return PTR_ERR(mxs_adc->ain_base);
++ }
++
++ /* audio-out IO memory */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioout");
++ if (IS_ERR(r)) {
++ dev_err(&pdev->dev, "failed to get resource\n");
++ return PTR_ERR(r);
++ }
++
++ mxs_adc->aout_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
++ if (IS_ERR(mxs_adc->aout_base)) {
++ dev_err(&pdev->dev, "ioremap failed\n");
++ return PTR_ERR(mxs_adc->aout_base);
++ }
++
++ /* rtc IO memory */
++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
++ if (IS_ERR(r)) {
++ dev_err(&pdev->dev, "failed to get resource\n");
++ return PTR_ERR(r);
++ }
++
++ mxs_adc->rtc_base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
++ if (IS_ERR(mxs_adc->rtc_base)) {
++ dev_err(&pdev->dev, "ioremap failed\n");
++ return PTR_ERR(mxs_adc->rtc_base);
++ }
++
++ /* Get audio clock */
++ mxs_adc->clk = devm_clk_get(&pdev->dev, "filt");
++ if (IS_ERR(mxs_adc->clk)) {
++ ret = PTR_ERR(mxs_adc->clk);
++ dev_err(&pdev->dev, "%s: Clock initialization failed\n", __func__);
++ return ret;
++ }
++
++ /* Turn on audio clock */
++ ret = clk_prepare_enable(mxs_adc->clk);
++ if (unlikely(ret != 0)) {
++ dev_err(&pdev->dev, "%s: Clock prepare or enable failed\n", __func__);
++ return ret;
++ }
++
++ ret = snd_soc_register_codec(&pdev->dev,
++ &mxs_codec_driver,&mxs_codec_dai_driver, 1);
++ if (unlikely(ret != 0)) {
++ dev_err(&pdev->dev, "Codec registration failed\n");
++ goto disable_clk;
++ }
++
++ return 0;
++
++disable_clk:
++ clk_disable_unprepare(mxs_adc->clk);
++ return ret;
++}
++
++static int mxs_adc_remove(struct platform_device *pdev)
++{
++ struct mxs_adc_priv *mxs_adc = platform_get_drvdata(pdev);
++
++ clk_disable_unprepare(mxs_adc->clk);
++ snd_soc_unregister_codec(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id mxs_adc_dt_ids[] = {
++ { .compatible = "fsl,mxs-builtin-codec", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mxs_adc_dt_ids);
++
++static struct platform_driver mxs_adc_driver = {
++ .driver = {
++ .name = "mxs-builtin-codec",
++ .owner = THIS_MODULE,
++ .of_match_table = mxs_adc_dt_ids,
++ },
++ .probe = mxs_adc_probe,
++ .remove = mxs_adc_remove,
++};
++
++module_platform_driver(mxs_adc_driver);
++/* END Underlying platform device that registers codec */
++
++MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec Driver");
++MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/sound/soc/codecs/mxs-builtin-codec.h
+@@ -0,0 +1,825 @@
++#ifndef __MXS_ADC_CODEC_H
++
++#include <linux/io.h>
++
++/* MXS ADC/DAC registers */
++#define DAC_CTRL_L 0
++#define DAC_CTRL_H 1
++#define DAC_STAT_L 2
++#define DAC_STAT_H 3
++#define DAC_SRR_L 4
++#define DAC_VOLUME_L 6
++#define DAC_VOLUME_H 7
++#define DAC_DEBUG_L 8
++#define DAC_DEBUG_H 9
++#define DAC_HPVOL_L 10
++#define DAC_HPVOL_H 11
++#define DAC_PWRDN_L 12
++#define DAC_PWRDN_H 13
++#define DAC_REFCTRL_L 14
++#define DAC_REFCTRL_H 15
++#define DAC_ANACTRL_L 16
++#define DAC_ANACTRL_H 17
++#define DAC_TEST_L 18
++#define DAC_TEST_H 19
++#define DAC_BISTCTRL_L 20
++#define DAC_BISTCTRL_H 21
++#define DAC_BISTSTAT0_L 22
++#define DAC_BISTSTAT0_H 23
++#define DAC_BISTSTAT1_L 24
++#define DAC_BISTSTAT1_H 25
++#define DAC_ANACLKCTRL_L 26
++#define DAC_ANACLKCTRL_H 27
++#define DAC_DATA_L 28
++#define DAC_DATA_H 29
++#define DAC_SPEAKERCTRL_L 30
++#define DAC_SPEAKERCTRL_H 31
++#define DAC_VERSION_L 32
++#define DAC_VERSION_H 33
++#define ADC_CTRL_L 34
++#define ADC_CTRL_H 35
++#define ADC_STAT_L 36
++#define ADC_STAT_H 37
++#define ADC_SRR_L 38
++#define ADC_SRR_H 39
++#define ADC_VOLUME_L 40
++#define ADC_VOLUME_H 41
++#define ADC_DEBUG_L 42
++#define ADC_DEBUG_H 43
++#define ADC_ADCVOL_L 44
++#define ADC_ADCVOL_H 45
++#define ADC_MICLINE_L 46
++#define ADC_MICLINE_H 47
++#define ADC_ANACLKCTRL_L 48
++#define ADC_ANACLKCTRL_H 49
++#define ADC_DATA_L 50
++#define ADC_DATA_H 51
++
++#define ADC_REGNUM 52
++
++#define DAC_VOLUME_MIN 0x37
++#define DAC_VOLUME_MAX 0xFE
++#define ADC_VOLUME_MIN 0x37
++#define ADC_VOLUME_MAX 0xFE
++#define HP_VOLUME_MAX 0x0
++#define HP_VOLUME_MIN 0x7F
++#define LO_VOLUME_MAX 0x0
++#define LO_VOLUME_MIN 0x1F
++
++/* RTC */
++#define HW_RTC_PERSISTENT0 (0x00000060)
++#define HW_RTC_PERSISTENT0_SET (0x00000064)
++#define HW_RTC_PERSISTENT0_CLR (0x00000068)
++#define HW_RTC_PERSISTENT0_TOG (0x0000006c)
++
++// TODO
++//#define BM_RTC_PERSISTENT0_RELEASE_GND 0x00080000
++
++/* AUDIOOUT */
++#define HW_AUDIOOUT_CTRL (0x00000000)
++#define HW_AUDIOOUT_CTRL_SET (0x00000004)
++#define HW_AUDIOOUT_CTRL_CLR (0x00000008)
++#define HW_AUDIOOUT_CTRL_TOG (0x0000000c)
++
++#define BM_AUDIOOUT_CTRL_SFTRST 0x80000000
++#define BM_AUDIOOUT_CTRL_CLKGATE 0x40000000
++#define BP_AUDIOOUT_CTRL_RSRVD4 21
++#define BM_AUDIOOUT_CTRL_RSRVD4 0x3FE00000
++#define BF_AUDIOOUT_CTRL_RSRVD4(v) \
++ (((v) << 21) & BM_AUDIOOUT_CTRL_RSRVD4)
++#define BP_AUDIOOUT_CTRL_DMAWAIT_COUNT 16
++#define BM_AUDIOOUT_CTRL_DMAWAIT_COUNT 0x001F0000
++#define BF_AUDIOOUT_CTRL_DMAWAIT_COUNT(v) \
++ (((v) << 16) & BM_AUDIOOUT_CTRL_DMAWAIT_COUNT)
++#define BM_AUDIOOUT_CTRL_RSRVD3 0x00008000
++#define BM_AUDIOOUT_CTRL_LR_SWAP 0x00004000
++#define BM_AUDIOOUT_CTRL_EDGE_SYNC 0x00002000
++#define BM_AUDIOOUT_CTRL_INVERT_1BIT 0x00001000
++#define BP_AUDIOOUT_CTRL_RSRVD2 10
++#define BM_AUDIOOUT_CTRL_RSRVD2 0x00000C00
++#define BF_AUDIOOUT_CTRL_RSRVD2(v) \
++ (((v) << 10) & BM_AUDIOOUT_CTRL_RSRVD2)
++#define BP_AUDIOOUT_CTRL_SS3D_EFFECT 8
++#define BM_AUDIOOUT_CTRL_SS3D_EFFECT 0x00000300
++#define BF_AUDIOOUT_CTRL_SS3D_EFFECT(v) \
++ (((v) << 8) & BM_AUDIOOUT_CTRL_SS3D_EFFECT)
++#define BM_AUDIOOUT_CTRL_RSRVD1 0x00000080
++#define BM_AUDIOOUT_CTRL_WORD_LENGTH 0x00000040
++#define BM_AUDIOOUT_CTRL_DAC_ZERO_ENABLE 0x00000020
++#define BM_AUDIOOUT_CTRL_LOOPBACK 0x00000010
++#define BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008
++#define BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ 0x00000004
++#define BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN 0x00000002
++#define BM_AUDIOOUT_CTRL_RUN 0x00000001
++
++#define HW_AUDIOOUT_STAT (0x00000010)
++#define HW_AUDIOOUT_STAT_SET (0x00000014)
++#define HW_AUDIOOUT_STAT_CLR (0x00000018)
++#define HW_AUDIOOUT_STAT_TOG (0x0000001c)
++
++#define BM_AUDIOOUT_STAT_DAC_PRESENT 0x80000000
++#define BP_AUDIOOUT_STAT_RSRVD1 0
++#define BM_AUDIOOUT_STAT_RSRVD1 0x7FFFFFFF
++#define BF_AUDIOOUT_STAT_RSRVD1(v) \
++ (((v) << 0) & BM_AUDIOOUT_STAT_RSRVD1)
++
++#define HW_AUDIOOUT_DACSRR (0x00000020)
++#define HW_AUDIOOUT_DACSRR_SET (0x00000024)
++#define HW_AUDIOOUT_DACSRR_CLR (0x00000028)
++#define HW_AUDIOOUT_DACSRR_TOG (0x0000002c)
++
++#define BM_AUDIOOUT_DACSRR_OSR 0x80000000
++#define BV_AUDIOOUT_DACSRR_OSR__OSR6 0x0
++#define BV_AUDIOOUT_DACSRR_OSR__OSR12 0x1
++#define BP_AUDIOOUT_DACSRR_BASEMULT 28
++#define BM_AUDIOOUT_DACSRR_BASEMULT 0x70000000
++#define BF_AUDIOOUT_DACSRR_BASEMULT(v) \
++ (((v) << 28) & BM_AUDIOOUT_DACSRR_BASEMULT)
++#define BV_AUDIOOUT_DACSRR_BASEMULT__SINGLE_RATE 0x1
++#define BV_AUDIOOUT_DACSRR_BASEMULT__DOUBLE_RATE 0x2
++#define BV_AUDIOOUT_DACSRR_BASEMULT__QUAD_RATE 0x4
++#define BM_AUDIOOUT_DACSRR_RSRVD2 0x08000000
++#define BP_AUDIOOUT_DACSRR_SRC_HOLD 24
++#define BM_AUDIOOUT_DACSRR_SRC_HOLD 0x07000000
++#define BF_AUDIOOUT_DACSRR_SRC_HOLD(v) \
++ (((v) << 24) & BM_AUDIOOUT_DACSRR_SRC_HOLD)
++#define BP_AUDIOOUT_DACSRR_RSRVD1 21
++#define BM_AUDIOOUT_DACSRR_RSRVD1 0x00E00000
++#define BF_AUDIOOUT_DACSRR_RSRVD1(v) \
++ (((v) << 21) & BM_AUDIOOUT_DACSRR_RSRVD1)
++#define BP_AUDIOOUT_DACSRR_SRC_INT 16
++#define BM_AUDIOOUT_DACSRR_SRC_INT 0x001F0000
++#define BF_AUDIOOUT_DACSRR_SRC_INT(v) \
++ (((v) << 16) & BM_AUDIOOUT_DACSRR_SRC_INT)
++#define BP_AUDIOOUT_DACSRR_RSRVD0 13
++#define BM_AUDIOOUT_DACSRR_RSRVD0 0x0000E000
++#define BF_AUDIOOUT_DACSRR_RSRVD0(v) \
++ (((v) << 13) & BM_AUDIOOUT_DACSRR_RSRVD0)
++#define BP_AUDIOOUT_DACSRR_SRC_FRAC 0
++#define BM_AUDIOOUT_DACSRR_SRC_FRAC 0x00001FFF
++#define BF_AUDIOOUT_DACSRR_SRC_FRAC(v) \
++ (((v) << 0) & BM_AUDIOOUT_DACSRR_SRC_FRAC)
++
++#define HW_AUDIOOUT_DACVOLUME (0x00000030)
++#define HW_AUDIOOUT_DACVOLUME_SET (0x00000034)
++#define HW_AUDIOOUT_DACVOLUME_CLR (0x00000038)
++#define HW_AUDIOOUT_DACVOLUME_TOG (0x0000003c)
++
++#define BP_AUDIOOUT_DACVOLUME_RSRVD4 29
++#define BM_AUDIOOUT_DACVOLUME_RSRVD4 0xE0000000
++#define BF_AUDIOOUT_DACVOLUME_RSRVD4(v) \
++ (((v) << 29) & BM_AUDIOOUT_DACVOLUME_RSRVD4)
++#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_LEFT 0x10000000
++#define BP_AUDIOOUT_DACVOLUME_RSRVD3 26
++#define BM_AUDIOOUT_DACVOLUME_RSRVD3 0x0C000000
++#define BF_AUDIOOUT_DACVOLUME_RSRVD3(v) \
++ (((v) << 26) & BM_AUDIOOUT_DACVOLUME_RSRVD3)
++#define BM_AUDIOOUT_DACVOLUME_EN_ZCD 0x02000000
++#define BM_AUDIOOUT_DACVOLUME_MUTE_LEFT 0x01000000
++#define BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT 16
++#define BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT 0x00FF0000
++#define BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(v) \
++ (((v) << 16) & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT)
++#define BP_AUDIOOUT_DACVOLUME_RSRVD2 13
++#define BM_AUDIOOUT_DACVOLUME_RSRVD2 0x0000E000
++#define BF_AUDIOOUT_DACVOLUME_RSRVD2(v) \
++ (((v) << 13) & BM_AUDIOOUT_DACVOLUME_RSRVD2)
++#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_RIGHT 0x00001000
++#define BP_AUDIOOUT_DACVOLUME_RSRVD1 9
++#define BM_AUDIOOUT_DACVOLUME_RSRVD1 0x00000E00
++#define BF_AUDIOOUT_DACVOLUME_RSRVD1(v) \
++ (((v) << 9) & BM_AUDIOOUT_DACVOLUME_RSRVD1)
++#define BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT 0x00000100
++#define BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0
++#define BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0x000000FF
++#define BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(v) \
++ (((v) << 0) & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT)
++
++#define HW_AUDIOOUT_DACDEBUG (0x00000040)
++#define HW_AUDIOOUT_DACDEBUG_SET (0x00000044)
++#define HW_AUDIOOUT_DACDEBUG_CLR (0x00000048)
++#define HW_AUDIOOUT_DACDEBUG_TOG (0x0000004c)
++
++#define BM_AUDIOOUT_DACDEBUG_ENABLE_DACDMA 0x80000000
++#define BP_AUDIOOUT_DACDEBUG_RSRVD2 12
++#define BM_AUDIOOUT_DACDEBUG_RSRVD2 0x7FFFF000
++#define BF_AUDIOOUT_DACDEBUG_RSRVD2(v) \
++ (((v) << 12) & BM_AUDIOOUT_DACDEBUG_RSRVD2)
++#define BP_AUDIOOUT_DACDEBUG_RAM_SS 8
++#define BM_AUDIOOUT_DACDEBUG_RAM_SS 0x00000F00
++#define BF_AUDIOOUT_DACDEBUG_RAM_SS(v) \
++ (((v) << 8) & BM_AUDIOOUT_DACDEBUG_RAM_SS)
++#define BP_AUDIOOUT_DACDEBUG_RSRVD1 6
++#define BM_AUDIOOUT_DACDEBUG_RSRVD1 0x000000C0
++#define BF_AUDIOOUT_DACDEBUG_RSRVD1(v) \
++ (((v) << 6) & BM_AUDIOOUT_DACDEBUG_RSRVD1)
++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_CLK_CROSS 0x00000020
++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_CLK_CROSS 0x00000010
++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_HAND_SHAKE 0x00000008
++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_HAND_SHAKE 0x00000004
++#define BM_AUDIOOUT_DACDEBUG_DMA_PREQ 0x00000002
++#define BM_AUDIOOUT_DACDEBUG_FIFO_STATUS 0x00000001
++
++#define HW_AUDIOOUT_HPVOL (0x00000050)
++#define HW_AUDIOOUT_HPVOL_SET (0x00000054)
++#define HW_AUDIOOUT_HPVOL_CLR (0x00000058)
++#define HW_AUDIOOUT_HPVOL_TOG (0x0000005c)
++
++#define BP_AUDIOOUT_HPVOL_RSRVD5 29
++#define BM_AUDIOOUT_HPVOL_RSRVD5 0xE0000000
++#define BF_AUDIOOUT_HPVOL_RSRVD5(v) \
++ (((v) << 29) & BM_AUDIOOUT_HPVOL_RSRVD5)
++#define BM_AUDIOOUT_HPVOL_VOLUME_UPDATE_PENDING 0x10000000
++#define BP_AUDIOOUT_HPVOL_RSRVD4 26
++#define BM_AUDIOOUT_HPVOL_RSRVD4 0x0C000000
++#define BF_AUDIOOUT_HPVOL_RSRVD4(v) \
++ (((v) << 26) & BM_AUDIOOUT_HPVOL_RSRVD4)
++#define BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD 0x02000000
++#define BM_AUDIOOUT_HPVOL_MUTE 0x01000000
++#define BP_AUDIOOUT_HPVOL_RSRVD3 17
++#define BM_AUDIOOUT_HPVOL_RSRVD3 0x00FE0000
++#define BF_AUDIOOUT_HPVOL_RSRVD3(v) \
++ (((v) << 17) & BM_AUDIOOUT_HPVOL_RSRVD3)
++#define BM_AUDIOOUT_HPVOL_SELECT 0x00010000
++#define BM_AUDIOOUT_HPVOL_RSRVD2 0x00008000
++#define BP_AUDIOOUT_HPVOL_VOL_LEFT 8
++#define BM_AUDIOOUT_HPVOL_VOL_LEFT 0x00007F00
++#define BF_AUDIOOUT_HPVOL_VOL_LEFT(v) \
++ (((v) << 8) & BM_AUDIOOUT_HPVOL_VOL_LEFT)
++#define BM_AUDIOOUT_HPVOL_RSRVD1 0x00000080
++#define BP_AUDIOOUT_HPVOL_VOL_RIGHT 0
++#define BM_AUDIOOUT_HPVOL_VOL_RIGHT 0x0000007F
++#define BF_AUDIOOUT_HPVOL_VOL_RIGHT(v) \
++ (((v) << 0) & BM_AUDIOOUT_HPVOL_VOL_RIGHT)
++
++#define HW_AUDIOOUT_RESERVED (0x00000060)
++#define HW_AUDIOOUT_RESERVED_SET (0x00000064)
++#define HW_AUDIOOUT_RESERVED_CLR (0x00000068)
++#define HW_AUDIOOUT_RESERVED_TOG (0x0000006c)
++
++#define BP_AUDIOOUT_RESERVED_RSRVD1 0
++#define BM_AUDIOOUT_RESERVED_RSRVD1 0xFFFFFFFF
++#define BF_AUDIOOUT_RESERVED_RSRVD1(v) (v)
++
++#define HW_AUDIOOUT_PWRDN (0x00000070)
++#define HW_AUDIOOUT_PWRDN_SET (0x00000074)
++#define HW_AUDIOOUT_PWRDN_CLR (0x00000078)
++#define HW_AUDIOOUT_PWRDN_TOG (0x0000007c)
++
++#define BP_AUDIOOUT_PWRDN_RSRVD7 25
++#define BM_AUDIOOUT_PWRDN_RSRVD7 0xFE000000
++#define BF_AUDIOOUT_PWRDN_RSRVD7(v) \
++ (((v) << 25) & BM_AUDIOOUT_PWRDN_RSRVD7)
++#define BM_AUDIOOUT_PWRDN_SPEAKER 0x01000000
++#define BP_AUDIOOUT_PWRDN_RSRVD6 21
++#define BM_AUDIOOUT_PWRDN_RSRVD6 0x00E00000
++#define BF_AUDIOOUT_PWRDN_RSRVD6(v) \
++ (((v) << 21) & BM_AUDIOOUT_PWRDN_RSRVD6)
++#define BM_AUDIOOUT_PWRDN_SELFBIAS 0x00100000
++#define BP_AUDIOOUT_PWRDN_RSRVD5 17
++#define BM_AUDIOOUT_PWRDN_RSRVD5 0x000E0000
++#define BF_AUDIOOUT_PWRDN_RSRVD5(v) \
++ (((v) << 17) & BM_AUDIOOUT_PWRDN_RSRVD5)
++#define BM_AUDIOOUT_PWRDN_RIGHT_ADC 0x00010000
++#define BP_AUDIOOUT_PWRDN_RSRVD4 13
++#define BM_AUDIOOUT_PWRDN_RSRVD4 0x0000E000
++#define BF_AUDIOOUT_PWRDN_RSRVD4(v) \
++ (((v) << 13) & BM_AUDIOOUT_PWRDN_RSRVD4)
++#define BM_AUDIOOUT_PWRDN_DAC 0x00001000
++#define BP_AUDIOOUT_PWRDN_RSRVD3 9
++#define BM_AUDIOOUT_PWRDN_RSRVD3 0x00000E00
++#define BF_AUDIOOUT_PWRDN_RSRVD3(v) \
++ (((v) << 9) & BM_AUDIOOUT_PWRDN_RSRVD3)
++#define BM_AUDIOOUT_PWRDN_ADC 0x00000100
++#define BP_AUDIOOUT_PWRDN_RSRVD2 5
++#define BM_AUDIOOUT_PWRDN_RSRVD2 0x000000E0
++#define BF_AUDIOOUT_PWRDN_RSRVD2(v) \
++ (((v) << 5) & BM_AUDIOOUT_PWRDN_RSRVD2)
++#define BM_AUDIOOUT_PWRDN_CAPLESS 0x00000010
++#define BP_AUDIOOUT_PWRDN_RSRVD1 1
++#define BM_AUDIOOUT_PWRDN_RSRVD1 0x0000000E
++#define BF_AUDIOOUT_PWRDN_RSRVD1(v) \
++ (((v) << 1) & BM_AUDIOOUT_PWRDN_RSRVD1)
++#define BM_AUDIOOUT_PWRDN_HEADPHONE 0x00000001
++
++#define HW_AUDIOOUT_REFCTRL (0x00000080)
++#define HW_AUDIOOUT_REFCTRL_SET (0x00000084)
++#define HW_AUDIOOUT_REFCTRL_CLR (0x00000088)
++#define HW_AUDIOOUT_REFCTRL_TOG (0x0000008c)
++
++#define BP_AUDIOOUT_REFCTRL_RSRVD4 27
++#define BM_AUDIOOUT_REFCTRL_RSRVD4 0xF8000000
++#define BF_AUDIOOUT_REFCTRL_RSRVD4(v) \
++ (((v) << 27) & BM_AUDIOOUT_REFCTRL_RSRVD4)
++#define BM_AUDIOOUT_REFCTRL_FASTSETTLING 0x04000000
++#define BM_AUDIOOUT_REFCTRL_RAISE_REF 0x02000000
++#define BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS 0x01000000
++#define BM_AUDIOOUT_REFCTRL_RSRVD3 0x00800000
++#define BP_AUDIOOUT_REFCTRL_VBG_ADJ 20
++#define BM_AUDIOOUT_REFCTRL_VBG_ADJ 0x00700000
++#define BF_AUDIOOUT_REFCTRL_VBG_ADJ(v) \
++ (((v) << 20) & BM_AUDIOOUT_REFCTRL_VBG_ADJ)
++#define BM_AUDIOOUT_REFCTRL_LOW_PWR 0x00080000
++#define BM_AUDIOOUT_REFCTRL_LW_REF 0x00040000
++#define BP_AUDIOOUT_REFCTRL_BIAS_CTRL 16
++#define BM_AUDIOOUT_REFCTRL_BIAS_CTRL 0x00030000
++#define BF_AUDIOOUT_REFCTRL_BIAS_CTRL(v) \
++ (((v) << 16) & BM_AUDIOOUT_REFCTRL_BIAS_CTRL)
++#define BM_AUDIOOUT_REFCTRL_RSRVD2 0x00008000
++#define BM_AUDIOOUT_REFCTRL_VDDXTAL_TO_VDDD 0x00004000
++#define BM_AUDIOOUT_REFCTRL_ADJ_ADC 0x00002000
++#define BM_AUDIOOUT_REFCTRL_ADJ_VAG 0x00001000
++#define BP_AUDIOOUT_REFCTRL_ADC_REFVAL 8
++#define BM_AUDIOOUT_REFCTRL_ADC_REFVAL 0x00000F00
++#define BF_AUDIOOUT_REFCTRL_ADC_REFVAL(v) \
++ (((v) << 8) & BM_AUDIOOUT_REFCTRL_ADC_REFVAL)
++#define BP_AUDIOOUT_REFCTRL_VAG_VAL 4
++#define BM_AUDIOOUT_REFCTRL_VAG_VAL 0x000000F0
++#define BF_AUDIOOUT_REFCTRL_VAG_VAL(v) \
++ (((v) << 4) & BM_AUDIOOUT_REFCTRL_VAG_VAL)
++#define BM_AUDIOOUT_REFCTRL_RSRVD1 0x00000008
++#define BP_AUDIOOUT_REFCTRL_DAC_ADJ 0
++#define BM_AUDIOOUT_REFCTRL_DAC_ADJ 0x00000007
++#define BF_AUDIOOUT_REFCTRL_DAC_ADJ(v) \
++ (((v) << 0) & BM_AUDIOOUT_REFCTRL_DAC_ADJ)
++
++#define HW_AUDIOOUT_ANACTRL (0x00000090)
++#define HW_AUDIOOUT_ANACTRL_SET (0x00000094)
++#define HW_AUDIOOUT_ANACTRL_CLR (0x00000098)
++#define HW_AUDIOOUT_ANACTRL_TOG (0x0000009c)
++
++#define BP_AUDIOOUT_ANACTRL_RSRVD8 29
++#define BM_AUDIOOUT_ANACTRL_RSRVD8 0xE0000000
++#define BF_AUDIOOUT_ANACTRL_RSRVD8(v) \
++ (((v) << 29) & BM_AUDIOOUT_ANACTRL_RSRVD8)
++#define BM_AUDIOOUT_ANACTRL_SHORT_CM_STS 0x10000000
++#define BP_AUDIOOUT_ANACTRL_RSRVD7 25
++#define BM_AUDIOOUT_ANACTRL_RSRVD7 0x0E000000
++#define BF_AUDIOOUT_ANACTRL_RSRVD7(v) \
++ (((v) << 25) & BM_AUDIOOUT_ANACTRL_RSRVD7)
++#define BM_AUDIOOUT_ANACTRL_SHORT_LR_STS 0x01000000
++#define BP_AUDIOOUT_ANACTRL_RSRVD6 22
++#define BM_AUDIOOUT_ANACTRL_RSRVD6 0x00C00000
++#define BF_AUDIOOUT_ANACTRL_RSRVD6(v) \
++ (((v) << 22) & BM_AUDIOOUT_ANACTRL_RSRVD6)
++#define BP_AUDIOOUT_ANACTRL_SHORTMODE_CM 20
++#define BM_AUDIOOUT_ANACTRL_SHORTMODE_CM 0x00300000
++#define BF_AUDIOOUT_ANACTRL_SHORTMODE_CM(v) \
++ (((v) << 20) & BM_AUDIOOUT_ANACTRL_SHORTMODE_CM)
++#define BM_AUDIOOUT_ANACTRL_RSRVD5 0x00080000
++#define BP_AUDIOOUT_ANACTRL_SHORTMODE_LR 17
++#define BM_AUDIOOUT_ANACTRL_SHORTMODE_LR 0x00060000
++#define BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(v) \
++ (((v) << 17) & BM_AUDIOOUT_ANACTRL_SHORTMODE_LR)
++#define BP_AUDIOOUT_ANACTRL_RSRVD4 15
++#define BM_AUDIOOUT_ANACTRL_RSRVD4 0x00018000
++#define BF_AUDIOOUT_ANACTRL_RSRVD4(v) \
++ (((v) << 15) & BM_AUDIOOUT_ANACTRL_RSRVD4)
++#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJL 12
++#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL 0x00007000
++#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJL(v) \
++ (((v) << 12) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL)
++#define BM_AUDIOOUT_ANACTRL_RSRVD3 0x00000800
++#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJR 8
++#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR 0x00000700
++#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJR(v) \
++ (((v) << 8) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR)
++#define BP_AUDIOOUT_ANACTRL_RSRVD2 6
++#define BM_AUDIOOUT_ANACTRL_RSRVD2 0x000000C0
++#define BF_AUDIOOUT_ANACTRL_RSRVD2(v) \
++ (((v) << 6) & BM_AUDIOOUT_ANACTRL_RSRVD2)
++#define BM_AUDIOOUT_ANACTRL_HP_HOLD_GND 0x00000020
++#define BM_AUDIOOUT_ANACTRL_HP_CLASSAB 0x00000010
++#define BP_AUDIOOUT_ANACTRL_RSRVD1 0
++#define BM_AUDIOOUT_ANACTRL_RSRVD1 0x0000000F
++#define BF_AUDIOOUT_ANACTRL_RSRVD1(v) \
++ (((v) << 0) & BM_AUDIOOUT_ANACTRL_RSRVD1)
++
++#define HW_AUDIOOUT_TEST (0x000000a0)
++#define HW_AUDIOOUT_TEST_SET (0x000000a4)
++#define HW_AUDIOOUT_TEST_CLR (0x000000a8)
++#define HW_AUDIOOUT_TEST_TOG (0x000000ac)
++
++#define BM_AUDIOOUT_TEST_RSRVD4 0x80000000
++#define BP_AUDIOOUT_TEST_HP_ANTIPOP 28
++#define BM_AUDIOOUT_TEST_HP_ANTIPOP 0x70000000
++#define BF_AUDIOOUT_TEST_HP_ANTIPOP(v) \
++ (((v) << 28) & BM_AUDIOOUT_TEST_HP_ANTIPOP)
++#define BM_AUDIOOUT_TEST_RSRVD3 0x08000000
++#define BM_AUDIOOUT_TEST_TM_ADCIN_TOHP 0x04000000
++#define BM_AUDIOOUT_TEST_TM_LOOP 0x02000000
++#define BM_AUDIOOUT_TEST_TM_HPCOMMON 0x01000000
++#define BP_AUDIOOUT_TEST_HP_I1_ADJ 22
++#define BM_AUDIOOUT_TEST_HP_I1_ADJ 0x00C00000
++#define BF_AUDIOOUT_TEST_HP_I1_ADJ(v) \
++ (((v) << 22) & BM_AUDIOOUT_TEST_HP_I1_ADJ)
++#define BP_AUDIOOUT_TEST_HP_IALL_ADJ 20
++#define BM_AUDIOOUT_TEST_HP_IALL_ADJ 0x00300000
++#define BF_AUDIOOUT_TEST_HP_IALL_ADJ(v) \
++ (((v) << 20) & BM_AUDIOOUT_TEST_HP_IALL_ADJ)
++#define BP_AUDIOOUT_TEST_RSRVD2 14
++#define BM_AUDIOOUT_TEST_RSRVD2 0x000FC000
++#define BF_AUDIOOUT_TEST_RSRVD2(v) \
++ (((v) << 14) & BM_AUDIOOUT_TEST_RSRVD2)
++#define BM_AUDIOOUT_TEST_VAG_CLASSA 0x00002000
++#define BM_AUDIOOUT_TEST_VAG_DOUBLE_I 0x00001000
++#define BP_AUDIOOUT_TEST_RSRVD1 4
++#define BM_AUDIOOUT_TEST_RSRVD1 0x00000FF0
++#define BF_AUDIOOUT_TEST_RSRVD1(v) \
++ (((v) << 4) & BM_AUDIOOUT_TEST_RSRVD1)
++#define BM_AUDIOOUT_TEST_ADCTODAC_LOOP 0x00000008
++#define BM_AUDIOOUT_TEST_DAC_CLASSA 0x00000004
++#define BM_AUDIOOUT_TEST_DAC_DOUBLE_I 0x00000002
++#define BM_AUDIOOUT_TEST_DAC_DIS_RTZ 0x00000001
++
++#define HW_AUDIOOUT_BISTCTRL (0x000000b0)
++#define HW_AUDIOOUT_BISTCTRL_SET (0x000000b4)
++#define HW_AUDIOOUT_BISTCTRL_CLR (0x000000b8)
++#define HW_AUDIOOUT_BISTCTRL_TOG (0x000000bc)
++
++#define BP_AUDIOOUT_BISTCTRL_RSVD0 4
++#define BM_AUDIOOUT_BISTCTRL_RSVD0 0xFFFFFFF0
++#define BF_AUDIOOUT_BISTCTRL_RSVD0(v) \
++ (((v) << 4) & BM_AUDIOOUT_BISTCTRL_RSVD0)
++#define BM_AUDIOOUT_BISTCTRL_FAIL 0x00000008
++#define BM_AUDIOOUT_BISTCTRL_PASS 0x00000004
++#define BM_AUDIOOUT_BISTCTRL_DONE 0x00000002
++#define BM_AUDIOOUT_BISTCTRL_START 0x00000001
++
++#define HW_AUDIOOUT_BISTSTAT0 (0x000000c0)
++#define HW_AUDIOOUT_BISTSTAT0_SET (0x000000c4)
++#define HW_AUDIOOUT_BISTSTAT0_CLR (0x000000c8)
++#define HW_AUDIOOUT_BISTSTAT0_TOG (0x000000cc)
++
++#define BP_AUDIOOUT_BISTSTAT0_RSVD0 24
++#define BM_AUDIOOUT_BISTSTAT0_RSVD0 0xFF000000
++#define BF_AUDIOOUT_BISTSTAT0_RSVD0(v) \
++ (((v) << 24) & BM_AUDIOOUT_BISTSTAT0_RSVD0)
++#define BP_AUDIOOUT_BISTSTAT0_DATA 0
++#define BM_AUDIOOUT_BISTSTAT0_DATA 0x00FFFFFF
++#define BF_AUDIOOUT_BISTSTAT0_DATA(v) \
++ (((v) << 0) & BM_AUDIOOUT_BISTSTAT0_DATA)
++
++#define HW_AUDIOOUT_BISTSTAT1 (0x000000d0)
++#define HW_AUDIOOUT_BISTSTAT1_SET (0x000000d4)
++#define HW_AUDIOOUT_BISTSTAT1_CLR (0x000000d8)
++#define HW_AUDIOOUT_BISTSTAT1_TOG (0x000000dc)
++
++#define BP_AUDIOOUT_BISTSTAT1_RSVD1 29
++#define BM_AUDIOOUT_BISTSTAT1_RSVD1 0xE0000000
++#define BF_AUDIOOUT_BISTSTAT1_RSVD1(v) \
++ (((v) << 29) & BM_AUDIOOUT_BISTSTAT1_RSVD1)
++#define BP_AUDIOOUT_BISTSTAT1_STATE 24
++#define BM_AUDIOOUT_BISTSTAT1_STATE 0x1F000000
++#define BF_AUDIOOUT_BISTSTAT1_STATE(v) \
++ (((v) << 24) & BM_AUDIOOUT_BISTSTAT1_STATE)
++#define BP_AUDIOOUT_BISTSTAT1_RSVD0 8
++#define BM_AUDIOOUT_BISTSTAT1_RSVD0 0x00FFFF00
++#define BF_AUDIOOUT_BISTSTAT1_RSVD0(v) \
++ (((v) << 8) & BM_AUDIOOUT_BISTSTAT1_RSVD0)
++#define BP_AUDIOOUT_BISTSTAT1_ADDR 0
++#define BM_AUDIOOUT_BISTSTAT1_ADDR 0x000000FF
++#define BF_AUDIOOUT_BISTSTAT1_ADDR(v) \
++ (((v) << 0) & BM_AUDIOOUT_BISTSTAT1_ADDR)
++
++#define HW_AUDIOOUT_ANACLKCTRL (0x000000e0)
++#define HW_AUDIOOUT_ANACLKCTRL_SET (0x000000e4)
++#define HW_AUDIOOUT_ANACLKCTRL_CLR (0x000000e8)
++#define HW_AUDIOOUT_ANACLKCTRL_TOG (0x000000ec)
++
++#define BM_AUDIOOUT_ANACLKCTRL_CLKGATE 0x80000000
++#define BP_AUDIOOUT_ANACLKCTRL_RSRVD3 5
++#define BM_AUDIOOUT_ANACLKCTRL_RSRVD3 0x7FFFFFE0
++#define BF_AUDIOOUT_ANACLKCTRL_RSRVD3(v) \
++ (((v) << 5) & BM_AUDIOOUT_ANACLKCTRL_RSRVD3)
++#define BM_AUDIOOUT_ANACLKCTRL_INVERT_DACCLK 0x00000010
++#define BM_AUDIOOUT_ANACLKCTRL_RSRVD2 0x00000008
++#define BP_AUDIOOUT_ANACLKCTRL_DACDIV 0
++#define BM_AUDIOOUT_ANACLKCTRL_DACDIV 0x00000007
++#define BF_AUDIOOUT_ANACLKCTRL_DACDIV(v) \
++ (((v) << 0) & BM_AUDIOOUT_ANACLKCTRL_DACDIV)
++
++#define HW_AUDIOOUT_DATA (0x000000f0)
++#define HW_AUDIOOUT_DATA_SET (0x000000f4)
++#define HW_AUDIOOUT_DATA_CLR (0x000000f8)
++#define HW_AUDIOOUT_DATA_TOG (0x000000fc)
++
++#define BP_AUDIOOUT_DATA_HIGH 16
++#define BM_AUDIOOUT_DATA_HIGH 0xFFFF0000
++#define BF_AUDIOOUT_DATA_HIGH(v) \
++ (((v) << 16) & BM_AUDIOOUT_DATA_HIGH)
++#define BP_AUDIOOUT_DATA_LOW 0
++#define BM_AUDIOOUT_DATA_LOW 0x0000FFFF
++#define BF_AUDIOOUT_DATA_LOW(v) \
++ (((v) << 0) & BM_AUDIOOUT_DATA_LOW)
++
++#define HW_AUDIOOUT_SPEAKERCTRL (0x00000100)
++#define HW_AUDIOOUT_SPEAKERCTRL_SET (0x00000104)
++#define HW_AUDIOOUT_SPEAKERCTRL_CLR (0x00000108)
++#define HW_AUDIOOUT_SPEAKERCTRL_TOG (0x0000010c)
++
++#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD2 25
++#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD2 0xFE000000
++#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD2(v) \
++ (((v) << 25) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD2)
++#define BM_AUDIOOUT_SPEAKERCTRL_MUTE 0x01000000
++#define BP_AUDIOOUT_SPEAKERCTRL_I1_ADJ 22
++#define BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ 0x00C00000
++#define BF_AUDIOOUT_SPEAKERCTRL_I1_ADJ(v) \
++ (((v) << 22) & BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ)
++#define BP_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 20
++#define BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 0x00300000
++#define BF_AUDIOOUT_SPEAKERCTRL_IALL_ADJ(v) \
++ (((v) << 20) & BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ)
++#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD1 16
++#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD1 0x000F0000
++#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD1(v) \
++ (((v) << 16) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD1)
++#define BP_AUDIOOUT_SPEAKERCTRL_POSDRIVER 14
++#define BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER 0x0000C000
++#define BF_AUDIOOUT_SPEAKERCTRL_POSDRIVER(v) \
++ (((v) << 14) & BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER)
++#define BP_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 12
++#define BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 0x00003000
++#define BF_AUDIOOUT_SPEAKERCTRL_NEGDRIVER(v) \
++ (((v) << 12) & BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER)
++#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD0 0
++#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD0 0x00000FFF
++#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD0(v) \
++ (((v) << 0) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD0)
++
++#define HW_AUDIOOUT_VERSION (0x00000200)
++
++#define BP_AUDIOOUT_VERSION_MAJOR 24
++#define BM_AUDIOOUT_VERSION_MAJOR 0xFF000000
++#define BF_AUDIOOUT_VERSION_MAJOR(v) \
++ (((v) << 24) & BM_AUDIOOUT_VERSION_MAJOR)
++#define BP_AUDIOOUT_VERSION_MINOR 16
++#define BM_AUDIOOUT_VERSION_MINOR 0x00FF0000
++#define BF_AUDIOOUT_VERSION_MINOR(v) \
++ (((v) << 16) & BM_AUDIOOUT_VERSION_MINOR)
++#define BP_AUDIOOUT_VERSION_STEP 0
++#define BM_AUDIOOUT_VERSION_STEP 0x0000FFFF
++#define BF_AUDIOOUT_VERSION_STEP(v) \
++ (((v) << 0) & BM_AUDIOOUT_VERSION_STEP)
++
++/* AUDIOIN */
++#define HW_AUDIOIN_CTRL (0x00000000)
++#define HW_AUDIOIN_CTRL_SET (0x00000004)
++#define HW_AUDIOIN_CTRL_CLR (0x00000008)
++#define HW_AUDIOIN_CTRL_TOG (0x0000000c)
++
++#define BM_AUDIOIN_CTRL_SFTRST 0x80000000
++#define BM_AUDIOIN_CTRL_CLKGATE 0x40000000
++#define BP_AUDIOIN_CTRL_RSRVD3 21
++#define BM_AUDIOIN_CTRL_RSRVD3 0x3FE00000
++#define BF_AUDIOIN_CTRL_RSRVD3(v) \
++ (((v) << 21) & BM_AUDIOIN_CTRL_RSRVD3)
++#define BP_AUDIOIN_CTRL_DMAWAIT_COUNT 16
++#define BM_AUDIOIN_CTRL_DMAWAIT_COUNT 0x001F0000
++#define BF_AUDIOIN_CTRL_DMAWAIT_COUNT(v) \
++ (((v) << 16) & BM_AUDIOIN_CTRL_DMAWAIT_COUNT)
++#define BP_AUDIOIN_CTRL_RSRVD1 11
++#define BM_AUDIOIN_CTRL_RSRVD1 0x0000F800
++#define BF_AUDIOIN_CTRL_RSRVD1(v) \
++ (((v) << 11) & BM_AUDIOIN_CTRL_RSRVD1)
++#define BM_AUDIOIN_CTRL_LR_SWAP 0x00000400
++#define BM_AUDIOIN_CTRL_EDGE_SYNC 0x00000200
++#define BM_AUDIOIN_CTRL_INVERT_1BIT 0x00000100
++#define BM_AUDIOIN_CTRL_OFFSET_ENABLE 0x00000080
++#define BM_AUDIOIN_CTRL_HPF_ENABLE 0x00000040
++#define BM_AUDIOIN_CTRL_WORD_LENGTH 0x00000020
++#define BM_AUDIOIN_CTRL_LOOPBACK 0x00000010
++#define BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008
++#define BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ 0x00000004
++#define BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN 0x00000002
++#define BM_AUDIOIN_CTRL_RUN 0x00000001
++
++#define HW_AUDIOIN_STAT (0x00000010)
++#define HW_AUDIOIN_STAT_SET (0x00000014)
++#define HW_AUDIOIN_STAT_CLR (0x00000018)
++#define HW_AUDIOIN_STAT_TOG (0x0000001c)
++
++#define BM_AUDIOIN_STAT_ADC_PRESENT 0x80000000
++#define BP_AUDIOIN_STAT_RSRVD3 0
++#define BM_AUDIOIN_STAT_RSRVD3 0x7FFFFFFF
++#define BF_AUDIOIN_STAT_RSRVD3(v) \
++ (((v) << 0) & BM_AUDIOIN_STAT_RSRVD3)
++
++#define HW_AUDIOIN_ADCSRR (0x00000020)
++#define HW_AUDIOIN_ADCSRR_SET (0x00000024)
++#define HW_AUDIOIN_ADCSRR_CLR (0x00000028)
++#define HW_AUDIOIN_ADCSRR_TOG (0x0000002c)
++
++#define BM_AUDIOIN_ADCSRR_OSR 0x80000000
++#define BV_AUDIOIN_ADCSRR_OSR__OSR6 0x0
++#define BV_AUDIOIN_ADCSRR_OSR__OSR12 0x1
++#define BP_AUDIOIN_ADCSRR_BASEMULT 28
++#define BM_AUDIOIN_ADCSRR_BASEMULT 0x70000000
++#define BF_AUDIOIN_ADCSRR_BASEMULT(v) \
++ (((v) << 28) & BM_AUDIOIN_ADCSRR_BASEMULT)
++#define BV_AUDIOIN_ADCSRR_BASEMULT__SINGLE_RATE 0x1
++#define BV_AUDIOIN_ADCSRR_BASEMULT__DOUBLE_RATE 0x2
++#define BV_AUDIOIN_ADCSRR_BASEMULT__QUAD_RATE 0x4
++#define BM_AUDIOIN_ADCSRR_RSRVD2 0x08000000
++#define BP_AUDIOIN_ADCSRR_SRC_HOLD 24
++#define BM_AUDIOIN_ADCSRR_SRC_HOLD 0x07000000
++#define BF_AUDIOIN_ADCSRR_SRC_HOLD(v) \
++ (((v) << 24) & BM_AUDIOIN_ADCSRR_SRC_HOLD)
++#define BP_AUDIOIN_ADCSRR_RSRVD1 21
++#define BM_AUDIOIN_ADCSRR_RSRVD1 0x00E00000
++#define BF_AUDIOIN_ADCSRR_RSRVD1(v) \
++ (((v) << 21) & BM_AUDIOIN_ADCSRR_RSRVD1)
++#define BP_AUDIOIN_ADCSRR_SRC_INT 16
++#define BM_AUDIOIN_ADCSRR_SRC_INT 0x001F0000
++#define BF_AUDIOIN_ADCSRR_SRC_INT(v) \
++ (((v) << 16) & BM_AUDIOIN_ADCSRR_SRC_INT)
++#define BP_AUDIOIN_ADCSRR_RSRVD0 13
++#define BM_AUDIOIN_ADCSRR_RSRVD0 0x0000E000
++#define BF_AUDIOIN_ADCSRR_RSRVD0(v) \
++ (((v) << 13) & BM_AUDIOIN_ADCSRR_RSRVD0)
++#define BP_AUDIOIN_ADCSRR_SRC_FRAC 0
++#define BM_AUDIOIN_ADCSRR_SRC_FRAC 0x00001FFF
++#define BF_AUDIOIN_ADCSRR_SRC_FRAC(v) \
++ (((v) << 0) & BM_AUDIOIN_ADCSRR_SRC_FRAC)
++
++#define HW_AUDIOIN_ADCVOLUME (0x00000030)
++#define HW_AUDIOIN_ADCVOLUME_SET (0x00000034)
++#define HW_AUDIOIN_ADCVOLUME_CLR (0x00000038)
++#define HW_AUDIOIN_ADCVOLUME_TOG (0x0000003c)
++
++#define BP_AUDIOIN_ADCVOLUME_RSRVD5 29
++#define BM_AUDIOIN_ADCVOLUME_RSRVD5 0xE0000000
++#define BF_AUDIOIN_ADCVOLUME_RSRVD5(v) \
++ (((v) << 29) & BM_AUDIOIN_ADCVOLUME_RSRVD5)
++#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_LEFT 0x10000000
++#define BP_AUDIOIN_ADCVOLUME_RSRVD4 26
++#define BM_AUDIOIN_ADCVOLUME_RSRVD4 0x0C000000
++#define BF_AUDIOIN_ADCVOLUME_RSRVD4(v) \
++ (((v) << 26) & BM_AUDIOIN_ADCVOLUME_RSRVD4)
++#define BM_AUDIOIN_ADCVOLUME_EN_ZCD 0x02000000
++#define BM_AUDIOIN_ADCVOLUME_RSRVD3 0x01000000
++#define BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT 16
++#define BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT 0x00FF0000
++#define BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(v) \
++ (((v) << 16) & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT)
++#define BP_AUDIOIN_ADCVOLUME_RSRVD2 13
++#define BM_AUDIOIN_ADCVOLUME_RSRVD2 0x0000E000
++#define BF_AUDIOIN_ADCVOLUME_RSRVD2(v) \
++ (((v) << 13) & BM_AUDIOIN_ADCVOLUME_RSRVD2)
++#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_RIGHT 0x00001000
++#define BP_AUDIOIN_ADCVOLUME_RSRVD1 8
++#define BM_AUDIOIN_ADCVOLUME_RSRVD1 0x00000F00
++#define BF_AUDIOIN_ADCVOLUME_RSRVD1(v) \
++ (((v) << 8) & BM_AUDIOIN_ADCVOLUME_RSRVD1)
++#define BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0
++#define BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0x000000FF
++#define BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(v) \
++ (((v) << 0) & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT)
++
++#define HW_AUDIOIN_ADCDEBUG (0x00000040)
++#define HW_AUDIOIN_ADCDEBUG_SET (0x00000044)
++#define HW_AUDIOIN_ADCDEBUG_CLR (0x00000048)
++#define HW_AUDIOIN_ADCDEBUG_TOG (0x0000004c)
++
++#define BM_AUDIOIN_ADCDEBUG_ENABLE_ADCDMA 0x80000000
++#define BP_AUDIOIN_ADCDEBUG_RSRVD1 4
++#define BM_AUDIOIN_ADCDEBUG_RSRVD1 0x7FFFFFF0
++#define BF_AUDIOIN_ADCDEBUG_RSRVD1(v) \
++ (((v) << 4) & BM_AUDIOIN_ADCDEBUG_RSRVD1)
++#define BM_AUDIOIN_ADCDEBUG_ADC_DMA_REQ_HAND_SHAKE_CLK_CROSS 0x00000008
++#define BM_AUDIOIN_ADCDEBUG_SET_INTERRUPT3_HAND_SHAKE 0x00000004
++#define BM_AUDIOIN_ADCDEBUG_DMA_PREQ 0x00000002
++#define BM_AUDIOIN_ADCDEBUG_FIFO_STATUS 0x00000001
++
++#define HW_AUDIOIN_ADCVOL (0x00000050)
++#define HW_AUDIOIN_ADCVOL_SET (0x00000054)
++#define HW_AUDIOIN_ADCVOL_CLR (0x00000058)
++#define HW_AUDIOIN_ADCVOL_TOG (0x0000005c)
++
++#define BP_AUDIOIN_ADCVOL_RSRVD4 29
++#define BM_AUDIOIN_ADCVOL_RSRVD4 0xE0000000
++#define BF_AUDIOIN_ADCVOL_RSRVD4(v) \
++ (((v) << 29) & BM_AUDIOIN_ADCVOL_RSRVD4)
++#define BM_AUDIOIN_ADCVOL_VOLUME_UPDATE_PENDING 0x10000000
++#define BP_AUDIOIN_ADCVOL_RSRVD3 26
++#define BM_AUDIOIN_ADCVOL_RSRVD3 0x0C000000
++#define BF_AUDIOIN_ADCVOL_RSRVD3(v) \
++ (((v) << 26) & BM_AUDIOIN_ADCVOL_RSRVD3)
++#define BM_AUDIOIN_ADCVOL_EN_ADC_ZCD 0x02000000
++#define BM_AUDIOIN_ADCVOL_MUTE 0x01000000
++#define BP_AUDIOIN_ADCVOL_RSRVD2 14
++#define BM_AUDIOIN_ADCVOL_RSRVD2 0x00FFC000
++#define BF_AUDIOIN_ADCVOL_RSRVD2(v) \
++ (((v) << 14) & BM_AUDIOIN_ADCVOL_RSRVD2)
++#define BP_AUDIOIN_ADCVOL_SELECT_LEFT 12
++#define BM_AUDIOIN_ADCVOL_SELECT_LEFT 0x00003000
++#define BF_AUDIOIN_ADCVOL_SELECT_LEFT(v) \
++ (((v) << 12) & BM_AUDIOIN_ADCVOL_SELECT_LEFT)
++#define BP_AUDIOIN_ADCVOL_GAIN_LEFT 8
++#define BM_AUDIOIN_ADCVOL_GAIN_LEFT 0x00000F00
++#define BF_AUDIOIN_ADCVOL_GAIN_LEFT(v) \
++ (((v) << 8) & BM_AUDIOIN_ADCVOL_GAIN_LEFT)
++#define BP_AUDIOIN_ADCVOL_RSRVD1 6
++#define BM_AUDIOIN_ADCVOL_RSRVD1 0x000000C0
++#define BF_AUDIOIN_ADCVOL_RSRVD1(v) \
++ (((v) << 6) & BM_AUDIOIN_ADCVOL_RSRVD1)
++#define BP_AUDIOIN_ADCVOL_SELECT_RIGHT 4
++#define BM_AUDIOIN_ADCVOL_SELECT_RIGHT 0x00000030
++#define BF_AUDIOIN_ADCVOL_SELECT_RIGHT(v) \
++ (((v) << 4) & BM_AUDIOIN_ADCVOL_SELECT_RIGHT)
++#define BP_AUDIOIN_ADCVOL_GAIN_RIGHT 0
++#define BM_AUDIOIN_ADCVOL_GAIN_RIGHT 0x0000000F
++#define BF_AUDIOIN_ADCVOL_GAIN_RIGHT(v) \
++ (((v) << 0) & BM_AUDIOIN_ADCVOL_GAIN_RIGHT)
++
++#define HW_AUDIOIN_MICLINE (0x00000060)
++#define HW_AUDIOIN_MICLINE_SET (0x00000064)
++#define HW_AUDIOIN_MICLINE_CLR (0x00000068)
++#define HW_AUDIOIN_MICLINE_TOG (0x0000006c)
++
++#define BP_AUDIOIN_MICLINE_RSRVD6 30
++#define BM_AUDIOIN_MICLINE_RSRVD6 0xC0000000
++#define BF_AUDIOIN_MICLINE_RSRVD6(v) \
++ (((v) << 30) & BM_AUDIOIN_MICLINE_RSRVD6)
++#define BM_AUDIOIN_MICLINE_DIVIDE_LINE1 0x20000000
++#define BM_AUDIOIN_MICLINE_DIVIDE_LINE2 0x10000000
++#define BP_AUDIOIN_MICLINE_RSRVD5 25
++#define BM_AUDIOIN_MICLINE_RSRVD5 0x0E000000
++#define BF_AUDIOIN_MICLINE_RSRVD5(v) \
++ (((v) << 25) & BM_AUDIOIN_MICLINE_RSRVD5)
++#define BM_AUDIOIN_MICLINE_MIC_SELECT 0x01000000
++#define BP_AUDIOIN_MICLINE_RSRVD4 22
++#define BM_AUDIOIN_MICLINE_RSRVD4 0x00C00000
++#define BF_AUDIOIN_MICLINE_RSRVD4(v) \
++ (((v) << 22) & BM_AUDIOIN_MICLINE_RSRVD4)
++#define BP_AUDIOIN_MICLINE_MIC_RESISTOR 20
++#define BM_AUDIOIN_MICLINE_MIC_RESISTOR 0x00300000
++#define BF_AUDIOIN_MICLINE_MIC_RESISTOR(v) \
++ (((v) << 20) & BM_AUDIOIN_MICLINE_MIC_RESISTOR)
++#define BM_AUDIOIN_MICLINE_RSRVD3 0x00080000
++#define BP_AUDIOIN_MICLINE_MIC_BIAS 16
++#define BM_AUDIOIN_MICLINE_MIC_BIAS 0x00070000
++#define BF_AUDIOIN_MICLINE_MIC_BIAS(v) \
++ (((v) << 16) & BM_AUDIOIN_MICLINE_MIC_BIAS)
++#define BP_AUDIOIN_MICLINE_RSRVD2 6
++#define BM_AUDIOIN_MICLINE_RSRVD2 0x0000FFC0
++#define BF_AUDIOIN_MICLINE_RSRVD2(v) \
++ (((v) << 6) & BM_AUDIOIN_MICLINE_RSRVD2)
++#define BP_AUDIOIN_MICLINE_MIC_CHOPCLK 4
++#define BM_AUDIOIN_MICLINE_MIC_CHOPCLK 0x00000030
++#define BF_AUDIOIN_MICLINE_MIC_CHOPCLK(v) \
++ (((v) << 4) & BM_AUDIOIN_MICLINE_MIC_CHOPCLK)
++#define BP_AUDIOIN_MICLINE_RSRVD1 2
++#define BM_AUDIOIN_MICLINE_RSRVD1 0x0000000C
++#define BF_AUDIOIN_MICLINE_RSRVD1(v) \
++ (((v) << 2) & BM_AUDIOIN_MICLINE_RSRVD1)
++#define BP_AUDIOIN_MICLINE_MIC_GAIN 0
++#define BM_AUDIOIN_MICLINE_MIC_GAIN 0x00000003
++#define BF_AUDIOIN_MICLINE_MIC_GAIN(v) \
++ (((v) << 0) & BM_AUDIOIN_MICLINE_MIC_GAIN)
++
++#define HW_AUDIOIN_ANACLKCTRL (0x00000070)
++#define HW_AUDIOIN_ANACLKCTRL_SET (0x00000074)
++#define HW_AUDIOIN_ANACLKCTRL_CLR (0x00000078)
++#define HW_AUDIOIN_ANACLKCTRL_TOG (0x0000007c)
++
++#define BM_AUDIOIN_ANACLKCTRL_CLKGATE 0x80000000
++#define BP_AUDIOIN_ANACLKCTRL_RSRVD4 11
++#define BM_AUDIOIN_ANACLKCTRL_RSRVD4 0x7FFFF800
++#define BF_AUDIOIN_ANACLKCTRL_RSRVD4(v) \
++ (((v) << 11) & BM_AUDIOIN_ANACLKCTRL_RSRVD4)
++#define BM_AUDIOIN_ANACLKCTRL_DITHER_OFF 0x00000400
++#define BM_AUDIOIN_ANACLKCTRL_SLOW_DITHER 0x00000200
++#define BM_AUDIOIN_ANACLKCTRL_INVERT_ADCCLK 0x00000100
++#define BP_AUDIOIN_ANACLKCTRL_RSRVD3 6
++#define BM_AUDIOIN_ANACLKCTRL_RSRVD3 0x000000C0
++#define BF_AUDIOIN_ANACLKCTRL_RSRVD3(v) \
++ (((v) << 6) & BM_AUDIOIN_ANACLKCTRL_RSRVD3)
++#define BP_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 4
++#define BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 0x00000030
++#define BF_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT(v) \
++ (((v) << 4) & BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT)
++#define BM_AUDIOIN_ANACLKCTRL_RSRVD2 0x00000008
++#define BP_AUDIOIN_ANACLKCTRL_ADCDIV 0
++#define BM_AUDIOIN_ANACLKCTRL_ADCDIV 0x00000007
++#define BF_AUDIOIN_ANACLKCTRL_ADCDIV(v) \
++ (((v) << 0) & BM_AUDIOIN_ANACLKCTRL_ADCDIV)
++
++#define HW_AUDIOIN_DATA (0x00000080)
++#define HW_AUDIOIN_DATA_SET (0x00000084)
++#define HW_AUDIOIN_DATA_CLR (0x00000088)
++#define HW_AUDIOIN_DATA_TOG (0x0000008c)
++
++#define BP_AUDIOIN_DATA_HIGH 16
++#define BM_AUDIOIN_DATA_HIGH 0xFFFF0000
++#define BF_AUDIOIN_DATA_HIGH(v) \
++ (((v) << 16) & BM_AUDIOIN_DATA_HIGH)
++#define BP_AUDIOIN_DATA_LOW 0
++#define BM_AUDIOIN_DATA_LOW 0x0000FFFF
++#define BF_AUDIOIN_DATA_LOW(v) \
++ (((v) << 0) & BM_AUDIOIN_DATA_LOW)
++
++#define BV_AUDIOIN_ADCVOL_SELECT__MIC 0x00
++
++#endif /* __MXS_ADC_CODEC_H */
+--- a/sound/soc/mxs/Kconfig
++++ b/sound/soc/mxs/Kconfig
+@@ -18,3 +18,13 @@ config SND_SOC_MXS_SGTL5000
+ a sgtl5000 codec.
+
+ endif # SND_MXS_SOC
++
++
++config SND_MXS_SOC_BUILTIN
++ tristate "SoC Audio for Freescale i.MX23 built-in codec"
++ depends on ARCH_MXS
++ select SND_SOC_GENERIC_DMAENGINE_PCM
++ select SND_SOC_MXS_BUILTIN_CODEC
++ help
++ Say Y or M if you want to add support for codecs attached to
++ the MXS SAIF interface.
+--- a/sound/soc/mxs/Makefile
++++ b/sound/soc/mxs/Makefile
+@@ -8,3 +8,12 @@ obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs
+ snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
+
+ obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
++
++# i.MX23 built-in audio Machine and Platform support
++snd-soc-mxs-builtin-pcm-objs := mxs-builtin-pcm.o
++snd-soc-mxs-builtin-dai-objs := mxs-builtin-dai.o
++snd-soc-mxs-builtin-audio-objs := mxs-builtin-audio.o
++
++obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-pcm.o
++obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-dai.o
++obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-audio.o
+--- /dev/null
++++ b/sound/soc/mxs/mxs-builtin-audio.c
+@@ -0,0 +1,120 @@
++/*
++ * mxs-builtin-audio.c -- i.MX233 built-in codec ALSA Soc Audio driver
++ *
++ * Author: Michal Ulianko <michal.ulianko@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/jack.h>
++#include <sound/soc-dapm.h>
++#include <asm/mach-types.h>
++
++static struct snd_soc_dai_link mxs_adc_dai_link[] = {
++ {
++ .name = "MXS ADC/DAC",
++ .stream_name = "MXS ADC/DAC",
++ .codec_dai_name = "mxs-builtin-codec-dai",
++// .codec_name = "mxs-builtin-codec",
++// .cpu_dai_name = "mxs-builtin-cpu-dai",
++// .platform_name = "mxs-builtin-cpu-dai",
++// .ops = &mxs_sgtl5000_hifi_ops,
++ },
++};
++
++static struct snd_soc_card mxs_adc_audio = {
++ .name = "mxs-builtin-audio",
++ .owner = THIS_MODULE,
++ .dai_link = mxs_adc_dai_link,
++ .num_links = ARRAY_SIZE(mxs_adc_dai_link),
++};
++
++static int mxsadc_audio_probe_dt(struct platform_device *pdev)
++{
++ struct device_node *np = pdev->dev.of_node;
++ struct device_node *cpu_dai_np, *codec_np;
++ int ret = 0;
++
++ if (!np)
++ return 1; /* no device tree */
++
++ cpu_dai_np = of_parse_phandle(np, "cpu-dai", 0);
++ codec_np = of_parse_phandle(np, "audio-codec", 0);
++ if (!cpu_dai_np || !codec_np) {
++ dev_err(&pdev->dev, "phandle missing or invalid\n");
++ return -EINVAL;
++ }
++
++ mxs_adc_dai_link[0].codec_name = NULL;
++ mxs_adc_dai_link[0].codec_of_node = codec_np;
++ mxs_adc_dai_link[0].cpu_dai_name = NULL;
++ mxs_adc_dai_link[0].cpu_of_node = cpu_dai_np;
++ mxs_adc_dai_link[0].platform_name = NULL;
++ mxs_adc_dai_link[0].platform_of_node = cpu_dai_np;
++
++// of_node_put(codec_np);
++// of_node_put(cpu_dai_np);
++
++ return ret;
++}
++
++static int mxsadc_audio_probe(struct platform_device *pdev)
++{
++ struct snd_soc_card *card = &mxs_adc_audio;
++ int ret;
++
++ ret = mxsadc_audio_probe_dt(pdev);
++ if (ret < 0)
++ return ret;
++
++ card->dev = &pdev->dev;
++ platform_set_drvdata(pdev, card);
++
++ ret = snd_soc_register_card(card);
++ if (ret) {
++ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int mxsadc_audio_remove(struct platform_device *pdev)
++{
++ struct snd_soc_card *card = platform_get_drvdata(pdev);
++
++ snd_soc_unregister_card(card);
++
++ return 0;
++}
++
++static const struct of_device_id mxs_adc_audio_dt_ids[] = {
++ { .compatible = "fsl,mxs-builtin-audio", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mxs_adc_audio_dt_ids);
++
++static struct platform_driver mxs_adc_audio_driver = {
++ .driver = {
++ .name = "mxs-builtin-audio",
++ .owner = THIS_MODULE,
++ .of_match_table = mxs_adc_audio_dt_ids,
++ },
++ .probe = mxsadc_audio_probe,
++ .remove = mxsadc_audio_remove,
++};
++
++module_platform_driver(mxs_adc_audio_driver);
++
++MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Machine Driver");
++MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/sound/soc/mxs/mxs-builtin-dai.c
+@@ -0,0 +1,588 @@
++/*
++ * mxs-builtin-dai.c -- i.MX233 built-in codec ALSA Soc Audio driver
++ *
++ * Author: Michal Ulianko <michal.ulianko@gmail.com>
++ *
++ * Based on sound/soc/mxs/mxs-adc.c for kernel 2.6.35
++ * by Vladislav Buzov <vbuzov@embeddedalley.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++
++#include "../codecs/mxs-builtin-codec.h"
++#include "mxs-builtin-pcm.h"
++
++#define ADC_VOLUME_MIN 0x37
++
++/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */
++
++// TODO use container_of
++struct mxs_irq_data {
++ struct snd_pcm_substream *substream;
++ struct mxs_adc_priv *mxs_adc;
++};
++
++struct mxs_adc_priv {
++ struct mxs_irq_data irq_data;
++ int dma_adc_err_irq;
++ int dma_dac_err_irq;
++ int hp_short_irq;
++ void __iomem *audioin_base;
++ void __iomem *audioout_base;
++ void __iomem *rtc_base;
++};
++
++typedef struct {
++ struct work_struct work;
++ struct timer_list timer;
++
++ /* target workqueue and CPU ->timer uses to queue ->work */
++ struct workqueue_struct *wq;
++ int cpu;
++
++ struct mxs_adc_priv *mxs_adc;
++} my_delayed_work_t;
++
++// static struct delayed_work work;
++// static struct delayed_work adc_ramp_work;
++// static struct delayed_work dac_ramp_work;
++// static struct delayed_work test;
++static my_delayed_work_t work;
++static my_delayed_work_t adc_ramp_work;
++static my_delayed_work_t dac_ramp_work;
++static my_delayed_work_t test;
++static bool adc_ramp_done = 1;
++static bool dac_ramp_done = 1;
++
++static inline void mxs_adc_schedule_work(struct delayed_work *work)
++{
++ schedule_delayed_work(work, HZ / 10);
++}
++
++static void mxs_adc_work(struct work_struct *work)
++{
++ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
++ /* disable irq */
++ disable_irq(mxs_adc->hp_short_irq);
++
++ while (true) {
++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR);
++ msleep(10);
++ if ((__raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL)
++ & BM_AUDIOOUT_ANACTRL_SHORT_LR_STS) != 0) {
++ /* rearm the short protection */
++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR,
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1),
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
++
++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET);
++ printk(KERN_WARNING "WARNING : Headphone LR short!\r\n");
++ } else {
++ printk(KERN_WARNING "INFO : Headphone LR no longer short!\r\n");
++ break;
++ }
++ msleep(1000);
++ }
++
++ /* power up the HEADPHONE and un-mute the HPVOL */
++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR);
++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR);
++
++ /* enable irq for next short detect*/
++ enable_irq(mxs_adc->hp_short_irq);
++}
++
++static void mxs_adc_schedule_ramp_work(struct delayed_work *work)
++{
++ schedule_delayed_work(work, msecs_to_jiffies(2));
++ adc_ramp_done = 0;
++}
++
++static void mxs_adc_ramp_work(struct work_struct *work)
++{
++ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
++ u32 reg = 0;
++ u32 reg1 = 0;
++ u32 reg2 = 0;
++ u32 l, r;
++ u32 ll, rr;
++ int i;
++
++ reg = __raw_readl(mxs_adc->audioin_base + \
++ HW_AUDIOIN_ADCVOLUME);
++
++ reg1 = reg & ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
++ reg1 = reg1 & ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
++ /* minimize adc volume */
++ reg2 = reg1 |
++ BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ADC_VOLUME_MIN) |
++ BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(ADC_VOLUME_MIN);
++ __raw_writel(reg2,
++ mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME);
++ msleep(1);
++
++ l = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT) >>
++ BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT;
++ r = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT) >>
++ BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT;
++
++ /* fade in adc vol */
++ for (i = ADC_VOLUME_MIN; (i < l) || (i < r);) {
++ i += 0x8;
++ ll = i < l ? i : l;
++ rr = i < r ? i : r;
++ reg2 = reg1 |
++ BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ll) |
++ BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(rr);
++ __raw_writel(reg2,
++ mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME);
++ msleep(1);
++ }
++ adc_ramp_done = 1;
++}
++
++static void mxs_dac_schedule_ramp_work(struct delayed_work *work)
++{
++ schedule_delayed_work(work, msecs_to_jiffies(2));
++ dac_ramp_done = 0;
++}
++
++static void mxs_dac_ramp_work(struct work_struct *work)
++{
++ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc;
++ u32 reg = 0;
++ u32 reg1 = 0;
++ u32 l, r;
++ u32 ll, rr;
++ int i;
++
++ /* unmute hp and speaker */
++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR);
++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_CLR);
++
++ reg = __raw_readl(mxs_adc->audioout_base + \
++ HW_AUDIOOUT_HPVOL);
++
++ reg1 = reg & ~BM_AUDIOOUT_HPVOL_VOL_LEFT;
++ reg1 = reg1 & ~BM_AUDIOOUT_HPVOL_VOL_RIGHT;
++
++ l = (reg & BM_AUDIOOUT_HPVOL_VOL_LEFT) >>
++ BP_AUDIOOUT_HPVOL_VOL_LEFT;
++ r = (reg & BM_AUDIOOUT_HPVOL_VOL_RIGHT) >>
++ BP_AUDIOOUT_HPVOL_VOL_RIGHT;
++ /* fade in hp vol */
++ for (i = 0x7f; i > 0 ;) {
++ i -= 0x8;
++ ll = i > (int)l ? i : l;
++ rr = i > (int)r ? i : r;
++ reg = reg1 | BF_AUDIOOUT_HPVOL_VOL_LEFT(ll)
++ | BF_AUDIOOUT_HPVOL_VOL_RIGHT(rr);
++ __raw_writel(reg,
++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL);
++ msleep(1);
++ }
++ dac_ramp_done = 1;
++}
++
++/* IRQs */
++static irqreturn_t mxs_short_irq(int irq, void *dev_id)
++{
++ struct mxs_adc_priv *mxs_adc = dev_id;
++ //struct snd_pcm_substream *substream = mxs_adc->irq_data.substream;
++
++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR,
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS,
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR);
++ __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1),
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
++
++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET);
++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET);
++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET);
++
++ mxs_adc_schedule_work((struct delayed_work *) &work);
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t mxs_err_irq(int irq, void *dev_id)
++{
++ struct mxs_adc_priv *mxs_adc = dev_id;
++ struct snd_pcm_substream *substream = mxs_adc->irq_data.substream;
++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
++ u32 ctrl_reg;
++ u32 overflow_mask;
++ u32 underflow_mask;
++
++ if (playback) {
++ ctrl_reg = __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL);
++ underflow_mask = BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ;
++ overflow_mask = BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ;
++ } else {
++ ctrl_reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_CTRL);
++ underflow_mask = BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ;
++ overflow_mask = BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ;
++ }
++
++ if (ctrl_reg & underflow_mask) {
++ printk(KERN_DEBUG "%s underflow detected\n",
++ playback ? "DAC" : "ADC");
++
++ if (playback)
++ __raw_writel(
++ BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
++ else
++ __raw_writel(
++ BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
++
++ } else if (ctrl_reg & overflow_mask) {
++ printk(KERN_DEBUG "%s overflow detected\n",
++ playback ? "DAC" : "ADC");
++
++ if (playback)
++ __raw_writel(
++ BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
++ else
++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
++ } else
++ printk(KERN_WARNING "Unknown DAC error interrupt\n");
++
++ return IRQ_HANDLED;
++}
++/* END IRQs */
++
++static int mxs_trigger(struct snd_pcm_substream *substream,
++ int cmd,
++ struct snd_soc_dai *cpu_dai)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
++ int ret = 0;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++
++ if (playback) {
++ /* enable the fifo error interrupt */
++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_SET);
++ /* write a data to data reg to trigger the transfer */
++ __raw_writel(0x0,
++ mxs_adc->audioout_base + HW_AUDIOOUT_DATA);
++ mxs_dac_schedule_ramp_work((struct delayed_work *) &dac_ramp_work);
++ } else {
++// mxs_dma_get_info(prtd->dma_ch, &dma_info);
++// cur_bar1 = dma_info.buf_addr;
++// xfer_count1 = dma_info.xfer_count;
++
++ __raw_writel(BM_AUDIOIN_CTRL_RUN,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET);
++ udelay(100);
++
++// mxs_dma_get_info(prtd->dma_ch, &dma_info);
++// cur_bar2 = dma_info.buf_addr;
++// xfer_count2 = dma_info.xfer_count;
++//
++// /* check if DMA getting stuck */
++// if ((xfer_count1 == xfer_count2) && (cur_bar1 == cur_bar2))
++// /* read a data from data reg to trigger the receive */
++// reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_DATA);
++
++ mxs_adc_schedule_ramp_work((struct delayed_work *) &adc_ramp_work);
++ }
++ break;
++
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++
++ if (playback) {
++// printk(KERN_INFO "SNDRV_PCM_TRIGGER_START\n");
++// printk(KERN_INFO "ctrl:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL));
++// printk(KERN_INFO "stat:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_STAT));
++// printk(KERN_INFO "srr:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACSRR));
++// printk(KERN_INFO "vol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACVOLUME));
++// printk(KERN_INFO "debug:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACDEBUG));
++// printk(KERN_INFO "hpvol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL));
++// printk(KERN_INFO "pwrdn:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN));
++// printk(KERN_INFO "refc:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_REFCTRL));
++// printk(KERN_INFO "anac:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL));
++// printk(KERN_INFO "test:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_TEST));
++// printk(KERN_INFO "bist:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_BISTCTRL));
++// printk(KERN_INFO "anaclk:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACLKCTRL));
++
++ if (dac_ramp_done == 0) {
++ cancel_delayed_work((struct delayed_work *) &dac_ramp_work);
++ dac_ramp_done = 1;
++ }
++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET);
++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
++ mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_SET);
++ /* disable the fifo error interrupt */
++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
++ mdelay(50);
++ } else {
++ if (adc_ramp_done == 0) {
++ cancel_delayed_work((struct delayed_work *) &adc_ramp_work);
++ adc_ramp_done = 1;
++ }
++ __raw_writel(BM_AUDIOIN_CTRL_RUN,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
++ }
++ break;
++
++ default:
++ printk(KERN_ERR "TRIGGER ERROR\n");
++ ret = -EINVAL;
++ }
++
++ return ret;
++}
++
++static int mxs_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *cpu_dai)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
++ mxs_adc->irq_data.mxs_adc = mxs_adc;
++ mxs_adc->irq_data.substream = substream;
++
++ work.mxs_adc = mxs_adc;
++ adc_ramp_work.mxs_adc = mxs_adc;
++ dac_ramp_work.mxs_adc = mxs_adc;
++ test.mxs_adc = mxs_adc;
++ INIT_DELAYED_WORK(&work, mxs_adc_work);
++ INIT_DELAYED_WORK(&adc_ramp_work, mxs_adc_ramp_work);
++ INIT_DELAYED_WORK(&dac_ramp_work, mxs_dac_ramp_work);
++
++ /* Enable error interrupt */
++ if (playback) {
++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
++ } else {
++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET);
++ }
++
++ return 0;
++}
++
++static void mxs_shutdown(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *cpu_dai)
++{
++ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai);
++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
++
++ /* Disable error interrupt */
++ if (playback) {
++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR);
++ } else {
++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR);
++ }
++}
++
++#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
++#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
++
++static const struct snd_soc_dai_ops mxs_adc_dai_ops = {
++ .startup = mxs_startup,
++ .trigger = mxs_trigger,
++ .shutdown = mxs_shutdown,
++};
++
++static int mxs_dai_probe(struct snd_soc_dai *dai)
++{
++ // TODO This does not make any sense.
++ struct mxs_adc_priv *mxs_adc = dev_get_drvdata(dai->dev);
++
++ snd_soc_dai_set_drvdata(dai, mxs_adc);
++
++ return 0;
++}
++
++static struct snd_soc_dai_driver mxs_adc_dai = {
++ .name = "mxs-builtin-cpu-dai",
++ .probe = mxs_dai_probe,
++ .playback = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = MXS_ADC_RATES,
++ .formats = MXS_ADC_FORMATS,
++ },
++ .capture = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = MXS_ADC_RATES,
++ .formats = MXS_ADC_FORMATS,
++ },
++ .ops = &mxs_adc_dai_ops,
++};
++
++static const struct snd_soc_component_driver mxs_adc_component = {
++ .name = "mxs-xxx", //TODO change this name
++};
++
++static int mxs_adc_probe(struct platform_device *pdev)
++{
++ struct device_node *np = pdev->dev.of_node;
++ struct mxs_adc_priv *mxs_adc;
++ int ret = 0;
++
++ if (!np)
++ return -EINVAL;
++
++ mxs_adc = devm_kzalloc(&pdev->dev, sizeof(*mxs_adc), GFP_KERNEL);
++ if (!mxs_adc)
++ return -ENOMEM;
++
++ mxs_adc->audioout_base = devm_ioremap(&pdev->dev, 0x80048000, 0x2000);
++ if (IS_ERR(mxs_adc->audioout_base))
++ return PTR_ERR(mxs_adc->audioout_base);
++
++ mxs_adc->audioin_base = devm_ioremap(&pdev->dev, 0x8004c000, 0x2000);
++ if (IS_ERR(mxs_adc->audioin_base))
++ return PTR_ERR(mxs_adc->audioin_base);
++
++ mxs_adc->rtc_base = devm_ioremap(&pdev->dev, 0x8005c000, 0x2000);
++ if (IS_ERR(mxs_adc->rtc_base))
++ return PTR_ERR(mxs_adc->rtc_base);
++
++ /* Get IRQ numbers */
++ mxs_adc->dma_adc_err_irq = platform_get_irq(pdev, 0);
++ if (mxs_adc->dma_adc_err_irq < 0) {
++ ret = mxs_adc->dma_adc_err_irq;
++ dev_err(&pdev->dev, "failed to get ADC DMA ERR irq resource: %d\n", ret);
++ return ret;
++ }
++
++ mxs_adc->dma_dac_err_irq = platform_get_irq(pdev, 1);
++ if (mxs_adc->dma_dac_err_irq < 0) {
++ ret = mxs_adc->dma_dac_err_irq;
++ dev_err(&pdev->dev, "failed to get DAC DMA ERR irq resource: %d\n", ret);
++ return ret;
++ }
++
++ mxs_adc->hp_short_irq = platform_get_irq(pdev, 2);
++ if (mxs_adc->hp_short_irq < 0) {
++ ret = mxs_adc->hp_short_irq;
++ dev_err(&pdev->dev, "failed to get HP_SHORT irq resource: %d\n", ret);
++ return ret;
++ }
++
++ /* Request IRQs */
++ ret = devm_request_irq(&pdev->dev, mxs_adc->dma_adc_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error",
++ mxs_adc);
++ if (ret) {
++ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
++ __func__, mxs_adc->dma_adc_err_irq);
++ return ret;
++ }
++
++ ret = devm_request_irq(&pdev->dev, mxs_adc->dma_dac_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error",
++ mxs_adc);
++ if (ret) {
++ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
++ __func__, mxs_adc->dma_dac_err_irq);
++ return ret;
++ }
++
++ ret = devm_request_irq(&pdev->dev, mxs_adc->hp_short_irq, mxs_short_irq,
++ IRQF_DISABLED | IRQF_SHARED, "MXS DAC and ADC HP SHORT", mxs_adc);
++ if (ret) {
++ printk(KERN_ERR "%s: Unable to request ADC/DAC HP SHORT irq %d\n",
++ __func__, mxs_adc->hp_short_irq);
++ return ret;
++ }
++
++ platform_set_drvdata(pdev, mxs_adc);
++
++ ret = snd_soc_register_component(&pdev->dev, &mxs_adc_component, &mxs_adc_dai, 1);
++ if (ret) {
++ dev_err(&pdev->dev, "register DAI failed\n");
++ return ret;
++ }
++
++ ret = mxs_adc_pcm_platform_register(&pdev->dev);
++ if (ret) {
++ dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
++ goto failed_pdev_alloc;
++ }
++
++ return 0;
++
++failed_pdev_alloc:
++ snd_soc_unregister_component(&pdev->dev);
++
++ return ret;
++}
++
++static int mxs_adc_remove(struct platform_device *pdev)
++{
++ mxs_adc_pcm_platform_unregister(&pdev->dev);
++ snd_soc_unregister_component(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id mxs_adc_dai_dt_ids[] = {
++ { .compatible = "fsl,mxs-builtin-cpu-dai", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mxs_adc_dai_dt_ids);
++
++static struct platform_driver mxs_adc_dai_driver = {
++ .probe = mxs_adc_probe,
++ .remove = mxs_adc_remove,
++
++ .driver = {
++ .name = "mxs-builtin-cpu-dai",
++ .owner = THIS_MODULE,
++ .of_match_table = mxs_adc_dai_dt_ids,
++ },
++};
++
++module_platform_driver(mxs_adc_dai_driver);
++
++MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec DAI Driver");
++MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/sound/soc/mxs/mxs-builtin-pcm.c
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ * Based on sound/soc/imx/imx-pcm-dma-mx2.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/dmaengine_pcm.h>
++
++#include "mxs-builtin-pcm.h"
++
++static const struct snd_pcm_hardware snd_mxs_hardware = {
++ .info = SNDRV_PCM_INFO_MMAP |
++ SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_PAUSE |
++ SNDRV_PCM_INFO_RESUME |
++ SNDRV_PCM_INFO_INTERLEAVED,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE |
++ SNDRV_PCM_FMTBIT_S20_3LE |
++ SNDRV_PCM_FMTBIT_S24_LE,
++ .channels_min = 2,
++ .channels_max = 2,
++ .period_bytes_min = 32,
++ .period_bytes_max = 8192,
++ .periods_min = 1,
++ .periods_max = 52,
++ .buffer_bytes_max = 64 * 1024,
++ .fifo_size = 32,
++};
++
++static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
++ .pcm_hardware = &snd_mxs_hardware,
++ .prealloc_buffer_size = 64 * 1024,
++};
++
++int mxs_adc_pcm_platform_register(struct device *dev)
++{
++ return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
++ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
++}
++EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_register);
++
++void mxs_adc_pcm_platform_unregister(struct device *dev)
++{
++ snd_dmaengine_pcm_unregister(dev);
++}
++EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_unregister);
++
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/sound/soc/mxs/mxs-builtin-pcm.h
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#ifndef _MXS_PCM_H
++#define _MXS_PCM_H
++
++int mxs_adc_pcm_platform_register(struct device *dev);
++void mxs_adc_pcm_platform_unregister(struct device *dev);
++
++#endif
--- /dev/null
+--- a/arch/arm/boot/dts/imx23-olinuxino.dts
++++ b/arch/arm/boot/dts/imx23-olinuxino.dts
+@@ -84,6 +84,25 @@
+ usbphy0: usbphy@8007c000 {
+ status = "okay";
+ };
++
++ codec: mxs-builtin-codec {
++ compatible = "fsl,mxs-builtin-codec";
++ reg = <0x80048000 0x2000>, <0x8004c000 0x2000>,
++ <0x8005c000 0x2000>;
++ reg-names = "audioout", "audioin", "rtc";
++ clocks = <&clks 31>;
++ clock-names = "filt";
++ };
++
++ platform_dai: mxs-builtin-cpu-dai {
++ compatible = "fsl,mxs-builtin-cpu-dai";
++ reg = <0x80048000 0x2000>, <0x8004c000 0x2000>,
++ <0x8005c000 0x2000>;
++ reg-names = "audioout", "audioin", "rtc";
++ interrupts = <8 6 4>;
++ dmas = <&dma_apbx 0>, <&dma_apbx 1>;
++ dma-names = "rx", "tx";
++ };
+ };
+ };
+
+@@ -118,4 +137,10 @@
+ gpios = <&gpio2 1 1>;
+ };
+ };
++
++ mxs-builtin-audio {
++ compatible = "fsl,mxs-builtin-audio";
++ audio-codec = <&codec>;
++ cpu-dai = <&platform_dai>;
++ };
+ };
--- /dev/null
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -287,6 +287,16 @@ config CRYPTO_DEV_SAHARA
+ This option enables support for the SAHARA HW crypto accelerator
+ found in some Freescale i.MX chips.
+
++config CRYPTO_DEV_DCP
++ tristate "Support for the DCP engine"
++ depends on ARCH_MXS && OF
++ select CRYPTO_BLKCIPHER
++ select CRYPTO_AES
++ select CRYPTO_CBC
++ help
++ This options enables support for the hardware crypto-acceleration
++ capabilities of the DCP co-processor
++
+ config CRYPTO_DEV_S5P
+ tristate "Support for Samsung S5PV210 crypto accelerator"
+ depends on ARCH_S5PV210
+--- a/drivers/crypto/Makefile
++++ b/drivers/crypto/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += om
+ obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
+ obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
+ obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
++obj-$(CONFIG_CRYPTO_DEV_DCP) += dcp.o
+ obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
+ obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o
+ obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
+--- /dev/null
++++ b/drivers/crypto/dcp.c
+@@ -0,0 +1,925 @@
++/*
++ * Cryptographic API.
++ *
++ * Support for DCP cryptographic accelerator.
++ *
++ * Copyright (c) 2013
++ * Author: Tobias Rauter <tobias.rau...@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Based on tegra-aes.c, dcp.c (from freescale SDK) and sahara.c
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/io.h>
++#include <linux/mutex.h>
++#include <linux/interrupt.h>
++#include <linux/completion.h>
++#include <linux/workqueue.h>
++#include <linux/delay.h>
++#include <linux/crypto.h>
++#include <linux/miscdevice.h>
++
++#include <crypto/scatterwalk.h>
++#include <crypto/aes.h>
++
++
++/* IOCTL for DCP OTP Key AES - taken from Freescale's SDK*/
++#define DBS_IOCTL_BASE 'd'
++#define DBS_ENC _IOW(DBS_IOCTL_BASE, 0x00, uint8_t[16])
++#define DBS_DEC _IOW(DBS_IOCTL_BASE, 0x01, uint8_t[16])
++
++/* DCP channel used for AES */
++#define USED_CHANNEL 1
++/* Ring Buffers' maximum size */
++#define DCP_MAX_PKG 20
++
++/* Control Register */
++#define DCP_REG_CTRL 0x000
++#define DCP_CTRL_SFRST (1<<31)
++#define DCP_CTRL_CLKGATE (1<<30)
++#define DCP_CTRL_CRYPTO_PRESENT (1<<29)
++#define DCP_CTRL_SHA_PRESENT (1<<28)
++#define DCP_CTRL_GATHER_RES_WRITE (1<<23)
++#define DCP_CTRL_ENABLE_CONTEXT_CACHE (1<<22)
++#define DCP_CTRL_ENABLE_CONTEXT_SWITCH (1<<21)
++#define DCP_CTRL_CH_IRQ_E_0 0x01
++#define DCP_CTRL_CH_IRQ_E_1 0x02
++#define DCP_CTRL_CH_IRQ_E_2 0x04
++#define DCP_CTRL_CH_IRQ_E_3 0x08
++
++/* Status register */
++#define DCP_REG_STAT 0x010
++#define DCP_STAT_OTP_KEY_READY (1<<28)
++#define DCP_STAT_CUR_CHANNEL(stat) ((stat>>24)&0x0F)
++#define DCP_STAT_READY_CHANNEL(stat) ((stat>>16)&0x0F)
++#define DCP_STAT_IRQ(stat) (stat&0x0F)
++#define DCP_STAT_CHAN_0 (0x01)
++#define DCP_STAT_CHAN_1 (0x02)
++#define DCP_STAT_CHAN_2 (0x04)
++#define DCP_STAT_CHAN_3 (0x08)
++
++/* Channel Control Register */
++#define DCP_REG_CHAN_CTRL 0x020
++#define DCP_CHAN_CTRL_CH0_IRQ_MERGED (1<<16)
++#define DCP_CHAN_CTRL_HIGH_PRIO_0 (0x0100)
++#define DCP_CHAN_CTRL_HIGH_PRIO_1 (0x0200)
++#define DCP_CHAN_CTRL_HIGH_PRIO_2 (0x0400)
++#define DCP_CHAN_CTRL_HIGH_PRIO_3 (0x0800)
++#define DCP_CHAN_CTRL_ENABLE_0 (0x01)
++#define DCP_CHAN_CTRL_ENABLE_1 (0x02)
++#define DCP_CHAN_CTRL_ENABLE_2 (0x04)
++#define DCP_CHAN_CTRL_ENABLE_3 (0x08)
++
++/*
++ * Channel Registers:
++ * The DCP has 4 channels. Each of this channels
++ * has 4 registers (command pointer, semaphore, status and options).
++ * The address of register REG of channel CHAN is obtained by
++ * dcp_chan_reg(REG, CHAN)
++ */
++#define DCP_REG_CHAN_PTR 0x00000100
++#define DCP_REG_CHAN_SEMA 0x00000110
++#define DCP_REG_CHAN_STAT 0x00000120
++#define DCP_REG_CHAN_OPT 0x00000130
++
++#define DCP_CHAN_STAT_NEXT_CHAIN_IS_0 0x010000
++#define DCP_CHAN_STAT_NO_CHAIN 0x020000
++#define DCP_CHAN_STAT_CONTEXT_ERROR 0x030000
++#define DCP_CHAN_STAT_PAYLOAD_ERROR 0x040000
++#define DCP_CHAN_STAT_INVALID_MODE 0x050000
++#define DCP_CHAN_STAT_PAGEFAULT 0x40
++#define DCP_CHAN_STAT_DST 0x20
++#define DCP_CHAN_STAT_SRC 0x10
++#define DCP_CHAN_STAT_PACKET 0x08
++#define DCP_CHAN_STAT_SETUP 0x04
++#define DCP_CHAN_STAT_MISMATCH 0x02
++
++/* hw packet control*/
++
++#define DCP_PKT_PAYLOAD_KEY (1<<11)
++#define DCP_PKT_OTP_KEY (1<<10)
++#define DCP_PKT_CIPHER_INIT (1<<9)
++#define DCP_PKG_CIPHER_ENCRYPT (1<<8)
++#define DCP_PKT_CIPHER_ENABLE (1<<5)
++#define DCP_PKT_DECR_SEM (1<<1)
++#define DCP_PKT_CHAIN (1<<2)
++#define DCP_PKT_IRQ 1
++
++#define DCP_PKT_MODE_CBC (1<<4)
++#define DCP_PKT_KEYSELECT_OTP (0xFF<<8)
++
++/* cipher flags */
++#define DCP_ENC 0x0001
++#define DCP_DEC 0x0002
++#define DCP_ECB 0x0004
++#define DCP_CBC 0x0008
++#define DCP_CBC_INIT 0x0010
++#define DCP_NEW_KEY 0x0040
++#define DCP_OTP_KEY 0x0080
++#define DCP_AES 0x1000
++
++/* DCP Flags */
++#define DCP_FLAG_BUSY 0x01
++#define DCP_FLAG_PRODUCING 0x02
++
++/* clock defines */
++#define CLOCK_ON 1
++#define CLOCK_OFF 0
++
++struct dcp_dev_req_ctx {
++ int mode;
++};
++
++struct dcp_op {
++ unsigned int flags;
++ u8 key[AES_KEYSIZE_128];
++ int keylen;
++
++ struct ablkcipher_request *req;
++ struct crypto_ablkcipher *fallback;
++
++ uint32_t stat;
++ uint32_t pkt1;
++ uint32_t pkt2;
++ struct ablkcipher_walk walk;
++};
++
++struct dcp_dev {
++ struct device *dev;
++ void __iomem *dcp_regs_base;
++
++ int dcp_vmi_irq;
++ int dcp_irq;
++
++ spinlock_t queue_lock;
++ struct crypto_queue queue;
++
++ uint32_t pkt_produced;
++ uint32_t pkt_consumed;
++
++ struct dcp_hw_packet *hw_pkg[DCP_MAX_PKG];
++ dma_addr_t hw_phys_pkg;
++
++ /* [KEY][IV] Both with 16 Bytes */
++ u8 *payload_base;
++ dma_addr_t payload_base_dma;
++
++
++ struct tasklet_struct done_task;
++ struct tasklet_struct queue_task;
++ struct timer_list watchdog;
++
++ unsigned long flags;
++
++ struct dcp_op *ctx;
++
++ struct miscdevice dcp_bootstream_misc;
++};
++
++struct dcp_hw_packet {
++ uint32_t next;
++ uint32_t pkt1;
++ uint32_t pkt2;
++ uint32_t src;
++ uint32_t dst;
++ uint32_t size;
++ uint32_t payload;
++ uint32_t stat;
++};
++
++struct dcp_dev *global_dev;
++
++static inline u32 dcp_chan_reg(u32 reg, int chan)
++{
++ return reg + (chan) * 0x40;
++}
++
++static inline void dcp_write(struct dcp_dev *dev, u32 data, u32 reg)
++{
++ writel(data, dev->dcp_regs_base + reg);
++}
++
++static inline void dcp_set(struct dcp_dev *dev, u32 data, u32 reg)
++{
++ writel(data, dev->dcp_regs_base + (reg | 0x04));
++}
++
++static inline void dcp_clear(struct dcp_dev *dev, u32 data, u32 reg)
++{
++ writel(data, dev->dcp_regs_base + (reg | 0x08));
++}
++
++static inline void dcp_toggle(struct dcp_dev *dev, u32 data, u32 reg)
++{
++ writel(data, dev->dcp_regs_base + (reg | 0x0C));
++}
++
++static inline unsigned int dcp_read(struct dcp_dev *dev, u32 reg)
++{
++ return readl(dev->dcp_regs_base + reg);
++}
++
++void dcp_dma_unmap(struct dcp_dev *dev, struct dcp_hw_packet *pkt)
++{
++ dma_unmap_page(dev->dev, pkt->src, pkt->size, DMA_TO_DEVICE);
++ dma_unmap_page(dev->dev, pkt->dst, pkt->size, DMA_FROM_DEVICE);
++ dev_dbg(dev->dev, "unmap packet %x", (unsigned int) pkt);
++}
++
++int dcp_dma_map(struct dcp_dev *dev,
++ struct ablkcipher_walk *walk, struct dcp_hw_packet *pkt)
++{
++ dev_dbg(dev->dev, "map packet %x", (unsigned int) pkt);
++ /* align to length = 16 */
++ pkt->size = walk->nbytes - (walk->nbytes % 16);
++
++ pkt->src = dma_map_page(dev->dev, walk->src.page, walk->src.offset,
++ pkt->size, DMA_TO_DEVICE);
++
++ if (pkt->src == 0) {
++ dev_err(dev->dev, "Unable to map src");
++ return -ENOMEM;
++ }
++
++ pkt->dst = dma_map_page(dev->dev, walk->dst.page, walk->dst.offset,
++ pkt->size, DMA_FROM_DEVICE);
++
++ if (pkt->dst == 0) {
++ dev_err(dev->dev, "Unable to map dst");
++ dma_unmap_page(dev->dev, pkt->src, pkt->size, DMA_TO_DEVICE);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void dcp_op_one(struct dcp_dev *dev, struct dcp_hw_packet *pkt,
++ uint8_t last)
++{
++ struct dcp_op *ctx = dev->ctx;
++ pkt->pkt1 = ctx->pkt1;
++ pkt->pkt2 = ctx->pkt2;
++
++ pkt->payload = (u32) dev->payload_base_dma;
++ pkt->stat = 0;
++
++ if (ctx->flags & DCP_CBC_INIT) {
++ pkt->pkt1 |= DCP_PKT_CIPHER_INIT;
++ ctx->flags &= ~DCP_CBC_INIT;
++ }
++
++ mod_timer(&dev->watchdog, jiffies + msecs_to_jiffies(500));
++ pkt->pkt1 |= DCP_PKT_IRQ;
++ if (!last)
++ pkt->pkt1 |= DCP_PKT_CHAIN;
++
++ dev->pkt_produced++;
++
++ dcp_write(dev, 1,
++ dcp_chan_reg(DCP_REG_CHAN_SEMA, USED_CHANNEL));
++}
++
++static void dcp_op_proceed(struct dcp_dev *dev)
++{
++ struct dcp_op *ctx = dev->ctx;
++ struct dcp_hw_packet *pkt;
++
++ while (ctx->walk.nbytes) {
++ int err = 0;
++
++ pkt = dev->hw_pkg[dev->pkt_produced % DCP_MAX_PKG];
++ err = dcp_dma_map(dev, &ctx->walk, pkt);
++ if (err) {
++ dev->ctx->stat |= err;
++ /* start timer to wait for already set up calls */
++ mod_timer(&dev->watchdog,
++ jiffies + msecs_to_jiffies(500));
++ break;
++ }
++
++
++ err = ctx->walk.nbytes - pkt->size;
++ ablkcipher_walk_done(dev->ctx->req, &dev->ctx->walk, err);
++
++ dcp_op_one(dev, pkt, ctx->walk.nbytes == 0);
++ /* we have to wait if no space is left in buffer */
++ if (dev->pkt_produced - dev->pkt_consumed == DCP_MAX_PKG)
++ break;
++ }
++ clear_bit(DCP_FLAG_PRODUCING, &dev->flags);
++}
++
++static void dcp_op_start(struct dcp_dev *dev, uint8_t use_walk)
++{
++ struct dcp_op *ctx = dev->ctx;
++
++ if (ctx->flags & DCP_NEW_KEY) {
++ memcpy(dev->payload_base, ctx->key, ctx->keylen);
++ ctx->flags &= ~DCP_NEW_KEY;
++ }
++
++ ctx->pkt1 = 0;
++ ctx->pkt1 |= DCP_PKT_CIPHER_ENABLE;
++ ctx->pkt1 |= DCP_PKT_DECR_SEM;
++
++ if (ctx->flags & DCP_OTP_KEY)
++ ctx->pkt1 |= DCP_PKT_OTP_KEY;
++ else
++ ctx->pkt1 |= DCP_PKT_PAYLOAD_KEY;
++
++ if (ctx->flags & DCP_ENC)
++ ctx->pkt1 |= DCP_PKG_CIPHER_ENCRYPT;
++
++ ctx->pkt2 = 0;
++ if (ctx->flags & DCP_CBC)
++ ctx->pkt2 |= DCP_PKT_MODE_CBC;
++
++ dev->pkt_produced = 0;
++ dev->pkt_consumed = 0;
++
++ ctx->stat = 0;
++ dcp_clear(dev, -1, dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
++ dcp_write(dev, (u32) dev->hw_phys_pkg,
++ dcp_chan_reg(DCP_REG_CHAN_PTR, USED_CHANNEL));
++
++ set_bit(DCP_FLAG_PRODUCING, &dev->flags);
++
++ if (use_walk) {
++ ablkcipher_walk_init(&ctx->walk, ctx->req->dst,
++ ctx->req->src, ctx->req->nbytes);
++ ablkcipher_walk_phys(ctx->req, &ctx->walk);
++ dcp_op_proceed(dev);
++ } else {
++ dcp_op_one(dev, dev->hw_pkg[0], 1);
++ clear_bit(DCP_FLAG_PRODUCING, &dev->flags);
++ }
++}
++
++static void dcp_done_task(unsigned long data)
++{
++ struct dcp_dev *dev = (struct dcp_dev *)data;
++ struct dcp_hw_packet *last_packet;
++ int fin;
++ fin = 0;
++
++ for (last_packet = dev->hw_pkg[(dev->pkt_consumed) % DCP_MAX_PKG];
++ last_packet->stat == 1;
++ last_packet =
++ dev->hw_pkg[++(dev->pkt_consumed) % DCP_MAX_PKG]) {
++
++ dcp_dma_unmap(dev, last_packet);
++ last_packet->stat = 0;
++ fin++;
++ }
++ /* the last call of this function already consumed this IRQ's packet */
++ if (fin == 0)
++ return;
++
++ dev_dbg(dev->dev,
++ "Packet(s) done with status %x; finished: %d, produced:%d, complete consumed: %d",
++ dev->ctx->stat, fin, dev->pkt_produced, dev->pkt_consumed);
++
++ last_packet = dev->hw_pkg[(dev->pkt_consumed - 1) % DCP_MAX_PKG];
++ if (!dev->ctx->stat && last_packet->pkt1 & DCP_PKT_CHAIN) {
++ if (!test_and_set_bit(DCP_FLAG_PRODUCING, &dev->flags))
++ dcp_op_proceed(dev);
++ return;
++ }
++
++ while (unlikely(dev->pkt_consumed < dev->pkt_produced)) {
++ dcp_dma_unmap(dev,
++ dev->hw_pkg[dev->pkt_consumed++ % DCP_MAX_PKG]);
++ }
++
++ if (dev->ctx->flags & DCP_OTP_KEY) {
++ /* we used the miscdevice, no walk to finish */
++ clear_bit(DCP_FLAG_BUSY, &dev->flags);
++ return;
++ }
++
++ ablkcipher_walk_complete(&dev->ctx->walk);
++ dev->ctx->req->base.complete(&dev->ctx->req->base,
++ dev->ctx->stat);
++ dev->ctx->req = 0;
++ /* in case there are other requests in the queue */
++ tasklet_schedule(&dev->queue_task);
++}
++
++void dcp_watchdog(unsigned long data)
++{
++ struct dcp_dev *dev = (struct dcp_dev *)data;
++ dev->ctx->stat |= dcp_read(dev,
++ dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
++
++ dev_err(dev->dev, "Timeout, Channel status: %x", dev->ctx->stat);
++
++ if (!dev->ctx->stat)
++ dev->ctx->stat = -ETIMEDOUT;
++
++ dcp_done_task(data);
++}
++
++
++static irqreturn_t dcp_common_irq(int irq, void *context)
++{
++ u32 msk;
++ struct dcp_dev *dev = (struct dcp_dev *) context;
++
++ del_timer(&dev->watchdog);
++
++ msk = DCP_STAT_IRQ(dcp_read(dev, DCP_REG_STAT));
++ dcp_clear(dev, msk, DCP_REG_STAT);
++ if (msk == 0)
++ return IRQ_NONE;
++
++ dev->ctx->stat |= dcp_read(dev,
++ dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
++
++ if (msk & DCP_STAT_CHAN_1)
++ tasklet_schedule(&dev->done_task);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t dcp_vmi_irq(int irq, void *context)
++{
++ return dcp_common_irq(irq, context);
++}
++
++static irqreturn_t dcp_irq(int irq, void *context)
++{
++ return dcp_common_irq(irq, context);
++}
++
++static void dcp_crypt(struct dcp_dev *dev, struct dcp_op *ctx)
++{
++ dev->ctx = ctx;
++
++ if ((ctx->flags & DCP_CBC) && ctx->req->info) {
++ ctx->flags |= DCP_CBC_INIT;
++ memcpy(dev->payload_base + AES_KEYSIZE_128,
++ ctx->req->info, AES_KEYSIZE_128);
++ }
++
++ dcp_op_start(dev, 1);
++}
++
++static void dcp_queue_task(unsigned long data)
++{
++ struct dcp_dev *dev = (struct dcp_dev *) data;
++ struct crypto_async_request *async_req, *backlog;
++ struct crypto_ablkcipher *tfm;
++ struct dcp_op *ctx;
++ struct dcp_dev_req_ctx *rctx;
++ struct ablkcipher_request *req;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dev->queue_lock, flags);
++
++ backlog = crypto_get_backlog(&dev->queue);
++ async_req = crypto_dequeue_request(&dev->queue);
++
++ spin_unlock_irqrestore(&dev->queue_lock, flags);
++
++ if (!async_req)
++ goto ret_nothing_done;
++
++ if (backlog)
++ backlog->complete(backlog, -EINPROGRESS);
++
++ req = ablkcipher_request_cast(async_req);
++ tfm = crypto_ablkcipher_reqtfm(req);
++ rctx = ablkcipher_request_ctx(req);
++ ctx = crypto_ablkcipher_ctx(tfm);
++
++ if (!req->src || !req->dst)
++ goto ret_nothing_done;
++
++ ctx->flags |= rctx->mode;
++ ctx->req = req;
++
++ dcp_crypt(dev, ctx);
++
++ return;
++
++ret_nothing_done:
++ clear_bit(DCP_FLAG_BUSY, &dev->flags);
++}
++
++
++static int dcp_cra_init(struct crypto_tfm *tfm)
++{
++ const char *name = tfm->__crt_alg->cra_name;
++ struct dcp_op *ctx = crypto_tfm_ctx(tfm);
++
++ tfm->crt_ablkcipher.reqsize = sizeof(struct dcp_dev_req_ctx);
++
++ ctx->fallback = crypto_alloc_ablkcipher(name, 0,
++ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
++
++ if (IS_ERR(ctx->fallback)) {
++ dev_err(global_dev->dev, "Error allocating fallback algo %s\n",
++ name);
++ return PTR_ERR(ctx->fallback);
++ }
++
++ return 0;
++}
++
++static void dcp_cra_exit(struct crypto_tfm *tfm)
++{
++ struct dcp_op *ctx = crypto_tfm_ctx(tfm);
++
++ if (ctx->fallback)
++ crypto_free_ablkcipher(ctx->fallback);
++
++ ctx->fallback = NULL;
++}
++
++/* async interface */
++static int dcp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
++ unsigned int len)
++{
++ struct dcp_op *ctx = crypto_ablkcipher_ctx(tfm);
++ unsigned int ret = 0;
++ ctx->keylen = len;
++ ctx->flags = 0;
++ if (len == AES_KEYSIZE_128) {
++ if (memcmp(ctx->key, key, AES_KEYSIZE_128)) {
++ memcpy(ctx->key, key, len);
++ ctx->flags |= DCP_NEW_KEY;
++ }
++ return 0;
++ }
++
++ ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
++ ctx->fallback->base.crt_flags |=
++ (tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
++
++ ret = crypto_ablkcipher_setkey(ctx->fallback, key, len);
++ if (ret) {
++ struct crypto_tfm *tfm_aux = crypto_ablkcipher_tfm(tfm);
++
++ tfm_aux->crt_flags &= ~CRYPTO_TFM_RES_MASK;
++ tfm_aux->crt_flags |=
++ (ctx->fallback->base.crt_flags & CRYPTO_TFM_RES_MASK);
++ }
++ return ret;
++}
++
++static int dcp_aes_cbc_crypt(struct ablkcipher_request *req, int mode)
++{
++ struct dcp_dev_req_ctx *rctx = ablkcipher_request_ctx(req);
++ struct dcp_dev *dev = global_dev;
++ unsigned long flags;
++ int err = 0;
++
++ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
++ return -EINVAL;
++
++ rctx->mode = mode;
++
++ spin_lock_irqsave(&dev->queue_lock, flags);
++ err = ablkcipher_enqueue_request(&dev->queue, req);
++ spin_unlock_irqrestore(&dev->queue_lock, flags);
++
++ flags = test_and_set_bit(DCP_FLAG_BUSY, &dev->flags);
++
++ if (!(flags & DCP_FLAG_BUSY))
++ tasklet_schedule(&dev->queue_task);
++
++ return err;
++}
++
++static int dcp_aes_cbc_encrypt(struct ablkcipher_request *req)
++{
++ struct crypto_tfm *tfm =
++ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
++ struct dcp_op *ctx = crypto_ablkcipher_ctx(
++ crypto_ablkcipher_reqtfm(req));
++
++ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
++ int err = 0;
++ ablkcipher_request_set_tfm(req, ctx->fallback);
++ err = crypto_ablkcipher_encrypt(req);
++ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
++ return err;
++ }
++
++ return dcp_aes_cbc_crypt(req, DCP_AES | DCP_ENC | DCP_CBC);
++}
++
++static int dcp_aes_cbc_decrypt(struct ablkcipher_request *req)
++{
++ struct crypto_tfm *tfm =
++ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
++ struct dcp_op *ctx = crypto_ablkcipher_ctx(
++ crypto_ablkcipher_reqtfm(req));
++
++ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
++ int err = 0;
++ ablkcipher_request_set_tfm(req, ctx->fallback);
++ err = crypto_ablkcipher_decrypt(req);
++ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
++ return err;
++ }
++ return dcp_aes_cbc_crypt(req, DCP_AES | DCP_DEC | DCP_CBC);
++}
++
++static struct crypto_alg algs[] = {
++ {
++ .cra_name = "cbc(aes)",
++ .cra_driver_name = "dcp-cbc-aes",
++ .cra_alignmask = 3,
++ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC |
++ CRYPTO_ALG_NEED_FALLBACK,
++ .cra_blocksize = AES_KEYSIZE_128,
++ .cra_type = &crypto_ablkcipher_type,
++ .cra_priority = 300,
++ .cra_u.ablkcipher = {
++ .min_keysize = AES_KEYSIZE_128,
++ .max_keysize = AES_KEYSIZE_128,
++ .setkey = dcp_aes_setkey,
++ .encrypt = dcp_aes_cbc_encrypt,
++ .decrypt = dcp_aes_cbc_decrypt,
++ .ivsize = AES_KEYSIZE_128,
++ }
++
++ },
++};
++
++/* DCP bootstream verification interface: uses OTP key for crypto */
++static int dcp_bootstream_open(struct inode *inode, struct file *file)
++{
++ file->private_data = container_of((file->private_data),
++ struct dcp_dev, dcp_bootstream_misc);
++ return 0;
++}
++
++static long dcp_bootstream_ioctl(struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++ struct dcp_dev *dev = (struct dcp_dev *) file->private_data;
++ void __user *argp = (void __user *)arg;
++ int ret;
++
++ if (dev == NULL)
++ return -EBADF;
++
++ if (cmd != DBS_ENC && cmd != DBS_DEC)
++ return -EINVAL;
++
++ if (copy_from_user(dev->payload_base, argp, 16))
++ return -EFAULT;
++
++ if (test_and_set_bit(DCP_FLAG_BUSY, &dev->flags))
++ return -EAGAIN;
++
++ dev->ctx = kzalloc(sizeof(struct dcp_op), GFP_KERNEL);
++ if (!dev->ctx) {
++ dev_err(dev->dev,
++ "cannot allocate context for OTP crypto");
++ clear_bit(DCP_FLAG_BUSY, &dev->flags);
++ return -ENOMEM;
++ }
++
++ dev->ctx->flags = DCP_AES | DCP_ECB | DCP_OTP_KEY | DCP_CBC_INIT;
++ dev->ctx->flags |= (cmd == DBS_ENC) ? DCP_ENC : DCP_DEC;
++ dev->hw_pkg[0]->src = dev->payload_base_dma;
++ dev->hw_pkg[0]->dst = dev->payload_base_dma;
++ dev->hw_pkg[0]->size = 16;
++
++ dcp_op_start(dev, 0);
++
++ while (test_bit(DCP_FLAG_BUSY, &dev->flags))
++ cpu_relax();
++
++ ret = dev->ctx->stat;
++ if (!ret && copy_to_user(argp, dev->payload_base, 16))
++ ret = -EFAULT;
++
++ kfree(dev->ctx);
++
++ return ret;
++}
++
++static const struct file_operations dcp_bootstream_fops = {
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = dcp_bootstream_ioctl,
++ .open = dcp_bootstream_open,
++};
++
++static int dcp_probe(struct platform_device *pdev)
++{
++ struct dcp_dev *dev = NULL;
++ struct resource *r;
++ int i, ret, j;
++
++ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
++ if (dev == NULL) {
++ dev_err(&pdev->dev, "Failed to allocate structure\n");
++ ret = -ENOMEM;
++ goto err;
++ }
++ global_dev = dev;
++ dev->dev = &pdev->dev;
++
++ platform_set_drvdata(pdev, dev);
++
++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!r) {
++ dev_err(&pdev->dev, "failed to get IORESOURCE_MEM\n");
++ ret = -ENXIO;
++ goto err_dev;
++ }
++ dev->dcp_regs_base = ioremap(r->start, resource_size(r));
++
++
++ dcp_set(dev, DCP_CTRL_SFRST, DCP_REG_CTRL);
++ udelay(10);
++ dcp_clear(dev, DCP_CTRL_SFRST | DCP_CTRL_CLKGATE, DCP_REG_CTRL);
++
++ dcp_write(dev, DCP_CTRL_GATHER_RES_WRITE |
++ DCP_CTRL_ENABLE_CONTEXT_CACHE | DCP_CTRL_CH_IRQ_E_1,
++ DCP_REG_CTRL);
++
++ dcp_write(dev, DCP_CHAN_CTRL_ENABLE_1, DCP_REG_CHAN_CTRL);
++
++ for (i = 0; i < 4; i++)
++ dcp_clear(dev, -1, dcp_chan_reg(DCP_REG_CHAN_STAT, i));
++
++ dcp_clear(dev, -1, DCP_REG_STAT);
++
++
++ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ if (!r) {
++ dev_err(&pdev->dev, "can't get IRQ resource (0)\n");
++ ret = -EIO;
++ goto err_unmap_mem;
++ }
++ dev->dcp_vmi_irq = r->start;
++ ret = request_irq(dev->dcp_vmi_irq, dcp_vmi_irq, 0, "dcp", dev);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "can't request_irq (0)\n");
++ ret = -EIO;
++ goto err_unmap_mem;
++ }
++
++ r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
++ if (!r) {
++ dev_err(&pdev->dev, "can't get IRQ resource (1)\n");
++ ret = -EIO;
++ goto err_free_irq0;
++ }
++ dev->dcp_irq = r->start;
++ ret = request_irq(dev->dcp_irq, dcp_irq, 0, "dcp", dev);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "can't request_irq (1)\n");
++ ret = -EIO;
++ goto err_free_irq0;
++ }
++
++ dev->hw_pkg[0] = dma_alloc_coherent(&pdev->dev,
++ DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
++ &dev->hw_phys_pkg,
++ GFP_KERNEL);
++ if (!dev->hw_pkg[0]) {
++ dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
++ ret = -ENOMEM;
++ goto err_free_irq1;
++ }
++
++ for (i = 1; i < DCP_MAX_PKG; i++) {
++ dev->hw_pkg[i - 1]->next = dev->hw_phys_pkg
++ + i * sizeof(struct dcp_hw_packet);
++ dev->hw_pkg[i] = dev->hw_pkg[i - 1] + 1;
++ }
++ dev->hw_pkg[i - 1]->next = dev->hw_phys_pkg;
++
++
++ dev->payload_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
++ &dev->payload_base_dma, GFP_KERNEL);
++ if (!dev->payload_base) {
++ dev_err(&pdev->dev, "Could not allocate memory for key\n");
++ ret = -ENOMEM;
++ goto err_free_hw_packet;
++ }
++ tasklet_init(&dev->queue_task, dcp_queue_task,
++ (unsigned long) dev);
++ tasklet_init(&dev->done_task, dcp_done_task,
++ (unsigned long) dev);
++ spin_lock_init(&dev->queue_lock);
++
++ crypto_init_queue(&dev->queue, 10);
++
++ init_timer(&dev->watchdog);
++ dev->watchdog.function = &dcp_watchdog;
++ dev->watchdog.data = (unsigned long)dev;
++
++ dev->dcp_bootstream_misc.minor = MISC_DYNAMIC_MINOR,
++ dev->dcp_bootstream_misc.name = "dcpboot",
++ dev->dcp_bootstream_misc.fops = &dcp_bootstream_fops,
++ ret = misc_register(&dev->dcp_bootstream_misc);
++ if (ret != 0) {
++ dev_err(dev->dev, "Unable to register misc device\n");
++ goto err_free_key_iv;
++ }
++
++ for (i = 0; i < ARRAY_SIZE(algs); i++) {
++ algs[i].cra_priority = 300;
++ algs[i].cra_ctxsize = sizeof(struct dcp_op);
++ algs[i].cra_module = THIS_MODULE;
++ algs[i].cra_init = dcp_cra_init;
++ algs[i].cra_exit = dcp_cra_exit;
++ if (crypto_register_alg(&algs[i])) {
++ dev_err(&pdev->dev, "register algorithm failed\n");
++ ret = -ENOMEM;
++ goto err_unregister;
++ }
++ }
++ dev_notice(&pdev->dev, "DCP crypto enabled.!\n");
++
++ return 0;
++
++err_unregister:
++ for (j = 0; j < i; j++)
++ crypto_unregister_alg(&algs[j]);
++err_free_key_iv:
++ dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
++ dev->payload_base_dma);
++err_free_hw_packet:
++ dma_free_coherent(&pdev->dev, DCP_MAX_PKG *
++ sizeof(struct dcp_hw_packet), dev->hw_pkg[0],
++ dev->hw_phys_pkg);
++err_free_irq1:
++ free_irq(dev->dcp_irq, dev);
++err_free_irq0:
++ free_irq(dev->dcp_vmi_irq, dev);
++err_unmap_mem:
++ iounmap((void *) dev->dcp_regs_base);
++err_dev:
++ kfree(dev);
++err:
++ return ret;
++}
++
++static int dcp_remove(struct platform_device *pdev)
++{
++ struct dcp_dev *dev;
++ int j;
++ dev = platform_get_drvdata(pdev);
++ platform_set_drvdata(pdev, NULL);
++
++ dma_free_coherent(&pdev->dev,
++ DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
++ dev->hw_pkg[0], dev->hw_phys_pkg);
++
++ dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
++ dev->payload_base_dma);
++
++ free_irq(dev->dcp_irq, dev);
++ free_irq(dev->dcp_vmi_irq, dev);
++
++ tasklet_kill(&dev->done_task);
++ tasklet_kill(&dev->queue_task);
++
++ iounmap((void *) dev->dcp_regs_base);
++
++ for (j = 0; j < ARRAY_SIZE(algs); j++)
++ crypto_unregister_alg(&algs[j]);
++
++ misc_deregister(&dev->dcp_bootstream_misc);
++
++ kfree(dev);
++ return 0;
++}
++
++static struct of_device_id fs_dcp_of_match[] = {
++ { .compatible = "fsl-dcp"},
++ {},
++};
++
++static struct platform_driver fs_dcp_driver = {
++ .probe = dcp_probe,
++ .remove = dcp_remove,
++ .driver = {
++ .name = "fsl-dcp",
++ .owner = THIS_MODULE,
++ .of_match_table = fs_dcp_of_match
++ }
++};
++
++module_platform_driver(fs_dcp_driver);
++
++
++MODULE_AUTHOR("Tobias Rauter <tobias.rau...@gmail.com>");
++MODULE_DESCRIPTION("Freescale DCP Crypto Driver");
++MODULE_LICENSE("GPL");
--- /dev/null
+--- a/arch/arm/boot/dts/imx23.dtsi
++++ b/arch/arm/boot/dts/imx23.dtsi
+@@ -337,6 +337,7 @@
+
+ dcp@80028000 {
+ reg = <0x80028000 0x2000>;
++ interrupts = <52 53 54>;
+ status = "disabled";
+ };
+
+--- a/arch/arm/boot/dts/imx23-olinuxino.dts
++++ b/arch/arm/boot/dts/imx23-olinuxino.dts
+@@ -66,6 +66,12 @@
+ pinctrl-0 = <&spi2_pins_a>;
+ status = "okay";
+ };
++
++ dcp@80028000 {
++ status = "okay";
++ compatible = "fsl-dcp";
++ };
++
+ };
+
+ apbx@80040000 {
--- /dev/null
+--- a/arch/arm/boot/dts/imx23-olinuxino.dts
++++ b/arch/arm/boot/dts/imx23-olinuxino.dts
+@@ -109,6 +109,11 @@
+ dmas = <&dma_apbx 0>, <&dma_apbx 1>;
+ dma-names = "rx", "tx";
+ };
++
++ lradc@80050000 {
++ status = "okay";
++ fsl,lradc-touchscreen-wires = <4>;
++ };
+ };
+ };
+
--- /dev/null
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/olinuxino
+ NAME:=Olimex Olinuxino boards
+ PACKAGES += imx-bootlets kmod-usb-mxs-phy kmod-usb-net kmod-usb-net-smsc95xx \
+ kmod-gpio-mcp23s08 kmod-leds-gpio kmod-ledtrig-heartbeat kmod-rtc-stmp3xxx \
+ kmod-sound-core kmod-sound-soc-mxs kmod-iio-mxs-lradc
+endef
+
+define Profile/olinuxino/Description
+ Olimex Olinuxino boards
+endef
+$(eval $(call Profile,olinuxino))
+
tools-$(CONFIG_TARGET_orion_generic) += wrt350nv2-builder upslug2
tools-$(CONFIG_powerpc) += upx
tools-$(CONFIG_TARGET_x86) += qemu
-tools-$(CONFIG_TARGET_imx23) += elftosb
+tools-$(CONFIG_TARGET_mxs) += elftosb
tools-$(CONFIG_TARGET_brcm2708) += mtools dosfstools
ifneq ($(CONFIG_TARGET_ar71xx),)
tools-y += lzma-old squashfs