From: Zoltan Herpai Date: Mon, 14 Oct 2013 19:01:23 +0000 (+0000) Subject: imx23: rename imx23 to mxs for upcoming imx23/28 support X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fstaging%2Fflorian.git;a=commitdiff_plain;h=07043a853a34292a12044ab524d301ab5932315f imx23: rename imx23 to mxs for upcoming imx23/28 support Signed-off-by: Michael Heimpold Signed-off-by: Zoltan HERPAI SVN-Revision: 38394 --- diff --git a/package/boot/imx-bootlets/Makefile b/package/boot/imx-bootlets/Makefile index 1c6a23c06f..2ff60ee2f8 100644 --- a/package/boot/imx-bootlets/Makefile +++ b/package/boot/imx-bootlets/Makefile @@ -18,12 +18,12 @@ include $(INCLUDE_DIR)/package.mk 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 diff --git a/package/boot/uboot-imx23/Makefile b/package/boot/uboot-imx23/Makefile index 13f1f963cd..f41b23db16 100644 --- a/package/boot/uboot-imx23/Makefile +++ b/package/boot/uboot-imx23/Makefile @@ -35,7 +35,7 @@ define Package/uboot/template 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) diff --git a/target/linux/imx23/Makefile b/target/linux/imx23/Makefile deleted file mode 100644 index 9195c2c95d..0000000000 --- a/target/linux/imx23/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# 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 -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)) diff --git a/target/linux/imx23/base-files/etc/inittab b/target/linux/imx23/base-files/etc/inittab deleted file mode 100644 index 09359b79d8..0000000000 --- a/target/linux/imx23/base-files/etc/inittab +++ /dev/null @@ -1,3 +0,0 @@ -::sysinit:/etc/init.d/rcS S boot -::shutdown:/etc/init.d/rcS K shutdown -ttyAMA0::askfirst:/bin/ash --login diff --git a/target/linux/imx23/config-default b/target/linux/imx23/config-default deleted file mode 100644 index 7d05e9f537..0000000000 --- a/target/linux/imx23/config-default +++ /dev/null @@ -1,285 +0,0 @@ -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 diff --git a/target/linux/imx23/image/Makefile b/target/linux/imx23/image/Makefile deleted file mode 100644 index b9102375d6..0000000000 --- a/target/linux/imx23/image/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# 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)) - diff --git a/target/linux/imx23/modules.mk b/target/linux/imx23/modules.mk deleted file mode 100644 index f999c31e85..0000000000 --- a/target/linux/imx23/modules.mk +++ /dev/null @@ -1,132 +0,0 @@ -# -# 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)) diff --git a/target/linux/imx23/patches/100-soc-audio-support.patch b/target/linux/imx23/patches/100-soc-audio-support.patch deleted file mode 100644 index ef07f92c78..0000000000 --- a/target/linux/imx23/patches/100-soc-audio-support.patch +++ /dev/null @@ -1,2842 +0,0 @@ ---- 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 -+ * -+ * Based on sound/soc/codecs/mxs-adc-codec.c for kernel 2.6.35 -+ * by Vladislav Buzov -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/sound/soc/codecs/mxs-builtin-codec.h -@@ -0,0 +1,825 @@ -+#ifndef __MXS_ADC_CODEC_H -+ -+#include -+ -+/* 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 "); -+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 -+ * -+ * Based on sound/soc/mxs/mxs-adc.c for kernel 2.6.35 -+ * by Vladislav Buzov -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#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 diff --git a/target/linux/imx23/patches/101-soc-audio-dts.patch b/target/linux/imx23/patches/101-soc-audio-dts.patch deleted file mode 100644 index 924cbebb08..0000000000 --- a/target/linux/imx23/patches/101-soc-audio-dts.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- 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>; -+ }; - }; diff --git a/target/linux/imx23/patches/105-imx23-dcp.patch b/target/linux/imx23/patches/105-imx23-dcp.patch deleted file mode 100644 index ae74209775..0000000000 --- a/target/linux/imx23/patches/105-imx23-dcp.patch +++ /dev/null @@ -1,957 +0,0 @@ ---- 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+/* 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 "); -+MODULE_DESCRIPTION("Freescale DCP Crypto Driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/imx23/patches/106-add-dcp-dts.patch b/target/linux/imx23/patches/106-add-dcp-dts.patch deleted file mode 100644 index ddb223c38c..0000000000 --- a/target/linux/imx23/patches/106-add-dcp-dts.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- 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 { diff --git a/target/linux/imx23/patches/110-lradc-dts.patch b/target/linux/imx23/patches/110-lradc-dts.patch deleted file mode 100644 index a2b9886959..0000000000 --- a/target/linux/imx23/patches/110-lradc-dts.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- 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>; -+ }; - }; - }; - diff --git a/target/linux/imx23/profiles/01-olinuxino.mk b/target/linux/imx23/profiles/01-olinuxino.mk deleted file mode 100644 index 252f99a854..0000000000 --- a/target/linux/imx23/profiles/01-olinuxino.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# 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)) - diff --git a/target/linux/mxs/Makefile b/target/linux/mxs/Makefile new file mode 100644 index 0000000000..fe08898fd3 --- /dev/null +++ b/target/linux/mxs/Makefile @@ -0,0 +1,27 @@ +# +# 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 +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)) diff --git a/target/linux/mxs/base-files/etc/inittab b/target/linux/mxs/base-files/etc/inittab new file mode 100644 index 0000000000..09359b79d8 --- /dev/null +++ b/target/linux/mxs/base-files/etc/inittab @@ -0,0 +1,3 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown +ttyAMA0::askfirst:/bin/ash --login diff --git a/target/linux/mxs/config-default b/target/linux/mxs/config-default new file mode 100644 index 0000000000..7d05e9f537 --- /dev/null +++ b/target/linux/mxs/config-default @@ -0,0 +1,285 @@ +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 diff --git a/target/linux/mxs/image/Makefile b/target/linux/mxs/image/Makefile new file mode 100644 index 0000000000..b9102375d6 --- /dev/null +++ b/target/linux/mxs/image/Makefile @@ -0,0 +1,45 @@ +# +# 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)) + diff --git a/target/linux/mxs/modules.mk b/target/linux/mxs/modules.mk new file mode 100644 index 0000000000..90967391f0 --- /dev/null +++ b/target/linux/mxs/modules.mk @@ -0,0 +1,132 @@ +# +# 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)) diff --git a/target/linux/mxs/patches/100-soc-audio-support.patch b/target/linux/mxs/patches/100-soc-audio-support.patch new file mode 100644 index 0000000000..ef07f92c78 --- /dev/null +++ b/target/linux/mxs/patches/100-soc-audio-support.patch @@ -0,0 +1,2842 @@ +--- 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 ++ * ++ * Based on sound/soc/codecs/mxs-adc-codec.c for kernel 2.6.35 ++ * by Vladislav Buzov ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/codecs/mxs-builtin-codec.h +@@ -0,0 +1,825 @@ ++#ifndef __MXS_ADC_CODEC_H ++ ++#include ++ ++/* 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 "); ++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 ++ * ++ * Based on sound/soc/mxs/mxs-adc.c for kernel 2.6.35 ++ * by Vladislav Buzov ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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 diff --git a/target/linux/mxs/patches/101-soc-audio-dts.patch b/target/linux/mxs/patches/101-soc-audio-dts.patch new file mode 100644 index 0000000000..924cbebb08 --- /dev/null +++ b/target/linux/mxs/patches/101-soc-audio-dts.patch @@ -0,0 +1,39 @@ +--- 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>; ++ }; + }; diff --git a/target/linux/mxs/patches/105-imx23-dcp.patch b/target/linux/mxs/patches/105-imx23-dcp.patch new file mode 100644 index 0000000000..ae74209775 --- /dev/null +++ b/target/linux/mxs/patches/105-imx23-dcp.patch @@ -0,0 +1,957 @@ +--- 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++/* 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 "); ++MODULE_DESCRIPTION("Freescale DCP Crypto Driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/mxs/patches/106-add-dcp-dts.patch b/target/linux/mxs/patches/106-add-dcp-dts.patch new file mode 100644 index 0000000000..ddb223c38c --- /dev/null +++ b/target/linux/mxs/patches/106-add-dcp-dts.patch @@ -0,0 +1,25 @@ +--- 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 { diff --git a/target/linux/mxs/patches/110-lradc-dts.patch b/target/linux/mxs/patches/110-lradc-dts.patch new file mode 100644 index 0000000000..a2b9886959 --- /dev/null +++ b/target/linux/mxs/patches/110-lradc-dts.patch @@ -0,0 +1,14 @@ +--- 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>; ++ }; + }; + }; + diff --git a/target/linux/mxs/profiles/01-olinuxino.mk b/target/linux/mxs/profiles/01-olinuxino.mk new file mode 100644 index 0000000000..9308cff8fc --- /dev/null +++ b/target/linux/mxs/profiles/01-olinuxino.mk @@ -0,0 +1,19 @@ +# +# 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)) + diff --git a/tools/Makefile b/tools/Makefile index b167a60544..7fea248113 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -21,7 +21,7 @@ tools-y += findutils 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