summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/configs/imx23evk_defconfig30
-rw-r--r--arch/arm/mach-mx23/clock.c12
-rw-r--r--arch/arm/mach-mx23/include/mach/dma.h4
-rw-r--r--arch/arm/mach-mx23/include/mach/mx23.h2
-rw-r--r--arch/arm/mach-mx23/include/mach/regs-audioin.h287
-rw-r--r--arch/arm/mach-mx23/include/mach/regs-audioout.h518
-rw-r--r--arch/arm/mach-mx23/mx23evk.c19
-rw-r--r--arch/arm/plat-mxs/device.c22
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/mxs-adc-codec.c1057
-rw-r--r--sound/soc/codecs/mxs-adc-codec.h87
-rw-r--r--sound/soc/mxs/Kconfig14
-rw-r--r--sound/soc/mxs/Makefile4
-rw-r--r--sound/soc/mxs/mxs-adc.c257
-rw-r--r--sound/soc/mxs/mxs-adc.h21
-rw-r--r--sound/soc/mxs/mxs-evk-adc.c91
17 files changed, 2428 insertions, 3 deletions
diff --git a/arch/arm/configs/imx23evk_defconfig b/arch/arm/configs/imx23evk_defconfig
index fd0003083d4f..827f9af45518 100644
--- a/arch/arm/configs/imx23evk_defconfig
+++ b/arch/arm/configs/imx23evk_defconfig
@@ -777,7 +777,35 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_MXS_SOC=y
+CONFIG_SND_MXS_SOC_EVK_ADC=y
+CONFIG_SND_MXS_SOC_ADC=y
+CONFIG_SND_SOC_MXS_ADC_CODEC=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
diff --git a/arch/arm/mach-mx23/clock.c b/arch/arm/mach-mx23/clock.c
index 242c7014fa62..97b005a5f9f0 100644
--- a/arch/arm/mach-mx23/clock.c
+++ b/arch/arm/mach-mx23/clock.c
@@ -585,6 +585,14 @@ static struct clk usb_clk = {
.enable_bits = BM_DIGCTL_CTRL_USB_CLKGATE,
};
+static struct clk audio_clk = {
+ .parent = &ref_xtal_clk,
+ .enable = mx23_raw_enable,
+ .disable = mx23_raw_disable,
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_XTAL,
+ .enable_bits = BM_CLKCTRL_XTAL_FILT_CLK24M_GATE,
+};
+
static struct clk_lookup onchip_clocks[] = {
{
@@ -674,6 +682,10 @@ static struct clk_lookup onchip_clocks[] = {
{
.con_id = "usb_clk0",
.clk = &usb_clk,
+ },
+ {
+ .con_id = "audio",
+ .clk = &audio_clk,
}
};
diff --git a/arch/arm/mach-mx23/include/mach/dma.h b/arch/arm/mach-mx23/include/mach/dma.h
index e80353a359ef..5fc24275ab3c 100644
--- a/arch/arm/mach-mx23/include/mach/dma.h
+++ b/arch/arm/mach-mx23/include/mach/dma.h
@@ -38,8 +38,8 @@ enum {
MXS_DMA_CHANNEL_AHB_APBH_14,
MXS_DMA_CHANNEL_AHB_APBH_15,
MXS_DMA_CHANNEL_AHB_APBX = 16,
- MXS_DMA_CHANNEL_AHB_APBX_UART4_RX = MXS_DMA_CHANNEL_AHB_APBX,
- MXS_DMA_CHANNEL_AHB_APBX_UART4_TX,
+ MXS_DMA_CHANNEL_AHB_APBX_AUDIOADC = MXS_DMA_CHANNEL_AHB_APBX,
+ MXS_DMA_CHANNEL_AHB_APBX_AUDIODAC,
MXS_DMA_CHANNEL_AHB_APBX_SPDIF,
MXS_DMA_CHANNEL_AHB_APBX_03,
MXS_DMA_CHANNEL_AHB_APBX_SAIF0,
diff --git a/arch/arm/mach-mx23/include/mach/mx23.h b/arch/arm/mach-mx23/include/mach/mx23.h
index 51bfb0cce7ca..ae7f43c0744f 100644
--- a/arch/arm/mach-mx23/include/mach/mx23.h
+++ b/arch/arm/mach-mx23/include/mach/mx23.h
@@ -54,6 +54,8 @@
#define SAIF0_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x042000)
#define POWER_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x044000)
#define SAIF1_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x046000)
+#define AUDIOOUT_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x048000)
+#define AUDIOIN_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x04c000)
#define LRADC_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x050000)
#define SPDIF_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x054000)
#define RTC_PHYS_ADDR (MX23_SOC_IO_PHYS_BASE + 0x05c000)
diff --git a/arch/arm/mach-mx23/include/mach/regs-audioin.h b/arch/arm/mach-mx23/include/mach/regs-audioin.h
new file mode 100644
index 000000000000..1a881ce0407e
--- /dev/null
+++ b/arch/arm/mach-mx23/include/mach/regs-audioin.h
@@ -0,0 +1,287 @@
+/*
+ * Freescale AUDIOIN Register Definitions
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.52
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___AUDIOIN_H
+#define __ARCH_ARM___AUDIOIN_H
+
+#define REGS_AUDIOIN_BASE (IO_ADDRESS(AUDIOIN_PHYS_ADDR))
+
+#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)
+#endif /* __ARCH_ARM___AUDIOIN_H */
diff --git a/arch/arm/mach-mx23/include/mach/regs-audioout.h b/arch/arm/mach-mx23/include/mach/regs-audioout.h
new file mode 100644
index 000000000000..d751858a1327
--- /dev/null
+++ b/arch/arm/mach-mx23/include/mach/regs-audioout.h
@@ -0,0 +1,518 @@
+/*
+ * Freescale AUDIOOUT Register Definitions
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.65
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___AUDIOOUT_H
+#define __ARCH_ARM___AUDIOOUT_H
+
+#define REGS_AUDIOOUT_BASE (IO_ADDRESS(AUDIOOUT_PHYS_ADDR))
+
+#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)
+#endif /* __ARCH_ARM___AUDIOOUT_H */
diff --git a/arch/arm/mach-mx23/mx23evk.c b/arch/arm/mach-mx23/mx23evk.c
index f3d20de5c6b5..edc75c1d23ca 100644
--- a/arch/arm/mach-mx23/mx23evk.c
+++ b/arch/arm/mach-mx23/mx23evk.c
@@ -39,11 +39,30 @@ static void __init fixup_board(struct machine_desc *desc, struct tag *tags,
mx23_set_input_clk(24000000, 24000000, 32000, 50000000);
}
+#if defined(CONFIG_SND_MXS_SOC_ADC) || defined(CONFIG_SND_MXS_SOC_ADC_MODULE)
+static void __init mx23evk_init_adc(void)
+{
+ struct platform_device *pdev;
+ pdev = mxs_get_device("mxs-adc", 0);
+ if (pdev == NULL)
+ return;
+ mxs_add_device(pdev, 3);
+}
+#else
+static void __init mx23evk_init_adc(void)
+{
+
+}
+#endif
+
+
static void __init mx23evk_device_init(void)
{
/* Add mx23evk special code */
+ mx23evk_init_adc();
}
+
static void __init mx23evk_init_machine(void)
{
mx23_pinctrl_init();
diff --git a/arch/arm/plat-mxs/device.c b/arch/arm/plat-mxs/device.c
index 58f483b5f1a2..88c477cfd05e 100644
--- a/arch/arm/plat-mxs/device.c
+++ b/arch/arm/plat-mxs/device.c
@@ -412,6 +412,18 @@ static struct platform_device mxs_spdif[] = {
};
#endif
+#if defined(CONFIG_SND_MXS_SOC_ADC) || \
+ defined(CONFIG_SND_MXS_SOC_ADC_MODULE)
+static struct platform_device mxs_adc = {
+ .name = "mxs-adc-audio",
+ .id = 0,
+ .dev = {
+ .release = mxs_nop_release,
+ },
+};
+#endif
+
+
static struct mxs_dev_lookup dev_lookup[] = {
#if defined(CONFIG_SERIAL_MXS_DUART) || \
defined(CONFIG_SERIAL_MXS_DUART_MODULE)
@@ -586,6 +598,16 @@ static struct mxs_dev_lookup dev_lookup[] = {
.pdev = mxs_spdif,
},
#endif
+
+#if defined(CONFIG_SND_MXS_SOC_ADC) || \
+ defined(CONFIG_SND_MXS_SOC_ADC_MODULE)
+ {
+ .name = "mxs-adc",
+ .size = 1,
+ .pdev = &mxs_adc,
+ },
+#endif
+
};
struct platform_device *mxs_get_device(char *name, int id)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 893ad3bea214..4362689dd639 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -197,6 +197,10 @@ config SND_SOC_STMP3XXX_SPDIF
tristate
depends on SND_SOC
+config SND_SOC_MXS_ADC_CODEC
+ tristate
+ depends on SND_SOC
+
config SND_SOC_BLUETOOTH
tristate
depends on SND_SOC
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 0b997cf20e75..8add6333d7c5 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -41,6 +41,7 @@ snd-soc-stmp378x-codec-objs := stmp378x_codec.o
snd-soc-stmp3xxx-spdif-objs := stmp3xxx_spdif.o
snd-soc-bluetooth-objs := bluetooth.o
snd-soc-mxs-spdif-objs := mxs_spdif.o
+snd-soc-mxs-adc-objs := mxs-adc-codec.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
@@ -85,3 +86,4 @@ obj-$(CONFIG_SND_SOC_STMP378X_CODEC) += snd-soc-stmp378x-codec.o
obj-$(CONFIG_SND_SOC_STMP3XXX_SPDIF) += snd-soc-stmp3xxx-spdif.o
obj-$(CONFIG_SND_SOC_BLUETOOTH) += snd-soc-bluetooth.o
obj-$(CONFIG_SND_SOC_MXS_SPDIF) += snd-soc-mxs-spdif.o
+obj-$(CONFIG_SND_SOC_MXS_ADC_CODEC) += snd-soc-mxs-adc.o
diff --git a/sound/soc/codecs/mxs-adc-codec.c b/sound/soc/codecs/mxs-adc-codec.c
new file mode 100644
index 000000000000..3499975875cb
--- /dev/null
+++ b/sound/soc/codecs/mxs-adc-codec.c
@@ -0,0 +1,1057 @@
+/*
+ * ALSA codec for Freescale MXS ADC/DAC Audio
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * 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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <asm/dma.h>
+
+#include <mach/dma.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/regs-audioin.h>
+#include <mach/regs-audioout.h>
+
+#include "mxs-adc-codec.h"
+
+#define BV_AUDIOIN_ADCVOL_SELECT__MIC 0x00 /* missing define */
+
+#ifndef BF
+#define BF(value, field) (((value) << BP_##field) & BM_##field)
+#endif
+
+struct mxs_codec_priv {
+ struct clk *clk;
+ struct snd_soc_codec codec;
+};
+
+/*
+ * ALSA API
+ */
+static void __iomem *adc_regmap[] = {
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_STAT,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACSRR,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACDEBUG,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_TEST,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_BISTCTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_BISTSTAT0,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_BISTSTAT1,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACLKCTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DATA,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_SPEAKERCTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_VERSION,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_STAT,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCSRR,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOLUME,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCDEBUG,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_MICLINE,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ANACLKCTRL,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_DATA,
+};
+
+static u16 mxs_audio_regs[ADC_REGNUM];
+
+static u8 dac_volumn_control_word[] = {
+ 0x37, 0x5e, 0x7e, 0x8e,
+ 0x9e, 0xae, 0xb6, 0xbe,
+ 0xc6, 0xce, 0xd6, 0xde,
+ 0xe6, 0xee, 0xf6, 0xfe,
+};
+
+/*
+ * ALSA core supports only 16 bit registers. It means we have to simulate it
+ * by virtually splitting a 32bit ADC/DAC registers into two halves
+ * high (bits 31:16) and low (bits 15:0). The routins abow detects which part
+ * of 32bit register is accessed.
+ */
+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)
+{
+ 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(adc_regmap[reg >> 1]);
+ reg_val = (reg_val & ~mask) | value;
+ __raw_writel(reg_val, adc_regmap[reg >> 1]);
+
+ return 0;
+}
+
+static unsigned int mxs_codec_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ unsigned int reg_val;
+
+ if (reg >= ADC_REGNUM)
+ return -1;
+
+ reg_val = __raw_readl(adc_regmap[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;
+}
+
+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)
+{
+ int reg, l, r;
+ int i;
+
+ reg = __raw_readl(REGS_AUDIOOUT_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)
+{
+ 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,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_CLR);
+ __raw_writel(reg, REGS_AUDIOOUT_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),
+};
+
+/* Codec controls */
+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),
+ SOC_SINGLE("HP Playback Switch", DAC_HPVOL_H, 8, 0x1, 1),
+ SOC_SINGLE("Speaker Playback Switch", DAC_SPEAKERCTRL_H, 8, 0x1, 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]),
+};
+
+/* 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_codec_widgets[] = {
+
+ SND_SOC_DAPM_ADC("Left ADC", "Left Capture", DAC_PWRDN_L, 8, 1),
+ SND_SOC_DAPM_ADC("Right ADC", "Right Capture", DAC_PWRDN_H, 0, 1),
+
+ 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("HP_AMP", DAC_PWRDN_L, 0, 1, NULL, 0),
+
+ SND_SOC_DAPM_PGA("HP_CAPLESS", DAC_PWRDN_L, 4, 1, NULL, 0),
+
+ SND_SOC_DAPM_PGA("SPK_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"),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+
+ /* 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 */
+ {"Left ADC", NULL, "Left ADC Mux"},
+ {"Right 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 output */
+ {"HP_CAPLESS", NULL, "HP Mux"},
+ {"HP_AMP", NULL, "HP_CAPLESS"},
+ {"HPR", NULL, "HP_AMP"},
+ {"HPL", NULL, "HP_AMP"},
+
+ /* Speaker amp */
+ {"SPK_AMP", NULL, "DAC"},
+ {"SPEAKER", NULL, "SPK_AMP"},
+};
+
+static int mxs_codec_add_widgets(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+
+ snd_soc_dapm_new_controls(codec, mxs_codec_widgets,
+ ARRAY_SIZE(mxs_codec_widgets));
+
+ if (ret) {
+ dev_err(codec->dev, "dapm control register failed\n");
+ return ret;
+ }
+ /* set up audio path interconnects */
+ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+
+ if (ret) {
+ dev_err(codec->dev, "DAPM route register failed\n");
+ return ret;
+ }
+
+ return snd_soc_dapm_new_widgets(codec);
+}
+
+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;
+}
+
+static int mxs_codec_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->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(socdev->dev, "%s doesn't support rate %d\n",
+ codec->name, params_rate(params));
+ else {
+ src_hold = srr_values[i].src_hold;
+
+ srr_value =
+ BF(srr_values[i].basemult, AUDIOOUT_DACSRR_BASEMULT) |
+ BF(srr_values[i].src_int, AUDIOOUT_DACSRR_SRC_INT) |
+ BF(srr_values[i].src_frac, AUDIOOUT_DACSRR_SRC_FRAC) |
+ BF(src_hold, AUDIOOUT_DACSRR_SRC_HOLD);
+
+ if (playback)
+ __raw_writel(srr_value,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACSRR);
+ else
+ __raw_writel(srr_value,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCSRR);
+ }
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ if (playback)
+ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+ else
+ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+
+ break;
+
+ case SNDRV_PCM_FORMAT_S32_LE:
+ if (playback)
+ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ else
+ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+
+ break;
+
+ default:
+ dev_warn(socdev->dev, "%s doesn't support format %d\n",
+ codec->name, params_format(params));
+
+ }
+
+ return 0;
+}
+
+static int mxs_codec_dig_mute(struct snd_soc_dai *dai, int mute)
+{
+ u32 dac_mask = BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
+ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT;
+
+ if (mute) {
+ __raw_writel(dac_mask,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_SET);
+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET);
+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_SPEAKERCTRL_SET);
+ } else {
+ __raw_writel(dac_mask,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_CLR);
+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_CLR);
+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_SPEAKERCTRL_CLR);
+ }
+ return 0;
+}
+
+/*
+ * Codec initialization
+ */
+#define VAG_BASE_VALUE ((1400/2 - 625)/25)
+static void mxs_codec_dac_set_vag(void)
+{
+ u32 refctrl_val = __raw_readl(REGS_AUDIOOUT_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, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL);
+}
+
+static void
+mxs_codec_dac_power_on(struct mxs_codec_priv *mxs_adc)
+{
+ /* Ungate DAC clocks */
+ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACLKCTRL_CLR);
+
+ /* 16 bit word length */
+ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+
+ /* Update DAC volume over zero crossings */
+ __raw_writel(BM_AUDIOOUT_DACVOLUME_EN_ZCD,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_SET);
+ /* Mute DAC */
+ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
+ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_SET);
+
+ /* Update HP volume over zero crossings */
+ __raw_writel(BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET);
+
+ /* Prepare powering up HP output */
+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET);
+ /*__raw_writel(BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG),
+ REGS_RTC_BASE + HW_RTC_PERSISTENT0_SET);*/
+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET);
+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR);
+ /* Mute HP output */
+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET);
+
+ /* Mute speaker amp */
+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_SPEAKERCTRL_SET);
+}
+
+static void
+mxs_codec_dac_power_down(struct mxs_codec_priv *mxs_adc)
+{
+ /* Disable class AB */
+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR);
+
+ /* Set hold to ground */
+ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET);
+
+ /* Mute HP output */
+ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET);
+ /* Power down HP output */
+ __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_SET);
+
+ /* Mute speaker amp */
+ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_SPEAKERCTRL_SET);
+ /* Power down speaker amp */
+ __raw_writel(BM_AUDIOOUT_PWRDN_SPEAKER,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_SET);
+
+ /* Mute DAC */
+ __raw_writel(BM_AUDIOOUT_DACVOLUME_MUTE_LEFT |
+ BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_SET);
+ /* Power down DAC */
+ __raw_writel(BM_AUDIOOUT_PWRDN_DAC,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_SET);
+
+ /* Gate DAC clocks */
+ __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACLKCTRL_SET);
+ __raw_writel(BM_AUDIOOUT_CTRL_CLKGATE,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+}
+
+static void
+mxs_codec_adc_power_on(struct mxs_codec_priv *mxs_adc)
+{
+ u32 reg;
+
+ /* Ungate ADC clocks */
+ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ANACLKCTRL_CLR);
+
+ /* 16 bit word length */
+ __raw_writel(BM_AUDIOIN_CTRL_WORD_LENGTH,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+
+ /* Unmute ADC channels */
+ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
+ REGS_AUDIOIN_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, REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOLUME_CLR);
+
+ /* Set the Input channel gain 3dB */
+ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_LEFT,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_CLR);
+ __raw_writel(BM_AUDIOIN_ADCVOL_GAIN_RIGHT,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_CLR);
+ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_LEFT),
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_SET);
+ __raw_writel(BF(2, AUDIOIN_ADCVOL_GAIN_RIGHT),
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_SET);
+
+ /* Select default input - Microphone */
+ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_LEFT,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_CLR);
+ __raw_writel(BM_AUDIOIN_ADCVOL_SELECT_RIGHT,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_CLR);
+ __raw_writel(BF
+ (BV_AUDIOIN_ADCVOL_SELECT__MIC,
+ AUDIOIN_ADCVOL_SELECT_LEFT),
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_SET);
+ __raw_writel(BF
+ (BV_AUDIOIN_ADCVOL_SELECT__MIC,
+ AUDIOIN_ADCVOL_SELECT_RIGHT),
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_SET);
+
+ /* Supply bias voltage to microphone */
+ __raw_writel(BF(2, AUDIOIN_MICLINE_MIC_RESISTOR),
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_MICLINE_SET);
+ __raw_writel(BM_AUDIOIN_MICLINE_MIC_SELECT,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_MICLINE_SET);
+
+ /* Set max ADC volume */
+ reg = __raw_readl(REGS_AUDIOIN_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, REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOLUME);
+}
+
+static void
+mxs_codec_adc_power_down(struct mxs_codec_priv *mxs_adc)
+{
+ /* Mute ADC channels */
+ __raw_writel(BM_AUDIOIN_ADCVOL_MUTE,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ADCVOL_SET);
+
+ /* Power Down ADC */
+ __raw_writel(BM_AUDIOOUT_PWRDN_ADC | BM_AUDIOOUT_PWRDN_RIGHT_ADC,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_SET);
+
+ /* Gate ADC clocks */
+ __raw_writel(BM_AUDIOIN_CTRL_CLKGATE,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+ __raw_writel(BM_AUDIOIN_ANACLKCTRL_CLKGATE,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_ANACLKCTRL_SET);
+
+ /* Disable bias voltage to microphone */
+ __raw_writel(BF(0, AUDIOIN_MICLINE_MIC_RESISTOR),
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_MICLINE_SET);
+}
+
+static void mxs_codec_dac_enable(struct mxs_codec_priv *mxs_adc)
+{
+ /* Move DAC codec out of reset */
+ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+
+ /* Reduce analog power */
+ __raw_writel(BM_AUDIOOUT_TEST_HP_I1_ADJ,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_TEST_CLR);
+ __raw_writel(BF(0x1, AUDIOOUT_TEST_HP_I1_ADJ),
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_TEST_SET);
+ __raw_writel(BM_AUDIOOUT_REFCTRL_LOW_PWR,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL_SET);
+ __raw_writel(BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL_SET);
+ __raw_writel(BM_AUDIOOUT_REFCTRL_BIAS_CTRL,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL_CLR);
+ __raw_writel(BF(0x1, AUDIOOUT_REFCTRL_BIAS_CTRL),
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL_CLR);
+
+ /* Set Vag value */
+ mxs_codec_dac_set_vag();
+
+ /* Power on DAC codec */
+ mxs_codec_dac_power_on(mxs_adc);
+}
+
+static void mxs_codec_dac_disable(struct mxs_codec_priv *mxs_adc)
+{
+ mxs_codec_dac_power_down(mxs_adc);
+}
+
+static void mxs_codec_adc_enable(struct mxs_codec_priv *mxs_adc)
+{
+ /* Move ADC codec out of reset */
+ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+
+ /* Power on ADC codec */
+ mxs_codec_adc_power_on(mxs_adc);
+}
+
+static void mxs_codec_adc_disable(struct mxs_codec_priv *mxs_adc)
+{
+ mxs_codec_adc_power_down(mxs_adc);
+}
+
+static void mxs_codec_startup(struct snd_soc_codec *codec)
+{
+ struct mxs_codec_priv *mxs_adc = codec->private_data;
+
+ /* Soft reset DAC block */
+ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+ while (!(__raw_readl(REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL)
+ & BM_AUDIOOUT_CTRL_CLKGATE)){
+ }
+
+ /* Soft reset ADC block */
+ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+ while (!(__raw_readl(REGS_AUDIOIN_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);
+
+ snd_soc_add_controls(codec, mxs_snd_controls,
+ ARRAY_SIZE(mxs_snd_controls));
+
+ mxs_codec_add_widgets(codec);
+}
+
+static void mxs_codec_stop(struct snd_soc_codec *codec)
+{
+ struct mxs_codec_priv *mxs_adc = codec->private_data;
+ mxs_codec_dac_disable(mxs_adc);
+ mxs_codec_adc_disable(mxs_adc);
+}
+
+#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
+#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops mxs_dai_ops = {
+ .hw_params = mxs_codec_hw_params,
+ .digital_mute = mxs_codec_dig_mute,
+};
+
+struct snd_soc_dai mxs_codec_dai = {
+ .name = "mxs adc/dac",
+ .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_dai_ops,
+};
+EXPORT_SYMBOL_GPL(mxs_codec_dai);
+
+static struct snd_soc_codec *mxs_codec;
+
+static int mxs_codec_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
+ int ret = 0;
+
+ socdev->card->codec = mxs_codec;
+ codec = mxs_codec;
+
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to create pcms\n");
+ return ret;
+ }
+
+ mxs_codec_startup(codec);
+
+ /* Register the socdev */
+ ret = snd_soc_init_card(socdev);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to register card\n");
+ snd_soc_dapm_free(socdev);
+ snd_soc_free_pcms(socdev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mxs_codec_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+
+ mxs_codec_stop(codec);
+
+ snd_soc_dapm_free(socdev);
+ snd_soc_free_pcms(socdev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxs_codec_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ struct mxs_codec_priv *mxs_adc;
+ int ret = -EINVAL;
+
+ if (codec == NULL)
+ goto out;
+
+ mxs_adc = codec->private_data;
+
+ mxs_codec_dac_disable(mxs_adc);
+ mxs_codec_adc_disable(mxs_adc);
+ clk_disable(mxs_adc->clk);
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int mxs_codec_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ struct mxs_codec_priv *mxs_adc;
+ int ret = -EINVAL;
+
+ if (codec == NULL)
+ goto out;
+
+ mxs_adc = codec->private_data;
+ clk_enable(mxs_adc->clk);
+
+ /* Soft reset DAC block */
+ __raw_writel(BM_AUDIOOUT_CTRL_SFTRST,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+ while (!
+ (__raw_readl(REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL)
+ & BM_AUDIOOUT_CTRL_CLKGATE)){
+ }
+
+ /* Soft reset ADC block */
+ __raw_writel(BM_AUDIOIN_CTRL_SFTRST,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+ while (!
+ (__raw_readl(REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL)
+ & BM_AUDIOIN_CTRL_CLKGATE)){
+ }
+
+ mxs_codec_dac_enable(mxs_adc);
+ mxs_codec_adc_enable(mxs_adc);
+
+ /*restore registers relevant to amixer controls */
+ mxs_codec_restore_reg(codec, DAC_CTRL_L);
+ mxs_codec_restore_reg(codec, DAC_VOLUME_L);
+ mxs_codec_restore_reg(codec, DAC_VOLUME_H);
+ mxs_codec_restore_reg(codec, DAC_HPVOL_L);
+ mxs_codec_restore_reg(codec, DAC_HPVOL_H);
+ mxs_codec_restore_reg(codec, DAC_SPEAKERCTRL_H);
+ mxs_codec_restore_reg(codec, ADC_VOLUME_L);
+ mxs_codec_restore_reg(codec, ADC_VOLUME_H);
+ mxs_codec_restore_reg(codec, ADC_ADCVOL_L);
+ mxs_codec_restore_reg(codec, ADC_ADCVOL_H);
+ mxs_codec_restore_reg(codec, ADC_MICLINE_L);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+#else
+#define mxs_codec_suspend NULL
+#define mxs_codec_resume NULL
+#endif /* CONFIG_PM */
+
+struct snd_soc_codec_device soc_codec_dev_mxs = {
+ .probe = mxs_codec_probe,
+ .remove = mxs_codec_remove,
+ .suspend = mxs_codec_suspend,
+ .resume = mxs_codec_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_mxs);
+
+/* codec register, unregister function */
+static int __init mxs_codec_audio_probe(struct platform_device *pdev)
+{
+ struct mxs_codec_priv *mxs_adc;
+ struct snd_soc_codec *codec;
+ int ret = 0;
+
+ dev_info(&pdev->dev,
+ "MXS ADC/DAC Audio Codec \n");
+
+ mxs_adc = kzalloc(sizeof(struct mxs_codec_priv), GFP_KERNEL);
+ if (mxs_adc == NULL)
+ return -ENOMEM;
+
+ codec = &mxs_adc->codec;
+ codec->dev = &pdev->dev;
+ codec->name = "mxs adc/dac";
+ codec->owner = THIS_MODULE;
+ codec->private_data = mxs_adc;
+ codec->read = mxs_codec_read;
+ codec->write = mxs_codec_write;
+ codec->dai = &mxs_codec_dai;
+ codec->num_dai = 1;
+ codec->reg_cache_size = sizeof(mxs_audio_regs) >> 1;
+ codec->reg_cache_step = 1;
+ codec->reg_cache = (void *)&mxs_audio_regs;
+
+ platform_set_drvdata(pdev, mxs_adc);
+
+ mxs_codec = codec;
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ /* Turn on audio clock */
+ mxs_adc->clk = clk_get(&pdev->dev, "audio");
+ if (IS_ERR(mxs_adc->clk)) {
+ ret = PTR_ERR(mxs_adc->clk);
+ dev_err(&pdev->dev, "%s: Clocks initialization failed\n",
+ __func__);
+ goto clk_err;
+ }
+ clk_enable(mxs_adc->clk);
+
+ ret = snd_soc_register_codec(codec);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register card\n");
+ goto card_err;
+ }
+
+ ret = snd_soc_register_dai(&mxs_codec_dai);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register codec dai\n");
+ goto dai_err;
+ }
+
+ return 0;
+
+dai_err:
+ snd_soc_unregister_codec(codec);
+card_err:
+ clk_disable(mxs_adc->clk);
+ clk_put(mxs_adc->clk);
+clk_err:
+ kfree(mxs_adc);
+ return ret;
+}
+
+static int __devexit mxs_codec_audio_remove(struct platform_device *pdev)
+{
+ struct mxs_codec_priv *mxs_adc = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = &mxs_adc->codec;
+
+ snd_soc_unregister_codec(codec);
+
+ clk_disable(mxs_adc->clk);
+ clk_put(mxs_adc->clk);
+
+ kfree(mxs_adc);
+
+ return 0;
+}
+
+struct platform_driver mxs_codec_audio_driver = {
+ .driver = {
+ .name = "mxs-adc-audio",
+ },
+ .probe = mxs_codec_audio_probe,
+ .remove = __devexit_p(mxs_codec_audio_remove),
+};
+
+static int __init mxs_codec_init(void)
+{
+ return platform_driver_register(&mxs_codec_audio_driver);
+}
+
+static void __exit mxs_codec_exit(void)
+{
+ return platform_driver_unregister(&mxs_codec_audio_driver);
+}
+
+module_init(mxs_codec_init);
+module_exit(mxs_codec_exit);
+
+MODULE_DESCRIPTION("MXS ADC/DAC codec");
+MODULE_AUTHOR("Vladislav Buzov");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/mxs-adc-codec.h b/sound/soc/codecs/mxs-adc-codec.h
new file mode 100644
index 000000000000..129c1c7bdf66
--- /dev/null
+++ b/sound/soc/codecs/mxs-adc-codec.h
@@ -0,0 +1,87 @@
+/*
+ * ALSA codec for Freescale MXS ADC/DAC Audio
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * 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
+ */
+#ifndef __MXS_ADC_CODEC_H
+#define __MXS_ADC_CODEC_H
+
+#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
+
+extern struct snd_soc_dai mxs_codec_dai;
+extern struct snd_soc_codec_device soc_codec_dev_mxs;
+
+#endif /* __MXS_ADC_CODEC_H */
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
index 12e95ab6dce4..d4dc2b795eb0 100644
--- a/sound/soc/mxs/Kconfig
+++ b/sound/soc/mxs/Kconfig
@@ -18,6 +18,14 @@ config SND_MXS_SOC_EVK_DEVB
Say Y if you want to add support for SoC audio on MXS EVK development
board with the sgtl5000 codec.
+config SND_MXS_SOC_EVK_ADC
+ tristate "SoC Audio support for MXS-EVK ADC/DAC"
+ depends on SND_MXS_SOC && ARCH_MX23
+ select SND_SOC_MXS_ADC_CODEC
+ help
+ Say Y if you want to add support for SoC audio on MXS EVK development
+ board with ADC/DAC audio interface.
+
config SND_MXS_SOC_DAI
tristate "MXS Digital Audio Interface SAIF"
default y
@@ -38,6 +46,12 @@ config SND_MXS_SOC_SAIF1_SELECT
help
Enable MXS SAIF1 Module
+config SND_MXS_SOC_ADC
+ tristate "MXS ADC/DAC Audio Interface"
+ default y
+ depends on SND_MXS_SOC_EVK_ADC
+ help
+ Enable MXS ADC/DAC Audio Interface
config SND_MXS_SOC_EVK_DEVB_SPDIF
tristate "SoC SPDIF support for MXS EVK Development Board"
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile
index 6a8ce0ef8d93..971c622a34fb 100644
--- a/sound/soc/mxs/Makefile
+++ b/sound/soc/mxs/Makefile
@@ -4,9 +4,13 @@ snd-soc-mxs-dai-objs := mxs-dai.o
snd-soc-mxs-spdif-dai-objs := mxs-spdif-dai.o
snd-soc-mxs-devb-objs := mxs-devb.o
snd-soc-mxs-devb-spdif-objs := mxs-devb-spdif.o
+snd-soc-mxs-adc-objs := mxs-adc.o
+snd-soc-mxs-evk-adc-objs := mxs-evk-adc.o
obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o
obj-$(CONFIG_SND_MXS_SOC_DAI) += snd-soc-mxs-dai.o
obj-$(CONFIG_SND_MXS_SOC_SPDIF_DAI) += snd-soc-mxs-spdif-dai.o
obj-$(CONFIG_SND_MXS_SOC_EVK_DEVB) += snd-soc-mxs-devb.o
obj-$(CONFIG_SND_MXS_SOC_EVK_DEVB_SPDIF) += snd-soc-mxs-devb-spdif.o
+obj-$(CONFIG_SND_MXS_SOC_ADC) += snd-soc-mxs-adc.o
+obj-$(CONFIG_SND_MXS_SOC_EVK_ADC) += snd-soc-mxs-evk-adc.o
diff --git a/sound/soc/mxs/mxs-adc.c b/sound/soc/mxs/mxs-adc.c
new file mode 100644
index 000000000000..a6b843bf7f9e
--- /dev/null
+++ b/sound/soc/mxs/mxs-adc.c
@@ -0,0 +1,257 @@
+/*
+ * ASoC Audio Layer for Freescale MXS ADC/DAC
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <mach/dma.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/regs-audioin.h>
+#include <mach/regs-audioout.h>
+
+#include "mxs-pcm.h"
+
+#define MXS_ADC_RATES SNDRV_PCM_RATE_8000_192000
+#define MXS_ADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+struct mxs_pcm_dma_params mxs_audio_in = {
+ .name = "mxs-audio-in",
+ .dma_ch = MXS_DMA_CHANNEL_AHB_APBX_AUDIOADC,
+ .irq = IRQ_ADC_DMA,
+};
+
+struct mxs_pcm_dma_params mxs_audio_out = {
+ .name = "mxs-audio-out",
+ .dma_ch = MXS_DMA_CHANNEL_AHB_APBX_AUDIODAC,
+ .irq = IRQ_DAC_DMA,
+};
+
+static irqreturn_t mxs_err_irq(int irq, void *dev_id)
+{
+ struct snd_pcm_substream *substream = dev_id;
+ 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(REGS_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(REGS_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,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ else
+ __raw_writel(
+ BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
+ REGS_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,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ else
+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+ } else
+ printk(KERN_WARNING "Unknown DAC error interrupt\n");
+
+ return IRQ_HANDLED;
+}
+
+static int mxs_adc_trigger(struct snd_pcm_substream *substream,
+ int cmd,
+ struct snd_soc_dai *dai)
+{
+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ if (playback)
+ __raw_writel(BM_AUDIOOUT_CTRL_RUN,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+ else
+ __raw_writel(BM_AUDIOIN_CTRL_RUN,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ if (playback)
+ __raw_writel(BM_AUDIOOUT_CTRL_RUN,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ else
+ __raw_writel(BM_AUDIOIN_CTRL_RUN,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+ break;
+
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mxs_adc_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0;
+ int irq;
+ int ret;
+
+ if (playback) {
+ irq = IRQ_DAC_ERROR;
+ cpu_dai->dma_data = &mxs_audio_out;
+ } else {
+ irq = IRQ_ADC_ERROR;
+ cpu_dai->dma_data = &mxs_audio_in;
+ }
+
+ ret = request_irq(irq, mxs_err_irq, 0, "MXS DAC/ADC Error",
+ substream);
+ if (ret) {
+ printk(KERN_ERR "%s: Unable to request ADC/DAC error irq %d\n",
+ __func__, IRQ_DAC_ERROR);
+ return ret;
+ }
+
+ /* Enable error interrupt */
+ if (playback) {
+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ __raw_writel(BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET);
+ } else {
+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_SET);
+ }
+
+ return 0;
+}
+
+static void mxs_adc_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *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,
+ REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR);
+ free_irq(IRQ_DAC_ERROR, substream);
+ } else {
+ __raw_writel(BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN,
+ REGS_AUDIOIN_BASE + HW_AUDIOIN_CTRL_CLR);
+ free_irq(IRQ_ADC_ERROR, substream);
+ }
+}
+
+#ifdef CONFIG_PM
+static int mxs_adc_suspend(struct snd_soc_dai *cpu_dai)
+{
+ return 0;
+}
+
+static int mxs_adc_resume(struct snd_soc_dai *cpu_dai)
+{
+ return 0;
+}
+#else
+#define mxs_adc_suspend NULL
+#define mxs_adc_resume NULL
+#endif /* CONFIG_PM */
+
+struct snd_soc_dai_ops mxs_adc_dai_ops = {
+ .startup = mxs_adc_startup,
+ .shutdown = mxs_adc_shutdown,
+ .trigger = mxs_adc_trigger,
+};
+
+struct snd_soc_dai mxs_adc_dai = {
+ .name = "mxs adc/dac",
+ .id = 0,
+ .suspend = mxs_adc_suspend,
+ .resume = mxs_adc_resume,
+ .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,
+};
+EXPORT_SYMBOL_GPL(mxs_adc_dai);
+
+static int __init mxs_adc_dai_init(void)
+{
+ return snd_soc_register_dai(&mxs_adc_dai);
+}
+
+static void __exit mxs_adc_dai_exit(void)
+{
+ snd_soc_unregister_dai(&mxs_adc_dai);
+}
+module_init(mxs_adc_dai_init);
+module_exit(mxs_adc_dai_exit);
+
+MODULE_AUTHOR("Vladislav Buzov");
+MODULE_DESCRIPTION("MXS ADC/DAC DAI");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/mxs/mxs-adc.h b/sound/soc/mxs/mxs-adc.h
new file mode 100644
index 000000000000..b922c14cb894
--- /dev/null
+++ b/sound/soc/mxs/mxs-adc.h
@@ -0,0 +1,21 @@
+/*
+ * ASoC Audio Layer for Freescale MXS ADC/DAC
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * 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
+ */
+#ifndef _MXS_ADC_H
+#define _MXS_ADC_H
+extern struct snd_soc_dai mxs_adc_dai;
+#endif
diff --git a/sound/soc/mxs/mxs-evk-adc.c b/sound/soc/mxs/mxs-evk-adc.c
new file mode 100644
index 000000000000..bd1ed6bf691f
--- /dev/null
+++ b/sound/soc/mxs/mxs-evk-adc.c
@@ -0,0 +1,91 @@
+/*
+ * ASoC driver for Freescale MXS EVK board
+ *
+ * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+/*
+ * 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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+
+#include "../codecs/mxs-adc-codec.h"
+#include "mxs-adc.h"
+#include "mxs-pcm.h"
+
+/* mxs evk dac/adc audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link mxs_evk_codec_dai = {
+ .name = "MXS ADC/DAC",
+ .stream_name = "MXS ADC/DAC",
+ .cpu_dai = &mxs_adc_dai,
+ .codec_dai = &mxs_codec_dai,
+};
+
+/* mxs evk audio machine driver */
+static struct snd_soc_card snd_soc_card_mxs_evk = {
+ .name = "MXS EVK",
+ .platform = &mxs_soc_platform,
+ .dai_link = &mxs_evk_codec_dai,
+ .num_links = 1,
+};
+
+/* mxs evk audio subsystem */
+static struct snd_soc_device mxs_evk_snd_devdata = {
+ .card = &snd_soc_card_mxs_evk,
+ .codec_dev = &soc_codec_dev_mxs,
+};
+
+static struct platform_device *mxs_evk_snd_device;
+
+static int __init mxs_evk_adc_init(void)
+{
+ int ret = 0;
+
+ mxs_evk_snd_device = platform_device_alloc("soc-audio", 0);
+ if (!mxs_evk_snd_device)
+ return -ENOMEM;
+
+ platform_set_drvdata(mxs_evk_snd_device,
+ &mxs_evk_snd_devdata);
+ mxs_evk_snd_devdata.dev = &mxs_evk_snd_device->dev;
+ mxs_evk_snd_device->dev.platform_data =
+ &mxs_evk_snd_devdata;
+
+ ret = platform_device_add(mxs_evk_snd_device);
+ if (ret)
+ platform_device_put(mxs_evk_snd_device);
+
+ return ret;
+}
+
+static void __exit mxs_evk_adc_exit(void)
+{
+ platform_device_unregister(mxs_evk_snd_device);
+}
+
+module_init(mxs_evk_adc_init);
+module_exit(mxs_evk_adc_exit);
+
+MODULE_AUTHOR("Vladislav Buzov");
+MODULE_DESCRIPTION("MXS EVK board ADC/DAC driver");
+MODULE_LICENSE("GPL");