diff options
author | James <> | 2015-11-04 11:49:21 +0000 |
---|---|---|
committer | James <> | 2015-11-04 11:49:21 +0000 |
commit | 716ca530e1c4515d8683c9d5be3d56b301758b66 (patch) | |
tree | 700eb5bcc1a462a5f21dcec15ce7c97ecfefa772 /target/linux/mxs | |
download | trunk-47381-master.tar.gz trunk-47381-master.tar.bz2 trunk-47381-master.zip |
Diffstat (limited to 'target/linux/mxs')
25 files changed, 5102 insertions, 0 deletions
diff --git a/target/linux/mxs/Makefile b/target/linux/mxs/Makefile new file mode 100644 index 0000000..91cab96 --- /dev/null +++ b/target/linux/mxs/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2013-2014 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 +FEATURES:=ext4 rtc usb gpio +CPU_TYPE:=arm926ej-s + +MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu> +KERNEL_PATCHVER:=4.1 +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/diag.sh b/target/linux/mxs/base-files/etc/diag.sh new file mode 100644 index 0000000..11b1f75 --- /dev/null +++ b/target/linux/mxs/base-files/etc/diag.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Copyright (C) 2013-2014 OpenWrt.org + +. /lib/functions/leds.sh +. /lib/mxs.sh + +get_status_led() { + case $(mxs_board_name) in + duckbill) + status_led="duckbill:green:status" + ;; + olinuxino) + status_led="green" + ;; + *) + status_led=$(cd /sys/class/leds && ls -1d *:status 2> /dev/null | head -n 1) + ;; + esac +} + +set_state() { + get_status_led + + case "$1" in + preinit) + status_led_blink_preinit + ;; + failsafe) + status_led_blink_failsafe + ;; + preinit_regular) + status_led_blink_preinit_regular + ;; + done) + status_led_on + ;; + esac +} diff --git a/target/linux/mxs/base-files/etc/inittab b/target/linux/mxs/base-files/etc/inittab new file mode 100644 index 0000000..09359b7 --- /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/base-files/etc/uci-defaults/02_network b/target/linux/mxs/base-files/etc/uci-defaults/02_network new file mode 100644 index 0000000..246cd89 --- /dev/null +++ b/target/linux/mxs/base-files/etc/uci-defaults/02_network @@ -0,0 +1,23 @@ +#!/bin/sh +# Copyright (C) 2013 OpenWrt.org + +[ -e /etc/config/network ] && exit 0 + +touch /etc/config/network + +. /lib/functions/uci-defaults.sh +. /lib/mxs.sh + +ucidef_set_interface_loopback + +board=$(mxs_board_name) + +case "$board" in +*) + ucidef_set_interface_lan 'eth0' + ;; +esac + +uci commit network + +exit 0 diff --git a/target/linux/mxs/base-files/lib/mxs.sh b/target/linux/mxs/base-files/lib/mxs.sh new file mode 100644 index 0000000..ed5a527 --- /dev/null +++ b/target/linux/mxs/base-files/lib/mxs.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (C) 2013 OpenWrt.org +# + +MXS_BOARD_NAME= +MXS_MODEL= + +mxs_board_detect() { + local machine + local name + + machine=$(cat /proc/device-tree/model) + + case "$machine" in + *"I2SE Duckbill"*) + name="duckbill" + ;; + *"i.MX23 Olinuxino Low Cost Board") + name="olinuxino" + ;; + esac + + [ -z "$name" ] && name="unknown" + + [ -z "$MXS_BOARD_NAME" ] && MXS_BOARD_NAME="$name" + [ -z "$MXS_MODEL" ] && MXS_MODEL="$machine" + + [ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/" + + echo "$MXS_BOARD_NAME" > /tmp/sysinfo/board_name + echo "$MXS_MODEL" > /tmp/sysinfo/model +} + +mxs_board_name() { + local name + + [ -f /tmp/sysinfo/board_name ] && name=$(cat /tmp/sysinfo/board_name) + [ -z "$name" ] && name="unknown" + + echo "$name" +} diff --git a/target/linux/mxs/base-files/lib/preinit/03_preinit_do_mxs.sh b/target/linux/mxs/base-files/lib/preinit/03_preinit_do_mxs.sh new file mode 100644 index 0000000..692078d --- /dev/null +++ b/target/linux/mxs/base-files/lib/preinit/03_preinit_do_mxs.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +do_mxs() { + . /lib/mxs.sh + + mxs_board_detect +} + +boot_hook_add preinit_main do_mxs diff --git a/target/linux/mxs/config-3.18 b/target/linux/mxs/config-3.18 new file mode 100644 index 0000000..2e1f81b --- /dev/null +++ b/target/linux/mxs/config-3.18 @@ -0,0 +1,293 @@ +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_HAS_SG_CHAIN=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=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_MXS=y +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_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARM=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=5 +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_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=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_DEV_MXS_DCP is not set +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HW=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEBUG_UART_8250 is not set +# CONFIG_DEBUG_UART_PL01X is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DTC=y +# CONFIG_DW_DMAC_CORE is not set +# CONFIG_EMAC_ROCKCHIP is not set +CONFIG_EXT4_FS=y +CONFIG_FEC=y +CONFIG_FRAME_POINTER=y +CONFIG_FS_MBCACHE=y +CONFIG_GENERIC_ALLOCATOR=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_SCHED_CLOCK=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_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=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_CC_STACKPROTECTOR=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_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZ4=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_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HZ_FIXED=0 +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_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 is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_PERIODIC_RTC_TRIGGER=y +CONFIG_IIO_SYSFS_TRIGGER=y +CONFIG_IIO_TRIGGER=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_IOMMU_HELPER=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +# CONFIG_ISDN is not set +CONFIG_JBD2=y +# CONFIG_LEDS_REGULATOR is not set +CONFIG_LIBFDT=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MDIO_BOARDINFO=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_MXS=y +CONFIG_MODULES_USE_ELF_REL=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_KUSER_HELPERS=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NLS=y +CONFIG_NO_BOOTMEM=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +CONFIG_OF_NET=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PCI is not set +# CONFIG_PCI_SYSCALL is not set +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PHYLIB=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX23=y +CONFIG_PINCTRL_IMX28=y +CONFIG_PINCTRL_MXS=y +# CONFIG_PINCTRL_SINGLE is not set +# 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_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_STMP is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +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_BUS=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_SWIOTLB=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_UID16=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_USB=y +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_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/config-4.1 b/target/linux/mxs/config-4.1 new file mode 100644 index 0000000..b837442 --- /dev/null +++ b/target/linux/mxs/config-4.1 @@ -0,0 +1,297 @@ +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=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_MXS=y +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_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARM=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_ARM_CPUIDLE is not set +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=5 +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_GOV_MENU=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_DEV_MXS_DCP is not set +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HW=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEBUG_UART_8250 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_FSL_PQ_MDIO is not set +CONFIG_FS_MBCACHE=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_SCHED_CLOCK=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_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +# CONFIG_HAVE_ARCH_BITREVERSE is not set +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_CC_STACKPROTECTOR=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_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZ4=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_OPTPROBES=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HZ_FIXED=0 +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_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 is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_PERIODIC_RTC_TRIGGER=y +CONFIG_IIO_SYSFS_TRIGGER=y +CONFIG_IIO_TRIGGER=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_IOMMU_HELPER=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +# CONFIG_ISDN is not set +CONFIG_JBD2=y +# CONFIG_LEDS_REGULATOR is not set +CONFIG_LIBFDT=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MDIO_BOARDINFO=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_MXS=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MTD_PHYSMAP_OF is not set +CONFIG_MULTI_IRQ_HANDLER=y +CONFIG_MXS_DMA=y +# CONFIG_MXS_LRADC is not set +CONFIG_MXS_POWER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_KUSER_HELPERS=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NLS=y +CONFIG_NO_BOOTMEM=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_MTD=y +CONFIG_OF_NET=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS_GENERIC is not set +# CONFIG_PCI_SYSCALL is not set +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX23=y +CONFIG_PINCTRL_IMX28=y +CONFIG_PINCTRL_MXS=y +# CONFIG_PINCTRL_SINGLE is not set +# CONFIG_PL330_DMA is not set +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PTP_1588_CLOCK=y +# CONFIG_RCU_STALL_COMMON is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MXS=y +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_STMP is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +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_MCTRL_GPIO=y +CONFIG_SERIAL_MXS_AUART=y +CONFIG_SERIAL_MXS_AUART_CONSOLE=y +CONFIG_SMSC_PHY=y +CONFIG_SOC_BUS=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_SRCU=y +CONFIG_STMP_DEVICE=y +CONFIG_SWIOTLB=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_UID16=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_USB=y +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_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/files/arch/arm/boot/dts/imx28-duckbill.dts b/target/linux/mxs/files/arch/arm/boot/dts/imx28-duckbill.dts new file mode 100644 index 0000000..305b4d0 --- /dev/null +++ b/target/linux/mxs/files/arch/arm/boot/dts/imx28-duckbill.dts @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2013-2014 Michael Heimpold <mhei@heimpold.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx28.dtsi" + +/ { + model = "I2SE Duckbill"; + compatible = "i2se,duckbill", "fsl,imx28"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_4bit_pins_a + &mmc0_cd_cfg &mmc0_sck_cfg>; + bus-width = <4>; + vmmc-supply = <®_3p3v>; + status = "okay"; + }; + + ssp2: ssp@80014000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx28-spi"; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins_a>; + status = "okay"; + + spidev: spidev@0 { + compatible = "spidev"; + reg = <0>; + spi-max-frequency = <1000000>; + }; + }; + + pinctrl@80018000 { + pinctrl-names = "default"; + pinctrl-0 = <&hog_pins_a>; + + hog_pins_a: hog@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_SSP0_DATA7__GPIO_2_7 /* PHY Reset */ + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + + led_pins_a: led_gpio@0 { + reg = <0>; + fsl,pinmux-ids = < + MX28_PAD_AUART1_RX__GPIO_3_4 + MX28_PAD_AUART1_TX__GPIO_3_5 + >; + fsl,drive-strength = <MXS_DRIVE_4mA>; + fsl,voltage = <MXS_VOLTAGE_HIGH>; + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + }; + }; + + apbx@80040000 { + i2c0: i2c@80058000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + + usbphy0: usbphy@8007c000 { + status = "okay"; + }; + }; + }; + + ahb@80080000 { + usb0: usb@80080000 { + status = "okay"; + }; + + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>; + phy-supply = <®_3p3v>; + phy-reset-gpios = <&gpio2 7 1>; + phy-reset-duration = <100>; + status = "okay"; + }; + }; + + regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_a>; + + status { + label = "duckbill:green:status"; + gpios = <&gpio3 5 0>; + }; + + failure { + label = "duckbill:red:status"; + gpios = <&gpio3 4 0>; + }; + }; +}; diff --git a/target/linux/mxs/image/Config.in b/target/linux/mxs/image/Config.in new file mode 100644 index 0000000..250553e --- /dev/null +++ b/target/linux/mxs/image/Config.in @@ -0,0 +1,8 @@ +config TARGET_BOOTFS_PARTSIZE + int "Boot (SD Card) filesystem partition size (in MB)" + depends on TARGET_mxs_olinuxino-maxi || TARGET_mxs_olinuxino-micro + default 8 + help + On the Olimex OLinuXino boards, mainline U-Boot loads the + linux kernel and device tree file from a FAT partition. + The default value of 8 MB should be more than adequate. diff --git a/target/linux/mxs/image/Makefile b/target/linux/mxs/image/Makefile new file mode 100644 index 0000000..94fed82 --- /dev/null +++ b/target/linux/mxs/image/Makefile @@ -0,0 +1,89 @@ +# +# Copyright (C) 2013-2015 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 + +BOARDS:= \ + imx23-olinuxino \ + imx28-duckbill + +FAT32_BLOCK_SIZE=1024 +FAT32_BLOCKS=$(shell echo $$(($(CONFIG_TARGET_BOOTFS_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) + +define Image/BuildKernel + mkimage -A arm -O linux -T kernel -C none \ + -a 0x40008000 -e 0x40008000 \ + -n 'ARM OpenWrt Linux-$(LINUX_VERSION)' \ + -d $(KDIR)/zImage $(KDIR)/uImage + cp $(KDIR)/uImage $(BIN_DIR)/$(IMG_PREFIX)-uImage +endef + +define Image/InstallKernel + + ifneq ($(CONFIG_TARGET_ROOTFS_INCLUDE_ZIMAGE),) + mkdir -p $(TARGET_DIR)/boot + cp $(KDIR)/zImage $(TARGET_DIR)/boot/ + endif + + ifneq ($(CONFIG_TARGET_ROOTFS_INCLUDE_UIMAGE),) + mkdir -p $(TARGET_DIR)/boot + cp $(KDIR)/uImage $(TARGET_DIR)/boot/ + endif + + ifneq ($(CONFIG_TARGET_ROOTFS_INCLUDE_DTB),) + mkdir -p $(TARGET_DIR)/boot + $(foreach board,$(BOARDS), + $(CP) $(DTS_DIR)/$(board).dtb $(TARGET_DIR)/boot/ + ) + endif + +endef + +define Image/Build/SDCard-vfat-ext4 + rm -f $(KDIR)/boot.img + mkdosfs $(KDIR)/boot.img -C $(FAT32_BLOCKS) + + mcopy -i $(KDIR)/boot.img $(DTS_DIR)/$(3).dtb ::$(3).dtb + mcopy -i $(KDIR)/boot.img $(BIN_DIR)/$(IMG_PREFIX)-uImage ::uImage + + ./gen_sdcard_vfat_ext4.sh \ + $(BIN_DIR)/$(2) \ + $(BIN_DIR)/uboot-mxs-$(4)/uboot-mxs-$(4).sb \ + $(KDIR)/boot.img \ + $(KDIR)/root.$(1) \ + $(CONFIG_TARGET_BOOTFS_PARTSIZE) \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) +endef + +define Image/Build/SDCard-ext4-ext4 + ./gen_sdcard_ext4_ext4.sh \ + $(BIN_DIR)/$(2) \ + $(BIN_DIR)/uboot-mxs-$(4)/uboot-mxs-$(4).sb \ + $(KDIR)/root.$(1) \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) +endef + +define Image/Build/Profile/olinuxino-maxi + $(call Image/Build/SDCard-vfat-ext4,$(1),$(2),imx23-olinuxino,mx23_olinuxino) +endef + +define Image/Build/Profile/olinuxino-micro + $(call Image/Build/SDCard-vfat-ext4,$(1),$(2),imx23-olinuxino,mx23_olinuxino) +endef + +define Image/Build/Profile/duckbill + $(call Image/Build/SDCard-ext4-ext4,$(1),$(2),imx28-duckbill,duckbill) +endef + +define Image/Build + $(call Image/Build/$(1),$(1)) + $(call Image/Build/Profile/$(PROFILE),$(1),$(IMG_PREFIX)-$(PROFILE)-sdcard.img) + 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/image/gen_sdcard_ext4_ext4.sh b/target/linux/mxs/image/gen_sdcard_ext4_ext4.sh new file mode 100755 index 0000000..5653ba8 --- /dev/null +++ b/target/linux/mxs/image/gen_sdcard_ext4_ext4.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +set -x +[ $# -eq 4 ] || { + echo "SYNTAX: $0 <file> <u-boot.sb image> <rootfs image> <rootfs size>" + exit 1 +} + +OUTPUT="$1" +UBOOT="$2" +ROOTFS="$3" +ROOTFSSIZE="$4" + +head=4 +sect=63 + +# set the Boot stream partition size to 1M +set `ptgen -o $OUTPUT -h $head -s $sect -l 1024 -t 53 -p 1M -t 83 -p ${ROOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M` + +ROOTFS1OFFSET="$(($3 / 512))" +ROOTFS1SIZE="$(($4 / 512))" +ROOTFS2OFFSET="$(($5 / 512))" +ROOTFS2SIZE="$(($6 / 512))" + +dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFS1OFFSET" conv=notrunc +dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFS2OFFSET" conv=notrunc +sdimage -d "$OUTPUT" -f "$UBOOT" diff --git a/target/linux/mxs/image/gen_sdcard_vfat_ext4.sh b/target/linux/mxs/image/gen_sdcard_vfat_ext4.sh new file mode 100755 index 0000000..616639d --- /dev/null +++ b/target/linux/mxs/image/gen_sdcard_vfat_ext4.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +set -x +[ $# -eq 6 ] || { + echo "SYNTAX: $0 <file> <u-boot.sb image> <bootfs image> <rootfs image> <bootfs size> <rootfs size>" + exit 1 +} + +OUTPUT="$1" +UBOOT="$2" +BOOTFS="$3" +ROOTFS="$4" +BOOTFSSIZE="$5" +ROOTFSSIZE="$6" + +head=4 +sect=63 + +# Set the u-boot storage to 2M +set `ptgen -o $OUTPUT -h $head -s $sect -l 1024 -t 53 -p 2M -t c -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M` + +UBOOTOFFSET="$(($1 / 512))" +UBOOTSIZE="$(($2 / 512))" +BOOTOFFSET="$(($3 / 512))" +BOOTSIZE="$(($4 / 512))" +ROOTFSOFFSET="$(($5 / 512))" +ROOTFSSIZE="$(($6 / 512))" + +dd bs=512 if="$BOOTFS" of="$OUTPUT" seek="$BOOTOFFSET" conv=notrunc +dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFSOFFSET" conv=notrunc +sdimage -d "$OUTPUT" -f "$UBOOT" diff --git a/target/linux/mxs/modules.mk b/target/linux/mxs/modules.mk new file mode 100644 index 0000000..d363360 --- /dev/null +++ b/target/linux/mxs/modules.mk @@ -0,0 +1,115 @@ +# +# Copyright (C) 2013-2014 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/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 @LINUX_3_18 + $(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:=Freescale i.MX23/28 LRADC driver + DEPENDS:=@TARGET_mxs +kmod-iio-core + KCONFIG:=CONFIG_MXS_LRADC + FILES:=$(LINUX_DIR)/drivers/staging/iio/adc/mxs-lradc.ko + AUTOLOAD:=$(call AutoLoad,70,mxs-lradc) +endef + +define KernelPackage/iio-mxs-lradc/description + Kernel module for Freescale i.MX23/28 LRADC driver +endef + +$(eval $(call KernelPackage,iio-mxs-lradc)) + +define KernelPackage/crypto-hw-dcp + TITLE:=Freescale i.MX23/28 DCP hardware crypto module + DEPENDS:=@TARGET_mxs + KCONFIG:=CONFIG_CRYPTO_DEV_MXS_DCP + FILES:=$(LINUX_DIR)/drivers/crypto/mxs-dcp.ko + AUTOLOAD:=$(call AutoLoad,90,mxs-dcp) + $(call AddDepends/crypto,+kmod-crypto-authenc +kmod-crypto-des) +endef + +define KernelPackage/crypto-hw-dcp/description + Kernel support for Freescale i.MX23/28 DCP crypto engine +endef + +$(eval $(call KernelPackage,crypto-hw-dcp)) + +define KernelPackage/spi-mxs + SUBMENU:=$(SPI_MENU) + TITLE:=Freescale i.MX23/28 SPI driver + DEPENDS:=@TARGET_mxs + KCONFIG:=CONFIG_SPI_MXS + FILES:=$(LINUX_DIR)/drivers/spi/spi-mxs.ko + AUTOLOAD:=$(call AutoProbe,spi-mxs) +endef + +define KernelPackage/spi-mxs/description + Kernel module for Freescale i.MX23/28 SPI controller +endef + +$(eval $(call KernelPackage,spi-mxs)) + +I2C_MXS_MODULES:= \ + CONFIG_I2C_MXS:drivers/i2c/busses/i2c-mxs + +define KernelPackage/i2c-mxs + $(call i2c_defaults,$(I2C_MXS_MODULES),55) + TITLE:=Freescale i.MX23/28 I2C driver + DEPENDS:=@TARGET_mxs +kmod-i2c-core +endef + +define KernelPackage/i2c-mxs/description + Kernel module for Freescale i.MX23/28 I2C controller +endef + +$(eval $(call KernelPackage,i2c-mxs)) diff --git a/target/linux/mxs/patches-3.18/001-soc-audio-support.patch b/target/linux/mxs/patches-3.18/001-soc-audio-support.patch new file mode 100644 index 0000000..65c3438 --- /dev/null +++ b/target/linux/mxs/patches-3.18/001-soc-audio-support.patch @@ -0,0 +1,2866 @@ +From ef05a3ce8340c7156610b173324ab793b06e0ae2 Mon Sep 17 00:00:00 2001 +From: Michal Ulianko <info@itserve.cz> +Date: Mon, 29 Jul 2013 20:14:38 +0200 +Subject: [PATCH 1/2] Added ASoC driver for i.MX233's builtin ADC/DAC codec. + +--- + sound/soc/codecs/Kconfig | 4 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/mxs-builtin-codec.c | 1128 ++++++++++++++++++++++++++++++++++ + sound/soc/codecs/mxs-builtin-codec.h | 825 +++++++++++++++++++++++++ + sound/soc/mxs/Kconfig | 10 + + sound/soc/mxs/Makefile | 9 + + sound/soc/mxs/mxs-builtin-audio.c | 120 ++++ + sound/soc/mxs/mxs-builtin-dai.c | 588 ++++++++++++++++++ + sound/soc/mxs/mxs-builtin-pcm.c | 69 +++ + sound/soc/mxs/mxs-builtin-pcm.h | 25 + + 10 files changed, 2780 insertions(+) + create mode 100644 sound/soc/codecs/mxs-builtin-codec.c + create mode 100644 sound/soc/codecs/mxs-builtin-codec.h + create mode 100644 sound/soc/mxs/mxs-builtin-audio.c + create mode 100644 sound/soc/mxs/mxs-builtin-dai.c + create mode 100644 sound/soc/mxs/mxs-builtin-pcm.c + create mode 100644 sound/soc/mxs/mxs-builtin-pcm.h + +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -164,6 +164,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 +@@ -789,6 +790,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 +@@ -166,6 +166,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 +@@ -339,6 +340,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc- + obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o + obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o + obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o ++obj-$(CONFIG_SND_SOC_MXS_BUILTIN_CODEC) += snd-soc-mxs-builtin-codec.o + + # Amp + obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o +--- /dev/null ++++ b/sound/soc/codecs/mxs-builtin-codec.c +@@ -0,0 +1,1128 @@ ++/* ++ * mxs-builtin-codec.c -- i.MX233 built-in codec ALSA Soc Audio driver ++ * ++ * Author: Michal Ulianko <michal.ulianko@gmail.com> ++ * ++ * Based on sound/soc/codecs/mxs-adc-codec.c for kernel 2.6.35 ++ * by Vladislav Buzov <vbuzov@embeddedalley.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++ ++#include "mxs-builtin-codec.h" ++ ++#ifndef BF ++#define BF(value, field) (((value) << BP_##field) & BM_##field) ++#endif ++ ++/* TODO Delete this and use BM_RTC_PERSISTENT0_RELEASE_GND from header file ++ * if it works. */ ++#define BP_RTC_PERSISTENT0_SPARE_ANALOG 18 ++#define BM_RTC_PERSISTENT0_SPARE_ANALOG 0xFFFC0000 ++#define BM_RTC_PERSISTENT0_RELEASE_GND BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG) ++ ++/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */ ++ ++struct mxs_adc_priv { ++ void __iomem *ain_base; ++ void __iomem *aout_base; ++ void __iomem *rtc_base; ++ struct clk *clk; ++}; ++ ++static unsigned int mxs_regmap[] = { ++ HW_AUDIOOUT_CTRL, ++ HW_AUDIOOUT_STAT, ++ HW_AUDIOOUT_DACSRR, ++ HW_AUDIOOUT_DACVOLUME, ++ HW_AUDIOOUT_DACDEBUG, ++ HW_AUDIOOUT_HPVOL, ++ HW_AUDIOOUT_PWRDN, ++ HW_AUDIOOUT_REFCTRL, ++ HW_AUDIOOUT_ANACTRL, ++ HW_AUDIOOUT_TEST, ++ HW_AUDIOOUT_BISTCTRL, ++ HW_AUDIOOUT_BISTSTAT0, ++ HW_AUDIOOUT_BISTSTAT1, ++ HW_AUDIOOUT_ANACLKCTRL, ++ HW_AUDIOOUT_DATA, ++ HW_AUDIOOUT_SPEAKERCTRL, ++ HW_AUDIOOUT_VERSION, ++ HW_AUDIOIN_CTRL, ++ HW_AUDIOIN_STAT, ++ HW_AUDIOIN_ADCSRR, ++ HW_AUDIOIN_ADCVOLUME, ++ HW_AUDIOIN_ADCDEBUG, ++ HW_AUDIOIN_ADCVOL, ++ HW_AUDIOIN_MICLINE, ++ HW_AUDIOIN_ANACLKCTRL, ++ HW_AUDIOIN_DATA, ++}; ++ ++static void __iomem *mxs_getreg(struct mxs_adc_priv *mxs_adc, int i) ++{ ++ if (i <= 16) ++ return mxs_adc->aout_base + mxs_regmap[i]; ++ else if (i < ADC_REGNUM) ++ return mxs_adc->ain_base + mxs_regmap[i]; ++ else ++ return NULL; ++} ++ ++static u8 dac_volumn_control_word[] = { ++ 0x37, 0x5e, 0x7e, 0x8e, ++ 0x9e, 0xae, 0xb6, 0xbe, ++ 0xc6, 0xce, 0xd6, 0xde, ++ 0xe6, 0xee, 0xf6, 0xfe, ++}; ++ ++struct dac_srr { ++ u32 rate; ++ u32 basemult; ++ u32 src_hold; ++ u32 src_int; ++ u32 src_frac; ++}; ++ ++static struct dac_srr srr_values[] = { ++ {192000, 0x4, 0x0, 0x0F, 0x13FF}, ++ {176400, 0x4, 0x0, 0x11, 0x0037}, ++ {128000, 0x4, 0x0, 0x17, 0x0E00}, ++ {96000, 0x2, 0x0, 0x0F, 0x13FF}, ++ {88200, 0x2, 0x0, 0x11, 0x0037}, ++ {64000, 0x2, 0x0, 0x17, 0x0E00}, ++ {48000, 0x1, 0x0, 0x0F, 0x13FF}, ++ {44100, 0x1, 0x0, 0x11, 0x0037}, ++ {32000, 0x1, 0x0, 0x17, 0x0E00}, ++ {24000, 0x1, 0x1, 0x0F, 0x13FF}, ++ {22050, 0x1, 0x1, 0x11, 0x0037}, ++ {16000, 0x1, 0x1, 0x17, 0x0E00}, ++ {12000, 0x1, 0x3, 0x0F, 0x13FF}, ++ {11025, 0x1, 0x3, 0x11, 0x0037}, ++ {8000, 0x1, 0x3, 0x17, 0x0E00} ++}; ++ ++static inline int get_srr_values(int rate) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(srr_values); i++) ++ if (srr_values[i].rate == rate) ++ return i; ++ ++ return -1; ++} ++ ++/* SoC IO functions */ ++static void mxs_codec_write_cache(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) ++{ ++ u16 *cache = codec->reg_cache; ++ if (reg < ADC_REGNUM) ++ cache[reg] = value; ++} ++ ++static int mxs_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ unsigned int reg_val; ++ unsigned int mask = 0xffff; ++ ++ if (reg >= ADC_REGNUM) ++ return -EIO; ++ ++ mxs_codec_write_cache(codec, reg, value); ++ ++ if (reg & 0x1) { ++ mask <<= 16; ++ value <<= 16; ++ } ++ ++ reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1)); ++ reg_val = (reg_val & ~mask) | value; ++ __raw_writel(reg_val, mxs_getreg(mxs_adc, reg >> 1)); ++ ++ return 0; ++} ++ ++static unsigned int mxs_codec_read(struct snd_soc_codec *codec, unsigned int reg) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ unsigned int reg_val; ++ ++ if (reg >= ADC_REGNUM) ++ return -1; ++ ++ reg_val = __raw_readl(mxs_getreg(mxs_adc, reg >> 1)); ++ if (reg & 1) ++ reg_val >>= 16; ++ ++ return reg_val & 0xffff; ++} ++ ++// static unsigned int mxs_codec_read_cache(struct snd_soc_codec *codec, unsigned int reg) ++// { ++// u16 *cache = codec->reg_cache; ++// if (reg >= ADC_REGNUM) ++// return -EINVAL; ++// return cache[reg]; ++// } ++ ++static void mxs_codec_sync_reg_cache(struct snd_soc_codec *codec) ++{ ++ int reg; ++ for (reg = 0; reg < ADC_REGNUM; reg += 1) ++ mxs_codec_write_cache(codec, reg, ++ mxs_codec_read(codec, reg)); ++} ++ ++// static int mxs_codec_restore_reg(struct snd_soc_codec *codec, unsigned int reg) ++// { ++// unsigned int cached_val, hw_val; ++// ++// cached_val = mxs_codec_read_cache(codec, reg); ++// hw_val = mxs_codec_read(codec, reg); ++// ++// if (hw_val != cached_val) ++// return mxs_codec_write(codec, reg, cached_val); ++// ++// return 0; ++// } ++/* END SoC IO functions */ ++ ++/* Codec routines */ ++#define VAG_BASE_VALUE ((1400/2 - 625)/25) ++ ++static void mxs_codec_dac_set_vag(struct mxs_adc_priv *mxs_adc) ++{ ++ u32 refctrl_val = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL); ++ ++ refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VAG_VAL); ++ refctrl_val &= ~(BM_AUDIOOUT_REFCTRL_VBG_ADJ); ++ refctrl_val |= BF(VAG_BASE_VALUE, AUDIOOUT_REFCTRL_VAG_VAL) | ++ BM_AUDIOOUT_REFCTRL_ADJ_VAG | ++ BF(0xF, AUDIOOUT_REFCTRL_ADC_REFVAL) | ++ BM_AUDIOOUT_REFCTRL_ADJ_ADC | ++ BF(0x3, AUDIOOUT_REFCTRL_VBG_ADJ) | BM_AUDIOOUT_REFCTRL_RAISE_REF; ++ ++ __raw_writel(refctrl_val, mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL); ++} ++ ++static bool mxs_codec_dac_is_capless(struct mxs_adc_priv *mxs_adc) ++{ ++ if ((__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_PWRDN) ++ & BM_AUDIOOUT_PWRDN_CAPLESS) == 0) ++ return false; ++ else ++ return true; ++} ++ ++static void mxs_codec_dac_arm_short_cm(struct mxs_adc_priv *mxs_adc, bool bShort) ++{ ++ __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_CM), ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_CM_STS, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ if (bShort) ++ __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_CM), ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET); ++} ++ ++static void mxs_codec_dac_arm_short_lr(struct mxs_adc_priv *mxs_adc, bool bShort) ++{ ++ __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_LR), ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ if (bShort) ++ __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_LR), ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET); ++} ++ ++static void mxs_codec_dac_set_short_trip_level(struct mxs_adc_priv *mxs_adc, u8 u8level) ++{ ++ __raw_writel(__raw_readl(mxs_adc->aout_base + ++ HW_AUDIOOUT_ANACTRL) ++ & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL) ++ & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR) ++ | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJL) ++ | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJR), ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL); ++} ++ ++static void mxs_codec_dac_arm_short(struct mxs_adc_priv *mxs_adc, bool bLatchCM, bool bLatchLR) ++{ ++ if (bLatchCM) { ++ if (mxs_codec_dac_is_capless(mxs_adc)) ++ mxs_codec_dac_arm_short_cm(mxs_adc, true); ++ } else ++ mxs_codec_dac_arm_short_cm(mxs_adc, false); ++ ++ if (bLatchLR) ++ mxs_codec_dac_arm_short_lr(mxs_adc, true); ++ else ++ mxs_codec_dac_arm_short_lr(mxs_adc, false); ++} ++ ++static void ++mxs_codec_dac_power_on(struct mxs_adc_priv *mxs_adc) ++{ ++ /* Ungate DAC clocks */ ++ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR); ++ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_CLR); ++ ++ /* 16 bit word length */ ++ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET); ++ ++ /* Arm headphone LR short protect */ ++ mxs_codec_dac_set_short_trip_level(mxs_adc, 0); ++ mxs_codec_dac_arm_short(mxs_adc, false, true); ++ ++ /* Update DAC volume over zero crossings */ ++ __raw_writel(BM_AUDIOOUT_DACVOLUME_EN_ZCD, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET); ++ /* Mute DAC */ ++ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT | ++ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET); ++ ++ /* Update HP volume over zero crossings */ ++ __raw_writel(BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD, ++ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET); ++ ++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET); ++ ++ /* Mute HP output */ ++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, ++ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET); ++ /* Mute speaker amp */ ++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE, ++ mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET); ++ /* Enable the audioout */ ++ __raw_writel(BM_AUDIOOUT_CTRL_RUN, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET); ++} ++ ++static void ++mxs_codec_dac_power_down(struct mxs_adc_priv *mxs_adc) ++{ ++ /* Disable the audioout */ ++ __raw_writel(BM_AUDIOOUT_CTRL_RUN, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR); ++ /* Disable class AB */ ++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ ++ /* Set hold to ground */ ++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET); ++ ++ /* Mute HP output */ ++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, ++ mxs_adc->aout_base + HW_AUDIOOUT_HPVOL_SET); ++ /* Power down HP output */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET); ++ ++ /* Mute speaker amp */ ++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE, ++ mxs_adc->aout_base + HW_AUDIOOUT_SPEAKERCTRL_SET); ++ /* Power down speaker amp */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_SPEAKER, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET); ++ ++ /* Mute DAC */ ++ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT | ++ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET); ++ /* Power down DAC */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_DAC, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET); ++ ++ /* Gate DAC clocks */ ++ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACLKCTRL_SET); ++ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET); ++} ++ ++static void ++mxs_codec_adc_power_on(struct mxs_adc_priv *mxs_adc) ++{ ++ u32 reg; ++ ++ /* Ungate ADC clocks */ ++ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE, ++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR); ++ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE, ++ mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_CLR); ++ ++ /* 16 bit word length */ ++ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH, ++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET); ++ ++ /* Unmute ADC channels */ ++ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE, ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR); ++ ++ /* ++ * The MUTE_LEFT and MUTE_RIGHT fields need to be cleared. ++ * They aren't presented in the datasheet, so this is hardcode. ++ */ ++ __raw_writel(0x01000100, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME_CLR); ++ ++ /* Set the Input channel gain 3dB */ ++ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_LEFT, ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR); ++ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_RIGHT, ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR); ++ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_LEFT), ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET); ++ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_RIGHT), ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET); ++ ++ /* Select default input - Microphone */ ++ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_LEFT, ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR); ++ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_RIGHT, ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_CLR); ++ __raw_writel(BF ++ (BV_AUDIOIN_ADCVOL_SELECT__MIC, ++ AUDIOIN_ADCVOL_SELECT_LEFT), ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET); ++ __raw_writel(BF ++ (BV_AUDIOIN_ADCVOL_SELECT__MIC, ++ AUDIOIN_ADCVOL_SELECT_RIGHT), ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET); ++ ++ /* Supply bias voltage to microphone */ ++ __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_RESISTOR), ++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET); ++ __raw_writel(BM_AUDIOIN_MICLINE_MIC_SELECT, ++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET); ++ __raw_writel(BF(1, AUDIOIN_MICLINE_MIC_GAIN), ++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET); ++ __raw_writel(BF(7, AUDIOIN_MICLINE_MIC_BIAS), ++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET); ++ ++ /* Set max ADC volume */ ++ reg = __raw_readl(mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME); ++ reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT; ++ reg &= ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT; ++ reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_LEFT); ++ reg |= BF(ADC_VOLUME_MAX, AUDIOIN_ADCVOLUME_VOLUME_RIGHT); ++ __raw_writel(reg, mxs_adc->ain_base + HW_AUDIOIN_ADCVOLUME); ++} ++ ++static void ++mxs_codec_adc_power_down(struct mxs_adc_priv *mxs_adc) ++{ ++ /* Mute ADC channels */ ++ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE, ++ mxs_adc->ain_base + HW_AUDIOIN_ADCVOL_SET); ++ ++ /* Power Down ADC */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_ADC | BM_AUDIOOUT_PWRDN_RIGHT_ADC, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET); ++ ++ /* Gate ADC clocks */ ++ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE, ++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET); ++ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE, ++ mxs_adc->ain_base + HW_AUDIOIN_ANACLKCTRL_SET); ++ ++ /* Disable bias voltage to microphone */ ++ __raw_writel(BF(0, AUDIOIN_MICLINE_MIC_RESISTOR), ++ mxs_adc->ain_base + HW_AUDIOIN_MICLINE_SET); ++} ++ ++static void mxs_codec_dac_enable(struct mxs_adc_priv *mxs_adc) ++{ ++ /* Move DAC codec out of reset */ ++ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_CLR); ++ ++ /* Reduce analog power */ ++ __raw_writel(BM_AUDIOOUT_TEST_HP_I1_ADJ, ++ mxs_adc->aout_base + HW_AUDIOOUT_TEST_CLR); ++ __raw_writel(BF(0x1, AUDIOOUT_TEST_HP_I1_ADJ), ++ mxs_adc->aout_base + HW_AUDIOOUT_TEST_SET); ++ __raw_writel(BM_AUDIOOUT_REFCTRL_LOW_PWR, ++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET); ++ __raw_writel(BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS, ++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_SET); ++ __raw_writel(BM_AUDIOOUT_REFCTRL_BIAS_CTRL, ++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR); ++ __raw_writel(BF(0x1, AUDIOOUT_REFCTRL_BIAS_CTRL), ++ mxs_adc->aout_base + HW_AUDIOOUT_REFCTRL_CLR); ++ ++ /* Set Vag value */ ++ mxs_codec_dac_set_vag(mxs_adc); ++ ++ /* Power on DAC codec */ ++ mxs_codec_dac_power_on(mxs_adc); ++} ++ ++static void mxs_codec_dac_disable(struct mxs_adc_priv *mxs_adc) ++{ ++ mxs_codec_dac_power_down(mxs_adc); ++} ++ ++static void mxs_codec_adc_enable(struct mxs_adc_priv *mxs_adc) ++{ ++ /* Move ADC codec out of reset */ ++ __raw_writel(BM_AUDIOIN_CTRL_SFTRST, ++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_CLR); ++ ++ /* Power on ADC codec */ ++ mxs_codec_adc_power_on(mxs_adc); ++} ++ ++static void mxs_codec_adc_disable(struct mxs_adc_priv *mxs_adc) ++{ ++ mxs_codec_adc_power_down(mxs_adc); ++} ++ ++static void mxs_codec_startup(struct snd_soc_codec *codec) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ ++ /* Soft reset DAC block */ ++ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST, ++ mxs_adc->aout_base + HW_AUDIOOUT_CTRL_SET); ++ while (!(__raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_CTRL) ++ & BM_AUDIOOUT_CTRL_CLKGATE)){ ++ } ++ ++ /* Soft reset ADC block */ ++ __raw_writel(BM_AUDIOIN_CTRL_SFTRST, ++ mxs_adc->ain_base + HW_AUDIOIN_CTRL_SET); ++ while (!(__raw_readl(mxs_adc->ain_base + HW_AUDIOIN_CTRL) ++ & BM_AUDIOIN_CTRL_CLKGATE)){ ++ } ++ ++ mxs_codec_dac_enable(mxs_adc); ++ mxs_codec_adc_enable(mxs_adc); ++ ++ /* Sync regs and cache */ ++ mxs_codec_sync_reg_cache(codec); ++} ++ ++static void mxs_codec_stop(struct snd_soc_codec *codec) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ ++ mxs_codec_dac_disable(mxs_adc); ++ mxs_codec_adc_disable(mxs_adc); ++} ++/* END Codec routines */ ++ ++/* kcontrol */ ++static int dac_info_volsw(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 2; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 0xf; ++ return 0; ++} ++ ++static int dac_get_volsw(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ int reg, l, r; ++ int i; ++ ++ reg = __raw_readl(mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME); ++ ++ l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >> ++ BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT; ++ r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >> ++ BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT; ++ /*Left channel */ ++ i = 0; ++ while (i < 16) { ++ if (l == dac_volumn_control_word[i]) { ++ ucontrol->value.integer.value[0] = i; ++ break; ++ } ++ i++; ++ } ++ if (i == 16) ++ ucontrol->value.integer.value[0] = i; ++ /*Right channel */ ++ i = 0; ++ while (i < 16) { ++ if (r == dac_volumn_control_word[i]) { ++ ucontrol->value.integer.value[1] = i; ++ break; ++ } ++ i++; ++ } ++ if (i == 16) ++ ucontrol->value.integer.value[1] = i; ++ ++ return 0; ++} ++ ++static int dac_put_volsw(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ int reg, l, r; ++ int i; ++ ++ i = ucontrol->value.integer.value[0]; ++ l = dac_volumn_control_word[i]; ++ /*Get dac volume for left channel */ ++ reg = BF(l, AUDIOOUT_DACVOLUME_VOLUME_LEFT); ++ ++ i = ucontrol->value.integer.value[1]; ++ r = dac_volumn_control_word[i]; ++ /*Get dac volume for right channel */ ++ reg = reg | BF(r, AUDIOOUT_DACVOLUME_VOLUME_RIGHT); ++ ++ /*Clear left/right dac volume */ ++ __raw_writel(BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT | ++ BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR); ++ __raw_writel(reg, mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET); ++ ++ return 0; ++} ++ ++static const char *mxs_codec_adc_input_sel[] = { ++ "Mic", "Line In 1", "Head Phone", "Line In 2" }; ++ ++static const char *mxs_codec_hp_output_sel[] = { "DAC Out", "Line In 1" }; ++ ++static const char *mxs_codec_adc_3d_sel[] = { ++ "Off", "Low", "Medium", "High" }; ++ ++static const struct soc_enum mxs_codec_enum[] = { ++ SOC_ENUM_SINGLE(ADC_ADCVOL_L, 12, 4, mxs_codec_adc_input_sel), ++ SOC_ENUM_SINGLE(ADC_ADCVOL_L, 4, 4, mxs_codec_adc_input_sel), ++ SOC_ENUM_SINGLE(DAC_HPVOL_H, 0, 2, mxs_codec_hp_output_sel), ++ SOC_ENUM_SINGLE(DAC_CTRL_L, 8, 4, mxs_codec_adc_3d_sel), ++}; ++ ++static const struct snd_kcontrol_new mxs_snd_controls[] = { ++ /* Playback Volume */ ++ { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "DAC Playback Volume", ++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | ++ SNDRV_CTL_ELEM_ACCESS_VOLATILE, ++ .info = dac_info_volsw, ++ .get = dac_get_volsw, ++ .put = dac_put_volsw, ++ }, ++ ++ SOC_DOUBLE_R("DAC Playback Switch", ++ DAC_VOLUME_H, DAC_VOLUME_L, 8, 0x01, 1), ++ SOC_DOUBLE("HP Playback Volume", DAC_HPVOL_L, 8, 0, 0x7F, 1), ++ ++ /* Capture Volume */ ++ SOC_DOUBLE_R("ADC Capture Volume", ++ ADC_VOLUME_H, ADC_VOLUME_L, 0, 0xFF, 0), ++ SOC_DOUBLE("ADC PGA Capture Volume", ADC_ADCVOL_L, 8, 0, 0x0F, 0), ++ SOC_SINGLE("ADC PGA Capture Switch", ADC_ADCVOL_H, 8, 0x1, 1), ++ SOC_SINGLE("Mic PGA Capture Volume", ADC_MICLINE_L, 0, 0x03, 0), ++ ++ /* Virtual 3D effect */ ++ SOC_ENUM("3D effect", mxs_codec_enum[3]), ++}; ++/* END kcontrol */ ++ ++/* DAPM */ ++static int pga_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec); ++ ++ switch (event) { ++ case SND_SOC_DAPM_PRE_PMU: ++ /* Prepare powering up HP and SPEAKER output */ ++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_SET); ++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, ++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET); ++ msleep(100); ++ break; ++ case SND_SOC_DAPM_POST_PMU: ++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, ++ mxs_adc->aout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ break; ++ case SND_SOC_DAPM_POST_PMD: ++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, ++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR); ++ break; ++ } ++ return 0; ++} ++ ++static int adc_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(w->codec); ++ ++ switch (event) { ++ case SND_SOC_DAPM_PRE_PMU: ++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, ++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_SET); ++ msleep(100); ++ break; ++ case SND_SOC_DAPM_POST_PMD: ++ __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, ++ mxs_adc->rtc_base + HW_RTC_PERSISTENT0_CLR); ++ break; ++ } ++ return 0; ++} ++ ++/* Left ADC Mux */ ++static const struct snd_kcontrol_new mxs_left_adc_controls = ++SOC_DAPM_ENUM("Route", mxs_codec_enum[0]); ++ ++/* Right ADC Mux */ ++static const struct snd_kcontrol_new mxs_right_adc_controls = ++SOC_DAPM_ENUM("Route", mxs_codec_enum[1]); ++ ++/* Head Phone Mux */ ++static const struct snd_kcontrol_new mxs_hp_controls = ++SOC_DAPM_ENUM("Route", mxs_codec_enum[2]); ++ ++static const struct snd_soc_dapm_widget mxs_dapm_widgets[] = { ++ SND_SOC_DAPM_ADC_E("ADC", "Capture", DAC_PWRDN_L, 8, 1, adc_event, ++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), ++ ++ SND_SOC_DAPM_DAC("DAC", "Playback", DAC_PWRDN_L, 12, 1), ++ ++ SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, ++ &mxs_left_adc_controls), ++ SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, ++ &mxs_right_adc_controls), ++ SND_SOC_DAPM_MUX("HP Mux", SND_SOC_NOPM, 0, 0, ++ &mxs_hp_controls), ++ SND_SOC_DAPM_PGA_E("HP AMP", DAC_PWRDN_L, 0, 1, NULL, 0, pga_event, ++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | ++ SND_SOC_DAPM_POST_PMD), ++ SND_SOC_DAPM_PGA("SPEAKER AMP", DAC_PWRDN_H, 8, 1, NULL, 0), ++ SND_SOC_DAPM_INPUT("LINE1L"), ++ SND_SOC_DAPM_INPUT("LINE1R"), ++ SND_SOC_DAPM_INPUT("LINE2L"), ++ SND_SOC_DAPM_INPUT("LINE2R"), ++ SND_SOC_DAPM_INPUT("MIC"), ++ ++ SND_SOC_DAPM_OUTPUT("SPEAKER"), ++ SND_SOC_DAPM_OUTPUT("HPL"), ++ SND_SOC_DAPM_OUTPUT("HPR"), ++}; ++ ++/* routes for sgtl5000 */ ++static const struct snd_soc_dapm_route mxs_dapm_routes[] = { ++ /* Left ADC Mux */ ++ {"Left ADC Mux", "Mic", "MIC"}, ++ {"Left ADC Mux", "Line In 1", "LINE1L"}, ++ {"Left ADC Mux", "Line In 2", "LINE2L"}, ++ {"Left ADC Mux", "Head Phone", "HPL"}, ++ ++ /* Right ADC Mux */ ++ {"Right ADC Mux", "Mic", "MIC"}, ++ {"Right ADC Mux", "Line In 1", "LINE1R"}, ++ {"Right ADC Mux", "Line In 2", "LINE2R"}, ++ {"Right ADC Mux", "Head Phone", "HPR"}, ++ ++ /* ADC */ ++ {"ADC", NULL, "Left ADC Mux"}, ++ {"ADC", NULL, "Right ADC Mux"}, ++ ++ /* HP Mux */ ++ {"HP Mux", "DAC Out", "DAC"}, ++ {"HP Mux", "Line In 1", "LINE1L"}, ++ {"HP Mux", "Line In 1", "LINE1R"}, ++ ++ /* HP amp */ ++ {"HP AMP", NULL, "HP Mux"}, ++ /* HP output */ ++ {"HPR", NULL, "HP AMP"}, ++ {"HPL", NULL, "HP AMP"}, ++ ++ /* Speaker amp */ ++ {"SPEAKER AMP", NULL, "DAC"}, ++ {"SPEAKER", NULL, "SPEAKER AMP"}, ++}; ++/* END DAPM */ ++ ++static int mxs_set_bias_level(struct snd_soc_codec *codec, ++ enum snd_soc_bias_level level) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ ++ pr_debug("dapm level %d\n", level); ++ switch (level) { ++ case SND_SOC_BIAS_ON: /* full On */ ++ if (codec->dapm.bias_level == SND_SOC_BIAS_ON) ++ break; ++ break; ++ ++ case SND_SOC_BIAS_PREPARE: /* partial On */ ++ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) ++ break; ++ /* Set Capless mode */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_CLR); ++ break; ++ ++ case SND_SOC_BIAS_STANDBY: /* Off, with power */ ++ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) ++ break; ++ /* Unset Capless mode */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET); ++ break; ++ ++ case SND_SOC_BIAS_OFF: /* Off, without power */ ++ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) ++ break; ++ /* Unset Capless mode */ ++ __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, ++ mxs_adc->aout_base + HW_AUDIOOUT_PWRDN_SET); ++ break; ++ } ++ ++ codec->dapm.bias_level = level; ++ return 0; ++} ++ ++/* MXS-ADC Codec DAI driver */ ++static int mxs_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_codec *codec = dai->codec; ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec); ++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0; ++ int i; ++ u32 srr_value = 0; ++ u32 src_hold = 0; ++ ++ i = get_srr_values(params_rate(params)); ++ if (i < 0) ++ dev_warn(codec->dev, "codec doesn't support rate %d\n", ++ 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, "codec doesn't support format %d\n", ++ params_format(params)); ++ ++ } ++ ++ return 0; ++} ++ ++/* mute the codec used by alsa core */ ++static int mxs_codec_dig_mute(struct snd_soc_dai *codec_dai, int mute) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_codec_get_drvdata(codec_dai->codec); ++ int l, r; ++ int ll, rr; ++ u32 reg, reg1, reg2; ++ u32 dac_mask = BM_AUDIOOUT_DACVOLUME_MUTE_LEFT | ++ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT; ++ ++ if (mute) { ++ reg = __raw_readl(mxs_adc->aout_base + \ ++ HW_AUDIOOUT_DACVOLUME); ++ ++ reg1 = reg & ~BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT; ++ reg1 = reg1 & ~BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT; ++ ++ l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >> ++ BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT; ++ r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >> ++ BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT; ++ ++ /* fade out dac vol */ ++ while ((l > DAC_VOLUME_MIN) || (r > DAC_VOLUME_MIN)) { ++ l -= 0x8; ++ r -= 0x8; ++ ll = l > DAC_VOLUME_MIN ? l : DAC_VOLUME_MIN; ++ rr = r > DAC_VOLUME_MIN ? r : DAC_VOLUME_MIN; ++ reg2 = reg1 | BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(ll) ++ | BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(rr); ++ __raw_writel(reg2, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME); ++ msleep(1); ++ } ++ ++ __raw_writel(dac_mask, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_SET); ++ reg = reg | dac_mask; ++ __raw_writel(reg, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME); ++ } else ++ __raw_writel(dac_mask, ++ mxs_adc->aout_base + HW_AUDIOOUT_DACVOLUME_CLR); ++ ++ return 0; ++} ++ ++#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000 ++#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) ++ ++static const struct snd_soc_dai_ops mxs_codec_dai_ops = { ++ .hw_params = mxs_pcm_hw_params, ++ .digital_mute = mxs_codec_dig_mute, ++}; ++ ++static struct snd_soc_dai_driver mxs_codec_dai_driver = { ++ .name = "mxs-builtin-codec-dai", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = MXS_ADC_RATES, ++ .formats = MXS_ADC_FORMATS, ++ }, ++ .capture = { ++ .stream_name = "Capture", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = MXS_ADC_RATES, ++ .formats = MXS_ADC_FORMATS, ++ }, ++ .ops = &mxs_codec_dai_ops, ++}; ++/* END MXS-ADC Codec DAI driver */ ++ ++/* MXS-ADC Codec driver */ ++static int mxs_codec_driver_probe(struct snd_soc_codec *codec) ++{ ++ int ret = 0; ++ /* We don't use snd_soc_codec_set_cache_io because we are using ++ * our own IO functions: write, read. */ ++ ++ mxs_codec_startup(codec); ++ ++ /* leading to standby state */ ++ ret = mxs_set_bias_level(codec, SND_SOC_BIAS_STANDBY); ++ if (ret) ++ goto err; ++ ++ return 0; ++ ++err: ++ mxs_codec_stop(codec); ++ ++ return ret; ++} ++ ++static int mxs_codec_driver_remove(struct snd_soc_codec *codec) ++{ ++ mxs_codec_stop(codec); ++ ++ return 0; ++} ++ ++// static int mxs_codec_driver_suspend(struct snd_soc_codec *codec) ++// { ++// /* TODO Enable power management. */ ++// return 0; ++// } ++ ++// static int mxs_codec_driver_resume(struct snd_soc_codec *codec) ++// { ++// /* TODO Enable power management. */ ++// return 0; ++// } ++ ++static struct snd_soc_codec_driver mxs_codec_driver = { ++ .probe = mxs_codec_driver_probe, ++ .remove = mxs_codec_driver_remove, ++// .suspend = mxs_codec_driver_suspend, ++// .resume = mxs_codec_driver_resume, ++ .set_bias_level = mxs_set_bias_level, ++ .reg_cache_size = ADC_REGNUM, ++ .reg_word_size = sizeof(u16), ++ .reg_cache_step = 1, ++// .reg_cache_default = mxsadc_regs, ++// .volatile_register = sgtl5000_volatile_register, ++ .controls = mxs_snd_controls, ++ .num_controls = ARRAY_SIZE(mxs_snd_controls), ++ .dapm_widgets = mxs_dapm_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(mxs_dapm_widgets), ++ .dapm_routes = mxs_dapm_routes, ++ .num_dapm_routes = ARRAY_SIZE(mxs_dapm_routes), ++ .write = mxs_codec_write, ++ .read = mxs_codec_read, ++}; ++/* END MXS-ADC Codec driver */ ++ ++/* Underlying platform device that registers codec */ ++static int mxs_adc_probe(struct platform_device *pdev) ++{ ++ struct mxs_adc_priv *mxs_adc; ++ struct resource *r; ++ int ret; ++ ++ mxs_adc = devm_kzalloc(&pdev->dev, sizeof(struct mxs_adc_priv), GFP_KERNEL); ++ if (!mxs_adc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, mxs_adc); ++ ++ /* audio-in IO memory */ ++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioin"); ++ if (IS_ERR(r)) { ++ dev_err(&pdev->dev, "failed to get resource\n"); ++ return PTR_ERR(r); ++ } ++ ++ mxs_adc->ain_base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); ++ if (IS_ERR(mxs_adc->ain_base)) { ++ dev_err(&pdev->dev, "ioremap failed\n"); ++ return PTR_ERR(mxs_adc->ain_base); ++ } ++ ++ /* audio-out IO memory */ ++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audioout"); ++ if (IS_ERR(r)) { ++ dev_err(&pdev->dev, "failed to get resource\n"); ++ return PTR_ERR(r); ++ } ++ ++ mxs_adc->aout_base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); ++ if (IS_ERR(mxs_adc->aout_base)) { ++ dev_err(&pdev->dev, "ioremap failed\n"); ++ return PTR_ERR(mxs_adc->aout_base); ++ } ++ ++ /* rtc IO memory */ ++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); ++ if (IS_ERR(r)) { ++ dev_err(&pdev->dev, "failed to get resource\n"); ++ return PTR_ERR(r); ++ } ++ ++ mxs_adc->rtc_base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); ++ if (IS_ERR(mxs_adc->rtc_base)) { ++ dev_err(&pdev->dev, "ioremap failed\n"); ++ return PTR_ERR(mxs_adc->rtc_base); ++ } ++ ++ /* Get audio clock */ ++ mxs_adc->clk = devm_clk_get(&pdev->dev, "filt"); ++ if (IS_ERR(mxs_adc->clk)) { ++ ret = PTR_ERR(mxs_adc->clk); ++ dev_err(&pdev->dev, "%s: Clock initialization failed\n", __func__); ++ return ret; ++ } ++ ++ /* Turn on audio clock */ ++ ret = clk_prepare_enable(mxs_adc->clk); ++ if (unlikely(ret != 0)) { ++ dev_err(&pdev->dev, "%s: Clock prepare or enable failed\n", __func__); ++ return ret; ++ } ++ ++ ret = snd_soc_register_codec(&pdev->dev, ++ &mxs_codec_driver,&mxs_codec_dai_driver, 1); ++ if (unlikely(ret != 0)) { ++ dev_err(&pdev->dev, "Codec registration failed\n"); ++ goto disable_clk; ++ } ++ ++ return 0; ++ ++disable_clk: ++ clk_disable_unprepare(mxs_adc->clk); ++ return ret; ++} ++ ++static int mxs_adc_remove(struct platform_device *pdev) ++{ ++ struct mxs_adc_priv *mxs_adc = platform_get_drvdata(pdev); ++ ++ clk_disable_unprepare(mxs_adc->clk); ++ snd_soc_unregister_codec(&pdev->dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id mxs_adc_dt_ids[] = { ++ { .compatible = "fsl,mxs-builtin-codec", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mxs_adc_dt_ids); ++ ++static struct platform_driver mxs_adc_driver = { ++ .driver = { ++ .name = "mxs-builtin-codec", ++ .owner = THIS_MODULE, ++ .of_match_table = mxs_adc_dt_ids, ++ }, ++ .probe = mxs_adc_probe, ++ .remove = mxs_adc_remove, ++}; ++ ++module_platform_driver(mxs_adc_driver); ++/* END Underlying platform device that registers codec */ ++ ++MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec Driver"); ++MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/codecs/mxs-builtin-codec.h +@@ -0,0 +1,825 @@ ++#ifndef __MXS_ADC_CODEC_H ++ ++#include <linux/io.h> ++ ++/* MXS ADC/DAC registers */ ++#define DAC_CTRL_L 0 ++#define DAC_CTRL_H 1 ++#define DAC_STAT_L 2 ++#define DAC_STAT_H 3 ++#define DAC_SRR_L 4 ++#define DAC_VOLUME_L 6 ++#define DAC_VOLUME_H 7 ++#define DAC_DEBUG_L 8 ++#define DAC_DEBUG_H 9 ++#define DAC_HPVOL_L 10 ++#define DAC_HPVOL_H 11 ++#define DAC_PWRDN_L 12 ++#define DAC_PWRDN_H 13 ++#define DAC_REFCTRL_L 14 ++#define DAC_REFCTRL_H 15 ++#define DAC_ANACTRL_L 16 ++#define DAC_ANACTRL_H 17 ++#define DAC_TEST_L 18 ++#define DAC_TEST_H 19 ++#define DAC_BISTCTRL_L 20 ++#define DAC_BISTCTRL_H 21 ++#define DAC_BISTSTAT0_L 22 ++#define DAC_BISTSTAT0_H 23 ++#define DAC_BISTSTAT1_L 24 ++#define DAC_BISTSTAT1_H 25 ++#define DAC_ANACLKCTRL_L 26 ++#define DAC_ANACLKCTRL_H 27 ++#define DAC_DATA_L 28 ++#define DAC_DATA_H 29 ++#define DAC_SPEAKERCTRL_L 30 ++#define DAC_SPEAKERCTRL_H 31 ++#define DAC_VERSION_L 32 ++#define DAC_VERSION_H 33 ++#define ADC_CTRL_L 34 ++#define ADC_CTRL_H 35 ++#define ADC_STAT_L 36 ++#define ADC_STAT_H 37 ++#define ADC_SRR_L 38 ++#define ADC_SRR_H 39 ++#define ADC_VOLUME_L 40 ++#define ADC_VOLUME_H 41 ++#define ADC_DEBUG_L 42 ++#define ADC_DEBUG_H 43 ++#define ADC_ADCVOL_L 44 ++#define ADC_ADCVOL_H 45 ++#define ADC_MICLINE_L 46 ++#define ADC_MICLINE_H 47 ++#define ADC_ANACLKCTRL_L 48 ++#define ADC_ANACLKCTRL_H 49 ++#define ADC_DATA_L 50 ++#define ADC_DATA_H 51 ++ ++#define ADC_REGNUM 52 ++ ++#define DAC_VOLUME_MIN 0x37 ++#define DAC_VOLUME_MAX 0xFE ++#define ADC_VOLUME_MIN 0x37 ++#define ADC_VOLUME_MAX 0xFE ++#define HP_VOLUME_MAX 0x0 ++#define HP_VOLUME_MIN 0x7F ++#define LO_VOLUME_MAX 0x0 ++#define LO_VOLUME_MIN 0x1F ++ ++/* RTC */ ++#define HW_RTC_PERSISTENT0 (0x00000060) ++#define HW_RTC_PERSISTENT0_SET (0x00000064) ++#define HW_RTC_PERSISTENT0_CLR (0x00000068) ++#define HW_RTC_PERSISTENT0_TOG (0x0000006c) ++ ++// TODO ++//#define BM_RTC_PERSISTENT0_RELEASE_GND 0x00080000 ++ ++/* AUDIOOUT */ ++#define HW_AUDIOOUT_CTRL (0x00000000) ++#define HW_AUDIOOUT_CTRL_SET (0x00000004) ++#define HW_AUDIOOUT_CTRL_CLR (0x00000008) ++#define HW_AUDIOOUT_CTRL_TOG (0x0000000c) ++ ++#define BM_AUDIOOUT_CTRL_SFTRST 0x80000000 ++#define BM_AUDIOOUT_CTRL_CLKGATE 0x40000000 ++#define BP_AUDIOOUT_CTRL_RSRVD4 21 ++#define BM_AUDIOOUT_CTRL_RSRVD4 0x3FE00000 ++#define BF_AUDIOOUT_CTRL_RSRVD4(v) \ ++ (((v) << 21) & BM_AUDIOOUT_CTRL_RSRVD4) ++#define BP_AUDIOOUT_CTRL_DMAWAIT_COUNT 16 ++#define BM_AUDIOOUT_CTRL_DMAWAIT_COUNT 0x001F0000 ++#define BF_AUDIOOUT_CTRL_DMAWAIT_COUNT(v) \ ++ (((v) << 16) & BM_AUDIOOUT_CTRL_DMAWAIT_COUNT) ++#define BM_AUDIOOUT_CTRL_RSRVD3 0x00008000 ++#define BM_AUDIOOUT_CTRL_LR_SWAP 0x00004000 ++#define BM_AUDIOOUT_CTRL_EDGE_SYNC 0x00002000 ++#define BM_AUDIOOUT_CTRL_INVERT_1BIT 0x00001000 ++#define BP_AUDIOOUT_CTRL_RSRVD2 10 ++#define BM_AUDIOOUT_CTRL_RSRVD2 0x00000C00 ++#define BF_AUDIOOUT_CTRL_RSRVD2(v) \ ++ (((v) << 10) & BM_AUDIOOUT_CTRL_RSRVD2) ++#define BP_AUDIOOUT_CTRL_SS3D_EFFECT 8 ++#define BM_AUDIOOUT_CTRL_SS3D_EFFECT 0x00000300 ++#define BF_AUDIOOUT_CTRL_SS3D_EFFECT(v) \ ++ (((v) << 8) & BM_AUDIOOUT_CTRL_SS3D_EFFECT) ++#define BM_AUDIOOUT_CTRL_RSRVD1 0x00000080 ++#define BM_AUDIOOUT_CTRL_WORD_LENGTH 0x00000040 ++#define BM_AUDIOOUT_CTRL_DAC_ZERO_ENABLE 0x00000020 ++#define BM_AUDIOOUT_CTRL_LOOPBACK 0x00000010 ++#define BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008 ++#define BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ 0x00000004 ++#define BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN 0x00000002 ++#define BM_AUDIOOUT_CTRL_RUN 0x00000001 ++ ++#define HW_AUDIOOUT_STAT (0x00000010) ++#define HW_AUDIOOUT_STAT_SET (0x00000014) ++#define HW_AUDIOOUT_STAT_CLR (0x00000018) ++#define HW_AUDIOOUT_STAT_TOG (0x0000001c) ++ ++#define BM_AUDIOOUT_STAT_DAC_PRESENT 0x80000000 ++#define BP_AUDIOOUT_STAT_RSRVD1 0 ++#define BM_AUDIOOUT_STAT_RSRVD1 0x7FFFFFFF ++#define BF_AUDIOOUT_STAT_RSRVD1(v) \ ++ (((v) << 0) & BM_AUDIOOUT_STAT_RSRVD1) ++ ++#define HW_AUDIOOUT_DACSRR (0x00000020) ++#define HW_AUDIOOUT_DACSRR_SET (0x00000024) ++#define HW_AUDIOOUT_DACSRR_CLR (0x00000028) ++#define HW_AUDIOOUT_DACSRR_TOG (0x0000002c) ++ ++#define BM_AUDIOOUT_DACSRR_OSR 0x80000000 ++#define BV_AUDIOOUT_DACSRR_OSR__OSR6 0x0 ++#define BV_AUDIOOUT_DACSRR_OSR__OSR12 0x1 ++#define BP_AUDIOOUT_DACSRR_BASEMULT 28 ++#define BM_AUDIOOUT_DACSRR_BASEMULT 0x70000000 ++#define BF_AUDIOOUT_DACSRR_BASEMULT(v) \ ++ (((v) << 28) & BM_AUDIOOUT_DACSRR_BASEMULT) ++#define BV_AUDIOOUT_DACSRR_BASEMULT__SINGLE_RATE 0x1 ++#define BV_AUDIOOUT_DACSRR_BASEMULT__DOUBLE_RATE 0x2 ++#define BV_AUDIOOUT_DACSRR_BASEMULT__QUAD_RATE 0x4 ++#define BM_AUDIOOUT_DACSRR_RSRVD2 0x08000000 ++#define BP_AUDIOOUT_DACSRR_SRC_HOLD 24 ++#define BM_AUDIOOUT_DACSRR_SRC_HOLD 0x07000000 ++#define BF_AUDIOOUT_DACSRR_SRC_HOLD(v) \ ++ (((v) << 24) & BM_AUDIOOUT_DACSRR_SRC_HOLD) ++#define BP_AUDIOOUT_DACSRR_RSRVD1 21 ++#define BM_AUDIOOUT_DACSRR_RSRVD1 0x00E00000 ++#define BF_AUDIOOUT_DACSRR_RSRVD1(v) \ ++ (((v) << 21) & BM_AUDIOOUT_DACSRR_RSRVD1) ++#define BP_AUDIOOUT_DACSRR_SRC_INT 16 ++#define BM_AUDIOOUT_DACSRR_SRC_INT 0x001F0000 ++#define BF_AUDIOOUT_DACSRR_SRC_INT(v) \ ++ (((v) << 16) & BM_AUDIOOUT_DACSRR_SRC_INT) ++#define BP_AUDIOOUT_DACSRR_RSRVD0 13 ++#define BM_AUDIOOUT_DACSRR_RSRVD0 0x0000E000 ++#define BF_AUDIOOUT_DACSRR_RSRVD0(v) \ ++ (((v) << 13) & BM_AUDIOOUT_DACSRR_RSRVD0) ++#define BP_AUDIOOUT_DACSRR_SRC_FRAC 0 ++#define BM_AUDIOOUT_DACSRR_SRC_FRAC 0x00001FFF ++#define BF_AUDIOOUT_DACSRR_SRC_FRAC(v) \ ++ (((v) << 0) & BM_AUDIOOUT_DACSRR_SRC_FRAC) ++ ++#define HW_AUDIOOUT_DACVOLUME (0x00000030) ++#define HW_AUDIOOUT_DACVOLUME_SET (0x00000034) ++#define HW_AUDIOOUT_DACVOLUME_CLR (0x00000038) ++#define HW_AUDIOOUT_DACVOLUME_TOG (0x0000003c) ++ ++#define BP_AUDIOOUT_DACVOLUME_RSRVD4 29 ++#define BM_AUDIOOUT_DACVOLUME_RSRVD4 0xE0000000 ++#define BF_AUDIOOUT_DACVOLUME_RSRVD4(v) \ ++ (((v) << 29) & BM_AUDIOOUT_DACVOLUME_RSRVD4) ++#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_LEFT 0x10000000 ++#define BP_AUDIOOUT_DACVOLUME_RSRVD3 26 ++#define BM_AUDIOOUT_DACVOLUME_RSRVD3 0x0C000000 ++#define BF_AUDIOOUT_DACVOLUME_RSRVD3(v) \ ++ (((v) << 26) & BM_AUDIOOUT_DACVOLUME_RSRVD3) ++#define BM_AUDIOOUT_DACVOLUME_EN_ZCD 0x02000000 ++#define BM_AUDIOOUT_DACVOLUME_MUTE_LEFT 0x01000000 ++#define BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT 16 ++#define BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT 0x00FF0000 ++#define BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(v) \ ++ (((v) << 16) & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) ++#define BP_AUDIOOUT_DACVOLUME_RSRVD2 13 ++#define BM_AUDIOOUT_DACVOLUME_RSRVD2 0x0000E000 ++#define BF_AUDIOOUT_DACVOLUME_RSRVD2(v) \ ++ (((v) << 13) & BM_AUDIOOUT_DACVOLUME_RSRVD2) ++#define BM_AUDIOOUT_DACVOLUME_VOLUME_UPDATE_RIGHT 0x00001000 ++#define BP_AUDIOOUT_DACVOLUME_RSRVD1 9 ++#define BM_AUDIOOUT_DACVOLUME_RSRVD1 0x00000E00 ++#define BF_AUDIOOUT_DACVOLUME_RSRVD1(v) \ ++ (((v) << 9) & BM_AUDIOOUT_DACVOLUME_RSRVD1) ++#define BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT 0x00000100 ++#define BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0 ++#define BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT 0x000000FF ++#define BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(v) \ ++ (((v) << 0) & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) ++ ++#define HW_AUDIOOUT_DACDEBUG (0x00000040) ++#define HW_AUDIOOUT_DACDEBUG_SET (0x00000044) ++#define HW_AUDIOOUT_DACDEBUG_CLR (0x00000048) ++#define HW_AUDIOOUT_DACDEBUG_TOG (0x0000004c) ++ ++#define BM_AUDIOOUT_DACDEBUG_ENABLE_DACDMA 0x80000000 ++#define BP_AUDIOOUT_DACDEBUG_RSRVD2 12 ++#define BM_AUDIOOUT_DACDEBUG_RSRVD2 0x7FFFF000 ++#define BF_AUDIOOUT_DACDEBUG_RSRVD2(v) \ ++ (((v) << 12) & BM_AUDIOOUT_DACDEBUG_RSRVD2) ++#define BP_AUDIOOUT_DACDEBUG_RAM_SS 8 ++#define BM_AUDIOOUT_DACDEBUG_RAM_SS 0x00000F00 ++#define BF_AUDIOOUT_DACDEBUG_RAM_SS(v) \ ++ (((v) << 8) & BM_AUDIOOUT_DACDEBUG_RAM_SS) ++#define BP_AUDIOOUT_DACDEBUG_RSRVD1 6 ++#define BM_AUDIOOUT_DACDEBUG_RSRVD1 0x000000C0 ++#define BF_AUDIOOUT_DACDEBUG_RSRVD1(v) \ ++ (((v) << 6) & BM_AUDIOOUT_DACDEBUG_RSRVD1) ++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_CLK_CROSS 0x00000020 ++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_CLK_CROSS 0x00000010 ++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT1_HAND_SHAKE 0x00000008 ++#define BM_AUDIOOUT_DACDEBUG_SET_INTERRUPT0_HAND_SHAKE 0x00000004 ++#define BM_AUDIOOUT_DACDEBUG_DMA_PREQ 0x00000002 ++#define BM_AUDIOOUT_DACDEBUG_FIFO_STATUS 0x00000001 ++ ++#define HW_AUDIOOUT_HPVOL (0x00000050) ++#define HW_AUDIOOUT_HPVOL_SET (0x00000054) ++#define HW_AUDIOOUT_HPVOL_CLR (0x00000058) ++#define HW_AUDIOOUT_HPVOL_TOG (0x0000005c) ++ ++#define BP_AUDIOOUT_HPVOL_RSRVD5 29 ++#define BM_AUDIOOUT_HPVOL_RSRVD5 0xE0000000 ++#define BF_AUDIOOUT_HPVOL_RSRVD5(v) \ ++ (((v) << 29) & BM_AUDIOOUT_HPVOL_RSRVD5) ++#define BM_AUDIOOUT_HPVOL_VOLUME_UPDATE_PENDING 0x10000000 ++#define BP_AUDIOOUT_HPVOL_RSRVD4 26 ++#define BM_AUDIOOUT_HPVOL_RSRVD4 0x0C000000 ++#define BF_AUDIOOUT_HPVOL_RSRVD4(v) \ ++ (((v) << 26) & BM_AUDIOOUT_HPVOL_RSRVD4) ++#define BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD 0x02000000 ++#define BM_AUDIOOUT_HPVOL_MUTE 0x01000000 ++#define BP_AUDIOOUT_HPVOL_RSRVD3 17 ++#define BM_AUDIOOUT_HPVOL_RSRVD3 0x00FE0000 ++#define BF_AUDIOOUT_HPVOL_RSRVD3(v) \ ++ (((v) << 17) & BM_AUDIOOUT_HPVOL_RSRVD3) ++#define BM_AUDIOOUT_HPVOL_SELECT 0x00010000 ++#define BM_AUDIOOUT_HPVOL_RSRVD2 0x00008000 ++#define BP_AUDIOOUT_HPVOL_VOL_LEFT 8 ++#define BM_AUDIOOUT_HPVOL_VOL_LEFT 0x00007F00 ++#define BF_AUDIOOUT_HPVOL_VOL_LEFT(v) \ ++ (((v) << 8) & BM_AUDIOOUT_HPVOL_VOL_LEFT) ++#define BM_AUDIOOUT_HPVOL_RSRVD1 0x00000080 ++#define BP_AUDIOOUT_HPVOL_VOL_RIGHT 0 ++#define BM_AUDIOOUT_HPVOL_VOL_RIGHT 0x0000007F ++#define BF_AUDIOOUT_HPVOL_VOL_RIGHT(v) \ ++ (((v) << 0) & BM_AUDIOOUT_HPVOL_VOL_RIGHT) ++ ++#define HW_AUDIOOUT_RESERVED (0x00000060) ++#define HW_AUDIOOUT_RESERVED_SET (0x00000064) ++#define HW_AUDIOOUT_RESERVED_CLR (0x00000068) ++#define HW_AUDIOOUT_RESERVED_TOG (0x0000006c) ++ ++#define BP_AUDIOOUT_RESERVED_RSRVD1 0 ++#define BM_AUDIOOUT_RESERVED_RSRVD1 0xFFFFFFFF ++#define BF_AUDIOOUT_RESERVED_RSRVD1(v) (v) ++ ++#define HW_AUDIOOUT_PWRDN (0x00000070) ++#define HW_AUDIOOUT_PWRDN_SET (0x00000074) ++#define HW_AUDIOOUT_PWRDN_CLR (0x00000078) ++#define HW_AUDIOOUT_PWRDN_TOG (0x0000007c) ++ ++#define BP_AUDIOOUT_PWRDN_RSRVD7 25 ++#define BM_AUDIOOUT_PWRDN_RSRVD7 0xFE000000 ++#define BF_AUDIOOUT_PWRDN_RSRVD7(v) \ ++ (((v) << 25) & BM_AUDIOOUT_PWRDN_RSRVD7) ++#define BM_AUDIOOUT_PWRDN_SPEAKER 0x01000000 ++#define BP_AUDIOOUT_PWRDN_RSRVD6 21 ++#define BM_AUDIOOUT_PWRDN_RSRVD6 0x00E00000 ++#define BF_AUDIOOUT_PWRDN_RSRVD6(v) \ ++ (((v) << 21) & BM_AUDIOOUT_PWRDN_RSRVD6) ++#define BM_AUDIOOUT_PWRDN_SELFBIAS 0x00100000 ++#define BP_AUDIOOUT_PWRDN_RSRVD5 17 ++#define BM_AUDIOOUT_PWRDN_RSRVD5 0x000E0000 ++#define BF_AUDIOOUT_PWRDN_RSRVD5(v) \ ++ (((v) << 17) & BM_AUDIOOUT_PWRDN_RSRVD5) ++#define BM_AUDIOOUT_PWRDN_RIGHT_ADC 0x00010000 ++#define BP_AUDIOOUT_PWRDN_RSRVD4 13 ++#define BM_AUDIOOUT_PWRDN_RSRVD4 0x0000E000 ++#define BF_AUDIOOUT_PWRDN_RSRVD4(v) \ ++ (((v) << 13) & BM_AUDIOOUT_PWRDN_RSRVD4) ++#define BM_AUDIOOUT_PWRDN_DAC 0x00001000 ++#define BP_AUDIOOUT_PWRDN_RSRVD3 9 ++#define BM_AUDIOOUT_PWRDN_RSRVD3 0x00000E00 ++#define BF_AUDIOOUT_PWRDN_RSRVD3(v) \ ++ (((v) << 9) & BM_AUDIOOUT_PWRDN_RSRVD3) ++#define BM_AUDIOOUT_PWRDN_ADC 0x00000100 ++#define BP_AUDIOOUT_PWRDN_RSRVD2 5 ++#define BM_AUDIOOUT_PWRDN_RSRVD2 0x000000E0 ++#define BF_AUDIOOUT_PWRDN_RSRVD2(v) \ ++ (((v) << 5) & BM_AUDIOOUT_PWRDN_RSRVD2) ++#define BM_AUDIOOUT_PWRDN_CAPLESS 0x00000010 ++#define BP_AUDIOOUT_PWRDN_RSRVD1 1 ++#define BM_AUDIOOUT_PWRDN_RSRVD1 0x0000000E ++#define BF_AUDIOOUT_PWRDN_RSRVD1(v) \ ++ (((v) << 1) & BM_AUDIOOUT_PWRDN_RSRVD1) ++#define BM_AUDIOOUT_PWRDN_HEADPHONE 0x00000001 ++ ++#define HW_AUDIOOUT_REFCTRL (0x00000080) ++#define HW_AUDIOOUT_REFCTRL_SET (0x00000084) ++#define HW_AUDIOOUT_REFCTRL_CLR (0x00000088) ++#define HW_AUDIOOUT_REFCTRL_TOG (0x0000008c) ++ ++#define BP_AUDIOOUT_REFCTRL_RSRVD4 27 ++#define BM_AUDIOOUT_REFCTRL_RSRVD4 0xF8000000 ++#define BF_AUDIOOUT_REFCTRL_RSRVD4(v) \ ++ (((v) << 27) & BM_AUDIOOUT_REFCTRL_RSRVD4) ++#define BM_AUDIOOUT_REFCTRL_FASTSETTLING 0x04000000 ++#define BM_AUDIOOUT_REFCTRL_RAISE_REF 0x02000000 ++#define BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS 0x01000000 ++#define BM_AUDIOOUT_REFCTRL_RSRVD3 0x00800000 ++#define BP_AUDIOOUT_REFCTRL_VBG_ADJ 20 ++#define BM_AUDIOOUT_REFCTRL_VBG_ADJ 0x00700000 ++#define BF_AUDIOOUT_REFCTRL_VBG_ADJ(v) \ ++ (((v) << 20) & BM_AUDIOOUT_REFCTRL_VBG_ADJ) ++#define BM_AUDIOOUT_REFCTRL_LOW_PWR 0x00080000 ++#define BM_AUDIOOUT_REFCTRL_LW_REF 0x00040000 ++#define BP_AUDIOOUT_REFCTRL_BIAS_CTRL 16 ++#define BM_AUDIOOUT_REFCTRL_BIAS_CTRL 0x00030000 ++#define BF_AUDIOOUT_REFCTRL_BIAS_CTRL(v) \ ++ (((v) << 16) & BM_AUDIOOUT_REFCTRL_BIAS_CTRL) ++#define BM_AUDIOOUT_REFCTRL_RSRVD2 0x00008000 ++#define BM_AUDIOOUT_REFCTRL_VDDXTAL_TO_VDDD 0x00004000 ++#define BM_AUDIOOUT_REFCTRL_ADJ_ADC 0x00002000 ++#define BM_AUDIOOUT_REFCTRL_ADJ_VAG 0x00001000 ++#define BP_AUDIOOUT_REFCTRL_ADC_REFVAL 8 ++#define BM_AUDIOOUT_REFCTRL_ADC_REFVAL 0x00000F00 ++#define BF_AUDIOOUT_REFCTRL_ADC_REFVAL(v) \ ++ (((v) << 8) & BM_AUDIOOUT_REFCTRL_ADC_REFVAL) ++#define BP_AUDIOOUT_REFCTRL_VAG_VAL 4 ++#define BM_AUDIOOUT_REFCTRL_VAG_VAL 0x000000F0 ++#define BF_AUDIOOUT_REFCTRL_VAG_VAL(v) \ ++ (((v) << 4) & BM_AUDIOOUT_REFCTRL_VAG_VAL) ++#define BM_AUDIOOUT_REFCTRL_RSRVD1 0x00000008 ++#define BP_AUDIOOUT_REFCTRL_DAC_ADJ 0 ++#define BM_AUDIOOUT_REFCTRL_DAC_ADJ 0x00000007 ++#define BF_AUDIOOUT_REFCTRL_DAC_ADJ(v) \ ++ (((v) << 0) & BM_AUDIOOUT_REFCTRL_DAC_ADJ) ++ ++#define HW_AUDIOOUT_ANACTRL (0x00000090) ++#define HW_AUDIOOUT_ANACTRL_SET (0x00000094) ++#define HW_AUDIOOUT_ANACTRL_CLR (0x00000098) ++#define HW_AUDIOOUT_ANACTRL_TOG (0x0000009c) ++ ++#define BP_AUDIOOUT_ANACTRL_RSRVD8 29 ++#define BM_AUDIOOUT_ANACTRL_RSRVD8 0xE0000000 ++#define BF_AUDIOOUT_ANACTRL_RSRVD8(v) \ ++ (((v) << 29) & BM_AUDIOOUT_ANACTRL_RSRVD8) ++#define BM_AUDIOOUT_ANACTRL_SHORT_CM_STS 0x10000000 ++#define BP_AUDIOOUT_ANACTRL_RSRVD7 25 ++#define BM_AUDIOOUT_ANACTRL_RSRVD7 0x0E000000 ++#define BF_AUDIOOUT_ANACTRL_RSRVD7(v) \ ++ (((v) << 25) & BM_AUDIOOUT_ANACTRL_RSRVD7) ++#define BM_AUDIOOUT_ANACTRL_SHORT_LR_STS 0x01000000 ++#define BP_AUDIOOUT_ANACTRL_RSRVD6 22 ++#define BM_AUDIOOUT_ANACTRL_RSRVD6 0x00C00000 ++#define BF_AUDIOOUT_ANACTRL_RSRVD6(v) \ ++ (((v) << 22) & BM_AUDIOOUT_ANACTRL_RSRVD6) ++#define BP_AUDIOOUT_ANACTRL_SHORTMODE_CM 20 ++#define BM_AUDIOOUT_ANACTRL_SHORTMODE_CM 0x00300000 ++#define BF_AUDIOOUT_ANACTRL_SHORTMODE_CM(v) \ ++ (((v) << 20) & BM_AUDIOOUT_ANACTRL_SHORTMODE_CM) ++#define BM_AUDIOOUT_ANACTRL_RSRVD5 0x00080000 ++#define BP_AUDIOOUT_ANACTRL_SHORTMODE_LR 17 ++#define BM_AUDIOOUT_ANACTRL_SHORTMODE_LR 0x00060000 ++#define BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(v) \ ++ (((v) << 17) & BM_AUDIOOUT_ANACTRL_SHORTMODE_LR) ++#define BP_AUDIOOUT_ANACTRL_RSRVD4 15 ++#define BM_AUDIOOUT_ANACTRL_RSRVD4 0x00018000 ++#define BF_AUDIOOUT_ANACTRL_RSRVD4(v) \ ++ (((v) << 15) & BM_AUDIOOUT_ANACTRL_RSRVD4) ++#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJL 12 ++#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL 0x00007000 ++#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJL(v) \ ++ (((v) << 12) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL) ++#define BM_AUDIOOUT_ANACTRL_RSRVD3 0x00000800 ++#define BP_AUDIOOUT_ANACTRL_SHORT_LVLADJR 8 ++#define BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR 0x00000700 ++#define BF_AUDIOOUT_ANACTRL_SHORT_LVLADJR(v) \ ++ (((v) << 8) & BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR) ++#define BP_AUDIOOUT_ANACTRL_RSRVD2 6 ++#define BM_AUDIOOUT_ANACTRL_RSRVD2 0x000000C0 ++#define BF_AUDIOOUT_ANACTRL_RSRVD2(v) \ ++ (((v) << 6) & BM_AUDIOOUT_ANACTRL_RSRVD2) ++#define BM_AUDIOOUT_ANACTRL_HP_HOLD_GND 0x00000020 ++#define BM_AUDIOOUT_ANACTRL_HP_CLASSAB 0x00000010 ++#define BP_AUDIOOUT_ANACTRL_RSRVD1 0 ++#define BM_AUDIOOUT_ANACTRL_RSRVD1 0x0000000F ++#define BF_AUDIOOUT_ANACTRL_RSRVD1(v) \ ++ (((v) << 0) & BM_AUDIOOUT_ANACTRL_RSRVD1) ++ ++#define HW_AUDIOOUT_TEST (0x000000a0) ++#define HW_AUDIOOUT_TEST_SET (0x000000a4) ++#define HW_AUDIOOUT_TEST_CLR (0x000000a8) ++#define HW_AUDIOOUT_TEST_TOG (0x000000ac) ++ ++#define BM_AUDIOOUT_TEST_RSRVD4 0x80000000 ++#define BP_AUDIOOUT_TEST_HP_ANTIPOP 28 ++#define BM_AUDIOOUT_TEST_HP_ANTIPOP 0x70000000 ++#define BF_AUDIOOUT_TEST_HP_ANTIPOP(v) \ ++ (((v) << 28) & BM_AUDIOOUT_TEST_HP_ANTIPOP) ++#define BM_AUDIOOUT_TEST_RSRVD3 0x08000000 ++#define BM_AUDIOOUT_TEST_TM_ADCIN_TOHP 0x04000000 ++#define BM_AUDIOOUT_TEST_TM_LOOP 0x02000000 ++#define BM_AUDIOOUT_TEST_TM_HPCOMMON 0x01000000 ++#define BP_AUDIOOUT_TEST_HP_I1_ADJ 22 ++#define BM_AUDIOOUT_TEST_HP_I1_ADJ 0x00C00000 ++#define BF_AUDIOOUT_TEST_HP_I1_ADJ(v) \ ++ (((v) << 22) & BM_AUDIOOUT_TEST_HP_I1_ADJ) ++#define BP_AUDIOOUT_TEST_HP_IALL_ADJ 20 ++#define BM_AUDIOOUT_TEST_HP_IALL_ADJ 0x00300000 ++#define BF_AUDIOOUT_TEST_HP_IALL_ADJ(v) \ ++ (((v) << 20) & BM_AUDIOOUT_TEST_HP_IALL_ADJ) ++#define BP_AUDIOOUT_TEST_RSRVD2 14 ++#define BM_AUDIOOUT_TEST_RSRVD2 0x000FC000 ++#define BF_AUDIOOUT_TEST_RSRVD2(v) \ ++ (((v) << 14) & BM_AUDIOOUT_TEST_RSRVD2) ++#define BM_AUDIOOUT_TEST_VAG_CLASSA 0x00002000 ++#define BM_AUDIOOUT_TEST_VAG_DOUBLE_I 0x00001000 ++#define BP_AUDIOOUT_TEST_RSRVD1 4 ++#define BM_AUDIOOUT_TEST_RSRVD1 0x00000FF0 ++#define BF_AUDIOOUT_TEST_RSRVD1(v) \ ++ (((v) << 4) & BM_AUDIOOUT_TEST_RSRVD1) ++#define BM_AUDIOOUT_TEST_ADCTODAC_LOOP 0x00000008 ++#define BM_AUDIOOUT_TEST_DAC_CLASSA 0x00000004 ++#define BM_AUDIOOUT_TEST_DAC_DOUBLE_I 0x00000002 ++#define BM_AUDIOOUT_TEST_DAC_DIS_RTZ 0x00000001 ++ ++#define HW_AUDIOOUT_BISTCTRL (0x000000b0) ++#define HW_AUDIOOUT_BISTCTRL_SET (0x000000b4) ++#define HW_AUDIOOUT_BISTCTRL_CLR (0x000000b8) ++#define HW_AUDIOOUT_BISTCTRL_TOG (0x000000bc) ++ ++#define BP_AUDIOOUT_BISTCTRL_RSVD0 4 ++#define BM_AUDIOOUT_BISTCTRL_RSVD0 0xFFFFFFF0 ++#define BF_AUDIOOUT_BISTCTRL_RSVD0(v) \ ++ (((v) << 4) & BM_AUDIOOUT_BISTCTRL_RSVD0) ++#define BM_AUDIOOUT_BISTCTRL_FAIL 0x00000008 ++#define BM_AUDIOOUT_BISTCTRL_PASS 0x00000004 ++#define BM_AUDIOOUT_BISTCTRL_DONE 0x00000002 ++#define BM_AUDIOOUT_BISTCTRL_START 0x00000001 ++ ++#define HW_AUDIOOUT_BISTSTAT0 (0x000000c0) ++#define HW_AUDIOOUT_BISTSTAT0_SET (0x000000c4) ++#define HW_AUDIOOUT_BISTSTAT0_CLR (0x000000c8) ++#define HW_AUDIOOUT_BISTSTAT0_TOG (0x000000cc) ++ ++#define BP_AUDIOOUT_BISTSTAT0_RSVD0 24 ++#define BM_AUDIOOUT_BISTSTAT0_RSVD0 0xFF000000 ++#define BF_AUDIOOUT_BISTSTAT0_RSVD0(v) \ ++ (((v) << 24) & BM_AUDIOOUT_BISTSTAT0_RSVD0) ++#define BP_AUDIOOUT_BISTSTAT0_DATA 0 ++#define BM_AUDIOOUT_BISTSTAT0_DATA 0x00FFFFFF ++#define BF_AUDIOOUT_BISTSTAT0_DATA(v) \ ++ (((v) << 0) & BM_AUDIOOUT_BISTSTAT0_DATA) ++ ++#define HW_AUDIOOUT_BISTSTAT1 (0x000000d0) ++#define HW_AUDIOOUT_BISTSTAT1_SET (0x000000d4) ++#define HW_AUDIOOUT_BISTSTAT1_CLR (0x000000d8) ++#define HW_AUDIOOUT_BISTSTAT1_TOG (0x000000dc) ++ ++#define BP_AUDIOOUT_BISTSTAT1_RSVD1 29 ++#define BM_AUDIOOUT_BISTSTAT1_RSVD1 0xE0000000 ++#define BF_AUDIOOUT_BISTSTAT1_RSVD1(v) \ ++ (((v) << 29) & BM_AUDIOOUT_BISTSTAT1_RSVD1) ++#define BP_AUDIOOUT_BISTSTAT1_STATE 24 ++#define BM_AUDIOOUT_BISTSTAT1_STATE 0x1F000000 ++#define BF_AUDIOOUT_BISTSTAT1_STATE(v) \ ++ (((v) << 24) & BM_AUDIOOUT_BISTSTAT1_STATE) ++#define BP_AUDIOOUT_BISTSTAT1_RSVD0 8 ++#define BM_AUDIOOUT_BISTSTAT1_RSVD0 0x00FFFF00 ++#define BF_AUDIOOUT_BISTSTAT1_RSVD0(v) \ ++ (((v) << 8) & BM_AUDIOOUT_BISTSTAT1_RSVD0) ++#define BP_AUDIOOUT_BISTSTAT1_ADDR 0 ++#define BM_AUDIOOUT_BISTSTAT1_ADDR 0x000000FF ++#define BF_AUDIOOUT_BISTSTAT1_ADDR(v) \ ++ (((v) << 0) & BM_AUDIOOUT_BISTSTAT1_ADDR) ++ ++#define HW_AUDIOOUT_ANACLKCTRL (0x000000e0) ++#define HW_AUDIOOUT_ANACLKCTRL_SET (0x000000e4) ++#define HW_AUDIOOUT_ANACLKCTRL_CLR (0x000000e8) ++#define HW_AUDIOOUT_ANACLKCTRL_TOG (0x000000ec) ++ ++#define BM_AUDIOOUT_ANACLKCTRL_CLKGATE 0x80000000 ++#define BP_AUDIOOUT_ANACLKCTRL_RSRVD3 5 ++#define BM_AUDIOOUT_ANACLKCTRL_RSRVD3 0x7FFFFFE0 ++#define BF_AUDIOOUT_ANACLKCTRL_RSRVD3(v) \ ++ (((v) << 5) & BM_AUDIOOUT_ANACLKCTRL_RSRVD3) ++#define BM_AUDIOOUT_ANACLKCTRL_INVERT_DACCLK 0x00000010 ++#define BM_AUDIOOUT_ANACLKCTRL_RSRVD2 0x00000008 ++#define BP_AUDIOOUT_ANACLKCTRL_DACDIV 0 ++#define BM_AUDIOOUT_ANACLKCTRL_DACDIV 0x00000007 ++#define BF_AUDIOOUT_ANACLKCTRL_DACDIV(v) \ ++ (((v) << 0) & BM_AUDIOOUT_ANACLKCTRL_DACDIV) ++ ++#define HW_AUDIOOUT_DATA (0x000000f0) ++#define HW_AUDIOOUT_DATA_SET (0x000000f4) ++#define HW_AUDIOOUT_DATA_CLR (0x000000f8) ++#define HW_AUDIOOUT_DATA_TOG (0x000000fc) ++ ++#define BP_AUDIOOUT_DATA_HIGH 16 ++#define BM_AUDIOOUT_DATA_HIGH 0xFFFF0000 ++#define BF_AUDIOOUT_DATA_HIGH(v) \ ++ (((v) << 16) & BM_AUDIOOUT_DATA_HIGH) ++#define BP_AUDIOOUT_DATA_LOW 0 ++#define BM_AUDIOOUT_DATA_LOW 0x0000FFFF ++#define BF_AUDIOOUT_DATA_LOW(v) \ ++ (((v) << 0) & BM_AUDIOOUT_DATA_LOW) ++ ++#define HW_AUDIOOUT_SPEAKERCTRL (0x00000100) ++#define HW_AUDIOOUT_SPEAKERCTRL_SET (0x00000104) ++#define HW_AUDIOOUT_SPEAKERCTRL_CLR (0x00000108) ++#define HW_AUDIOOUT_SPEAKERCTRL_TOG (0x0000010c) ++ ++#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD2 25 ++#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD2 0xFE000000 ++#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD2(v) \ ++ (((v) << 25) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD2) ++#define BM_AUDIOOUT_SPEAKERCTRL_MUTE 0x01000000 ++#define BP_AUDIOOUT_SPEAKERCTRL_I1_ADJ 22 ++#define BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ 0x00C00000 ++#define BF_AUDIOOUT_SPEAKERCTRL_I1_ADJ(v) \ ++ (((v) << 22) & BM_AUDIOOUT_SPEAKERCTRL_I1_ADJ) ++#define BP_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 20 ++#define BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ 0x00300000 ++#define BF_AUDIOOUT_SPEAKERCTRL_IALL_ADJ(v) \ ++ (((v) << 20) & BM_AUDIOOUT_SPEAKERCTRL_IALL_ADJ) ++#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD1 16 ++#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD1 0x000F0000 ++#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD1(v) \ ++ (((v) << 16) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD1) ++#define BP_AUDIOOUT_SPEAKERCTRL_POSDRIVER 14 ++#define BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER 0x0000C000 ++#define BF_AUDIOOUT_SPEAKERCTRL_POSDRIVER(v) \ ++ (((v) << 14) & BM_AUDIOOUT_SPEAKERCTRL_POSDRIVER) ++#define BP_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 12 ++#define BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER 0x00003000 ++#define BF_AUDIOOUT_SPEAKERCTRL_NEGDRIVER(v) \ ++ (((v) << 12) & BM_AUDIOOUT_SPEAKERCTRL_NEGDRIVER) ++#define BP_AUDIOOUT_SPEAKERCTRL_RSRVD0 0 ++#define BM_AUDIOOUT_SPEAKERCTRL_RSRVD0 0x00000FFF ++#define BF_AUDIOOUT_SPEAKERCTRL_RSRVD0(v) \ ++ (((v) << 0) & BM_AUDIOOUT_SPEAKERCTRL_RSRVD0) ++ ++#define HW_AUDIOOUT_VERSION (0x00000200) ++ ++#define BP_AUDIOOUT_VERSION_MAJOR 24 ++#define BM_AUDIOOUT_VERSION_MAJOR 0xFF000000 ++#define BF_AUDIOOUT_VERSION_MAJOR(v) \ ++ (((v) << 24) & BM_AUDIOOUT_VERSION_MAJOR) ++#define BP_AUDIOOUT_VERSION_MINOR 16 ++#define BM_AUDIOOUT_VERSION_MINOR 0x00FF0000 ++#define BF_AUDIOOUT_VERSION_MINOR(v) \ ++ (((v) << 16) & BM_AUDIOOUT_VERSION_MINOR) ++#define BP_AUDIOOUT_VERSION_STEP 0 ++#define BM_AUDIOOUT_VERSION_STEP 0x0000FFFF ++#define BF_AUDIOOUT_VERSION_STEP(v) \ ++ (((v) << 0) & BM_AUDIOOUT_VERSION_STEP) ++ ++/* AUDIOIN */ ++#define HW_AUDIOIN_CTRL (0x00000000) ++#define HW_AUDIOIN_CTRL_SET (0x00000004) ++#define HW_AUDIOIN_CTRL_CLR (0x00000008) ++#define HW_AUDIOIN_CTRL_TOG (0x0000000c) ++ ++#define BM_AUDIOIN_CTRL_SFTRST 0x80000000 ++#define BM_AUDIOIN_CTRL_CLKGATE 0x40000000 ++#define BP_AUDIOIN_CTRL_RSRVD3 21 ++#define BM_AUDIOIN_CTRL_RSRVD3 0x3FE00000 ++#define BF_AUDIOIN_CTRL_RSRVD3(v) \ ++ (((v) << 21) & BM_AUDIOIN_CTRL_RSRVD3) ++#define BP_AUDIOIN_CTRL_DMAWAIT_COUNT 16 ++#define BM_AUDIOIN_CTRL_DMAWAIT_COUNT 0x001F0000 ++#define BF_AUDIOIN_CTRL_DMAWAIT_COUNT(v) \ ++ (((v) << 16) & BM_AUDIOIN_CTRL_DMAWAIT_COUNT) ++#define BP_AUDIOIN_CTRL_RSRVD1 11 ++#define BM_AUDIOIN_CTRL_RSRVD1 0x0000F800 ++#define BF_AUDIOIN_CTRL_RSRVD1(v) \ ++ (((v) << 11) & BM_AUDIOIN_CTRL_RSRVD1) ++#define BM_AUDIOIN_CTRL_LR_SWAP 0x00000400 ++#define BM_AUDIOIN_CTRL_EDGE_SYNC 0x00000200 ++#define BM_AUDIOIN_CTRL_INVERT_1BIT 0x00000100 ++#define BM_AUDIOIN_CTRL_OFFSET_ENABLE 0x00000080 ++#define BM_AUDIOIN_CTRL_HPF_ENABLE 0x00000040 ++#define BM_AUDIOIN_CTRL_WORD_LENGTH 0x00000020 ++#define BM_AUDIOIN_CTRL_LOOPBACK 0x00000010 ++#define BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ 0x00000008 ++#define BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ 0x00000004 ++#define BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN 0x00000002 ++#define BM_AUDIOIN_CTRL_RUN 0x00000001 ++ ++#define HW_AUDIOIN_STAT (0x00000010) ++#define HW_AUDIOIN_STAT_SET (0x00000014) ++#define HW_AUDIOIN_STAT_CLR (0x00000018) ++#define HW_AUDIOIN_STAT_TOG (0x0000001c) ++ ++#define BM_AUDIOIN_STAT_ADC_PRESENT 0x80000000 ++#define BP_AUDIOIN_STAT_RSRVD3 0 ++#define BM_AUDIOIN_STAT_RSRVD3 0x7FFFFFFF ++#define BF_AUDIOIN_STAT_RSRVD3(v) \ ++ (((v) << 0) & BM_AUDIOIN_STAT_RSRVD3) ++ ++#define HW_AUDIOIN_ADCSRR (0x00000020) ++#define HW_AUDIOIN_ADCSRR_SET (0x00000024) ++#define HW_AUDIOIN_ADCSRR_CLR (0x00000028) ++#define HW_AUDIOIN_ADCSRR_TOG (0x0000002c) ++ ++#define BM_AUDIOIN_ADCSRR_OSR 0x80000000 ++#define BV_AUDIOIN_ADCSRR_OSR__OSR6 0x0 ++#define BV_AUDIOIN_ADCSRR_OSR__OSR12 0x1 ++#define BP_AUDIOIN_ADCSRR_BASEMULT 28 ++#define BM_AUDIOIN_ADCSRR_BASEMULT 0x70000000 ++#define BF_AUDIOIN_ADCSRR_BASEMULT(v) \ ++ (((v) << 28) & BM_AUDIOIN_ADCSRR_BASEMULT) ++#define BV_AUDIOIN_ADCSRR_BASEMULT__SINGLE_RATE 0x1 ++#define BV_AUDIOIN_ADCSRR_BASEMULT__DOUBLE_RATE 0x2 ++#define BV_AUDIOIN_ADCSRR_BASEMULT__QUAD_RATE 0x4 ++#define BM_AUDIOIN_ADCSRR_RSRVD2 0x08000000 ++#define BP_AUDIOIN_ADCSRR_SRC_HOLD 24 ++#define BM_AUDIOIN_ADCSRR_SRC_HOLD 0x07000000 ++#define BF_AUDIOIN_ADCSRR_SRC_HOLD(v) \ ++ (((v) << 24) & BM_AUDIOIN_ADCSRR_SRC_HOLD) ++#define BP_AUDIOIN_ADCSRR_RSRVD1 21 ++#define BM_AUDIOIN_ADCSRR_RSRVD1 0x00E00000 ++#define BF_AUDIOIN_ADCSRR_RSRVD1(v) \ ++ (((v) << 21) & BM_AUDIOIN_ADCSRR_RSRVD1) ++#define BP_AUDIOIN_ADCSRR_SRC_INT 16 ++#define BM_AUDIOIN_ADCSRR_SRC_INT 0x001F0000 ++#define BF_AUDIOIN_ADCSRR_SRC_INT(v) \ ++ (((v) << 16) & BM_AUDIOIN_ADCSRR_SRC_INT) ++#define BP_AUDIOIN_ADCSRR_RSRVD0 13 ++#define BM_AUDIOIN_ADCSRR_RSRVD0 0x0000E000 ++#define BF_AUDIOIN_ADCSRR_RSRVD0(v) \ ++ (((v) << 13) & BM_AUDIOIN_ADCSRR_RSRVD0) ++#define BP_AUDIOIN_ADCSRR_SRC_FRAC 0 ++#define BM_AUDIOIN_ADCSRR_SRC_FRAC 0x00001FFF ++#define BF_AUDIOIN_ADCSRR_SRC_FRAC(v) \ ++ (((v) << 0) & BM_AUDIOIN_ADCSRR_SRC_FRAC) ++ ++#define HW_AUDIOIN_ADCVOLUME (0x00000030) ++#define HW_AUDIOIN_ADCVOLUME_SET (0x00000034) ++#define HW_AUDIOIN_ADCVOLUME_CLR (0x00000038) ++#define HW_AUDIOIN_ADCVOLUME_TOG (0x0000003c) ++ ++#define BP_AUDIOIN_ADCVOLUME_RSRVD5 29 ++#define BM_AUDIOIN_ADCVOLUME_RSRVD5 0xE0000000 ++#define BF_AUDIOIN_ADCVOLUME_RSRVD5(v) \ ++ (((v) << 29) & BM_AUDIOIN_ADCVOLUME_RSRVD5) ++#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_LEFT 0x10000000 ++#define BP_AUDIOIN_ADCVOLUME_RSRVD4 26 ++#define BM_AUDIOIN_ADCVOLUME_RSRVD4 0x0C000000 ++#define BF_AUDIOIN_ADCVOLUME_RSRVD4(v) \ ++ (((v) << 26) & BM_AUDIOIN_ADCVOLUME_RSRVD4) ++#define BM_AUDIOIN_ADCVOLUME_EN_ZCD 0x02000000 ++#define BM_AUDIOIN_ADCVOLUME_RSRVD3 0x01000000 ++#define BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT 16 ++#define BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT 0x00FF0000 ++#define BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(v) \ ++ (((v) << 16) & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT) ++#define BP_AUDIOIN_ADCVOLUME_RSRVD2 13 ++#define BM_AUDIOIN_ADCVOLUME_RSRVD2 0x0000E000 ++#define BF_AUDIOIN_ADCVOLUME_RSRVD2(v) \ ++ (((v) << 13) & BM_AUDIOIN_ADCVOLUME_RSRVD2) ++#define BM_AUDIOIN_ADCVOLUME_VOLUME_UPDATE_RIGHT 0x00001000 ++#define BP_AUDIOIN_ADCVOLUME_RSRVD1 8 ++#define BM_AUDIOIN_ADCVOLUME_RSRVD1 0x00000F00 ++#define BF_AUDIOIN_ADCVOLUME_RSRVD1(v) \ ++ (((v) << 8) & BM_AUDIOIN_ADCVOLUME_RSRVD1) ++#define BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0 ++#define BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT 0x000000FF ++#define BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(v) \ ++ (((v) << 0) & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT) ++ ++#define HW_AUDIOIN_ADCDEBUG (0x00000040) ++#define HW_AUDIOIN_ADCDEBUG_SET (0x00000044) ++#define HW_AUDIOIN_ADCDEBUG_CLR (0x00000048) ++#define HW_AUDIOIN_ADCDEBUG_TOG (0x0000004c) ++ ++#define BM_AUDIOIN_ADCDEBUG_ENABLE_ADCDMA 0x80000000 ++#define BP_AUDIOIN_ADCDEBUG_RSRVD1 4 ++#define BM_AUDIOIN_ADCDEBUG_RSRVD1 0x7FFFFFF0 ++#define BF_AUDIOIN_ADCDEBUG_RSRVD1(v) \ ++ (((v) << 4) & BM_AUDIOIN_ADCDEBUG_RSRVD1) ++#define BM_AUDIOIN_ADCDEBUG_ADC_DMA_REQ_HAND_SHAKE_CLK_CROSS 0x00000008 ++#define BM_AUDIOIN_ADCDEBUG_SET_INTERRUPT3_HAND_SHAKE 0x00000004 ++#define BM_AUDIOIN_ADCDEBUG_DMA_PREQ 0x00000002 ++#define BM_AUDIOIN_ADCDEBUG_FIFO_STATUS 0x00000001 ++ ++#define HW_AUDIOIN_ADCVOL (0x00000050) ++#define HW_AUDIOIN_ADCVOL_SET (0x00000054) ++#define HW_AUDIOIN_ADCVOL_CLR (0x00000058) ++#define HW_AUDIOIN_ADCVOL_TOG (0x0000005c) ++ ++#define BP_AUDIOIN_ADCVOL_RSRVD4 29 ++#define BM_AUDIOIN_ADCVOL_RSRVD4 0xE0000000 ++#define BF_AUDIOIN_ADCVOL_RSRVD4(v) \ ++ (((v) << 29) & BM_AUDIOIN_ADCVOL_RSRVD4) ++#define BM_AUDIOIN_ADCVOL_VOLUME_UPDATE_PENDING 0x10000000 ++#define BP_AUDIOIN_ADCVOL_RSRVD3 26 ++#define BM_AUDIOIN_ADCVOL_RSRVD3 0x0C000000 ++#define BF_AUDIOIN_ADCVOL_RSRVD3(v) \ ++ (((v) << 26) & BM_AUDIOIN_ADCVOL_RSRVD3) ++#define BM_AUDIOIN_ADCVOL_EN_ADC_ZCD 0x02000000 ++#define BM_AUDIOIN_ADCVOL_MUTE 0x01000000 ++#define BP_AUDIOIN_ADCVOL_RSRVD2 14 ++#define BM_AUDIOIN_ADCVOL_RSRVD2 0x00FFC000 ++#define BF_AUDIOIN_ADCVOL_RSRVD2(v) \ ++ (((v) << 14) & BM_AUDIOIN_ADCVOL_RSRVD2) ++#define BP_AUDIOIN_ADCVOL_SELECT_LEFT 12 ++#define BM_AUDIOIN_ADCVOL_SELECT_LEFT 0x00003000 ++#define BF_AUDIOIN_ADCVOL_SELECT_LEFT(v) \ ++ (((v) << 12) & BM_AUDIOIN_ADCVOL_SELECT_LEFT) ++#define BP_AUDIOIN_ADCVOL_GAIN_LEFT 8 ++#define BM_AUDIOIN_ADCVOL_GAIN_LEFT 0x00000F00 ++#define BF_AUDIOIN_ADCVOL_GAIN_LEFT(v) \ ++ (((v) << 8) & BM_AUDIOIN_ADCVOL_GAIN_LEFT) ++#define BP_AUDIOIN_ADCVOL_RSRVD1 6 ++#define BM_AUDIOIN_ADCVOL_RSRVD1 0x000000C0 ++#define BF_AUDIOIN_ADCVOL_RSRVD1(v) \ ++ (((v) << 6) & BM_AUDIOIN_ADCVOL_RSRVD1) ++#define BP_AUDIOIN_ADCVOL_SELECT_RIGHT 4 ++#define BM_AUDIOIN_ADCVOL_SELECT_RIGHT 0x00000030 ++#define BF_AUDIOIN_ADCVOL_SELECT_RIGHT(v) \ ++ (((v) << 4) & BM_AUDIOIN_ADCVOL_SELECT_RIGHT) ++#define BP_AUDIOIN_ADCVOL_GAIN_RIGHT 0 ++#define BM_AUDIOIN_ADCVOL_GAIN_RIGHT 0x0000000F ++#define BF_AUDIOIN_ADCVOL_GAIN_RIGHT(v) \ ++ (((v) << 0) & BM_AUDIOIN_ADCVOL_GAIN_RIGHT) ++ ++#define HW_AUDIOIN_MICLINE (0x00000060) ++#define HW_AUDIOIN_MICLINE_SET (0x00000064) ++#define HW_AUDIOIN_MICLINE_CLR (0x00000068) ++#define HW_AUDIOIN_MICLINE_TOG (0x0000006c) ++ ++#define BP_AUDIOIN_MICLINE_RSRVD6 30 ++#define BM_AUDIOIN_MICLINE_RSRVD6 0xC0000000 ++#define BF_AUDIOIN_MICLINE_RSRVD6(v) \ ++ (((v) << 30) & BM_AUDIOIN_MICLINE_RSRVD6) ++#define BM_AUDIOIN_MICLINE_DIVIDE_LINE1 0x20000000 ++#define BM_AUDIOIN_MICLINE_DIVIDE_LINE2 0x10000000 ++#define BP_AUDIOIN_MICLINE_RSRVD5 25 ++#define BM_AUDIOIN_MICLINE_RSRVD5 0x0E000000 ++#define BF_AUDIOIN_MICLINE_RSRVD5(v) \ ++ (((v) << 25) & BM_AUDIOIN_MICLINE_RSRVD5) ++#define BM_AUDIOIN_MICLINE_MIC_SELECT 0x01000000 ++#define BP_AUDIOIN_MICLINE_RSRVD4 22 ++#define BM_AUDIOIN_MICLINE_RSRVD4 0x00C00000 ++#define BF_AUDIOIN_MICLINE_RSRVD4(v) \ ++ (((v) << 22) & BM_AUDIOIN_MICLINE_RSRVD4) ++#define BP_AUDIOIN_MICLINE_MIC_RESISTOR 20 ++#define BM_AUDIOIN_MICLINE_MIC_RESISTOR 0x00300000 ++#define BF_AUDIOIN_MICLINE_MIC_RESISTOR(v) \ ++ (((v) << 20) & BM_AUDIOIN_MICLINE_MIC_RESISTOR) ++#define BM_AUDIOIN_MICLINE_RSRVD3 0x00080000 ++#define BP_AUDIOIN_MICLINE_MIC_BIAS 16 ++#define BM_AUDIOIN_MICLINE_MIC_BIAS 0x00070000 ++#define BF_AUDIOIN_MICLINE_MIC_BIAS(v) \ ++ (((v) << 16) & BM_AUDIOIN_MICLINE_MIC_BIAS) ++#define BP_AUDIOIN_MICLINE_RSRVD2 6 ++#define BM_AUDIOIN_MICLINE_RSRVD2 0x0000FFC0 ++#define BF_AUDIOIN_MICLINE_RSRVD2(v) \ ++ (((v) << 6) & BM_AUDIOIN_MICLINE_RSRVD2) ++#define BP_AUDIOIN_MICLINE_MIC_CHOPCLK 4 ++#define BM_AUDIOIN_MICLINE_MIC_CHOPCLK 0x00000030 ++#define BF_AUDIOIN_MICLINE_MIC_CHOPCLK(v) \ ++ (((v) << 4) & BM_AUDIOIN_MICLINE_MIC_CHOPCLK) ++#define BP_AUDIOIN_MICLINE_RSRVD1 2 ++#define BM_AUDIOIN_MICLINE_RSRVD1 0x0000000C ++#define BF_AUDIOIN_MICLINE_RSRVD1(v) \ ++ (((v) << 2) & BM_AUDIOIN_MICLINE_RSRVD1) ++#define BP_AUDIOIN_MICLINE_MIC_GAIN 0 ++#define BM_AUDIOIN_MICLINE_MIC_GAIN 0x00000003 ++#define BF_AUDIOIN_MICLINE_MIC_GAIN(v) \ ++ (((v) << 0) & BM_AUDIOIN_MICLINE_MIC_GAIN) ++ ++#define HW_AUDIOIN_ANACLKCTRL (0x00000070) ++#define HW_AUDIOIN_ANACLKCTRL_SET (0x00000074) ++#define HW_AUDIOIN_ANACLKCTRL_CLR (0x00000078) ++#define HW_AUDIOIN_ANACLKCTRL_TOG (0x0000007c) ++ ++#define BM_AUDIOIN_ANACLKCTRL_CLKGATE 0x80000000 ++#define BP_AUDIOIN_ANACLKCTRL_RSRVD4 11 ++#define BM_AUDIOIN_ANACLKCTRL_RSRVD4 0x7FFFF800 ++#define BF_AUDIOIN_ANACLKCTRL_RSRVD4(v) \ ++ (((v) << 11) & BM_AUDIOIN_ANACLKCTRL_RSRVD4) ++#define BM_AUDIOIN_ANACLKCTRL_DITHER_OFF 0x00000400 ++#define BM_AUDIOIN_ANACLKCTRL_SLOW_DITHER 0x00000200 ++#define BM_AUDIOIN_ANACLKCTRL_INVERT_ADCCLK 0x00000100 ++#define BP_AUDIOIN_ANACLKCTRL_RSRVD3 6 ++#define BM_AUDIOIN_ANACLKCTRL_RSRVD3 0x000000C0 ++#define BF_AUDIOIN_ANACLKCTRL_RSRVD3(v) \ ++ (((v) << 6) & BM_AUDIOIN_ANACLKCTRL_RSRVD3) ++#define BP_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 4 ++#define BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT 0x00000030 ++#define BF_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT(v) \ ++ (((v) << 4) & BM_AUDIOIN_ANACLKCTRL_ADCCLK_SHIFT) ++#define BM_AUDIOIN_ANACLKCTRL_RSRVD2 0x00000008 ++#define BP_AUDIOIN_ANACLKCTRL_ADCDIV 0 ++#define BM_AUDIOIN_ANACLKCTRL_ADCDIV 0x00000007 ++#define BF_AUDIOIN_ANACLKCTRL_ADCDIV(v) \ ++ (((v) << 0) & BM_AUDIOIN_ANACLKCTRL_ADCDIV) ++ ++#define HW_AUDIOIN_DATA (0x00000080) ++#define HW_AUDIOIN_DATA_SET (0x00000084) ++#define HW_AUDIOIN_DATA_CLR (0x00000088) ++#define HW_AUDIOIN_DATA_TOG (0x0000008c) ++ ++#define BP_AUDIOIN_DATA_HIGH 16 ++#define BM_AUDIOIN_DATA_HIGH 0xFFFF0000 ++#define BF_AUDIOIN_DATA_HIGH(v) \ ++ (((v) << 16) & BM_AUDIOIN_DATA_HIGH) ++#define BP_AUDIOIN_DATA_LOW 0 ++#define BM_AUDIOIN_DATA_LOW 0x0000FFFF ++#define BF_AUDIOIN_DATA_LOW(v) \ ++ (((v) << 0) & BM_AUDIOIN_DATA_LOW) ++ ++#define BV_AUDIOIN_ADCVOL_SELECT__MIC 0x00 ++ ++#endif /* __MXS_ADC_CODEC_H */ +--- a/sound/soc/mxs/Kconfig ++++ b/sound/soc/mxs/Kconfig +@@ -19,3 +19,13 @@ config SND_SOC_MXS_SGTL5000 + a sgtl5000 codec. + + endif # SND_MXS_SOC ++ ++ ++config SND_MXS_SOC_BUILTIN ++ tristate "SoC Audio for Freescale i.MX23 built-in codec" ++ depends on ARCH_MXS ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ select SND_SOC_MXS_BUILTIN_CODEC ++ help ++ Say Y or M if you want to add support for codecs attached to ++ the MXS SAIF interface. +--- a/sound/soc/mxs/Makefile ++++ b/sound/soc/mxs/Makefile +@@ -8,3 +8,12 @@ obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs + snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o + + obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o ++ ++# i.MX23 built-in audio Machine and Platform support ++snd-soc-mxs-builtin-pcm-objs := mxs-builtin-pcm.o ++snd-soc-mxs-builtin-dai-objs := mxs-builtin-dai.o ++snd-soc-mxs-builtin-audio-objs := mxs-builtin-audio.o ++ ++obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-pcm.o ++obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-dai.o ++obj-$(CONFIG_SND_MXS_SOC_BUILTIN) += snd-soc-mxs-builtin-audio.o +--- /dev/null ++++ b/sound/soc/mxs/mxs-builtin-audio.c +@@ -0,0 +1,120 @@ ++/* ++ * mxs-builtin-audio.c -- i.MX233 built-in codec ALSA Soc Audio driver ++ * ++ * Author: Michal Ulianko <michal.ulianko@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/jack.h> ++#include <sound/soc-dapm.h> ++#include <asm/mach-types.h> ++ ++static struct snd_soc_dai_link mxs_adc_dai_link[] = { ++ { ++ .name = "MXS ADC/DAC", ++ .stream_name = "MXS ADC/DAC", ++ .codec_dai_name = "mxs-builtin-codec-dai", ++// .codec_name = "mxs-builtin-codec", ++// .cpu_dai_name = "mxs-builtin-cpu-dai", ++// .platform_name = "mxs-builtin-cpu-dai", ++// .ops = &mxs_sgtl5000_hifi_ops, ++ }, ++}; ++ ++static struct snd_soc_card mxs_adc_audio = { ++ .name = "mxs-builtin-audio", ++ .owner = THIS_MODULE, ++ .dai_link = mxs_adc_dai_link, ++ .num_links = ARRAY_SIZE(mxs_adc_dai_link), ++}; ++ ++static int mxsadc_audio_probe_dt(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *cpu_dai_np, *codec_np; ++ int ret = 0; ++ ++ if (!np) ++ return 1; /* no device tree */ ++ ++ cpu_dai_np = of_parse_phandle(np, "cpu-dai", 0); ++ codec_np = of_parse_phandle(np, "audio-codec", 0); ++ if (!cpu_dai_np || !codec_np) { ++ dev_err(&pdev->dev, "phandle missing or invalid\n"); ++ return -EINVAL; ++ } ++ ++ mxs_adc_dai_link[0].codec_name = NULL; ++ mxs_adc_dai_link[0].codec_of_node = codec_np; ++ mxs_adc_dai_link[0].cpu_dai_name = NULL; ++ mxs_adc_dai_link[0].cpu_of_node = cpu_dai_np; ++ mxs_adc_dai_link[0].platform_name = NULL; ++ mxs_adc_dai_link[0].platform_of_node = cpu_dai_np; ++ ++// of_node_put(codec_np); ++// of_node_put(cpu_dai_np); ++ ++ return ret; ++} ++ ++static int mxsadc_audio_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = &mxs_adc_audio; ++ int ret; ++ ++ ret = mxsadc_audio_probe_dt(pdev); ++ if (ret < 0) ++ return ret; ++ ++ card->dev = &pdev->dev; ++ platform_set_drvdata(pdev, card); ++ ++ ret = snd_soc_register_card(card); ++ if (ret) { ++ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mxsadc_audio_remove(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = platform_get_drvdata(pdev); ++ ++ snd_soc_unregister_card(card); ++ ++ return 0; ++} ++ ++static const struct of_device_id mxs_adc_audio_dt_ids[] = { ++ { .compatible = "fsl,mxs-builtin-audio", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mxs_adc_audio_dt_ids); ++ ++static struct platform_driver mxs_adc_audio_driver = { ++ .driver = { ++ .name = "mxs-builtin-audio", ++ .owner = THIS_MODULE, ++ .of_match_table = mxs_adc_audio_dt_ids, ++ }, ++ .probe = mxsadc_audio_probe, ++ .remove = mxsadc_audio_remove, ++}; ++ ++module_platform_driver(mxs_adc_audio_driver); ++ ++MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Machine Driver"); ++MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/mxs/mxs-builtin-dai.c +@@ -0,0 +1,588 @@ ++/* ++ * mxs-builtin-dai.c -- i.MX233 built-in codec ALSA Soc Audio driver ++ * ++ * Author: Michal Ulianko <michal.ulianko@gmail.com> ++ * ++ * Based on sound/soc/mxs/mxs-adc.c for kernel 2.6.35 ++ * by Vladislav Buzov <vbuzov@embeddedalley.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/delay.h> ++#include <linux/dma-mapping.h> ++#include <linux/platform_device.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++ ++#include "../codecs/mxs-builtin-codec.h" ++#include "mxs-builtin-pcm.h" ++ ++#define ADC_VOLUME_MIN 0x37 ++ ++/* TODO Use codec IO function soc snd write etc, instead of __writel __readl */ ++ ++// TODO use container_of ++struct mxs_irq_data { ++ struct snd_pcm_substream *substream; ++ struct mxs_adc_priv *mxs_adc; ++}; ++ ++struct mxs_adc_priv { ++ struct mxs_irq_data irq_data; ++ int dma_adc_err_irq; ++ int dma_dac_err_irq; ++ int hp_short_irq; ++ void __iomem *audioin_base; ++ void __iomem *audioout_base; ++ void __iomem *rtc_base; ++}; ++ ++typedef struct { ++ struct work_struct work; ++ struct timer_list timer; ++ ++ /* target workqueue and CPU ->timer uses to queue ->work */ ++ struct workqueue_struct *wq; ++ int cpu; ++ ++ struct mxs_adc_priv *mxs_adc; ++} my_delayed_work_t; ++ ++// static struct delayed_work work; ++// static struct delayed_work adc_ramp_work; ++// static struct delayed_work dac_ramp_work; ++// static struct delayed_work test; ++static my_delayed_work_t work; ++static my_delayed_work_t adc_ramp_work; ++static my_delayed_work_t dac_ramp_work; ++static my_delayed_work_t test; ++static bool adc_ramp_done = 1; ++static bool dac_ramp_done = 1; ++ ++static inline void mxs_adc_schedule_work(struct delayed_work *work) ++{ ++ schedule_delayed_work(work, HZ / 10); ++} ++ ++static void mxs_adc_work(struct work_struct *work) ++{ ++ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc; ++ /* disable irq */ ++ disable_irq(mxs_adc->hp_short_irq); ++ ++ while (true) { ++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR); ++ msleep(10); ++ if ((__raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL) ++ & BM_AUDIOOUT_ANACTRL_SHORT_LR_STS) != 0) { ++ /* rearm the short protection */ ++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR, ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS, ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1), ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET); ++ ++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET); ++ printk(KERN_WARNING "WARNING : Headphone LR short!\r\n"); ++ } else { ++ printk(KERN_WARNING "INFO : Headphone LR no longer short!\r\n"); ++ break; ++ } ++ msleep(1000); ++ } ++ ++ /* power up the HEADPHONE and un-mute the HPVOL */ ++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR); ++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_CLR); ++ ++ /* enable irq for next short detect*/ ++ enable_irq(mxs_adc->hp_short_irq); ++} ++ ++static void mxs_adc_schedule_ramp_work(struct delayed_work *work) ++{ ++ schedule_delayed_work(work, msecs_to_jiffies(2)); ++ adc_ramp_done = 0; ++} ++ ++static void mxs_adc_ramp_work(struct work_struct *work) ++{ ++ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc; ++ u32 reg = 0; ++ u32 reg1 = 0; ++ u32 reg2 = 0; ++ u32 l, r; ++ u32 ll, rr; ++ int i; ++ ++ reg = __raw_readl(mxs_adc->audioin_base + \ ++ HW_AUDIOIN_ADCVOLUME); ++ ++ reg1 = reg & ~BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT; ++ reg1 = reg1 & ~BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT; ++ /* minimize adc volume */ ++ reg2 = reg1 | ++ BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ADC_VOLUME_MIN) | ++ BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(ADC_VOLUME_MIN); ++ __raw_writel(reg2, ++ mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME); ++ msleep(1); ++ ++ l = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT) >> ++ BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT; ++ r = (reg & BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT) >> ++ BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT; ++ ++ /* fade in adc vol */ ++ for (i = ADC_VOLUME_MIN; (i < l) || (i < r);) { ++ i += 0x8; ++ ll = i < l ? i : l; ++ rr = i < r ? i : r; ++ reg2 = reg1 | ++ BF_AUDIOIN_ADCVOLUME_VOLUME_LEFT(ll) | ++ BF_AUDIOIN_ADCVOLUME_VOLUME_RIGHT(rr); ++ __raw_writel(reg2, ++ mxs_adc->audioin_base + HW_AUDIOIN_ADCVOLUME); ++ msleep(1); ++ } ++ adc_ramp_done = 1; ++} ++ ++static void mxs_dac_schedule_ramp_work(struct delayed_work *work) ++{ ++ schedule_delayed_work(work, msecs_to_jiffies(2)); ++ dac_ramp_done = 0; ++} ++ ++static void mxs_dac_ramp_work(struct work_struct *work) ++{ ++ struct mxs_adc_priv *mxs_adc = ((my_delayed_work_t *)work)->mxs_adc; ++ u32 reg = 0; ++ u32 reg1 = 0; ++ u32 l, r; ++ u32 ll, rr; ++ int i; ++ ++ /* unmute hp and speaker */ ++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_CLR); ++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_CLR); ++ ++ reg = __raw_readl(mxs_adc->audioout_base + \ ++ HW_AUDIOOUT_HPVOL); ++ ++ reg1 = reg & ~BM_AUDIOOUT_HPVOL_VOL_LEFT; ++ reg1 = reg1 & ~BM_AUDIOOUT_HPVOL_VOL_RIGHT; ++ ++ l = (reg & BM_AUDIOOUT_HPVOL_VOL_LEFT) >> ++ BP_AUDIOOUT_HPVOL_VOL_LEFT; ++ r = (reg & BM_AUDIOOUT_HPVOL_VOL_RIGHT) >> ++ BP_AUDIOOUT_HPVOL_VOL_RIGHT; ++ /* fade in hp vol */ ++ for (i = 0x7f; i > 0 ;) { ++ i -= 0x8; ++ ll = i > (int)l ? i : l; ++ rr = i > (int)r ? i : r; ++ reg = reg1 | BF_AUDIOOUT_HPVOL_VOL_LEFT(ll) ++ | BF_AUDIOOUT_HPVOL_VOL_RIGHT(rr); ++ __raw_writel(reg, ++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL); ++ msleep(1); ++ } ++ dac_ramp_done = 1; ++} ++ ++/* IRQs */ ++static irqreturn_t mxs_short_irq(int irq, void *dev_id) ++{ ++ struct mxs_adc_priv *mxs_adc = dev_id; ++ //struct snd_pcm_substream *substream = mxs_adc->irq_data.substream; ++ ++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORTMODE_LR, ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS, ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_CLR); ++ __raw_writel(BF_AUDIOOUT_ANACTRL_SHORTMODE_LR(0x1), ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET); ++ ++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET); ++ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN_SET); ++ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB, ++ mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL_SET); ++ ++ mxs_adc_schedule_work((struct delayed_work *) &work); ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t mxs_err_irq(int irq, void *dev_id) ++{ ++ struct mxs_adc_priv *mxs_adc = dev_id; ++ struct snd_pcm_substream *substream = mxs_adc->irq_data.substream; ++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0; ++ u32 ctrl_reg; ++ u32 overflow_mask; ++ u32 underflow_mask; ++ ++ if (playback) { ++ ctrl_reg = __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL); ++ underflow_mask = BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ; ++ overflow_mask = BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ; ++ } else { ++ ctrl_reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_CTRL); ++ underflow_mask = BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ; ++ overflow_mask = BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ; ++ } ++ ++ if (ctrl_reg & underflow_mask) { ++ printk(KERN_DEBUG "%s underflow detected\n", ++ playback ? "DAC" : "ADC"); ++ ++ if (playback) ++ __raw_writel( ++ BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR); ++ else ++ __raw_writel( ++ BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR); ++ ++ } else if (ctrl_reg & overflow_mask) { ++ printk(KERN_DEBUG "%s overflow detected\n", ++ playback ? "DAC" : "ADC"); ++ ++ if (playback) ++ __raw_writel( ++ BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR); ++ else ++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR); ++ } else ++ printk(KERN_WARNING "Unknown DAC error interrupt\n"); ++ ++ return IRQ_HANDLED; ++} ++/* END IRQs */ ++ ++static int mxs_trigger(struct snd_pcm_substream *substream, ++ int cmd, ++ struct snd_soc_dai *cpu_dai) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai); ++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0; ++ int ret = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ ++ if (playback) { ++ /* enable the fifo error interrupt */ ++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_SET); ++ /* write a data to data reg to trigger the transfer */ ++ __raw_writel(0x0, ++ mxs_adc->audioout_base + HW_AUDIOOUT_DATA); ++ mxs_dac_schedule_ramp_work((struct delayed_work *) &dac_ramp_work); ++ } else { ++// mxs_dma_get_info(prtd->dma_ch, &dma_info); ++// cur_bar1 = dma_info.buf_addr; ++// xfer_count1 = dma_info.xfer_count; ++ ++ __raw_writel(BM_AUDIOIN_CTRL_RUN, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET); ++ udelay(100); ++ ++// mxs_dma_get_info(prtd->dma_ch, &dma_info); ++// cur_bar2 = dma_info.buf_addr; ++// xfer_count2 = dma_info.xfer_count; ++// ++// /* check if DMA getting stuck */ ++// if ((xfer_count1 == xfer_count2) && (cur_bar1 == cur_bar2)) ++// /* read a data from data reg to trigger the receive */ ++// reg = __raw_readl(mxs_adc->audioin_base + HW_AUDIOIN_DATA); ++ ++ mxs_adc_schedule_ramp_work((struct delayed_work *) &adc_ramp_work); ++ } ++ break; ++ ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ ++ if (playback) { ++// printk(KERN_INFO "SNDRV_PCM_TRIGGER_START\n"); ++// printk(KERN_INFO "ctrl:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_CTRL)); ++// printk(KERN_INFO "stat:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_STAT)); ++// printk(KERN_INFO "srr:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACSRR)); ++// printk(KERN_INFO "vol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACVOLUME)); ++// printk(KERN_INFO "debug:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_DACDEBUG)); ++// printk(KERN_INFO "hpvol:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL)); ++// printk(KERN_INFO "pwrdn:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_PWRDN)); ++// printk(KERN_INFO "refc:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_REFCTRL)); ++// printk(KERN_INFO "anac:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACTRL)); ++// printk(KERN_INFO "test:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_TEST)); ++// printk(KERN_INFO "bist:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_BISTCTRL)); ++// printk(KERN_INFO "anaclk:%x\n", __raw_readl(mxs_adc->audioout_base + HW_AUDIOOUT_ANACLKCTRL)); ++ ++ if (dac_ramp_done == 0) { ++ cancel_delayed_work((struct delayed_work *) &dac_ramp_work); ++ dac_ramp_done = 1; ++ } ++ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_HPVOL_SET); ++ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE, ++ mxs_adc->audioout_base + HW_AUDIOOUT_SPEAKERCTRL_SET); ++ /* disable the fifo error interrupt */ ++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR); ++ mdelay(50); ++ } else { ++ if (adc_ramp_done == 0) { ++ cancel_delayed_work((struct delayed_work *) &adc_ramp_work); ++ adc_ramp_done = 1; ++ } ++ __raw_writel(BM_AUDIOIN_CTRL_RUN, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR); ++ } ++ break; ++ ++ default: ++ printk(KERN_ERR "TRIGGER ERROR\n"); ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int mxs_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *cpu_dai) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai); ++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0; ++ mxs_adc->irq_data.mxs_adc = mxs_adc; ++ mxs_adc->irq_data.substream = substream; ++ ++ work.mxs_adc = mxs_adc; ++ adc_ramp_work.mxs_adc = mxs_adc; ++ dac_ramp_work.mxs_adc = mxs_adc; ++ test.mxs_adc = mxs_adc; ++ INIT_DELAYED_WORK(&work, mxs_adc_work); ++ INIT_DELAYED_WORK(&adc_ramp_work, mxs_adc_ramp_work); ++ INIT_DELAYED_WORK(&dac_ramp_work, mxs_dac_ramp_work); ++ ++ /* Enable error interrupt */ ++ if (playback) { ++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR); ++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR); ++ } else { ++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR); ++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR); ++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_SET); ++ } ++ ++ return 0; ++} ++ ++static void mxs_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *cpu_dai) ++{ ++ struct mxs_adc_priv *mxs_adc = snd_soc_dai_get_drvdata(cpu_dai); ++ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0; ++ ++ /* Disable error interrupt */ ++ if (playback) { ++ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN, ++ mxs_adc->audioout_base + HW_AUDIOOUT_CTRL_CLR); ++ } else { ++ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN, ++ mxs_adc->audioin_base + HW_AUDIOIN_CTRL_CLR); ++ } ++} ++ ++#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000 ++#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) ++ ++static const struct snd_soc_dai_ops mxs_adc_dai_ops = { ++ .startup = mxs_startup, ++ .trigger = mxs_trigger, ++ .shutdown = mxs_shutdown, ++}; ++ ++static int mxs_dai_probe(struct snd_soc_dai *dai) ++{ ++ // TODO This does not make any sense. ++ struct mxs_adc_priv *mxs_adc = dev_get_drvdata(dai->dev); ++ ++ snd_soc_dai_set_drvdata(dai, mxs_adc); ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_driver mxs_adc_dai = { ++ .name = "mxs-builtin-cpu-dai", ++ .probe = mxs_dai_probe, ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = MXS_ADC_RATES, ++ .formats = MXS_ADC_FORMATS, ++ }, ++ .capture = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = MXS_ADC_RATES, ++ .formats = MXS_ADC_FORMATS, ++ }, ++ .ops = &mxs_adc_dai_ops, ++}; ++ ++static const struct snd_soc_component_driver mxs_adc_component = { ++ .name = "mxs-xxx", //TODO change this name ++}; ++ ++static int mxs_adc_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct mxs_adc_priv *mxs_adc; ++ int ret = 0; ++ ++ if (!np) ++ return -EINVAL; ++ ++ mxs_adc = devm_kzalloc(&pdev->dev, sizeof(*mxs_adc), GFP_KERNEL); ++ if (!mxs_adc) ++ return -ENOMEM; ++ ++ mxs_adc->audioout_base = devm_ioremap(&pdev->dev, 0x80048000, 0x2000); ++ if (IS_ERR(mxs_adc->audioout_base)) ++ return PTR_ERR(mxs_adc->audioout_base); ++ ++ mxs_adc->audioin_base = devm_ioremap(&pdev->dev, 0x8004c000, 0x2000); ++ if (IS_ERR(mxs_adc->audioin_base)) ++ return PTR_ERR(mxs_adc->audioin_base); ++ ++ mxs_adc->rtc_base = devm_ioremap(&pdev->dev, 0x8005c000, 0x2000); ++ if (IS_ERR(mxs_adc->rtc_base)) ++ return PTR_ERR(mxs_adc->rtc_base); ++ ++ /* Get IRQ numbers */ ++ mxs_adc->dma_adc_err_irq = platform_get_irq(pdev, 0); ++ if (mxs_adc->dma_adc_err_irq < 0) { ++ ret = mxs_adc->dma_adc_err_irq; ++ dev_err(&pdev->dev, "failed to get ADC DMA ERR irq resource: %d\n", ret); ++ return ret; ++ } ++ ++ mxs_adc->dma_dac_err_irq = platform_get_irq(pdev, 1); ++ if (mxs_adc->dma_dac_err_irq < 0) { ++ ret = mxs_adc->dma_dac_err_irq; ++ dev_err(&pdev->dev, "failed to get DAC DMA ERR irq resource: %d\n", ret); ++ return ret; ++ } ++ ++ mxs_adc->hp_short_irq = platform_get_irq(pdev, 2); ++ if (mxs_adc->hp_short_irq < 0) { ++ ret = mxs_adc->hp_short_irq; ++ dev_err(&pdev->dev, "failed to get HP_SHORT irq resource: %d\n", ret); ++ return ret; ++ } ++ ++ /* Request IRQs */ ++ ret = devm_request_irq(&pdev->dev, mxs_adc->dma_adc_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error", ++ mxs_adc); ++ if (ret) { ++ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n", ++ __func__, mxs_adc->dma_adc_err_irq); ++ return ret; ++ } ++ ++ ret = devm_request_irq(&pdev->dev, mxs_adc->dma_dac_err_irq, mxs_err_irq, 0, "MXS DAC and ADC Error", ++ mxs_adc); ++ if (ret) { ++ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n", ++ __func__, mxs_adc->dma_dac_err_irq); ++ return ret; ++ } ++ ++ ret = devm_request_irq(&pdev->dev, mxs_adc->hp_short_irq, mxs_short_irq, ++ IRQF_DISABLED | IRQF_SHARED, "MXS DAC and ADC HP SHORT", mxs_adc); ++ if (ret) { ++ printk(KERN_ERR "%s: Unable to request ADC/DAC HP SHORT irq %d\n", ++ __func__, mxs_adc->hp_short_irq); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, mxs_adc); ++ ++ ret = snd_soc_register_component(&pdev->dev, &mxs_adc_component, &mxs_adc_dai, 1); ++ if (ret) { ++ dev_err(&pdev->dev, "register DAI failed\n"); ++ return ret; ++ } ++ ++ ret = mxs_adc_pcm_platform_register(&pdev->dev); ++ if (ret) { ++ dev_err(&pdev->dev, "register PCM failed: %d\n", ret); ++ goto failed_pdev_alloc; ++ } ++ ++ return 0; ++ ++failed_pdev_alloc: ++ snd_soc_unregister_component(&pdev->dev); ++ ++ return ret; ++} ++ ++static int mxs_adc_remove(struct platform_device *pdev) ++{ ++ mxs_adc_pcm_platform_unregister(&pdev->dev); ++ snd_soc_unregister_component(&pdev->dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id mxs_adc_dai_dt_ids[] = { ++ { .compatible = "fsl,mxs-builtin-cpu-dai", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, mxs_adc_dai_dt_ids); ++ ++static struct platform_driver mxs_adc_dai_driver = { ++ .probe = mxs_adc_probe, ++ .remove = mxs_adc_remove, ++ ++ .driver = { ++ .name = "mxs-builtin-cpu-dai", ++ .owner = THIS_MODULE, ++ .of_match_table = mxs_adc_dai_dt_ids, ++ }, ++}; ++ ++module_platform_driver(mxs_adc_dai_driver); ++ ++MODULE_DESCRIPTION("Freescale MXS ADC/DAC SoC Codec DAI Driver"); ++MODULE_AUTHOR("Michal Ulianko <michal.ulianko@gmail.com>"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/mxs/mxs-builtin-pcm.c +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. ++ * ++ * Based on sound/soc/imx/imx-pcm-dma-mx2.c ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include <linux/device.h> ++#include <linux/init.h> ++#include <linux/module.h> ++ ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/dmaengine_pcm.h> ++ ++#include "mxs-builtin-pcm.h" ++ ++static const struct snd_pcm_hardware snd_mxs_hardware = { ++ .info = SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE | ++ SNDRV_PCM_INFO_RESUME | ++ SNDRV_PCM_INFO_INTERLEAVED, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S20_3LE | ++ SNDRV_PCM_FMTBIT_S24_LE, ++ .channels_min = 2, ++ .channels_max = 2, ++ .period_bytes_min = 32, ++ .period_bytes_max = 8192, ++ .periods_min = 1, ++ .periods_max = 52, ++ .buffer_bytes_max = 64 * 1024, ++ .fifo_size = 32, ++}; ++ ++static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { ++ .pcm_hardware = &snd_mxs_hardware, ++ .prealloc_buffer_size = 64 * 1024, ++}; ++ ++int mxs_adc_pcm_platform_register(struct device *dev) ++{ ++ return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, ++ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); ++} ++EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_register); ++ ++void mxs_adc_pcm_platform_unregister(struct device *dev) ++{ ++ snd_dmaengine_pcm_unregister(dev); ++} ++EXPORT_SYMBOL_GPL(mxs_adc_pcm_platform_unregister); ++ ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/mxs/mxs-builtin-pcm.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef _MXS_PCM_H ++#define _MXS_PCM_H ++ ++int mxs_adc_pcm_platform_register(struct device *dev); ++void mxs_adc_pcm_platform_unregister(struct device *dev); ++ ++#endif diff --git a/target/linux/mxs/patches-3.18/101-soc-audio-dts.patch b/target/linux/mxs/patches-3.18/101-soc-audio-dts.patch new file mode 100644 index 0000000..3c3ad86 --- /dev/null +++ b/target/linux/mxs/patches-3.18/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 +@@ -89,6 +89,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"; ++ }; + }; + }; + +@@ -127,4 +146,10 @@ + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + }; + }; ++ ++ mxs-builtin-audio { ++ compatible = "fsl,mxs-builtin-audio"; ++ audio-codec = <&codec>; ++ cpu-dai = <&platform_dai>; ++ }; + }; diff --git a/target/linux/mxs/patches-3.18/120-dt-add-i2c.patch b/target/linux/mxs/patches-3.18/120-dt-add-i2c.patch new file mode 100644 index 0000000..43b42ce --- /dev/null +++ b/target/linux/mxs/patches-3.18/120-dt-add-i2c.patch @@ -0,0 +1,79 @@ +--- a/arch/arm/boot/dts/imx23.dtsi ++++ b/arch/arm/boot/dts/imx23.dtsi +@@ -147,6 +147,39 @@ + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + ++ i2c0_pins_a: i2c0@0 { ++ reg = <0>; ++ fsl,pinmux-ids = < ++ 0x01e0 /* MX23_PAD_I2C_SCL__I2C_SCL */ ++ 0x01f0 /* MX23_PAD_I2C_SDA__I2C_SDA */ ++ >; ++ fsl,drive-strength = <1>; ++ fsl,voltage = <1>; ++ fsl,pull-up = <1>; ++ }; ++ ++ i2c1_pins_a: i2c1@0 { ++ reg = <0>; ++ fsl,pinmux-ids = < ++ 0x1171 /* MX23_PAD_LCD_ENABLE__I2C_SCL */ ++ 0x1181 /* MX23_PAD_LCD_HSYNC__I2C_SDA */ ++ >; ++ fsl,drive-strength = <1>; ++ fsl,voltage = <1>; ++ fsl,pull-up = <1>; ++ }; ++ ++ i2c2_pins_a: i2c2@0 { ++ reg = <0>; ++ fsl,pinmux-ids = < ++ 0x2031 /* MX23_PAD_SSP1_DATA1__I2C_SCL */ ++ 0x2041 /* MX23_PAD_SSP1_DATA2__I2C_SDA */ ++ >; ++ fsl,drive-strength = <1>; ++ fsl,voltage = <1>; ++ fsl,pull-up = <1>; ++ }; ++ + auart0_pins_a: auart0@0 { + reg = <0>; + fsl,pinmux-ids = < +@@ -445,7 +478,12 @@ + }; + + i2c@80058000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "fsl,imx23-i2c"; + reg = <0x80058000 0x2000>; ++ interrupts = <27>; ++ clock-frequency = <100000>; + dmas = <&dma_apbx 3>; + dma-names = "rx-tx"; + status = "disabled"; +--- a/arch/arm/boot/dts/imx23-olinuxino.dts ++++ b/arch/arm/boot/dts/imx23-olinuxino.dts +@@ -74,6 +74,12 @@ + status = "okay"; + }; + ++ i2c0: i2c@80058000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins_a>; ++ status = "okay"; ++ }; ++ + duart: serial@80070000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; +@@ -89,7 +95,7 @@ + usbphy0: usbphy@8007c000 { + status = "okay"; + }; +- ++ + codec: mxs-builtin-codec { + compatible = "fsl,mxs-builtin-codec"; + reg = <0x80048000 0x2000>, <0x8004c000 0x2000>, diff --git a/target/linux/mxs/patches-4.1/100-mxs-select-syscon.patch b/target/linux/mxs/patches-4.1/100-mxs-select-syscon.patch new file mode 100644 index 0000000..81ebec4 --- /dev/null +++ b/target/linux/mxs/patches-4.1/100-mxs-select-syscon.patch @@ -0,0 +1,10 @@ +--- a/arch/arm/mach-mxs/Kconfig ++++ b/arch/arm/mach-mxs/Kconfig +@@ -17,6 +17,7 @@ config ARCH_MXS + depends on ARCH_MULTI_V5 + select ARCH_REQUIRE_GPIOLIB + select CLKSRC_MMIO ++ select MFD_SYSCON + select PINCTRL + select SOC_BUS + select SOC_IMX23 diff --git a/target/linux/mxs/patches-4.1/101-mxs-add-mxs_power.patch b/target/linux/mxs/patches-4.1/101-mxs-add-mxs_power.patch new file mode 100644 index 0000000..104736c --- /dev/null +++ b/target/linux/mxs/patches-4.1/101-mxs-add-mxs_power.patch @@ -0,0 +1,166 @@ +--- a/drivers/power/Kconfig ++++ b/drivers/power/Kconfig +@@ -43,6 +43,14 @@ config MAX8925_POWER + Say Y here to enable support for the battery charger in the Maxim + MAX8925 PMIC. + ++config MXS_POWER ++ tristate "Freescale MXS power subsystem support" ++ depends on ARCH_MXS || COMPILE_TEST ++ help ++ Say Y here to enable support for the Freescale i.MX23/i.MX28 ++ power subsystem. This is a requirement to get access to on-chip ++ regulators, battery charger and many more. ++ + config WM831X_BACKUP + tristate "WM831X backup battery charger support" + depends on MFD_WM831X +--- a/drivers/power/Makefile ++++ b/drivers/power/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_GENERIC_ADC_BATTERY) += gen + obj-$(CONFIG_PDA_POWER) += pda_power.o + obj-$(CONFIG_APM_POWER) += apm_power.o + obj-$(CONFIG_MAX8925_POWER) += max8925_power.o ++obj-$(CONFIG_MXS_POWER) += mxs_power.o + obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o + obj-$(CONFIG_WM831X_POWER) += wm831x_power.o + obj-$(CONFIG_WM8350_POWER) += wm8350_power.o +--- /dev/null ++++ b/drivers/power/mxs_power.c +@@ -0,0 +1,136 @@ ++/* ++ * Freescale MXS power subsystem ++ * ++ * Copyright (C) 2014 Stefan Wahren ++ * ++ * Inspired by imx-bootlets ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include <linux/device.h> ++#include <linux/err.h> ++#include <linux/io.h> ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_platform.h> ++#include <linux/platform_device.h> ++#include <linux/power_supply.h> ++#include <linux/stmp_device.h> ++#include <linux/types.h> ++ ++#define BM_POWER_CTRL_POLARITY_VBUSVALID BIT(5) ++#define BM_POWER_CTRL_VBUSVALID_IRQ BIT(4) ++#define BM_POWER_CTRL_ENIRQ_VBUS_VALID BIT(3) ++ ++#define HW_POWER_5VCTRL_OFFSET 0x10 ++ ++#define BM_POWER_5VCTRL_VBUSVALID_THRESH (7 << 8) ++#define BM_POWER_5VCTRL_PWDN_5VBRNOUT BIT(7) ++#define BM_POWER_5VCTRL_ENABLE_LINREG_ILIMIT BIT(6) ++#define BM_POWER_5VCTRL_VBUSVALID_5VDETECT BIT(4) ++ ++#define HW_POWER_5VCTRL_VBUSVALID_THRESH_4_40V (5 << 8) ++ ++struct mxs_power_data { ++ void __iomem *base_addr; ++ struct power_supply *ac; ++}; ++ ++static enum power_supply_property mxs_power_ac_props[] = { ++ POWER_SUPPLY_PROP_ONLINE, ++}; ++ ++static int mxs_power_ac_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ int ret = 0; ++ ++ switch (psp) { ++ case POWER_SUPPLY_PROP_ONLINE: ++ val->intval = 1; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static const struct of_device_id of_mxs_power_match[] = { ++ { .compatible = "fsl,imx23-power" }, ++ { .compatible = "fsl,imx28-power" }, ++ { /* end */ } ++}; ++MODULE_DEVICE_TABLE(of, of_mxs_power_match); ++ ++static const struct power_supply_desc ac_desc = { ++ .properties = mxs_power_ac_props, ++ .num_properties = ARRAY_SIZE(mxs_power_ac_props), ++ .get_property = mxs_power_ac_get_property, ++ .name = "ac", ++ .type = POWER_SUPPLY_TYPE_MAINS, ++}; ++ ++static int mxs_power_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct resource *res; ++ struct mxs_power_data *data; ++ struct power_supply_config psy_cfg = {}; ++ void __iomem *v5ctrl_addr; ++ ++ if (!np) { ++ dev_err(dev, "missing device tree\n"); ++ return -EINVAL; ++ } ++ ++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ data->base_addr = devm_ioremap_resource(dev, res); ++ if (IS_ERR(data->base_addr)) ++ return PTR_ERR(data->base_addr); ++ ++ psy_cfg.drv_data = data; ++ ++ data->ac = devm_power_supply_register(dev, &ac_desc, &psy_cfg); ++ if (IS_ERR(data->ac)) ++ return PTR_ERR(data->ac); ++ ++ platform_set_drvdata(pdev, data); ++ ++ v5ctrl_addr = data->base_addr + HW_POWER_5VCTRL_OFFSET; ++ ++ /* Make sure the current limit of the linregs are disabled. */ ++ writel(BM_POWER_5VCTRL_ENABLE_LINREG_ILIMIT, ++ v5ctrl_addr + STMP_OFFSET_REG_CLR); ++ ++ return of_platform_populate(np, NULL, NULL, dev); ++} ++ ++static struct platform_driver mxs_power_driver = { ++ .driver = { ++ .name = "mxs_power", ++ .of_match_table = of_mxs_power_match, ++ }, ++ .probe = mxs_power_probe, ++}; ++ ++module_platform_driver(mxs_power_driver); ++ ++MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>"); ++MODULE_DESCRIPTION("Freescale MXS power subsystem"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/mxs/patches-4.1/102-mxs-add-regulator-driver.patch b/target/linux/mxs/patches-4.1/102-mxs-add-regulator-driver.patch new file mode 100644 index 0000000..4690b3c --- /dev/null +++ b/target/linux/mxs/patches-4.1/102-mxs-add-regulator-driver.patch @@ -0,0 +1,570 @@ +--- a/drivers/regulator/Kconfig ++++ b/drivers/regulator/Kconfig +@@ -450,6 +450,14 @@ config REGULATOR_MT6397 + This driver supports the control of different power rails of device + through regulator interface. + ++config REGULATOR_MXS ++ tristate "Freescale MXS on-chip regulators" ++ depends on (MXS_POWER || COMPILE_TEST) ++ help ++ Say y here to support Freescale MXS on-chip regulators. ++ It is recommended that this option be enabled on i.MX23, ++ i.MX28 platform. ++ + config REGULATOR_PALMAS + tristate "TI Palmas PMIC Regulators" + depends on MFD_PALMAS +--- a/drivers/regulator/Makefile ++++ b/drivers/regulator/Makefile +@@ -60,6 +60,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc137 + obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o + obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o + obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o ++obj-$(CONFIG_REGULATOR_MXS) += mxs-regulator.o + obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o + obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o + obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o +--- /dev/null ++++ b/drivers/regulator/mxs-regulator.c +@@ -0,0 +1,540 @@ ++/* ++ * Freescale MXS on-chip regulators ++ * ++ * Embedded Alley Solutions, Inc <source@embeddedalley.com> ++ * ++ * Copyright (C) 2014 Stefan Wahren ++ * Copyright (C) 2010 Freescale Semiconductor, Inc. ++ * Copyright (C) 2008 Embedded Alley Solutions, Inc All Rights Reserved. ++ * ++ * Inspired by imx-bootlets ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/err.h> ++#include <linux/kernel.h> ++#include <linux/mfd/syscon.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/platform_device.h> ++#include <linux/regmap.h> ++#include <linux/regulator/driver.h> ++#include <linux/regulator/machine.h> ++#include <linux/regulator/of_regulator.h> ++#include <linux/slab.h> ++ ++/* Powered by linear regulator. DCDC output is gated off and ++ the linreg output is equal to the target. */ ++#define HW_POWER_LINREG_DCDC_OFF 1 ++ ++/* Powered by linear regulator. DCDC output is not gated off ++ and is ready for the automatic hardware transistion after a 5V ++ event. The converters are not enabled when 5V is present. LinReg output ++ is 25mV below target. */ ++#define HW_POWER_LINREG_DCDC_READY 2 ++ ++/* Powered by DCDC converter and the LinReg is on. LinReg output ++ is 25mV below target. */ ++#define HW_POWER_DCDC_LINREG_ON 3 ++ ++/* Powered by DCDC converter and the LinReg is off. LinReg output ++ is 25mV below target. */ ++#define HW_POWER_DCDC_LINREG_OFF 4 ++ ++/* Powered by DCDC converter and the LinReg is ready for the ++ automatic hardware transfer. The LinReg output is not enabled and ++ depends on the 5V presence to enable the LinRegs. LinReg offset is 25mV ++ below target. */ ++#define HW_POWER_DCDC_LINREG_READY 5 ++ ++/* Powered by an external source when 5V is present. This does not ++ necessarily mean the external source is powered by 5V,but the chip needs ++ to be aware that 5V is present. */ ++#define HW_POWER_EXTERNAL_SOURCE_5V 6 ++ ++/* Powered by an external source when 5V is not present.This doesn't ++ necessarily mean the external source is powered by the battery, but the ++ chip needs to be aware that the battery is present */ ++#define HW_POWER_EXTERNAL_SOURCE_BATTERY 7 ++ ++/* Unknown configuration. This is an error. */ ++#define HW_POWER_UNKNOWN_SOURCE 8 ++ ++/* TODO: Move power register offsets into header file */ ++#define HW_POWER_5VCTRL 0x00000010 ++#define HW_POWER_VDDDCTRL 0x00000040 ++#define HW_POWER_VDDACTRL 0x00000050 ++#define HW_POWER_VDDIOCTRL 0x00000060 ++#define HW_POWER_MISC 0x00000090 ++#define HW_POWER_STS 0x000000c0 ++ ++#define BM_POWER_STS_VBUSVALID0_STATUS BIT(15) ++#define BM_POWER_STS_DC_OK BIT(9) ++ ++#define BM_POWER_5VCTRL_ILIMIT_EQ_ZERO BIT(2) ++#define BM_POWER_5VCTRL_ENABLE_DCDC BIT(0) ++ ++#define BM_POWER_LINREG_OFFSET_DCDC_MODE BIT(1) ++ ++#define SHIFT_FREQSEL 4 ++ ++#define BM_POWER_MISC_FREQSEL (7 << SHIFT_FREQSEL) ++ ++/* Recommended DC-DC clock source values */ ++#define HW_POWER_MISC_FREQSEL_20000_KHZ 1 ++#define HW_POWER_MISC_FREQSEL_24000_KHZ 2 ++#define HW_POWER_MISC_FREQSEL_19200_KHZ 3 ++ ++#define HW_POWER_MISC_SEL_PLLCLK BIT(0) ++ ++/* Regulator IDs */ ++#define MXS_DCDC 1 ++#define MXS_VDDIO 2 ++#define MXS_VDDA 3 ++#define MXS_VDDD 4 ++ ++struct mxs_reg_info { ++ /* regulator descriptor */ ++ struct regulator_desc desc; ++ ++ /* regulator control register */ ++ int ctrl_reg; ++ ++ /* disable DC-DC output */ ++ unsigned int disable_fet_mask; ++ ++ /* steps between linreg output and DC-DC target */ ++ unsigned int linreg_offset_mask; ++ u8 linreg_offset_shift; ++ ++ /* function which determine power source */ ++ u8 (*get_power_source)(struct regulator_dev *); ++}; ++ ++static inline u8 get_linreg_offset(struct mxs_reg_info *ldo, u32 regs) ++{ ++ return (regs & ldo->linreg_offset_mask) >> ldo->linreg_offset_shift; ++} ++ ++static u8 get_vddio_power_source(struct regulator_dev *reg) ++{ ++ struct mxs_reg_info *ldo = rdev_get_drvdata(reg); ++ u32 v5ctrl, status, base; ++ u8 offset; ++ ++ if (regmap_read(reg->regmap, HW_POWER_5VCTRL, &v5ctrl)) ++ return HW_POWER_UNKNOWN_SOURCE; ++ ++ if (regmap_read(reg->regmap, HW_POWER_STS, &status)) ++ return HW_POWER_UNKNOWN_SOURCE; ++ ++ if (regmap_read(reg->regmap, ldo->ctrl_reg, &base)) ++ return HW_POWER_UNKNOWN_SOURCE; ++ ++ offset = get_linreg_offset(ldo, base); ++ ++ /* If VBUS valid then 5 V power supply present */ ++ if (status & BM_POWER_STS_VBUSVALID0_STATUS) { ++ /* Powered by Linreg, DC-DC is off */ ++ if ((base & ldo->disable_fet_mask) && ++ !(offset & BM_POWER_LINREG_OFFSET_DCDC_MODE)) { ++ return HW_POWER_LINREG_DCDC_OFF; ++ } ++ ++ if (v5ctrl & BM_POWER_5VCTRL_ENABLE_DCDC) { ++ /* Powered by DC-DC, Linreg is on */ ++ if (offset & BM_POWER_LINREG_OFFSET_DCDC_MODE) ++ return HW_POWER_DCDC_LINREG_ON; ++ } else { ++ /* Powered by Linreg, DC-DC is off */ ++ if (!(offset & BM_POWER_LINREG_OFFSET_DCDC_MODE)) ++ return HW_POWER_LINREG_DCDC_OFF; ++ } ++ } else { ++ /* Powered by DC-DC, Linreg is on */ ++ if (offset & BM_POWER_LINREG_OFFSET_DCDC_MODE) ++ return HW_POWER_DCDC_LINREG_ON; ++ } ++ ++ return HW_POWER_UNKNOWN_SOURCE; ++} ++ ++static u8 get_vdda_vddd_power_source(struct regulator_dev *reg) ++{ ++ struct mxs_reg_info *ldo = rdev_get_drvdata(reg); ++ struct regulator_desc *desc = &ldo->desc; ++ u32 v5ctrl, status, base; ++ u8 offset; ++ ++ if (regmap_read(reg->regmap, HW_POWER_5VCTRL, &v5ctrl)) ++ return HW_POWER_UNKNOWN_SOURCE; ++ ++ if (regmap_read(reg->regmap, HW_POWER_STS, &status)) ++ return HW_POWER_UNKNOWN_SOURCE; ++ ++ if (regmap_read(reg->regmap, ldo->ctrl_reg, &base)) ++ return HW_POWER_UNKNOWN_SOURCE; ++ ++ offset = get_linreg_offset(ldo, base); ++ ++ /* DC-DC output is disabled */ ++ if (base & ldo->disable_fet_mask) { ++ /* Powered by 5 V supply */ ++ if (status & BM_POWER_STS_VBUSVALID0_STATUS) ++ return HW_POWER_EXTERNAL_SOURCE_5V; ++ ++ /* Powered by Linreg, DC-DC is off */ ++ if (!(offset & BM_POWER_LINREG_OFFSET_DCDC_MODE)) ++ return HW_POWER_LINREG_DCDC_OFF; ++ } ++ ++ /* If VBUS valid then 5 V power supply present */ ++ if (status & BM_POWER_STS_VBUSVALID0_STATUS) { ++ /* Powered by DC-DC, Linreg is on */ ++ if (v5ctrl & BM_POWER_5VCTRL_ENABLE_DCDC) ++ return HW_POWER_DCDC_LINREG_ON; ++ ++ /* Powered by Linreg, DC-DC is off */ ++ return HW_POWER_LINREG_DCDC_OFF; ++ } ++ ++ /* DC-DC is on */ ++ if (offset & BM_POWER_LINREG_OFFSET_DCDC_MODE) { ++ /* Powered by DC-DC, Linreg is on */ ++ if (base & desc->enable_mask) ++ return HW_POWER_DCDC_LINREG_ON; ++ ++ /* Powered by DC-DC, Linreg is off */ ++ return HW_POWER_DCDC_LINREG_OFF; ++ } ++ ++ return HW_POWER_UNKNOWN_SOURCE; ++} ++ ++static int mxs_set_dcdc_freq(struct regulator_dev *reg, u32 hz) ++{ ++ struct mxs_reg_info *dcdc = rdev_get_drvdata(reg); ++ u32 val; ++ int ret; ++ ++ if (dcdc->desc.id != MXS_DCDC) { ++ dev_warn(®->dev, "Setting switching freq is not supported\n"); ++ return -EINVAL; ++ } ++ ++ ret = regmap_read(reg->regmap, HW_POWER_MISC, &val); ++ if (ret) ++ return ret; ++ ++ val &= ~BM_POWER_MISC_FREQSEL; ++ val &= ~HW_POWER_MISC_SEL_PLLCLK; ++ ++ /* ++ * Select the PLL/PFD based frequency that the DC-DC converter uses. ++ * The actual switching frequency driving the power inductor is ++ * DCDC_CLK/16. Accept only values recommend by Freescale. ++ */ ++ switch (hz) { ++ case 1200000: ++ val |= HW_POWER_MISC_FREQSEL_19200_KHZ << SHIFT_FREQSEL; ++ break; ++ case 1250000: ++ val |= HW_POWER_MISC_FREQSEL_20000_KHZ << SHIFT_FREQSEL; ++ break; ++ case 1500000: ++ val |= HW_POWER_MISC_FREQSEL_24000_KHZ << SHIFT_FREQSEL; ++ break; ++ default: ++ dev_warn(®->dev, "Switching freq: %u Hz not supported\n", ++ hz); ++ return -EINVAL; ++ } ++ ++ /* First program FREQSEL */ ++ ret = regmap_write(reg->regmap, HW_POWER_MISC, val); ++ if (ret) ++ return ret; ++ ++ /* then set PLL as clock for DC-DC converter */ ++ val |= HW_POWER_MISC_SEL_PLLCLK; ++ ++ return regmap_write(reg->regmap, HW_POWER_MISC, val); ++} ++ ++static int mxs_ldo_set_voltage_sel(struct regulator_dev *reg, unsigned sel) ++{ ++ struct mxs_reg_info *ldo = rdev_get_drvdata(reg); ++ struct regulator_desc *desc = &ldo->desc; ++ u32 status = 0; ++ int timeout; ++ int ret; ++ ++ ret = regmap_update_bits(reg->regmap, desc->vsel_reg, desc->vsel_mask, ++ sel); ++ if (ret) ++ return ret; ++ ++ if (ldo->get_power_source) { ++ switch (ldo->get_power_source(reg)) { ++ case HW_POWER_LINREG_DCDC_OFF: ++ case HW_POWER_LINREG_DCDC_READY: ++ case HW_POWER_EXTERNAL_SOURCE_5V: ++ /* ++ * Since the DC-DC converter is off we can't ++ * trigger on DC_OK. So wait at least 1 ms ++ * for stabilization. ++ */ ++ usleep_range(1000, 2000); ++ return 0; ++ } ++ } ++ ++ /* Make sure DC_OK has changed */ ++ usleep_range(15, 20); ++ ++ for (timeout = 0; timeout < 20; timeout++) { ++ ret = regmap_read(reg->regmap, HW_POWER_STS, &status); ++ ++ if (ret) ++ break; ++ ++ /* DC-DC converter control loop has stabilized */ ++ if (status & BM_POWER_STS_DC_OK) ++ return 0; ++ ++ udelay(1); ++ } ++ ++ if (!ret) ++ dev_warn_ratelimited(®->dev, "%s: timeout status=0x%08x\n", ++ __func__, status); ++ ++ msleep(20); ++ ++ return -ETIMEDOUT; ++} ++ ++static int mxs_ldo_is_enabled(struct regulator_dev *reg) ++{ ++ struct mxs_reg_info *ldo = rdev_get_drvdata(reg); ++ ++ if (ldo->get_power_source) { ++ switch (ldo->get_power_source(reg)) { ++ case HW_POWER_LINREG_DCDC_OFF: ++ case HW_POWER_LINREG_DCDC_READY: ++ case HW_POWER_DCDC_LINREG_ON: ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static struct regulator_ops mxs_dcdc_ops = { ++ .is_enabled = regulator_is_enabled_regmap, ++}; ++ ++static struct regulator_ops mxs_ldo_ops = { ++ .list_voltage = regulator_list_voltage_linear, ++ .map_voltage = regulator_map_voltage_linear, ++ .set_voltage_sel = mxs_ldo_set_voltage_sel, ++ .get_voltage_sel = regulator_get_voltage_sel_regmap, ++ .is_enabled = mxs_ldo_is_enabled, ++}; ++ ++static const struct mxs_reg_info mxs_info_dcdc = { ++ .desc = { ++ .name = "dcdc", ++ .id = MXS_DCDC, ++ .type = REGULATOR_VOLTAGE, ++ .owner = THIS_MODULE, ++ .ops = &mxs_dcdc_ops, ++ .enable_reg = HW_POWER_STS, ++ .enable_mask = (1 << 0), ++ }, ++}; ++ ++static const struct mxs_reg_info imx23_info_vddio = { ++ .desc = { ++ .name = "vddio", ++ .id = MXS_VDDIO, ++ .type = REGULATOR_VOLTAGE, ++ .owner = THIS_MODULE, ++ .n_voltages = 0x20, ++ .uV_step = 25000, ++ .linear_min_sel = 0, ++ .min_uV = 2800000, ++ .vsel_reg = HW_POWER_VDDIOCTRL, ++ .vsel_mask = 0x1f, ++ .ops = &mxs_ldo_ops, ++ }, ++ .ctrl_reg = HW_POWER_VDDIOCTRL, ++ .disable_fet_mask = 1 << 16, ++ .linreg_offset_mask = 3 << 12, ++ .linreg_offset_shift = 12, ++ .get_power_source = get_vddio_power_source, ++}; ++ ++static const struct mxs_reg_info imx28_info_vddio = { ++ .desc = { ++ .name = "vddio", ++ .id = MXS_VDDIO, ++ .type = REGULATOR_VOLTAGE, ++ .owner = THIS_MODULE, ++ .n_voltages = 0x11, ++ .uV_step = 50000, ++ .linear_min_sel = 0, ++ .min_uV = 2800000, ++ .vsel_reg = HW_POWER_VDDIOCTRL, ++ .vsel_mask = 0x1f, ++ .ops = &mxs_ldo_ops, ++ }, ++ .ctrl_reg = HW_POWER_VDDIOCTRL, ++ .disable_fet_mask = 1 << 16, ++ .linreg_offset_mask = 3 << 12, ++ .linreg_offset_shift = 12, ++ .get_power_source = get_vddio_power_source, ++}; ++ ++static const struct mxs_reg_info mxs_info_vdda = { ++ .desc = { ++ .name = "vdda", ++ .id = MXS_VDDA, ++ .type = REGULATOR_VOLTAGE, ++ .owner = THIS_MODULE, ++ .n_voltages = 0x20, ++ .uV_step = 25000, ++ .linear_min_sel = 0, ++ .min_uV = 1500000, ++ .vsel_reg = HW_POWER_VDDACTRL, ++ .vsel_mask = 0x1f, ++ .ops = &mxs_ldo_ops, ++ .enable_mask = (1 << 17), ++ }, ++ .ctrl_reg = HW_POWER_VDDACTRL, ++ .disable_fet_mask = 1 << 16, ++ .linreg_offset_mask = 3 << 12, ++ .linreg_offset_shift = 12, ++ .get_power_source = get_vdda_vddd_power_source, ++}; ++ ++static const struct mxs_reg_info mxs_info_vddd = { ++ .desc = { ++ .name = "vddd", ++ .id = MXS_VDDD, ++ .type = REGULATOR_VOLTAGE, ++ .owner = THIS_MODULE, ++ .n_voltages = 0x20, ++ .uV_step = 25000, ++ .linear_min_sel = 0, ++ .min_uV = 800000, ++ .vsel_reg = HW_POWER_VDDDCTRL, ++ .vsel_mask = 0x1f, ++ .ops = &mxs_ldo_ops, ++ .enable_mask = (1 << 21), ++ }, ++ .ctrl_reg = HW_POWER_VDDDCTRL, ++ .disable_fet_mask = 1 << 20, ++ .linreg_offset_mask = 3 << 16, ++ .linreg_offset_shift = 16, ++ .get_power_source = get_vdda_vddd_power_source, ++}; ++ ++static const struct of_device_id of_mxs_regulator_match[] = { ++ { .compatible = "fsl,imx23-dcdc", .data = &mxs_info_dcdc }, ++ { .compatible = "fsl,imx28-dcdc", .data = &mxs_info_dcdc }, ++ { .compatible = "fsl,imx23-vddio", .data = &imx23_info_vddio }, ++ { .compatible = "fsl,imx23-vdda", .data = &mxs_info_vdda }, ++ { .compatible = "fsl,imx23-vddd", .data = &mxs_info_vddd }, ++ { .compatible = "fsl,imx28-vddio", .data = &imx28_info_vddio }, ++ { .compatible = "fsl,imx28-vdda", .data = &mxs_info_vdda }, ++ { .compatible = "fsl,imx28-vddd", .data = &mxs_info_vddd }, ++ { /* end */ } ++}; ++MODULE_DEVICE_TABLE(of, of_mxs_regulator_match); ++ ++static int mxs_regulator_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct of_device_id *match; ++ struct device_node *parent_np; ++ struct regulator_dev *rdev = NULL; ++ struct mxs_reg_info *info; ++ struct regulator_init_data *initdata; ++ struct regulator_config config = { }; ++ u32 switch_freq; ++ ++ match = of_match_device(of_mxs_regulator_match, dev); ++ if (!match) { ++ /* We do not expect this to happen */ ++ dev_err(dev, "%s: Unable to match device\n", __func__); ++ return -ENODEV; ++ } ++ ++ info = devm_kmemdup(dev, match->data, sizeof(struct mxs_reg_info), ++ GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; ++ ++ initdata = of_get_regulator_init_data(dev, dev->of_node, &info->desc); ++ if (!initdata) { ++ dev_err(dev, "missing regulator init data\n"); ++ return -EINVAL; ++ } ++ ++ parent_np = of_get_parent(dev->of_node); ++ if (!parent_np) ++ return -ENODEV; ++ config.regmap = syscon_node_to_regmap(parent_np); ++ of_node_put(parent_np); ++ if (IS_ERR(config.regmap)) ++ return PTR_ERR(config.regmap); ++ ++ config.dev = dev; ++ config.init_data = initdata; ++ config.driver_data = info; ++ config.of_node = dev->of_node; ++ ++ rdev = devm_regulator_register(dev, &info->desc, &config); ++ if (IS_ERR(rdev)) { ++ int ret = PTR_ERR(rdev); ++ ++ dev_err(dev, "%s: failed to register regulator(%d)\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ if (!of_property_read_u32(dev->of_node, "switching-frequency", ++ &switch_freq)) ++ mxs_set_dcdc_freq(rdev, switch_freq); ++ ++ platform_set_drvdata(pdev, rdev); ++ ++ return 0; ++} ++ ++static struct platform_driver mxs_regulator_driver = { ++ .driver = { ++ .name = "mxs_regulator", ++ .of_match_table = of_mxs_regulator_match, ++ }, ++ .probe = mxs_regulator_probe, ++}; ++ ++module_platform_driver(mxs_regulator_driver); ++ ++MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>"); ++MODULE_DESCRIPTION("Freescale MXS regulators"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:mxs_regulator"); diff --git a/target/linux/mxs/patches-4.1/103-dt-enable-regulator.patch b/target/linux/mxs/patches-4.1/103-dt-enable-regulator.patch new file mode 100644 index 0000000..bfcf247 --- /dev/null +++ b/target/linux/mxs/patches-4.1/103-dt-enable-regulator.patch @@ -0,0 +1,100 @@ +--- a/arch/arm/boot/dts/imx23.dtsi ++++ b/arch/arm/boot/dts/imx23.dtsi +@@ -404,8 +404,46 @@ + }; + + power@80044000 { ++ compatible = "fsl,imx23-power", "syscon"; + reg = <0x80044000 0x2000>; +- status = "disabled"; ++ interrupts = <3>; ++ ++ dcdc: regulator@1 { ++ compatible = "fsl,imx23-dcdc"; ++ regulator-name = "dcdc"; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vddd: regulator@2 { ++ compatible = "fsl,imx23-vddd"; ++ regulator-name = "vddd"; ++ regulator-min-microvolt = <1350000>; ++ regulator-max-microvolt = <1550000>; ++ vddd-supply = <®_vdda>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vdda: regulator@3 { ++ compatible = "fsl,imx23-vdda"; ++ regulator-name = "vdda"; ++ regulator-min-microvolt = <1725000>; ++ regulator-max-microvolt = <1950000>; ++ vdda-supply = <®_vddio>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vddio: regulator@4 { ++ compatible = "fsl,imx23-vddio"; ++ regulator-name = "vddio"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3575000>; ++ regulator-microvolt-offset = <80000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; + }; + + saif1: saif@80046000 { +--- a/arch/arm/boot/dts/imx28.dtsi ++++ b/arch/arm/boot/dts/imx28.dtsi +@@ -1035,8 +1035,46 @@ + }; + + power: power@80044000 { ++ compatible = "fsl,imx28-power", "syscon"; + reg = <0x80044000 0x2000>; +- status = "disabled"; ++ interrupts = <6>; ++ ++ dcdc: regulator@1 { ++ compatible = "fsl,imx28-dcdc"; ++ regulator-name = "dcdc"; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vddd: regulator@2 { ++ compatible = "fsl,imx28-vddd"; ++ regulator-name = "vddd"; ++ regulator-min-microvolt = <1350000>; ++ regulator-max-microvolt = <1550000>; ++ vddd-supply = <®_vdda>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vdda: regulator@3 { ++ compatible = "fsl,imx28-vdda"; ++ regulator-name = "vdda"; ++ regulator-min-microvolt = <1725000>; ++ regulator-max-microvolt = <1950000>; ++ vdda-supply = <®_vddio>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_vddio: regulator@4 { ++ compatible = "fsl,imx28-vddio"; ++ regulator-name = "vddio"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3550000>; ++ regulator-microvolt-offset = <80000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; + }; + + saif1: saif@80046000 { diff --git a/target/linux/mxs/patches-4.1/120-dt-add-i2c.patch b/target/linux/mxs/patches-4.1/120-dt-add-i2c.patch new file mode 100644 index 0000000..79c162a --- /dev/null +++ b/target/linux/mxs/patches-4.1/120-dt-add-i2c.patch @@ -0,0 +1,55 @@ +--- a/arch/arm/boot/dts/imx23.dtsi ++++ b/arch/arm/boot/dts/imx23.dtsi +@@ -147,6 +147,39 @@ + fsl,pull-up = <MXS_PULL_DISABLE>; + }; + ++ i2c0_pins_a: i2c0@0 { ++ reg = <0>; ++ fsl,pinmux-ids = < ++ 0x01e0 /* MX23_PAD_I2C_SCL__I2C_SCL */ ++ 0x01f0 /* MX23_PAD_I2C_SDA__I2C_SDA */ ++ >; ++ fsl,drive-strength = <1>; ++ fsl,voltage = <1>; ++ fsl,pull-up = <1>; ++ }; ++ ++ i2c1_pins_a: i2c1@0 { ++ reg = <0>; ++ fsl,pinmux-ids = < ++ 0x1171 /* MX23_PAD_LCD_ENABLE__I2C_SCL */ ++ 0x1181 /* MX23_PAD_LCD_HSYNC__I2C_SDA */ ++ >; ++ fsl,drive-strength = <1>; ++ fsl,voltage = <1>; ++ fsl,pull-up = <1>; ++ }; ++ ++ i2c2_pins_a: i2c2@0 { ++ reg = <0>; ++ fsl,pinmux-ids = < ++ 0x2031 /* MX23_PAD_SSP1_DATA1__I2C_SCL */ ++ 0x2041 /* MX23_PAD_SSP1_DATA2__I2C_SDA */ ++ >; ++ fsl,drive-strength = <1>; ++ fsl,voltage = <1>; ++ fsl,pull-up = <1>; ++ }; ++ + auart0_pins_a: auart0@0 { + reg = <0>; + fsl,pinmux-ids = < +@@ -484,7 +517,12 @@ + }; + + i2c@80058000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "fsl,imx23-i2c"; + reg = <0x80058000 0x2000>; ++ interrupts = <27>; ++ clock-frequency = <100000>; + dmas = <&dma_apbx 3>; + dma-names = "rx-tx"; + status = "disabled"; diff --git a/target/linux/mxs/profiles/01-duckbill.mk b/target/linux/mxs/profiles/01-duckbill.mk new file mode 100644 index 0000000..85a1237 --- /dev/null +++ b/target/linux/mxs/profiles/01-duckbill.mk @@ -0,0 +1,22 @@ +# +# Copyright (C) 2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/duckbill + NAME:=I2SE Duckbill boards + DEPENDS:=+@TARGET_ROOTFS_INCLUDE_KERNEL +@TARGET_ROOTFS_INCLUDE_DTB + FEATURES+=usbgadget + PACKAGES+= \ + -dnsmasq -firewall -ppp -ip6tables -iptables -6relayd -mtd uboot-envtools \ + kmod-leds-gpio kmod-ledtrig-timer kmod-usb-mxs-phy -kmod-ipt-nathelper \ + kmod-i2c-mxs kmod-spi-mxs uboot-mxs-duckbill +endef + +define Profile/duckbill/Description + I2SE's Duckbill devices +endef + +$(eval $(call Profile,duckbill)) diff --git a/target/linux/mxs/profiles/02-olinuxino-maxi.mk b/target/linux/mxs/profiles/02-olinuxino-maxi.mk new file mode 100644 index 0000000..7885d1f --- /dev/null +++ b/target/linux/mxs/profiles/02-olinuxino-maxi.mk @@ -0,0 +1,21 @@ +# +# 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-maxi + NAME:=Olimex OLinuXino Maxi/Mini boards + PACKAGES += imx-bootlets uboot-mxs-mx23_olinuxino \ + 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 kmod-crypto-hw-dcp \ + kmod-i2c-mxs kmod-spi-mxs +endef + +define Profile/olinuxino-maxi/Description + Olimex OLinuXino Maxi/Mini boards +endef + +$(eval $(call Profile,olinuxino-maxi)) diff --git a/target/linux/mxs/profiles/03-olinuxino-micro.mk b/target/linux/mxs/profiles/03-olinuxino-micro.mk new file mode 100644 index 0000000..356a877 --- /dev/null +++ b/target/linux/mxs/profiles/03-olinuxino-micro.mk @@ -0,0 +1,21 @@ +# +# 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-micro + NAME:=Olimex OLinuXino Micro/Nano boards + PACKAGES += imx-bootlets uboot-mxs-mx23_olinuxino \ + kmod-usb-mxs-phy kmod-gpio-mcp23s08 kmod-leds-gpio \ + kmod-ledtrig-heartbeat kmod-rtc-stmp3xxx \ + kmod-iio-mxs-lradc kmod-crypto-hw-dcp \ + kmod-i2c-mxs kmod-spi-mxs +endef + +define Profile/olinuxino-micro/Description + Olimex OLinuXino Micro/Nano boards +endef + +$(eval $(call Profile,olinuxino-micro)) |