ASoC: imx: merge sound/soc/imx into sound/soc/fsl
authorShawn Guo <shawn.guo@linaro.org>
Fri, 16 Mar 2012 08:56:38 +0000 (16:56 +0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sun, 1 Apr 2012 10:28:26 +0000 (11:28 +0100)
Freescale PowerPC and ARM/IMX families share the same SSI IP block.
The patch merges sound/soc/imx into sound/soc/fsl, so that the possible
code sharing and consolidation can happen.

This is a plain merge, except that menuconfig SND_POWERPC_SOC is added
in Kconfig for PowerPC platform as a correspondence to SND_IMX_SOC for
IMX platform.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
33 files changed:
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/fsl/Kconfig
sound/soc/fsl/Makefile
sound/soc/fsl/eukrea-tlv320.c [new file with mode: 0644]
sound/soc/fsl/imx-audmux.c [new file with mode: 0644]
sound/soc/fsl/imx-audmux.h [new file with mode: 0644]
sound/soc/fsl/imx-pcm-dma-mx2.c [new file with mode: 0644]
sound/soc/fsl/imx-pcm-fiq.c [new file with mode: 0644]
sound/soc/fsl/imx-pcm.c [new file with mode: 0644]
sound/soc/fsl/imx-pcm.h [new file with mode: 0644]
sound/soc/fsl/imx-ssi.c [new file with mode: 0644]
sound/soc/fsl/imx-ssi.h [new file with mode: 0644]
sound/soc/fsl/mx27vis-aic32x4.c [new file with mode: 0644]
sound/soc/fsl/phycore-ac97.c [new file with mode: 0644]
sound/soc/fsl/wm1133-ev1.c [new file with mode: 0644]
sound/soc/imx/Kconfig [deleted file]
sound/soc/imx/Makefile [deleted file]
sound/soc/imx/eukrea-tlv320.c [deleted file]
sound/soc/imx/imx-audmux.c [deleted file]
sound/soc/imx/imx-audmux.h [deleted file]
sound/soc/imx/imx-pcm-dma-mx2.c [deleted file]
sound/soc/imx/imx-pcm-fiq.c [deleted file]
sound/soc/imx/imx-pcm.c [deleted file]
sound/soc/imx/imx-pcm.h [deleted file]
sound/soc/imx/imx-ssi.c [deleted file]
sound/soc/imx/imx-ssi.h [deleted file]
sound/soc/imx/mx27vis-aic32x4.c [deleted file]
sound/soc/imx/phycore-ac97.c [deleted file]
sound/soc/imx/wm1133-ev1.c [deleted file]

index 0db9ba0423ff9e2fea406de92234a05846681662..c09598b31de1bb6ded595721edf7e8cbb213ace9 100644 (file)
@@ -100,6 +100,7 @@ CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 # CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_SOC=y
+CONFIG_SND_POWERPC_SOC=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_EXT2_FS=y
index cc87a8441566d663071aa6b2fff7d105fc796a60..b7ac92a8b28f121b48396e91e0747f6e9506fb4e 100644 (file)
@@ -140,6 +140,7 @@ CONFIG_SND_INTEL8X0=y
 # CONFIG_SND_PPC is not set
 # CONFIG_SND_USB is not set
 CONFIG_SND_SOC=y
+CONFIG_SND_POWERPC_SOC=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
index 48d6682f2434bfcc3ea0cbe70eb847e62de92d45..41d5e4709a084493f3fa1854901a1b835769b033 100644 (file)
@@ -142,6 +142,7 @@ CONFIG_SND_INTEL8X0=y
 # CONFIG_SND_PPC is not set
 # CONFIG_SND_USB is not set
 CONFIG_SND_SOC=y
+CONFIG_SND_POWERPC_SOC=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
index 91c985599d32c782c9b42029ccb409bb9afec429..0f85f6d526e03430da092598142938ee2d627caa 100644 (file)
@@ -35,7 +35,6 @@ source "sound/soc/blackfin/Kconfig"
 source "sound/soc/davinci/Kconfig"
 source "sound/soc/ep93xx/Kconfig"
 source "sound/soc/fsl/Kconfig"
-source "sound/soc/imx/Kconfig"
 source "sound/soc/jz4740/Kconfig"
 source "sound/soc/nuc900/Kconfig"
 source "sound/soc/omap/Kconfig"
index 2feaf376e94b2fc4ab06ca821e4ac328d3d423bb..363dfd6cffe708970966df0f14c0808029bf2277 100644 (file)
@@ -12,7 +12,6 @@ obj-$(CONFIG_SND_SOC) += blackfin/
 obj-$(CONFIG_SND_SOC)  += davinci/
 obj-$(CONFIG_SND_SOC)  += ep93xx/
 obj-$(CONFIG_SND_SOC)  += fsl/
-obj-$(CONFIG_SND_SOC)   += imx/
 obj-$(CONFIG_SND_SOC)  += jz4740/
 obj-$(CONFIG_SND_SOC)  += mid-x86/
 obj-$(CONFIG_SND_SOC)  += mxs/
index ca693b2ed8382d1e351f8612d1be446385873400..19856a05208c5b6b307ca1ffbf25ec265f1b6fc6 100644 (file)
@@ -1,3 +1,15 @@
+config SND_SOC_FSL_SSI
+       tristate
+
+menuconfig SND_POWERPC_SOC
+       tristate "SoC Audio for Freescale PowerPC CPUs"
+       depends on FSL_SOC
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the PowerPC CPUs.
+
+if SND_POWERPC_SOC
+
 config SND_MPC52xx_DMA
        tristate
 
@@ -68,3 +80,83 @@ config SND_MPC52xx_SOC_EFIKA
        help
          Say Y if you want to add support for sound on the Efika.
 
+endif # SND_POWERPC_SOC
+
+menuconfig SND_IMX_SOC
+       tristate "SoC Audio for Freescale i.MX CPUs"
+       depends on ARCH_MXC
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the i.MX CPUs.
+
+if SND_IMX_SOC
+
+config SND_SOC_IMX_SSI
+       tristate
+
+config SND_SOC_IMX_PCM
+       tristate
+
+config SND_MXC_SOC_FIQ
+       tristate
+       select FIQ
+       select SND_SOC_IMX_PCM
+
+config SND_MXC_SOC_MX2
+       tristate
+       select SND_SOC_DMAENGINE_PCM
+       select SND_SOC_IMX_PCM
+
+config SND_SOC_IMX_AUDMUX
+       tristate
+
+config SND_MXC_SOC_WM1133_EV1
+       tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
+       depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
+       select SND_SOC_WM8350
+       select SND_MXC_SOC_FIQ
+       select SND_SOC_IMX_AUDMUX
+       select SND_SOC_IMX_SSI
+       help
+         Enable support for audio on the i.MX31ADS with the WM1133-EV1
+         PMIC board with WM8835x fitted.
+
+config SND_SOC_MX27VIS_AIC32X4
+       tristate "SoC audio support for Visstrim M10 boards"
+       depends on MACH_IMX27_VISSTRIM_M10 && I2C
+       select SND_SOC_TLV320AIC32X4
+       select SND_MXC_SOC_MX2
+       select SND_SOC_IMX_AUDMUX
+       select SND_SOC_IMX_SSI
+       help
+         Say Y if you want to add support for SoC audio on Visstrim SM10
+         board with TLV320AIC32X4 codec.
+
+config SND_SOC_PHYCORE_AC97
+       tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
+       depends on MACH_PCM043 || MACH_PCA100
+       select SND_SOC_AC97_BUS
+       select SND_SOC_WM9712
+       select SND_MXC_SOC_FIQ
+       select SND_SOC_IMX_AUDMUX
+       select SND_SOC_IMX_SSI
+       help
+         Say Y if you want to add support for SoC audio on Phytec phyCORE
+         and phyCARD boards in AC97 mode
+
+config SND_SOC_EUKREA_TLV320
+       tristate "Eukrea TLV320"
+       depends on MACH_EUKREA_MBIMX27_BASEBOARD \
+               || MACH_EUKREA_MBIMXSD25_BASEBOARD \
+               || MACH_EUKREA_MBIMXSD35_BASEBOARD \
+               || MACH_EUKREA_MBIMXSD51_BASEBOARD
+       depends on I2C
+       select SND_SOC_TLV320AIC23
+       select SND_MXC_SOC_FIQ
+       select SND_SOC_IMX_AUDMUX
+       select SND_SOC_IMX_SSI
+       help
+         Enable I2S based access to the TLV320AIC23B codec attached
+         to the SSI interface
+
+endif # SND_IMX_SOC
index 95d483f6af7ff4937a23706df544866510bd0f7d..36c257fd35bb30db31aebff75213baa6f068d029 100644 (file)
@@ -21,3 +21,25 @@ obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
 obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
 obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
 
+# i.MX Platform Support
+snd-soc-imx-ssi-objs := imx-ssi.o
+snd-soc-imx-audmux-objs := imx-audmux.o
+
+obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
+
+obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
+snd-soc-imx-pcm-y := imx-pcm.o
+snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
+snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o
+
+# i.MX Machine Support
+snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
+snd-soc-phycore-ac97-objs := phycore-ac97.o
+snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
+snd-soc-wm1133-ev1-objs := wm1133-ev1.o
+
+obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
+obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
+obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
+obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
new file mode 100644 (file)
index 0000000..efb9ede
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * eukrea-tlv320.c  --  SoC audio for eukrea_cpuimxXX in I2S mode
+ *
+ * Copyright 2010 Eric Bénard, Eukréa Electromatique <eric@eukrea.com>
+ *
+ * based on sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+ * which is Copyright 2009 Simtec Electronics
+ * and on sound/soc/imx/phycore-ac97.c which is
+ * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ *  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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <asm/mach-types.h>
+
+#include "../codecs/tlv320aic23.h"
+#include "imx-ssi.h"
+#include "imx-audmux.h"
+
+#define CODEC_CLOCK 12000000
+
+static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       int ret;
+
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret) {
+               pr_err("%s: failed set cpu dai format\n", __func__);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret) {
+               pr_err("%s: failed set codec dai format\n", __func__);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+                                    CODEC_CLOCK, SND_SOC_CLOCK_OUT);
+       if (ret) {
+               pr_err("%s: failed setting codec sysclk\n", __func__);
+               return ret;
+       }
+       snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
+                               SND_SOC_CLOCK_IN);
+       if (ret) {
+               pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops eukrea_tlv320_snd_ops = {
+       .hw_params      = eukrea_tlv320_hw_params,
+};
+
+static struct snd_soc_dai_link eukrea_tlv320_dai = {
+       .name           = "tlv320aic23",
+       .stream_name    = "TLV320AIC23",
+       .codec_dai_name = "tlv320aic23-hifi",
+       .platform_name  = "imx-fiq-pcm-audio.0",
+       .codec_name     = "tlv320aic23-codec.0-001a",
+       .cpu_dai_name   = "imx-ssi.0",
+       .ops            = &eukrea_tlv320_snd_ops,
+};
+
+static struct snd_soc_card eukrea_tlv320 = {
+       .name           = "cpuimx-audio",
+       .owner          = THIS_MODULE,
+       .dai_link       = &eukrea_tlv320_dai,
+       .num_links      = 1,
+};
+
+static struct platform_device *eukrea_tlv320_snd_device;
+
+static int __init eukrea_tlv320_init(void)
+{
+       int ret;
+       int int_port = 0, ext_port;
+
+       if (machine_is_eukrea_cpuimx27()) {
+               imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+                       IMX_AUDMUX_V1_PCR_SYN |
+                       IMX_AUDMUX_V1_PCR_TFSDIR |
+                       IMX_AUDMUX_V1_PCR_TCLKDIR |
+                       IMX_AUDMUX_V1_PCR_RFSDIR |
+                       IMX_AUDMUX_V1_PCR_RCLKDIR |
+                       IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
+                       IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
+                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
+               );
+               imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
+                       IMX_AUDMUX_V1_PCR_SYN |
+                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+               );
+       } else if (machine_is_eukrea_cpuimx25sd() ||
+                  machine_is_eukrea_cpuimx35sd() ||
+                  machine_is_eukrea_cpuimx51sd()) {
+               ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3;
+               imx_audmux_v2_configure_port(int_port,
+                       IMX_AUDMUX_V2_PTCR_SYN |
+                       IMX_AUDMUX_V2_PTCR_TFSDIR |
+                       IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
+                       IMX_AUDMUX_V2_PTCR_TCLKDIR |
+                       IMX_AUDMUX_V2_PTCR_TCSEL(ext_port),
+                       IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)
+               );
+               imx_audmux_v2_configure_port(ext_port,
+                       IMX_AUDMUX_V2_PTCR_SYN,
+                       IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
+               );
+       } else {
+               /* return happy. We might run on a totally different machine */
+               return 0;
+       }
+
+       eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!eukrea_tlv320_snd_device)
+               return -ENOMEM;
+
+       platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
+       ret = platform_device_add(eukrea_tlv320_snd_device);
+
+       if (ret) {
+               printk(KERN_ERR "ASoC: Platform device allocation failed\n");
+               platform_device_put(eukrea_tlv320_snd_device);
+       }
+
+       return ret;
+}
+
+static void __exit eukrea_tlv320_exit(void)
+{
+       platform_device_unregister(eukrea_tlv320_snd_device);
+}
+
+module_init(eukrea_tlv320_init);
+module_exit(eukrea_tlv320_exit);
+
+MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>");
+MODULE_DESCRIPTION("CPUIMX ALSA SoC driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
new file mode 100644 (file)
index 0000000..601df80
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "imx-audmux.h"
+
+#define DRIVER_NAME "imx-audmux"
+
+static struct clk *audmux_clk;
+static void __iomem *audmux_base;
+
+#define IMX_AUDMUX_V2_PTCR(x)          ((x) * 8)
+#define IMX_AUDMUX_V2_PDCR(x)          ((x) * 8 + 4)
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *audmux_debugfs_root;
+
+static int audmux_open_file(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+/* There is an annoying discontinuity in the SSI numbering with regard
+ * to the Linux number of the devices */
+static const char *audmux_port_string(int port)
+{
+       switch (port) {
+       case MX31_AUDMUX_PORT1_SSI0:
+               return "imx-ssi.0";
+       case MX31_AUDMUX_PORT2_SSI1:
+               return "imx-ssi.1";
+       case MX31_AUDMUX_PORT3_SSI_PINS_3:
+               return "SSI3";
+       case MX31_AUDMUX_PORT4_SSI_PINS_4:
+               return "SSI4";
+       case MX31_AUDMUX_PORT5_SSI_PINS_5:
+               return "SSI5";
+       case MX31_AUDMUX_PORT6_SSI_PINS_6:
+               return "SSI6";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       ssize_t ret;
+       char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       int port = (int)file->private_data;
+       u32 pdcr, ptcr;
+
+       if (!buf)
+               return -ENOMEM;
+
+       if (audmux_clk)
+               clk_prepare_enable(audmux_clk);
+
+       ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
+       pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
+
+       if (audmux_clk)
+               clk_disable_unprepare(audmux_clk);
+
+       ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
+                      pdcr, ptcr);
+
+       if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
+               ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                               "TxFS output from %s, ",
+                               audmux_port_string((ptcr >> 27) & 0x7));
+       else
+               ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                               "TxFS input, ");
+
+       if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
+               ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                               "TxClk output from %s",
+                               audmux_port_string((ptcr >> 22) & 0x7));
+       else
+               ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                               "TxClk input");
+
+       ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+
+       if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
+               ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                               "Port is symmetric");
+       } else {
+               if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
+                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                                       "RxFS output from %s, ",
+                                       audmux_port_string((ptcr >> 17) & 0x7));
+               else
+                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                                       "RxFS input, ");
+
+               if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
+                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                                       "RxClk output from %s",
+                                       audmux_port_string((ptcr >> 12) & 0x7));
+               else
+                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                                       "RxClk input");
+       }
+
+       ret += snprintf(buf + ret, PAGE_SIZE - ret,
+                       "\nData received from %s\n",
+                       audmux_port_string((pdcr >> 13) & 0x7));
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+
+       kfree(buf);
+
+       return ret;
+}
+
+static const struct file_operations audmux_debugfs_fops = {
+       .open = audmux_open_file,
+       .read = audmux_read_file,
+       .llseek = default_llseek,
+};
+
+static void __init audmux_debugfs_init(void)
+{
+       int i;
+       char buf[20];
+
+       audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
+       if (!audmux_debugfs_root) {
+               pr_warning("Failed to create AUDMUX debugfs root\n");
+               return;
+       }
+
+       for (i = 1; i < 8; i++) {
+               snprintf(buf, sizeof(buf), "ssi%d", i);
+               if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
+                                        (void *)i, &audmux_debugfs_fops))
+                       pr_warning("Failed to create AUDMUX port %d debugfs file\n",
+                                  i);
+       }
+}
+
+static void __devexit audmux_debugfs_remove(void)
+{
+       debugfs_remove_recursive(audmux_debugfs_root);
+}
+#else
+static inline void audmux_debugfs_init(void)
+{
+}
+
+static inline void audmux_debugfs_remove(void)
+{
+}
+#endif
+
+enum imx_audmux_type {
+       IMX21_AUDMUX,
+       IMX31_AUDMUX,
+} audmux_type;
+
+static struct platform_device_id imx_audmux_ids[] = {
+       {
+               .name = "imx21-audmux",
+               .driver_data = IMX21_AUDMUX,
+       }, {
+               .name = "imx31-audmux",
+               .driver_data = IMX31_AUDMUX,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, imx_audmux_ids);
+
+static const struct of_device_id imx_audmux_dt_ids[] = {
+       { .compatible = "fsl,imx21-audmux", .data = &imx_audmux_ids[0], },
+       { .compatible = "fsl,imx31-audmux", .data = &imx_audmux_ids[1], },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_audmux_dt_ids);
+
+static const uint8_t port_mapping[] = {
+       0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
+};
+
+int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
+{
+       if (audmux_type != IMX21_AUDMUX)
+               return -EINVAL;
+
+       if (!audmux_base)
+               return -ENOSYS;
+
+       if (port >= ARRAY_SIZE(port_mapping))
+               return -EINVAL;
+
+       writel(pcr, audmux_base + port_mapping[port]);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port);
+
+int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
+               unsigned int pdcr)
+{
+       if (audmux_type != IMX31_AUDMUX)
+               return -EINVAL;
+
+       if (!audmux_base)
+               return -ENOSYS;
+
+       if (audmux_clk)
+               clk_prepare_enable(audmux_clk);
+
+       writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
+       writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
+
+       if (audmux_clk)
+               clk_disable_unprepare(audmux_clk);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
+
+static int __devinit imx_audmux_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       const struct of_device_id *of_id =
+                       of_match_device(imx_audmux_dt_ids, &pdev->dev);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       audmux_base = devm_request_and_ioremap(&pdev->dev, res);
+       if (!audmux_base)
+               return -EADDRNOTAVAIL;
+
+       audmux_clk = clk_get(&pdev->dev, "audmux");
+       if (IS_ERR(audmux_clk)) {
+               dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
+                               PTR_ERR(audmux_clk));
+               audmux_clk = NULL;
+       }
+
+       if (of_id)
+               pdev->id_entry = of_id->data;
+       audmux_type = pdev->id_entry->driver_data;
+       if (audmux_type == IMX31_AUDMUX)
+               audmux_debugfs_init();
+
+       return 0;
+}
+
+static int __devexit imx_audmux_remove(struct platform_device *pdev)
+{
+       if (audmux_type == IMX31_AUDMUX)
+               audmux_debugfs_remove();
+       clk_put(audmux_clk);
+
+       return 0;
+}
+
+static struct platform_driver imx_audmux_driver = {
+       .probe          = imx_audmux_probe,
+       .remove         = __devexit_p(imx_audmux_remove),
+       .id_table       = imx_audmux_ids,
+       .driver = {
+               .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
+               .of_match_table = imx_audmux_dt_ids,
+       }
+};
+
+static int __init imx_audmux_init(void)
+{
+       return platform_driver_register(&imx_audmux_driver);
+}
+subsys_initcall(imx_audmux_init);
+
+static void __exit imx_audmux_exit(void)
+{
+       platform_driver_unregister(&imx_audmux_driver);
+}
+module_exit(imx_audmux_exit);
+
+MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/sound/soc/fsl/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
new file mode 100644 (file)
index 0000000..04ebbab
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __IMX_AUDMUX_H
+#define __IMX_AUDMUX_H
+
+#define MX27_AUDMUX_HPCR1_SSI0         0
+#define MX27_AUDMUX_HPCR2_SSI1         1
+#define MX27_AUDMUX_HPCR3_SSI_PINS_4   2
+#define MX27_AUDMUX_PPCR1_SSI_PINS_1   3
+#define MX27_AUDMUX_PPCR2_SSI_PINS_2   4
+#define MX27_AUDMUX_PPCR3_SSI_PINS_3   5
+
+#define MX31_AUDMUX_PORT1_SSI0         0
+#define MX31_AUDMUX_PORT2_SSI1         1
+#define MX31_AUDMUX_PORT3_SSI_PINS_3   2
+#define MX31_AUDMUX_PORT4_SSI_PINS_4   3
+#define MX31_AUDMUX_PORT5_SSI_PINS_5   4
+#define MX31_AUDMUX_PORT6_SSI_PINS_6   5
+
+#define MX51_AUDMUX_PORT1_SSI0         0
+#define MX51_AUDMUX_PORT2_SSI1         1
+#define MX51_AUDMUX_PORT3              2
+#define MX51_AUDMUX_PORT4              3
+#define MX51_AUDMUX_PORT5              4
+#define MX51_AUDMUX_PORT6              5
+#define MX51_AUDMUX_PORT7              6
+
+/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
+#define IMX_AUDMUX_V1_PCR_INMMASK(x)   ((x) & 0xff)
+#define IMX_AUDMUX_V1_PCR_INMEN                (1 << 8)
+#define IMX_AUDMUX_V1_PCR_TXRXEN       (1 << 10)
+#define IMX_AUDMUX_V1_PCR_SYN          (1 << 12)
+#define IMX_AUDMUX_V1_PCR_RXDSEL(x)    (((x) & 0x7) << 13)
+#define IMX_AUDMUX_V1_PCR_RFCSEL(x)    (((x) & 0xf) << 20)
+#define IMX_AUDMUX_V1_PCR_RCLKDIR      (1 << 24)
+#define IMX_AUDMUX_V1_PCR_RFSDIR       (1 << 25)
+#define IMX_AUDMUX_V1_PCR_TFCSEL(x)    (((x) & 0xf) << 26)
+#define IMX_AUDMUX_V1_PCR_TCLKDIR      (1 << 30)
+#define IMX_AUDMUX_V1_PCR_TFSDIR       (1 << 31)
+
+/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
+#define IMX_AUDMUX_V2_PTCR_TFSDIR      (1 << 31)
+#define IMX_AUDMUX_V2_PTCR_TFSEL(x)    (((x) & 0xf) << 27)
+#define IMX_AUDMUX_V2_PTCR_TCLKDIR     (1 << 26)
+#define IMX_AUDMUX_V2_PTCR_TCSEL(x)    (((x) & 0xf) << 22)
+#define IMX_AUDMUX_V2_PTCR_RFSDIR      (1 << 21)
+#define IMX_AUDMUX_V2_PTCR_RFSEL(x)    (((x) & 0xf) << 17)
+#define IMX_AUDMUX_V2_PTCR_RCLKDIR     (1 << 16)
+#define IMX_AUDMUX_V2_PTCR_RCSEL(x)    (((x) & 0xf) << 12)
+#define IMX_AUDMUX_V2_PTCR_SYN         (1 << 11)
+
+#define IMX_AUDMUX_V2_PDCR_RXDSEL(x)   (((x) & 0x7) << 13)
+#define IMX_AUDMUX_V2_PDCR_TXRXEN      (1 << 12)
+#define IMX_AUDMUX_V2_PDCR_MODE(x)     (((x) & 0x3) << 8)
+#define IMX_AUDMUX_V2_PDCR_INMMASK(x)  ((x) & 0xff)
+
+int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
+
+int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
+               unsigned int pdcr);
+
+#endif /* __IMX_AUDMUX_H */
diff --git a/sound/soc/fsl/imx-pcm-dma-mx2.c b/sound/soc/fsl/imx-pcm-dma-mx2.c
new file mode 100644 (file)
index 0000000..6b818de
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * imx-pcm-dma-mx2.c  --  ALSA Soc Audio Layer
+ *
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ *  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.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/types.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#include <mach/dma.h>
+
+#include "imx-pcm.h"
+
+static bool filter(struct dma_chan *chan, void *param)
+{
+       if (!imx_dma_is_general_purpose(chan))
+               return false;
+
+       chan->private = param;
+
+       return true;
+}
+
+static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+       struct imx_pcm_dma_params *dma_params;
+       struct dma_slave_config slave_config;
+       int ret;
+
+       dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+       ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
+       if (ret)
+               return ret;
+
+       slave_config.device_fc = false;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               slave_config.dst_addr = dma_params->dma_addr;
+               slave_config.dst_maxburst = dma_params->burstsize;
+       } else {
+               slave_config.src_addr = dma_params->dma_addr;
+               slave_config.src_maxburst = dma_params->burstsize;
+       }
+
+       ret = dmaengine_slave_config(chan, &slave_config);
+       if (ret)
+               return ret;
+
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+       return 0;
+}
+
+static struct snd_pcm_hardware snd_imx_hardware = {
+       .info = SNDRV_PCM_INFO_INTERLEAVED |
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_MMAP_VALID |
+               SNDRV_PCM_INFO_PAUSE |
+               SNDRV_PCM_INFO_RESUME,
+       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .rate_min = 8000,
+       .channels_min = 2,
+       .channels_max = 2,
+       .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
+       .period_bytes_min = 128,
+       .period_bytes_max = 65535, /* Limited by SDMA engine */
+       .periods_min = 2,
+       .periods_max = 255,
+       .fifo_size = 0,
+};
+
+static int snd_imx_open(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct imx_pcm_dma_params *dma_params;
+       struct imx_dma_data *dma_data;
+       int ret;
+
+       snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
+
+       dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+       dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
+       dma_data->peripheral_type = IMX_DMATYPE_SSI;
+       dma_data->priority = DMA_PRIO_HIGH;
+       dma_data->dma_request = dma_params->dma;
+
+       ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
+       if (ret) {
+               kfree(dma_data);
+               return 0;
+       }
+
+       snd_dmaengine_pcm_set_data(substream, dma_data);
+
+       return 0;
+}
+
+static int snd_imx_close(struct snd_pcm_substream *substream)
+{
+       struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
+
+       snd_dmaengine_pcm_close(substream);
+       kfree(dma_data);
+
+       return 0;
+}
+
+static struct snd_pcm_ops imx_pcm_ops = {
+       .open           = snd_imx_open,
+       .close          = snd_imx_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = snd_imx_pcm_hw_params,
+       .trigger        = snd_dmaengine_pcm_trigger,
+       .pointer        = snd_dmaengine_pcm_pointer,
+       .mmap           = snd_imx_pcm_mmap,
+};
+
+static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
+       .ops            = &imx_pcm_ops,
+       .pcm_new        = imx_pcm_new,
+       .pcm_free       = imx_pcm_free,
+};
+
+static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
+{
+       return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
+}
+
+static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
+{
+       snd_soc_unregister_platform(&pdev->dev);
+       return 0;
+}
+
+static struct platform_driver imx_pcm_driver = {
+       .driver = {
+                       .name = "imx-pcm-audio",
+                       .owner = THIS_MODULE,
+       },
+       .probe = imx_soc_platform_probe,
+       .remove = __devexit_p(imx_soc_platform_remove),
+};
+
+module_platform_driver(imx_pcm_driver);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-pcm-audio");
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
new file mode 100644 (file)
index 0000000..456b7d7
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * imx-pcm-fiq.c  --  ALSA Soc Audio Layer
+ *
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ *  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.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <asm/fiq.h>
+
+#include <mach/ssi.h>
+
+#include "imx-ssi.h"
+
+struct imx_pcm_runtime_data {
+       int period;
+       int periods;
+       unsigned long offset;
+       unsigned long last_offset;
+       unsigned long size;
+       struct hrtimer hrt;
+       int poll_time_ns;
+       struct snd_pcm_substream *substream;
+       atomic_t running;
+};
+
+static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
+{
+       struct imx_pcm_runtime_data *iprtd =
+               container_of(hrt, struct imx_pcm_runtime_data, hrt);
+       struct snd_pcm_substream *substream = iprtd->substream;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct pt_regs regs;
+       unsigned long delta;
+
+       if (!atomic_read(&iprtd->running))
+               return HRTIMER_NORESTART;
+
+       get_fiq_regs(&regs);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               iprtd->offset = regs.ARM_r8 & 0xffff;
+       else
+               iprtd->offset = regs.ARM_r9 & 0xffff;
+
+       /* How much data have we transferred since the last period report? */
+       if (iprtd->offset >= iprtd->last_offset)
+               delta = iprtd->offset - iprtd->last_offset;
+       else
+               delta = runtime->buffer_size + iprtd->offset
+                       - iprtd->last_offset;
+
+       /* If we've transferred at least a period then report it and
+        * reset our poll time */
+       if (delta >= iprtd->period) {
+               snd_pcm_period_elapsed(substream);
+               iprtd->last_offset = iprtd->offset;
+       }
+
+       hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
+
+       return HRTIMER_RESTART;
+}
+
+static struct fiq_handler fh = {
+       .name           = DRV_NAME,
+};
+
+static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+       iprtd->size = params_buffer_bytes(params);
+       iprtd->periods = params_periods(params);
+       iprtd->period = params_period_bytes(params) ;
+       iprtd->offset = 0;
+       iprtd->last_offset = 0;
+       iprtd->poll_time_ns = 1000000000 / params_rate(params) *
+                               params_period_size(params);
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+       return 0;
+}
+
+static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+       struct pt_regs regs;
+
+       get_fiq_regs(&regs);
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               regs.ARM_r8 = (iprtd->period * iprtd->periods - 1) << 16;
+       else
+               regs.ARM_r9 = (iprtd->period * iprtd->periods - 1) << 16;
+
+       set_fiq_regs(&regs);
+
+       return 0;
+}
+
+static int fiq_enable;
+static int imx_pcm_fiq;
+
+static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               atomic_set(&iprtd->running, 1);
+               hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
+                     HRTIMER_MODE_REL);
+               if (++fiq_enable == 1)
+                       enable_fiq(imx_pcm_fiq);
+
+               break;
+
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               atomic_set(&iprtd->running, 0);
+
+               if (--fiq_enable == 0)
+                       disable_fiq(imx_pcm_fiq);
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+       return bytes_to_frames(substream->runtime, iprtd->offset);
+}
+
+static struct snd_pcm_hardware snd_imx_hardware = {
+       .info = SNDRV_PCM_INFO_INTERLEAVED |
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_MMAP_VALID |
+               SNDRV_PCM_INFO_PAUSE |
+               SNDRV_PCM_INFO_RESUME,
+       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .rate_min = 8000,
+       .channels_min = 2,
+       .channels_max = 2,
+       .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
+       .period_bytes_min = 128,
+       .period_bytes_max = 16 * 1024,
+       .periods_min = 4,
+       .periods_max = 255,
+       .fifo_size = 0,
+};
+
+static int snd_imx_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd;
+       int ret;
+
+       iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
+       if (iprtd == NULL)
+               return -ENOMEM;
+       runtime->private_data = iprtd;
+
+       iprtd->substream = substream;
+
+       atomic_set(&iprtd->running, 0);
+       hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       iprtd->hrt.function = snd_hrtimer_callback;
+
+       ret = snd_pcm_hw_constraint_integer(substream->runtime,
+                       SNDRV_PCM_HW_PARAM_PERIODS);
+       if (ret < 0) {
+               kfree(iprtd);
+               return ret;
+       }
+
+       snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
+       return 0;
+}
+
+static int snd_imx_close(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+       hrtimer_cancel(&iprtd->hrt);
+
+       kfree(iprtd);
+
+       return 0;
+}
+
+static struct snd_pcm_ops imx_pcm_ops = {
+       .open           = snd_imx_open,
+       .close          = snd_imx_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = snd_imx_pcm_hw_params,
+       .prepare        = snd_imx_pcm_prepare,
+       .trigger        = snd_imx_pcm_trigger,
+       .pointer        = snd_imx_pcm_pointer,
+       .mmap           = snd_imx_pcm_mmap,
+};
+
+static int ssi_irq = 0;
+
+static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_pcm *pcm = rtd->pcm;
+       struct snd_pcm_substream *substream;
+       int ret;
+
+       ret = imx_pcm_new(rtd);
+       if (ret)
+               return ret;
+
+       substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+       if (substream) {
+               struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+               imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
+       }
+
+       substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
+       if (substream) {
+               struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+               imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
+       }
+
+       set_fiq_handler(&imx_ssi_fiq_start,
+               &imx_ssi_fiq_end - &imx_ssi_fiq_start);
+
+       return 0;
+}
+
+static void imx_pcm_fiq_free(struct snd_pcm *pcm)
+{
+       mxc_set_irq_fiq(ssi_irq, 0);
+       release_fiq(&fh);
+       imx_pcm_free(pcm);
+}
+
+static struct snd_soc_platform_driver imx_soc_platform_fiq = {
+       .ops            = &imx_pcm_ops,
+       .pcm_new        = imx_pcm_fiq_new,
+       .pcm_free       = imx_pcm_fiq_free,
+};
+
+static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
+{
+       struct imx_ssi *ssi = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = claim_fiq(&fh);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
+               return ret;
+       }
+
+       mxc_set_irq_fiq(ssi->irq, 1);
+       ssi_irq = ssi->irq;
+
+       imx_pcm_fiq = ssi->irq;
+
+       imx_ssi_fiq_base = (unsigned long)ssi->base;
+
+       ssi->dma_params_tx.burstsize = 4;
+       ssi->dma_params_rx.burstsize = 6;
+
+       ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
+       if (ret)
+               goto failed_register;
+
+       return 0;
+
+failed_register:
+       mxc_set_irq_fiq(ssi_irq, 0);
+       release_fiq(&fh);
+
+       return ret;
+}
+
+static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
+{
+       snd_soc_unregister_platform(&pdev->dev);
+       return 0;
+}
+
+static struct platform_driver imx_pcm_driver = {
+       .driver = {
+                       .name = "imx-fiq-pcm-audio",
+                       .owner = THIS_MODULE,
+       },
+
+       .probe = imx_soc_platform_probe,
+       .remove = __devexit_p(imx_soc_platform_remove),
+};
+
+module_platform_driver(imx_pcm_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c
new file mode 100644 (file)
index 0000000..93dc360
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ * 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.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include "imx-pcm.h"
+
+int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
+               struct vm_area_struct *vma)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       int ret;
+
+       ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
+               runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
+
+       pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
+                       runtime->dma_area,
+                       runtime->dma_addr,
+                       runtime->dma_bytes);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
+
+static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+{
+       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+       struct snd_dma_buffer *buf = &substream->dma_buffer;
+       size_t size = IMX_SSI_DMABUF_SIZE;
+
+       buf->dev.type = SNDRV_DMA_TYPE_DEV;
+       buf->dev.dev = pcm->card->dev;
+       buf->private_data = NULL;
+       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+                                          &buf->addr, GFP_KERNEL);
+       if (!buf->area)
+               return -ENOMEM;
+       buf->bytes = size;
+
+       return 0;
+}
+
+static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
+
+int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_card *card = rtd->card->snd_card;
+       struct snd_pcm *pcm = rtd->pcm;
+       int ret = 0;
+
+       if (!card->dev->dma_mask)
+               card->dev->dma_mask = &imx_pcm_dmamask;
+       if (!card->dev->coherent_dma_mask)
+               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+               ret = imx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_PLAYBACK);
+               if (ret)
+                       goto out;
+       }
+
+       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+               ret = imx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_CAPTURE);
+               if (ret)
+                       goto out;
+       }
+
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(imx_pcm_new);
+
+void imx_pcm_free(struct snd_pcm *pcm)
+{
+       struct snd_pcm_substream *substream;
+       struct snd_dma_buffer *buf;
+       int stream;
+
+       for (stream = 0; stream < 2; stream++) {
+               substream = pcm->streams[stream].substream;
+               if (!substream)
+                       continue;
+
+               buf = &substream->dma_buffer;
+               if (!buf->area)
+                       continue;
+
+               dma_free_writecombine(pcm->card->dev, buf->bytes,
+                                     buf->area, buf->addr);
+               buf->area = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(imx_pcm_free);
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
new file mode 100644 (file)
index 0000000..b5f5c3a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ * 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.
+ */
+
+#ifndef _IMX_PCM_H
+#define _IMX_PCM_H
+
+/*
+ * Do not change this as the FIQ handler depends on this size
+ */
+#define IMX_SSI_DMABUF_SIZE    (64 * 1024)
+
+struct imx_pcm_dma_params {
+       int dma;
+       unsigned long dma_addr;
+       int burstsize;
+};
+
+int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
+                    struct vm_area_struct *vma);
+int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
+void imx_pcm_free(struct snd_pcm *pcm);
+
+#endif /* _IMX_PCM_H */
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
new file mode 100644 (file)
index 0000000..cf3ed03
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * imx-ssi.c  --  ALSA Soc Audio Layer
+ *
+ * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is based on code copyrighted by Freescale,
+ * Liam Girdwood, Javier Martin and probably others.
+ *
+ *  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.
+ *
+ *
+ * The i.MX SSI core has some nasty limitations in AC97 mode. While most
+ * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
+ * one FIFO which combines all valid receive slots. We cannot even select
+ * which slots we want to receive. The WM9712 with which this driver
+ * was developed with always sends GPIO status data in slot 12 which
+ * we receive in our (PCM-) data stream. The only chance we have is to
+ * manually skip this data in the FIQ handler. With sampling rates different
+ * from 48000Hz not every frame has valid receive data, so the ratio
+ * between pcm data and GPIO status data changes. Our FIQ handler is not
+ * able to handle this, hence this driver only works with 48000Hz sampling
+ * rate.
+ * Reading and writing AC97 registers is another challenge. The core
+ * provides us status bits when the read register is updated with *another*
+ * value. When we read the same register two times (and the register still
+ * contains the same value) these status bits are not set. We work
+ * around this by not polling these bits but only wait a fixed delay.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <mach/ssi.h>
+#include <mach/hardware.h>
+
+#include "imx-ssi.h"
+
+#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
+
+/*
+ * SSI Network Mode or TDM slots configuration.
+ * Should only be called when port is inactive (i.e. SSIEN = 0).
+ */
+static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
+       unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 sccr;
+
+       sccr = readl(ssi->base + SSI_STCCR);
+       sccr &= ~SSI_STCCR_DC_MASK;
+       sccr |= SSI_STCCR_DC(slots - 1);
+       writel(sccr, ssi->base + SSI_STCCR);
+
+       sccr = readl(ssi->base + SSI_SRCCR);
+       sccr &= ~SSI_STCCR_DC_MASK;
+       sccr |= SSI_STCCR_DC(slots - 1);
+       writel(sccr, ssi->base + SSI_SRCCR);
+
+       writel(tx_mask, ssi->base + SSI_STMSK);
+       writel(rx_mask, ssi->base + SSI_SRMSK);
+
+       return 0;
+}
+
+/*
+ * SSI DAI format configuration.
+ * Should only be called when port is inactive (i.e. SSIEN = 0).
+ */
+static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 strcr = 0, scr;
+
+       scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
+
+       /* DAI mode */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               /* data on rising edge of bclk, frame low 1clk before data */
+               strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
+               scr |= SSI_SCR_NET;
+               if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
+                       scr &= ~SSI_I2S_MODE_MASK;
+                       scr |= SSI_SCR_I2S_MODE_SLAVE;
+               }
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               /* data on rising edge of bclk, frame high with data */
+               strcr |= SSI_STCR_TXBIT0;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               /* data on rising edge of bclk, frame high with data */
+               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               /* data on rising edge of bclk, frame high 1clk before data */
+               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+               break;
+       }
+
+       /* DAI clock inversion */
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_IB_IF:
+               strcr |= SSI_STCR_TFSI;
+               strcr &= ~SSI_STCR_TSCKP;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
+               break;
+       case SND_SOC_DAIFMT_NB_NF:
+               strcr &= ~SSI_STCR_TFSI;
+               strcr |= SSI_STCR_TSCKP;
+               break;
+       }
+
+       /* DAI clock master masks */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               break;
+       default:
+               /* Master mode not implemented, needs handling of clocks. */
+               return -EINVAL;
+       }
+
+       strcr |= SSI_STCR_TFEN0;
+
+       if (ssi->flags & IMX_SSI_NET)
+               scr |= SSI_SCR_NET;
+       if (ssi->flags & IMX_SSI_SYN)
+               scr |= SSI_SCR_SYN;
+
+       writel(strcr, ssi->base + SSI_STCR);
+       writel(strcr, ssi->base + SSI_SRCR);
+       writel(scr, ssi->base + SSI_SCR);
+
+       return 0;
+}
+
+/*
+ * SSI system clock configuration.
+ * Should only be called when port is inactive (i.e. SSIEN = 0).
+ */
+static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+                                 int clk_id, unsigned int freq, int dir)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 scr;
+
+       scr = readl(ssi->base + SSI_SCR);
+
+       switch (clk_id) {
+       case IMX_SSP_SYS_CLK:
+               if (dir == SND_SOC_CLOCK_OUT)
+                       scr |= SSI_SCR_SYS_CLK_EN;
+               else
+                       scr &= ~SSI_SCR_SYS_CLK_EN;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       writel(scr, ssi->base + SSI_SCR);
+
+       return 0;
+}
+
+/*
+ * SSI Clock dividers
+ * Should only be called when port is inactive (i.e. SSIEN = 0).
+ */
+static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
+                                 int div_id, int div)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 stccr, srccr;
+
+       stccr = readl(ssi->base + SSI_STCCR);
+       srccr = readl(ssi->base + SSI_SRCCR);
+
+       switch (div_id) {
+       case IMX_SSI_TX_DIV_2:
+               stccr &= ~SSI_STCCR_DIV2;
+               stccr |= div;
+               break;
+       case IMX_SSI_TX_DIV_PSR:
+               stccr &= ~SSI_STCCR_PSR;
+               stccr |= div;
+               break;
+       case IMX_SSI_TX_DIV_PM:
+               stccr &= ~0xff;
+               stccr |= SSI_STCCR_PM(div);
+               break;
+       case IMX_SSI_RX_DIV_2:
+               stccr &= ~SSI_STCCR_DIV2;
+               stccr |= div;
+               break;
+       case IMX_SSI_RX_DIV_PSR:
+               stccr &= ~SSI_STCCR_PSR;
+               stccr |= div;
+               break;
+       case IMX_SSI_RX_DIV_PM:
+               stccr &= ~0xff;
+               stccr |= SSI_STCCR_PM(div);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       writel(stccr, ssi->base + SSI_STCCR);
+       writel(srccr, ssi->base + SSI_SRCCR);
+
+       return 0;
+}
+
+static int imx_ssi_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *cpu_dai)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+       struct imx_pcm_dma_params *dma_data;
+
+       /* Tx/Rx config */
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dma_data = &ssi->dma_params_tx;
+       else
+               dma_data = &ssi->dma_params_rx;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
+
+       return 0;
+}
+
+/*
+ * Should only be called when port is inactive (i.e. SSIEN = 0),
+ * although can be called multiple times by upper layers.
+ */
+static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params,
+                            struct snd_soc_dai *cpu_dai)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 reg, sccr;
+
+       /* Tx/Rx config */
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               reg = SSI_STCCR;
+       else
+               reg = SSI_SRCCR;
+
+       if (ssi->flags & IMX_SSI_SYN)
+               reg = SSI_STCCR;
+
+       sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
+
+       /* DAI data (word) size */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               sccr |= SSI_SRCCR_WL(16);
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               sccr |= SSI_SRCCR_WL(20);
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               sccr |= SSI_SRCCR_WL(24);
+               break;
+       }
+
+       writel(sccr, ssi->base + reg);
+
+       return 0;
+}
+
+static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
+               struct snd_soc_dai *dai)
+{
+       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(dai);
+       unsigned int sier_bits, sier;
+       unsigned int scr;
+
+       scr = readl(ssi->base + SSI_SCR);
+       sier = readl(ssi->base + SSI_SIER);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               if (ssi->flags & IMX_SSI_DMA)
+                       sier_bits = SSI_SIER_TDMAE;
+               else
+                       sier_bits = SSI_SIER_TIE | SSI_SIER_TFE0_EN;
+       } else {
+               if (ssi->flags & IMX_SSI_DMA)
+                       sier_bits = SSI_SIER_RDMAE;
+               else
+                       sier_bits = SSI_SIER_RIE | SSI_SIER_RFF0_EN;
+       }
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       scr |= SSI_SCR_TE;
+               else
+                       scr |= SSI_SCR_RE;
+               sier |= sier_bits;
+
+               if (++ssi->enabled == 1)
+                       scr |= SSI_SCR_SSIEN;
+
+               break;
+
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       scr &= ~SSI_SCR_TE;
+               else
+                       scr &= ~SSI_SCR_RE;
+               sier &= ~sier_bits;
+
+               if (--ssi->enabled == 0)
+                       scr &= ~SSI_SCR_SSIEN;
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (!(ssi->flags & IMX_SSI_USE_AC97))
+               /* rx/tx are always enabled to access ac97 registers */
+               writel(scr, ssi->base + SSI_SCR);
+
+       writel(sier, ssi->base + SSI_SIER);
+
+       return 0;
+}
+
+static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
+       .startup        = imx_ssi_startup,
+       .hw_params      = imx_ssi_hw_params,
+       .set_fmt        = imx_ssi_set_dai_fmt,
+       .set_clkdiv     = imx_ssi_set_dai_clkdiv,
+       .set_sysclk     = imx_ssi_set_dai_sysclk,
+       .set_tdm_slot   = imx_ssi_set_dai_tdm_slot,
+       .trigger        = imx_ssi_trigger,
+};
+
+static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
+{
+       struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
+       uint32_t val;
+
+       snd_soc_dai_set_drvdata(dai, ssi);
+
+       val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
+               SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
+       writel(val, ssi->base + SSI_SFCSR);
+
+       return 0;
+}
+
+static struct snd_soc_dai_driver imx_ssi_dai = {
+       .probe = imx_ssi_dai_probe,
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_96000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_96000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .ops = &imx_ssi_pcm_dai_ops,
+};
+
+static struct snd_soc_dai_driver imx_ac97_dai = {
+       .probe = imx_ssi_dai_probe,
+       .ac97_control = 1,
+       .playback = {
+               .stream_name = "AC97 Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .capture = {
+               .stream_name = "AC97 Capture",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .ops = &imx_ssi_pcm_dai_ops,
+};
+
+static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
+{
+       void __iomem *base = imx_ssi->base;
+
+       writel(0x0, base + SSI_SCR);
+       writel(0x0, base + SSI_STCR);
+       writel(0x0, base + SSI_SRCR);
+
+       writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);
+
+       writel(SSI_SFCSR_RFWM0(8) |
+               SSI_SFCSR_TFWM0(8) |
+               SSI_SFCSR_RFWM1(8) |
+               SSI_SFCSR_TFWM1(8), base + SSI_SFCSR);
+
+       writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);
+       writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);
+
+       writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);
+       writel(SSI_SOR_WAIT(3), base + SSI_SOR);
+
+       writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |
+                       SSI_SCR_TE | SSI_SCR_RE,
+                       base + SSI_SCR);
+
+       writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);
+       writel(0xff, base + SSI_SACCDIS);
+       writel(0x300, base + SSI_SACCEN);
+}
+
+static struct imx_ssi *ac97_ssi;
+
+static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+               unsigned short val)
+{
+       struct imx_ssi *imx_ssi = ac97_ssi;
+       void __iomem *base = imx_ssi->base;
+       unsigned int lreg;
+       unsigned int lval;
+
+       if (reg > 0x7f)
+               return;
+
+       pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
+
+       lreg = reg <<  12;
+       writel(lreg, base + SSI_SACADD);
+
+       lval = val << 4;
+       writel(lval , base + SSI_SACDAT);
+
+       writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);
+       udelay(100);
+}
+
+static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,
+               unsigned short reg)
+{
+       struct imx_ssi *imx_ssi = ac97_ssi;
+       void __iomem *base = imx_ssi->base;
+
+       unsigned short val = -1;
+       unsigned int lreg;
+
+       lreg = (reg & 0x7f) <<  12 ;
+       writel(lreg, base + SSI_SACADD);
+       writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);
+
+       udelay(100);
+
+       val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;
+
+       pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
+
+       return val;
+}
+
+static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
+{
+       struct imx_ssi *imx_ssi = ac97_ssi;
+
+       if (imx_ssi->ac97_reset)
+               imx_ssi->ac97_reset(ac97);
+}
+
+static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+       struct imx_ssi *imx_ssi = ac97_ssi;
+
+       if (imx_ssi->ac97_warm_reset)
+               imx_ssi->ac97_warm_reset(ac97);
+}
+
+struct snd_ac97_bus_ops soc_ac97_ops = {
+       .read           = imx_ssi_ac97_read,
+       .write          = imx_ssi_ac97_write,
+       .reset          = imx_ssi_ac97_reset,
+       .warm_reset     = imx_ssi_ac97_warm_reset
+};
+EXPORT_SYMBOL_GPL(soc_ac97_ops);
+
+static int imx_ssi_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct imx_ssi *ssi;
+       struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
+       int ret = 0;
+       struct snd_soc_dai_driver *dai;
+
+       ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
+       if (!ssi)
+               return -ENOMEM;
+       dev_set_drvdata(&pdev->dev, ssi);
+
+       if (pdata) {
+               ssi->ac97_reset = pdata->ac97_reset;
+               ssi->ac97_warm_reset = pdata->ac97_warm_reset;
+               ssi->flags = pdata->flags;
+       }
+
+       ssi->irq = platform_get_irq(pdev, 0);
+
+       ssi->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(ssi->clk)) {
+               ret = PTR_ERR(ssi->clk);
+               dev_err(&pdev->dev, "Cannot get the clock: %d\n",
+                       ret);
+               goto failed_clk;
+       }
+       clk_enable(ssi->clk);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               goto failed_get_resource;
+       }
+
+       if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
+               dev_err(&pdev->dev, "request_mem_region failed\n");
+               ret = -EBUSY;
+               goto failed_get_resource;
+       }
+
+       ssi->base = ioremap(res->start, resource_size(res));
+       if (!ssi->base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENODEV;
+               goto failed_ioremap;
+       }
+
+       if (ssi->flags & IMX_SSI_USE_AC97) {
+               if (ac97_ssi) {
+                       ret = -EBUSY;
+                       goto failed_ac97;
+               }
+               ac97_ssi = ssi;
+               setup_channel_to_ac97(ssi);
+               dai = &imx_ac97_dai;
+       } else
+               dai = &imx_ssi_dai;
+
+       writel(0x0, ssi->base + SSI_SIER);
+
+       ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
+       ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
+
+       ssi->dma_params_tx.burstsize = 6;
+       ssi->dma_params_rx.burstsize = 4;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
+       if (res)
+               ssi->dma_params_tx.dma = res->start;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
+       if (res)
+               ssi->dma_params_rx.dma = res->start;
+
+       platform_set_drvdata(pdev, ssi);
+
+       ret = snd_soc_register_dai(&pdev->dev, dai);
+       if (ret) {
+               dev_err(&pdev->dev, "register DAI failed\n");
+               goto failed_register;
+       }
+
+       ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
+       if (!ssi->soc_platform_pdev_fiq) {
+               ret = -ENOMEM;
+               goto failed_pdev_fiq_alloc;
+       }
+
+       platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
+       ret = platform_device_add(ssi->soc_platform_pdev_fiq);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add platform device\n");
+               goto failed_pdev_fiq_add;
+       }
+
+       ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
+       if (!ssi->soc_platform_pdev) {
+               ret = -ENOMEM;
+               goto failed_pdev_alloc;
+       }
+
+       platform_set_drvdata(ssi->soc_platform_pdev, ssi);
+       ret = platform_device_add(ssi->soc_platform_pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add platform device\n");
+               goto failed_pdev_add;
+       }
+
+       return 0;
+
+failed_pdev_add:
+       platform_device_put(ssi->soc_platform_pdev);
+failed_pdev_alloc:
+       platform_device_del(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_add:
+       platform_device_put(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_alloc:
+       snd_soc_unregister_dai(&pdev->dev);
+failed_register:
+failed_ac97:
+       iounmap(ssi->base);
+failed_ioremap:
+       release_mem_region(res->start, resource_size(res));
+failed_get_resource:
+       clk_disable(ssi->clk);
+       clk_put(ssi->clk);
+failed_clk:
+       kfree(ssi);
+
+       return ret;
+}
+
+static int __devexit imx_ssi_remove(struct platform_device *pdev)
+{
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct imx_ssi *ssi = platform_get_drvdata(pdev);
+
+       platform_device_unregister(ssi->soc_platform_pdev);
+       platform_device_unregister(ssi->soc_platform_pdev_fiq);
+
+       snd_soc_unregister_dai(&pdev->dev);
+
+       if (ssi->flags & IMX_SSI_USE_AC97)
+               ac97_ssi = NULL;
+
+       iounmap(ssi->base);
+       release_mem_region(res->start, resource_size(res));
+       clk_disable(ssi->clk);
+       clk_put(ssi->clk);
+       kfree(ssi);
+
+       return 0;
+}
+
+static struct platform_driver imx_ssi_driver = {
+       .probe = imx_ssi_probe,
+       .remove = __devexit_p(imx_ssi_remove),
+
+       .driver = {
+               .name = "imx-ssi",
+               .owner = THIS_MODULE,
+       },
+};
+
+module_platform_driver(imx_ssi_driver);
+
+/* Module information */
+MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-ssi");
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
new file mode 100644 (file)
index 0000000..5744e86
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+#ifndef _IMX_SSI_H
+#define _IMX_SSI_H
+
+#define SSI_STX0       0x00
+#define SSI_STX1       0x04
+#define SSI_SRX0       0x08
+#define SSI_SRX1       0x0c
+
+#define SSI_SCR                0x10
+#define SSI_SCR_CLK_IST                (1 << 9)
+#define SSI_SCR_CLK_IST_SHIFT  9
+#define SSI_SCR_TCH_EN         (1 << 8)
+#define SSI_SCR_SYS_CLK_EN     (1 << 7)
+#define SSI_SCR_I2S_MODE_NORM  (0 << 5)
+#define SSI_SCR_I2S_MODE_MSTR  (1 << 5)
+#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
+#define SSI_I2S_MODE_MASK      (3 << 5)
+#define SSI_SCR_SYN            (1 << 4)
+#define SSI_SCR_NET            (1 << 3)
+#define SSI_SCR_RE             (1 << 2)
+#define SSI_SCR_TE             (1 << 1)
+#define SSI_SCR_SSIEN          (1 << 0)
+
+#define SSI_SISR       0x14
+#define SSI_SISR_MASK          ((1 << 19) - 1)
+#define SSI_SISR_CMDAU         (1 << 18)
+#define SSI_SISR_CMDDU         (1 << 17)
+#define SSI_SISR_RXT           (1 << 16)
+#define SSI_SISR_RDR1          (1 << 15)
+#define SSI_SISR_RDR0          (1 << 14)
+#define SSI_SISR_TDE1          (1 << 13)
+#define SSI_SISR_TDE0          (1 << 12)
+#define SSI_SISR_ROE1          (1 << 11)
+#define SSI_SISR_ROE0          (1 << 10)
+#define SSI_SISR_TUE1          (1 << 9)
+#define SSI_SISR_TUE0          (1 << 8)
+#define SSI_SISR_TFS           (1 << 7)
+#define SSI_SISR_RFS           (1 << 6)
+#define SSI_SISR_TLS           (1 << 5)
+#define SSI_SISR_RLS           (1 << 4)
+#define SSI_SISR_RFF1          (1 << 3)
+#define SSI_SISR_RFF0          (1 << 2)
+#define SSI_SISR_TFE1          (1 << 1)
+#define SSI_SISR_TFE0          (1 << 0)
+
+#define SSI_SIER       0x18
+#define SSI_SIER_RDMAE         (1 << 22)
+#define SSI_SIER_RIE           (1 << 21)
+#define SSI_SIER_TDMAE         (1 << 20)
+#define SSI_SIER_TIE           (1 << 19)
+#define SSI_SIER_CMDAU_EN      (1 << 18)
+#define SSI_SIER_CMDDU_EN      (1 << 17)
+#define SSI_SIER_RXT_EN                (1 << 16)
+#define SSI_SIER_RDR1_EN       (1 << 15)
+#define SSI_SIER_RDR0_EN       (1 << 14)
+#define SSI_SIER_TDE1_EN       (1 << 13)
+#define SSI_SIER_TDE0_EN       (1 << 12)
+#define SSI_SIER_ROE1_EN       (1 << 11)
+#define SSI_SIER_ROE0_EN       (1 << 10)
+#define SSI_SIER_TUE1_EN       (1 << 9)
+#define SSI_SIER_TUE0_EN       (1 << 8)
+#define SSI_SIER_TFS_EN                (1 << 7)
+#define SSI_SIER_RFS_EN                (1 << 6)
+#define SSI_SIER_TLS_EN                (1 << 5)
+#define SSI_SIER_RLS_EN                (1 << 4)
+#define SSI_SIER_RFF1_EN       (1 << 3)
+#define SSI_SIER_RFF0_EN       (1 << 2)
+#define SSI_SIER_TFE1_EN       (1 << 1)
+#define SSI_SIER_TFE0_EN       (1 << 0)
+
+#define SSI_STCR       0x1c
+#define SSI_STCR_TXBIT0                (1 << 9)
+#define SSI_STCR_TFEN1         (1 << 8)
+#define SSI_STCR_TFEN0         (1 << 7)
+#define SSI_FIFO_ENABLE_0_SHIFT 7
+#define SSI_STCR_TFDIR         (1 << 6)
+#define SSI_STCR_TXDIR         (1 << 5)
+#define SSI_STCR_TSHFD         (1 << 4)
+#define SSI_STCR_TSCKP         (1 << 3)
+#define SSI_STCR_TFSI          (1 << 2)
+#define SSI_STCR_TFSL          (1 << 1)
+#define SSI_STCR_TEFS          (1 << 0)
+
+#define SSI_SRCR       0x20
+#define SSI_SRCR_RXBIT0                (1 << 9)
+#define SSI_SRCR_RFEN1         (1 << 8)
+#define SSI_SRCR_RFEN0         (1 << 7)
+#define SSI_FIFO_ENABLE_0_SHIFT 7
+#define SSI_SRCR_RFDIR         (1 << 6)
+#define SSI_SRCR_RXDIR         (1 << 5)
+#define SSI_SRCR_RSHFD         (1 << 4)
+#define SSI_SRCR_RSCKP         (1 << 3)
+#define SSI_SRCR_RFSI          (1 << 2)
+#define SSI_SRCR_RFSL          (1 << 1)
+#define SSI_SRCR_REFS          (1 << 0)
+
+#define SSI_SRCCR              0x28
+#define SSI_SRCCR_DIV2         (1 << 18)
+#define SSI_SRCCR_PSR          (1 << 17)
+#define SSI_SRCCR_WL(x)                ((((x) - 2) >> 1) << 13)
+#define SSI_SRCCR_DC(x)                (((x) & 0x1f) << 8)
+#define SSI_SRCCR_PM(x)                (((x) & 0xff) << 0)
+#define SSI_SRCCR_WL_MASK      (0xf << 13)
+#define SSI_SRCCR_DC_MASK      (0x1f << 8)
+#define SSI_SRCCR_PM_MASK      (0xff << 0)
+
+#define SSI_STCCR              0x24
+#define SSI_STCCR_DIV2         (1 << 18)
+#define SSI_STCCR_PSR          (1 << 17)
+#define SSI_STCCR_WL(x)                ((((x) - 2) >> 1) << 13)
+#define SSI_STCCR_DC(x)                (((x) & 0x1f) << 8)
+#define SSI_STCCR_PM(x)                (((x) & 0xff) << 0)
+#define SSI_STCCR_WL_MASK      (0xf << 13)
+#define SSI_STCCR_DC_MASK      (0x1f << 8)
+#define SSI_STCCR_PM_MASK      (0xff << 0)
+
+#define SSI_SFCSR      0x2c
+#define SSI_SFCSR_RFCNT1(x)    (((x) & 0xf) << 28)
+#define SSI_RX_FIFO_1_COUNT_SHIFT 28
+#define SSI_SFCSR_TFCNT1(x)    (((x) & 0xf) << 24)
+#define SSI_TX_FIFO_1_COUNT_SHIFT 24
+#define SSI_SFCSR_RFWM1(x)     (((x) & 0xf) << 20)
+#define SSI_SFCSR_TFWM1(x)     (((x) & 0xf) << 16)
+#define SSI_SFCSR_RFCNT0(x)    (((x) & 0xf) << 12)
+#define SSI_RX_FIFO_0_COUNT_SHIFT 12
+#define SSI_SFCSR_TFCNT0(x)    (((x) & 0xf) <<  8)
+#define SSI_TX_FIFO_0_COUNT_SHIFT 8
+#define SSI_SFCSR_RFWM0(x)     (((x) & 0xf) <<  4)
+#define SSI_SFCSR_TFWM0(x)     (((x) & 0xf) <<  0)
+#define SSI_SFCSR_RFWM0_MASK   (0xf <<  4)
+#define SSI_SFCSR_TFWM0_MASK   (0xf <<  0)
+
+#define SSI_STR                0x30
+#define SSI_STR_TEST           (1 << 15)
+#define SSI_STR_RCK2TCK                (1 << 14)
+#define SSI_STR_RFS2TFS                (1 << 13)
+#define SSI_STR_RXSTATE(x)     (((x) & 0xf) << 8)
+#define SSI_STR_TXD2RXD                (1 <<  7)
+#define SSI_STR_TCK2RCK                (1 <<  6)
+#define SSI_STR_TFS2RFS                (1 <<  5)
+#define SSI_STR_TXSTATE(x)     (((x) & 0xf) << 0)
+
+#define SSI_SOR                0x34
+#define SSI_SOR_CLKOFF         (1 << 6)
+#define SSI_SOR_RX_CLR         (1 << 5)
+#define SSI_SOR_TX_CLR         (1 << 4)
+#define SSI_SOR_INIT           (1 << 3)
+#define SSI_SOR_WAIT(x)                (((x) & 0x3) << 1)
+#define SSI_SOR_WAIT_MASK      (0x3 << 1)
+#define SSI_SOR_SYNRST         (1 << 0)
+
+#define SSI_SACNT      0x38
+#define SSI_SACNT_FRDIV(x)     (((x) & 0x3f) << 5)
+#define SSI_SACNT_WR           (1 << 4)
+#define SSI_SACNT_RD           (1 << 3)
+#define SSI_SACNT_TIF          (1 << 2)
+#define SSI_SACNT_FV           (1 << 1)
+#define SSI_SACNT_AC97EN       (1 << 0)
+
+#define SSI_SACADD     0x3c
+#define SSI_SACDAT     0x40
+#define SSI_SATAG      0x44
+#define SSI_STMSK      0x48
+#define SSI_SRMSK      0x4c
+#define SSI_SACCST     0x50
+#define SSI_SACCEN     0x54
+#define SSI_SACCDIS    0x58
+
+/* SSI clock sources */
+#define IMX_SSP_SYS_CLK                0
+
+/* SSI audio dividers */
+#define IMX_SSI_TX_DIV_2       0
+#define IMX_SSI_TX_DIV_PSR     1
+#define IMX_SSI_TX_DIV_PM      2
+#define IMX_SSI_RX_DIV_2       3
+#define IMX_SSI_RX_DIV_PSR     4
+#define IMX_SSI_RX_DIV_PM      5
+
+#define DRV_NAME "imx-ssi"
+
+#include <linux/dmaengine.h>
+#include <mach/dma.h>
+#include "imx-pcm.h"
+
+struct imx_ssi {
+       struct platform_device *ac97_dev;
+
+       struct snd_soc_dai *imx_ac97;
+       struct clk *clk;
+       void __iomem *base;
+       int irq;
+       int fiq_enable;
+       unsigned int offset;
+
+       unsigned int flags;
+
+       void (*ac97_reset) (struct snd_ac97 *ac97);
+       void (*ac97_warm_reset)(struct snd_ac97 *ac97);
+
+       struct imx_pcm_dma_params       dma_params_rx;
+       struct imx_pcm_dma_params       dma_params_tx;
+
+       int enabled;
+
+       struct platform_device *soc_platform_pdev;
+       struct platform_device *soc_platform_pdev_fiq;
+};
+
+#endif /* _IMX_SSI_H */
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
new file mode 100644 (file)
index 0000000..f6d04ad
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * mx27vis-aic32x4.c
+ *
+ * Copyright 2011 Vista Silicon S.L.
+ *
+ * Author: Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * 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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <asm/mach-types.h>
+#include <mach/iomux-mx27.h>
+
+#include "../codecs/tlv320aic32x4.h"
+#include "imx-ssi.h"
+#include "imx-audmux.h"
+
+#define MX27VIS_AMP_GAIN       0
+#define MX27VIS_AMP_MUTE       1
+
+#define MX27VIS_PIN_G0         (GPIO_PORTF + 9)
+#define MX27VIS_PIN_G1         (GPIO_PORTF + 8)
+#define MX27VIS_PIN_SDL                (GPIO_PORTE + 5)
+#define MX27VIS_PIN_SDR                (GPIO_PORTF + 7)
+
+static int mx27vis_amp_gain;
+static int mx27vis_amp_mute;
+
+static const int mx27vis_amp_pins[] = {
+       MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
+       MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
+       MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
+       MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
+};
+
+static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       int ret;
+       u32 dai_format;
+
+       dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
+               SND_SOC_DAIFMT_CBM_CFM;
+
+       /* set codec DAI configuration */
+       snd_soc_dai_set_fmt(codec_dai, dai_format);
+
+       /* set cpu DAI configuration */
+       snd_soc_dai_set_fmt(cpu_dai, dai_format);
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+                                    25000000, SND_SOC_CLOCK_OUT);
+       if (ret) {
+               pr_err("%s: failed setting codec sysclk\n", __func__);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
+                               SND_SOC_CLOCK_IN);
+       if (ret) {
+               pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
+       .hw_params      = mx27vis_aic32x4_hw_params,
+};
+
+static int mx27vis_amp_set(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       int value = ucontrol->value.integer.value[0];
+       unsigned int reg = mc->reg;
+       int max = mc->max;
+
+       if (value > max)
+               return -EINVAL;
+
+       switch (reg) {
+       case MX27VIS_AMP_GAIN:
+               gpio_set_value(MX27VIS_PIN_G0, value & 1);
+               gpio_set_value(MX27VIS_PIN_G1, value >> 1);
+               mx27vis_amp_gain = value;
+               break;
+       case MX27VIS_AMP_MUTE:
+               gpio_set_value(MX27VIS_PIN_SDL, value & 1);
+               gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
+               mx27vis_amp_mute = value;
+               break;
+       }
+       return 0;
+}
+
+static int mx27vis_amp_get(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       unsigned int reg = mc->reg;
+
+       switch (reg) {
+       case MX27VIS_AMP_GAIN:
+               ucontrol->value.integer.value[0] = mx27vis_amp_gain;
+               break;
+       case MX27VIS_AMP_MUTE:
+               ucontrol->value.integer.value[0] = mx27vis_amp_mute;
+               break;
+       }
+       return 0;
+}
+
+/* From 6dB to 24dB in steps of 6dB */
+static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0);
+
+static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = {
+       SOC_DAPM_PIN_SWITCH("External Mic"),
+       SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0,
+                      mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv),
+       SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0,
+                      mx27vis_amp_get, mx27vis_amp_set),
+};
+
+static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
+       SND_SOC_DAPM_MIC("External Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
+       {"Mic Bias", NULL, "External Mic"},
+       {"IN1_R", NULL, "Mic Bias"},
+       {"IN2_R", NULL, "Mic Bias"},
+       {"IN3_R", NULL, "Mic Bias"},
+       {"IN1_L", NULL, "Mic Bias"},
+       {"IN2_L", NULL, "Mic Bias"},
+       {"IN3_L", NULL, "Mic Bias"},
+};
+
+static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
+       .name           = "tlv320aic32x4",
+       .stream_name    = "TLV320AIC32X4",
+       .codec_dai_name = "tlv320aic32x4-hifi",
+       .platform_name  = "imx-pcm-audio.0",
+       .codec_name     = "tlv320aic32x4.0-0018",
+       .cpu_dai_name   = "imx-ssi.0",
+       .ops            = &mx27vis_aic32x4_snd_ops,
+};
+
+static struct snd_soc_card mx27vis_aic32x4 = {
+       .name           = "visstrim_m10-audio",
+       .owner          = THIS_MODULE,
+       .dai_link       = &mx27vis_aic32x4_dai,
+       .num_links      = 1,
+       .controls       = mx27vis_aic32x4_controls,
+       .num_controls   = ARRAY_SIZE(mx27vis_aic32x4_controls),
+       .dapm_widgets   = aic32x4_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
+       .dapm_routes    = aic32x4_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
+};
+
+static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       mx27vis_aic32x4.dev = &pdev->dev;
+       ret = snd_soc_register_card(&mx27vis_aic32x4);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+                       ret);
+               return ret;
+       }
+
+       /* Connect SSI0 as clock slave to SSI1 external pins */
+       imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+                       IMX_AUDMUX_V1_PCR_SYN |
+                       IMX_AUDMUX_V1_PCR_TFSDIR |
+                       IMX_AUDMUX_V1_PCR_TCLKDIR |
+                       IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
+                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
+       );
+       imx_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
+                       IMX_AUDMUX_V1_PCR_SYN |
+                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+       );
+
+       ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
+                       ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
+       if (ret)
+               printk(KERN_ERR "ASoC: unable to setup gpios\n");
+
+       return ret;
+}
+
+static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev)
+{
+       snd_soc_unregister_card(&mx27vis_aic32x4);
+
+       return 0;
+}
+
+static struct platform_driver mx27vis_aic32x4_audio_driver = {
+       .driver = {
+               .name = "mx27vis",
+               .owner = THIS_MODULE,
+       },
+       .probe = mx27vis_aic32x4_probe,
+       .remove = __devexit_p(mx27vis_aic32x4_remove),
+};
+
+module_platform_driver(mx27vis_aic32x4_audio_driver);
+
+MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
+MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mx27vis");
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
new file mode 100644 (file)
index 0000000..f8da6dd
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * phycore-ac97.c  --  SoC audio for imx_phycore in AC97 mode
+ *
+ * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ *  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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <asm/mach-types.h>
+
+#include "imx-audmux.h"
+
+static struct snd_soc_card imx_phycore;
+
+static struct snd_soc_ops imx_phycore_hifi_ops = {
+};
+
+static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
+       {
+               .name           = "HiFi",
+               .stream_name    = "HiFi",
+               .codec_dai_name         = "wm9712-hifi",
+               .codec_name     = "wm9712-codec",
+               .cpu_dai_name   = "imx-ssi.0",
+               .platform_name  = "imx-fiq-pcm-audio.0",
+               .ops            = &imx_phycore_hifi_ops,
+       },
+};
+
+static struct snd_soc_card imx_phycore = {
+       .name           = "PhyCORE-ac97-audio",
+       .owner          = THIS_MODULE,
+       .dai_link       = imx_phycore_dai_ac97,
+       .num_links      = ARRAY_SIZE(imx_phycore_dai_ac97),
+};
+
+static struct platform_device *imx_phycore_snd_ac97_device;
+static struct platform_device *imx_phycore_snd_device;
+
+static int __init imx_phycore_init(void)
+{
+       int ret;
+
+       if (machine_is_pca100()) {
+               imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+                       IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+                       IMX_AUDMUX_V1_PCR_TFCSEL(3) |
+                       IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
+                       IMX_AUDMUX_V1_PCR_RXDSEL(3));
+               imx_audmux_v1_configure_port(3,
+                       IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+                       IMX_AUDMUX_V1_PCR_TFCSEL(0) |
+                       IMX_AUDMUX_V1_PCR_TFSDIR |
+                       IMX_AUDMUX_V1_PCR_RXDSEL(0));
+       } else if (machine_is_pcm043()) {
+               imx_audmux_v2_configure_port(3,
+                       IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+                       IMX_AUDMUX_V2_PTCR_TFSEL(0) |
+                       IMX_AUDMUX_V2_PTCR_TFSDIR,
+                       IMX_AUDMUX_V2_PDCR_RXDSEL(0));
+               imx_audmux_v2_configure_port(0,
+                       IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+                       IMX_AUDMUX_V2_PTCR_TCSEL(3) |
+                       IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
+                       IMX_AUDMUX_V2_PDCR_RXDSEL(3));
+       } else {
+               /* return happy. We might run on a totally different machine */
+               return 0;
+       }
+
+       imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
+       if (!imx_phycore_snd_ac97_device)
+               return -ENOMEM;
+
+       platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
+       ret = platform_device_add(imx_phycore_snd_ac97_device);
+       if (ret)
+               goto fail1;
+
+       imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
+       if (!imx_phycore_snd_device) {
+               ret = -ENOMEM;
+               goto fail2;
+       }
+       ret = platform_device_add(imx_phycore_snd_device);
+
+       if (ret) {
+               printk(KERN_ERR "ASoC: Platform device allocation failed\n");
+               goto fail3;
+       }
+
+       return 0;
+
+fail3:
+       platform_device_put(imx_phycore_snd_device);
+fail2:
+       platform_device_del(imx_phycore_snd_ac97_device);
+fail1:
+       platform_device_put(imx_phycore_snd_ac97_device);
+       return ret;
+}
+
+static void __exit imx_phycore_exit(void)
+{
+       platform_device_unregister(imx_phycore_snd_device);
+       platform_device_unregister(imx_phycore_snd_ac97_device);
+}
+
+late_initcall(imx_phycore_init);
+module_exit(imx_phycore_exit);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
new file mode 100644 (file)
index 0000000..fe54a69
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ *  wm1133-ev1.c - Audio for WM1133-EV1 on i.MX31ADS
+ *
+ *  Copyright (c) 2010 Wolfson Microelectronics plc
+ *  Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  Based on an earlier driver for the same hardware by Liam Girdwood.
+ *
+ *  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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "imx-ssi.h"
+#include "../codecs/wm8350.h"
+#include "imx-audmux.h"
+
+/* There is a silicon mic on the board optionally connected via a solder pad
+ * SP1.  Define this to enable it.
+ */
+#undef USE_SIMIC
+
+struct _wm8350_audio {
+       unsigned int channels;
+       snd_pcm_format_t format;
+       unsigned int rate;
+       unsigned int sysclk;
+       unsigned int bclkdiv;
+       unsigned int clkdiv;
+       unsigned int lr_rate;
+};
+
+/* in order of power consumption per rate (lowest first) */
+static const struct _wm8350_audio wm8350_audio[] = {
+       /* 16bit mono modes */
+       {1, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000 >> 1,
+        WM8350_BCLK_DIV_48, WM8350_DACDIV_3, 16,},
+
+       /* 16 bit stereo modes */
+       {2, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000,
+        WM8350_BCLK_DIV_48, WM8350_DACDIV_6, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 16000, 12288000,
+        WM8350_BCLK_DIV_24, WM8350_DACDIV_3, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 32000, 12288000,
+        WM8350_BCLK_DIV_12, WM8350_DACDIV_1_5, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 48000, 12288000,
+        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 96000, 24576000,
+        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 11025, 11289600,
+        WM8350_BCLK_DIV_32, WM8350_DACDIV_4, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 22050, 11289600,
+        WM8350_BCLK_DIV_16, WM8350_DACDIV_2, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 44100, 11289600,
+        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
+       {2, SNDRV_PCM_FORMAT_S16_LE, 88200, 22579200,
+        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
+
+       /* 24bit stereo modes */
+       {2, SNDRV_PCM_FORMAT_S24_LE, 48000, 12288000,
+        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
+       {2, SNDRV_PCM_FORMAT_S24_LE, 96000, 24576000,
+        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
+       {2, SNDRV_PCM_FORMAT_S24_LE, 44100, 11289600,
+        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
+       {2, SNDRV_PCM_FORMAT_S24_LE, 88200, 22579200,
+        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
+};
+
+static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       int i, found = 0;
+       snd_pcm_format_t format = params_format(params);
+       unsigned int rate = params_rate(params);
+       unsigned int channels = params_channels(params);
+       u32 dai_format;
+
+       /* find the correct audio parameters */
+       for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) {
+               if (rate == wm8350_audio[i].rate &&
+                   format == wm8350_audio[i].format &&
+                   channels == wm8350_audio[i].channels) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found)
+               return -EINVAL;
+
+       /* codec FLL input is 14.75 MHz from MCLK */
+       snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk);
+
+       dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+               SND_SOC_DAIFMT_CBM_CFM;
+
+       /* set codec DAI configuration */
+       snd_soc_dai_set_fmt(codec_dai, dai_format);
+
+       /* set cpu DAI configuration */
+       snd_soc_dai_set_fmt(cpu_dai, dai_format);
+
+       /* TODO: The SSI driver should figure this out for us */
+       switch (channels) {
+       case 2:
+               snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
+               break;
+       case 1:
+               snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffe, 0xffffffe, 1, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* set MCLK as the codec system clock for DAC and ADC */
+       snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_MCLK,
+                              wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
+
+       /* set codec BCLK division for sample rate */
+       snd_soc_dai_set_clkdiv(codec_dai, WM8350_BCLK_CLKDIV,
+                              wm8350_audio[i].bclkdiv);
+
+       /* DAI is synchronous and clocked with DAC LRCLK & ADC LRC */
+       snd_soc_dai_set_clkdiv(codec_dai,
+                              WM8350_DACLR_CLKDIV, wm8350_audio[i].lr_rate);
+       snd_soc_dai_set_clkdiv(codec_dai,
+                              WM8350_ADCLR_CLKDIV, wm8350_audio[i].lr_rate);
+
+       /* now configure DAC and ADC clocks */
+       snd_soc_dai_set_clkdiv(codec_dai,
+                              WM8350_DAC_CLKDIV, wm8350_audio[i].clkdiv);
+
+       snd_soc_dai_set_clkdiv(codec_dai,
+                              WM8350_ADC_CLKDIV, wm8350_audio[i].clkdiv);
+
+       return 0;
+}
+
+static struct snd_soc_ops wm1133_ev1_ops = {
+       .hw_params = wm1133_ev1_hw_params,
+};
+
+static const struct snd_soc_dapm_widget wm1133_ev1_widgets[] = {
+#ifdef USE_SIMIC
+       SND_SOC_DAPM_MIC("SiMIC", NULL),
+#endif
+       SND_SOC_DAPM_MIC("Mic1 Jack", NULL),
+       SND_SOC_DAPM_MIC("Mic2 Jack", NULL),
+       SND_SOC_DAPM_LINE("Line In Jack", NULL),
+       SND_SOC_DAPM_LINE("Line Out Jack", NULL),
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+};
+
+/* imx32ads soc_card audio map */
+static const struct snd_soc_dapm_route wm1133_ev1_map[] = {
+
+#ifdef USE_SIMIC
+       /* SiMIC --> IN1LN (with automatic bias) via SP1 */
+       { "IN1LN", NULL, "Mic Bias" },
+       { "Mic Bias", NULL, "SiMIC" },
+#endif
+
+       /* Mic 1 Jack --> IN1LN and IN1LP (with automatic bias) */
+       { "IN1LN", NULL, "Mic Bias" },
+       { "IN1LP", NULL, "Mic1 Jack" },
+       { "Mic Bias", NULL, "Mic1 Jack" },
+
+       /* Mic 2 Jack --> IN1RN and IN1RP (with automatic bias) */
+       { "IN1RN", NULL, "Mic Bias" },
+       { "IN1RP", NULL, "Mic2 Jack" },
+       { "Mic Bias", NULL, "Mic2 Jack" },
+
+       /* Line in Jack --> AUX (L+R) */
+       { "IN3R", NULL, "Line In Jack" },
+       { "IN3L", NULL, "Line In Jack" },
+
+       /* Out1 --> Headphone Jack */
+       { "Headphone Jack", NULL, "OUT1R" },
+       { "Headphone Jack", NULL, "OUT1L" },
+
+       /* Out1 --> Line Out Jack */
+       { "Line Out Jack", NULL, "OUT2R" },
+       { "Line Out Jack", NULL, "OUT2L" },
+};
+
+static struct snd_soc_jack hp_jack;
+
+static struct snd_soc_jack_pin hp_jack_pins[] = {
+       { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE },
+};
+
+static struct snd_soc_jack mic_jack;
+
+static struct snd_soc_jack_pin mic_jack_pins[] = {
+       { .pin = "Mic1 Jack", .mask = SND_JACK_MICROPHONE },
+       { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
+};
+
+static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+       snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
+                                 ARRAY_SIZE(wm1133_ev1_widgets));
+
+       snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
+                               ARRAY_SIZE(wm1133_ev1_map));
+
+       /* Headphone jack detection */
+       snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
+       snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
+                             hp_jack_pins);
+       wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
+
+       /* Microphone jack detection */
+       snd_soc_jack_new(codec, "Microphone",
+                        SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
+       snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
+                             mic_jack_pins);
+       wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
+                              SND_JACK_BTN_0);
+
+       snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
+
+       return 0;
+}
+
+
+static struct snd_soc_dai_link wm1133_ev1_dai = {
+       .name = "WM1133-EV1",
+       .stream_name = "Audio",
+       .cpu_dai_name = "imx-ssi.0",
+       .codec_dai_name = "wm8350-hifi",
+       .platform_name = "imx-fiq-pcm-audio.0",
+       .codec_name = "wm8350-codec.0-0x1a",
+       .init = wm1133_ev1_init,
+       .ops = &wm1133_ev1_ops,
+       .symmetric_rates = 1,
+};
+
+static struct snd_soc_card wm1133_ev1 = {
+       .name = "WM1133-EV1",
+       .owner = THIS_MODULE,
+       .dai_link = &wm1133_ev1_dai,
+       .num_links = 1,
+};
+
+static struct platform_device *wm1133_ev1_snd_device;
+
+static int __init wm1133_ev1_audio_init(void)
+{
+       int ret;
+       unsigned int ptcr, pdcr;
+
+       /* SSI0 mastered by port 5 */
+       ptcr = IMX_AUDMUX_V2_PTCR_SYN |
+               IMX_AUDMUX_V2_PTCR_TFSDIR |
+               IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
+               IMX_AUDMUX_V2_PTCR_TCLKDIR |
+               IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
+       pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
+       imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
+
+       ptcr = IMX_AUDMUX_V2_PTCR_SYN;
+       pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
+       imx_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
+
+       wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!wm1133_ev1_snd_device)
+               return -ENOMEM;
+
+       platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1);
+       ret = platform_device_add(wm1133_ev1_snd_device);
+
+       if (ret)
+               platform_device_put(wm1133_ev1_snd_device);
+
+       return ret;
+}
+module_init(wm1133_ev1_audio_init);
+
+static void __exit wm1133_ev1_audio_exit(void)
+{
+       platform_device_unregister(wm1133_ev1_snd_device);
+}
+module_exit(wm1133_ev1_audio_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("Audio for WM1133-EV1 on i.MX31ADS");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
deleted file mode 100644 (file)
index 810acaa..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-menuconfig SND_IMX_SOC
-       tristate "SoC Audio for Freescale i.MX CPUs"
-       depends on ARCH_MXC
-       help
-         Say Y or M if you want to add support for codecs attached to
-         the i.MX SSI interface.
-
-
-if SND_IMX_SOC
-
-config SND_SOC_IMX_SSI
-       tristate
-
-config SND_SOC_IMX_PCM
-       tristate
-
-config SND_MXC_SOC_FIQ
-       tristate
-       select FIQ
-       select SND_SOC_IMX_PCM
-
-config SND_MXC_SOC_MX2
-       select SND_SOC_DMAENGINE_PCM
-       tristate
-       select SND_SOC_IMX_PCM
-
-config SND_SOC_IMX_AUDMUX
-       tristate
-
-config SND_MXC_SOC_WM1133_EV1
-       tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
-       depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
-       select SND_SOC_WM8350
-       select SND_MXC_SOC_FIQ
-       select SND_SOC_IMX_AUDMUX
-       select SND_SOC_IMX_SSI
-       help
-         Enable support for audio on the i.MX31ADS with the WM1133-EV1
-         PMIC board with WM8835x fitted.
-
-config SND_SOC_MX27VIS_AIC32X4
-       tristate "SoC audio support for Visstrim M10 boards"
-       depends on MACH_IMX27_VISSTRIM_M10 && I2C
-       select SND_SOC_TLV320AIC32X4
-       select SND_MXC_SOC_MX2
-       select SND_SOC_IMX_AUDMUX
-       select SND_SOC_IMX_SSI
-       help
-         Say Y if you want to add support for SoC audio on Visstrim SM10
-         board with TLV320AIC32X4 codec.
-
-config SND_SOC_PHYCORE_AC97
-       tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
-       depends on MACH_PCM043 || MACH_PCA100
-       select SND_SOC_AC97_BUS
-       select SND_SOC_WM9712
-       select SND_MXC_SOC_FIQ
-       select SND_SOC_IMX_AUDMUX
-       select SND_SOC_IMX_SSI
-       help
-         Say Y if you want to add support for SoC audio on Phytec phyCORE
-         and phyCARD boards in AC97 mode
-
-config SND_SOC_EUKREA_TLV320
-       tristate "Eukrea TLV320"
-       depends on MACH_EUKREA_MBIMX27_BASEBOARD \
-               || MACH_EUKREA_MBIMXSD25_BASEBOARD \
-               || MACH_EUKREA_MBIMXSD35_BASEBOARD \
-               || MACH_EUKREA_MBIMXSD51_BASEBOARD
-       depends on I2C
-       select SND_SOC_TLV320AIC23
-       select SND_MXC_SOC_FIQ
-       select SND_SOC_IMX_AUDMUX
-       select SND_SOC_IMX_SSI
-       help
-         Enable I2S based access to the TLV320AIC23B codec attached
-         to the SSI interface
-
-endif  # SND_IMX_SOC
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
deleted file mode 100644 (file)
index f5db3e9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# i.MX Platform Support
-snd-soc-imx-ssi-objs := imx-ssi.o
-snd-soc-imx-audmux-objs := imx-audmux.o
-
-obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
-obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
-
-obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
-snd-soc-imx-pcm-y := imx-pcm.o
-snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
-snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o
-
-# i.MX Machine Support
-snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
-snd-soc-phycore-ac97-objs := phycore-ac97.o
-snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
-snd-soc-wm1133-ev1-objs := wm1133-ev1.o
-
-obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
-obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
-obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
-obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
deleted file mode 100644 (file)
index 7d4475c..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * eukrea-tlv320.c  --  SoC audio for eukrea_cpuimxXX in I2S mode
- *
- * Copyright 2010 Eric Bénard, Eukréa Electromatique <eric@eukrea.com>
- *
- * based on sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
- * which is Copyright 2009 Simtec Electronics
- * and on sound/soc/imx/phycore-ac97.c which is
- * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- * 
- *  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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-types.h>
-
-#include "../codecs/tlv320aic23.h"
-#include "imx-ssi.h"
-#include "imx-audmux.h"
-
-#define CODEC_CLOCK 12000000
-
-static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
-                           struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       int ret;
-
-       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-                                 SND_SOC_DAIFMT_NB_NF |
-                                 SND_SOC_DAIFMT_CBM_CFM);
-       if (ret) {
-               pr_err("%s: failed set cpu dai format\n", __func__);
-               return ret;
-       }
-
-       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-                                 SND_SOC_DAIFMT_NB_NF |
-                                 SND_SOC_DAIFMT_CBM_CFM);
-       if (ret) {
-               pr_err("%s: failed set codec dai format\n", __func__);
-               return ret;
-       }
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0,
-                                    CODEC_CLOCK, SND_SOC_CLOCK_OUT);
-       if (ret) {
-               pr_err("%s: failed setting codec sysclk\n", __func__);
-               return ret;
-       }
-       snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
-
-       ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
-                               SND_SOC_CLOCK_IN);
-       if (ret) {
-               pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-static struct snd_soc_ops eukrea_tlv320_snd_ops = {
-       .hw_params      = eukrea_tlv320_hw_params,
-};
-
-static struct snd_soc_dai_link eukrea_tlv320_dai = {
-       .name           = "tlv320aic23",
-       .stream_name    = "TLV320AIC23",
-       .codec_dai_name = "tlv320aic23-hifi",
-       .platform_name  = "imx-fiq-pcm-audio.0",
-       .codec_name     = "tlv320aic23-codec.0-001a",
-       .cpu_dai_name   = "imx-ssi.0",
-       .ops            = &eukrea_tlv320_snd_ops,
-};
-
-static struct snd_soc_card eukrea_tlv320 = {
-       .name           = "cpuimx-audio",
-       .owner          = THIS_MODULE,
-       .dai_link       = &eukrea_tlv320_dai,
-       .num_links      = 1,
-};
-
-static struct platform_device *eukrea_tlv320_snd_device;
-
-static int __init eukrea_tlv320_init(void)
-{
-       int ret;
-       int int_port = 0, ext_port;
-
-       if (machine_is_eukrea_cpuimx27()) {
-               imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-                       IMX_AUDMUX_V1_PCR_SYN |
-                       IMX_AUDMUX_V1_PCR_TFSDIR |
-                       IMX_AUDMUX_V1_PCR_TCLKDIR |
-                       IMX_AUDMUX_V1_PCR_RFSDIR |
-                       IMX_AUDMUX_V1_PCR_RCLKDIR |
-                       IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
-                       IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
-                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
-               );
-               imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
-                       IMX_AUDMUX_V1_PCR_SYN |
-                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
-               );
-       } else if (machine_is_eukrea_cpuimx25sd() ||
-                  machine_is_eukrea_cpuimx35sd() ||
-                  machine_is_eukrea_cpuimx51sd()) {
-               ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3;
-               imx_audmux_v2_configure_port(int_port,
-                       IMX_AUDMUX_V2_PTCR_SYN |
-                       IMX_AUDMUX_V2_PTCR_TFSDIR |
-                       IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
-                       IMX_AUDMUX_V2_PTCR_TCLKDIR |
-                       IMX_AUDMUX_V2_PTCR_TCSEL(ext_port),
-                       IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)
-               );
-               imx_audmux_v2_configure_port(ext_port,
-                       IMX_AUDMUX_V2_PTCR_SYN,
-                       IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
-               );
-       } else {
-               /* return happy. We might run on a totally different machine */
-               return 0;
-       }
-
-       eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!eukrea_tlv320_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
-       ret = platform_device_add(eukrea_tlv320_snd_device);
-
-       if (ret) {
-               printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-               platform_device_put(eukrea_tlv320_snd_device);
-       }
-
-       return ret;
-}
-
-static void __exit eukrea_tlv320_exit(void)
-{
-       platform_device_unregister(eukrea_tlv320_snd_device);
-}
-
-module_init(eukrea_tlv320_init);
-module_exit(eukrea_tlv320_exit);
-
-MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>");
-MODULE_DESCRIPTION("CPUIMX ALSA SoC driver");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/imx/imx-audmux.c
deleted file mode 100644 (file)
index 601df80..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 Linaro Ltd.
- * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
- *
- * Initial development of this code was funded by
- * Phytec Messtechnik GmbH, http://www.phytec.de
- *
- * 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.
- */
-
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "imx-audmux.h"
-
-#define DRIVER_NAME "imx-audmux"
-
-static struct clk *audmux_clk;
-static void __iomem *audmux_base;
-
-#define IMX_AUDMUX_V2_PTCR(x)          ((x) * 8)
-#define IMX_AUDMUX_V2_PDCR(x)          ((x) * 8 + 4)
-
-#ifdef CONFIG_DEBUG_FS
-static struct dentry *audmux_debugfs_root;
-
-static int audmux_open_file(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-/* There is an annoying discontinuity in the SSI numbering with regard
- * to the Linux number of the devices */
-static const char *audmux_port_string(int port)
-{
-       switch (port) {
-       case MX31_AUDMUX_PORT1_SSI0:
-               return "imx-ssi.0";
-       case MX31_AUDMUX_PORT2_SSI1:
-               return "imx-ssi.1";
-       case MX31_AUDMUX_PORT3_SSI_PINS_3:
-               return "SSI3";
-       case MX31_AUDMUX_PORT4_SSI_PINS_4:
-               return "SSI4";
-       case MX31_AUDMUX_PORT5_SSI_PINS_5:
-               return "SSI5";
-       case MX31_AUDMUX_PORT6_SSI_PINS_6:
-               return "SSI6";
-       default:
-               return "UNKNOWN";
-       }
-}
-
-static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       ssize_t ret;
-       char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       int port = (int)file->private_data;
-       u32 pdcr, ptcr;
-
-       if (!buf)
-               return -ENOMEM;
-
-       if (audmux_clk)
-               clk_prepare_enable(audmux_clk);
-
-       ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
-       pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
-
-       if (audmux_clk)
-               clk_disable_unprepare(audmux_clk);
-
-       ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
-                      pdcr, ptcr);
-
-       if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                               "TxFS output from %s, ",
-                               audmux_port_string((ptcr >> 27) & 0x7));
-       else
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                               "TxFS input, ");
-
-       if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                               "TxClk output from %s",
-                               audmux_port_string((ptcr >> 22) & 0x7));
-       else
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                               "TxClk input");
-
-       ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
-
-       if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                               "Port is symmetric");
-       } else {
-               if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
-                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                                       "RxFS output from %s, ",
-                                       audmux_port_string((ptcr >> 17) & 0x7));
-               else
-                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                                       "RxFS input, ");
-
-               if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
-                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                                       "RxClk output from %s",
-                                       audmux_port_string((ptcr >> 12) & 0x7));
-               else
-                       ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                                       "RxClk input");
-       }
-
-       ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                       "\nData received from %s\n",
-                       audmux_port_string((pdcr >> 13) & 0x7));
-
-       ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
-       kfree(buf);
-
-       return ret;
-}
-
-static const struct file_operations audmux_debugfs_fops = {
-       .open = audmux_open_file,
-       .read = audmux_read_file,
-       .llseek = default_llseek,
-};
-
-static void __init audmux_debugfs_init(void)
-{
-       int i;
-       char buf[20];
-
-       audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
-       if (!audmux_debugfs_root) {
-               pr_warning("Failed to create AUDMUX debugfs root\n");
-               return;
-       }
-
-       for (i = 1; i < 8; i++) {
-               snprintf(buf, sizeof(buf), "ssi%d", i);
-               if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
-                                        (void *)i, &audmux_debugfs_fops))
-                       pr_warning("Failed to create AUDMUX port %d debugfs file\n",
-                                  i);
-       }
-}
-
-static void __devexit audmux_debugfs_remove(void)
-{
-       debugfs_remove_recursive(audmux_debugfs_root);
-}
-#else
-static inline void audmux_debugfs_init(void)
-{
-}
-
-static inline void audmux_debugfs_remove(void)
-{
-}
-#endif
-
-enum imx_audmux_type {
-       IMX21_AUDMUX,
-       IMX31_AUDMUX,
-} audmux_type;
-
-static struct platform_device_id imx_audmux_ids[] = {
-       {
-               .name = "imx21-audmux",
-               .driver_data = IMX21_AUDMUX,
-       }, {
-               .name = "imx31-audmux",
-               .driver_data = IMX31_AUDMUX,
-       }, {
-               /* sentinel */
-       }
-};
-MODULE_DEVICE_TABLE(platform, imx_audmux_ids);
-
-static const struct of_device_id imx_audmux_dt_ids[] = {
-       { .compatible = "fsl,imx21-audmux", .data = &imx_audmux_ids[0], },
-       { .compatible = "fsl,imx31-audmux", .data = &imx_audmux_ids[1], },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_audmux_dt_ids);
-
-static const uint8_t port_mapping[] = {
-       0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
-};
-
-int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
-{
-       if (audmux_type != IMX21_AUDMUX)
-               return -EINVAL;
-
-       if (!audmux_base)
-               return -ENOSYS;
-
-       if (port >= ARRAY_SIZE(port_mapping))
-               return -EINVAL;
-
-       writel(pcr, audmux_base + port_mapping[port]);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port);
-
-int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
-               unsigned int pdcr)
-{
-       if (audmux_type != IMX31_AUDMUX)
-               return -EINVAL;
-
-       if (!audmux_base)
-               return -ENOSYS;
-
-       if (audmux_clk)
-               clk_prepare_enable(audmux_clk);
-
-       writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
-       writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
-
-       if (audmux_clk)
-               clk_disable_unprepare(audmux_clk);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
-
-static int __devinit imx_audmux_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       const struct of_device_id *of_id =
-                       of_match_device(imx_audmux_dt_ids, &pdev->dev);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       audmux_base = devm_request_and_ioremap(&pdev->dev, res);
-       if (!audmux_base)
-               return -EADDRNOTAVAIL;
-
-       audmux_clk = clk_get(&pdev->dev, "audmux");
-       if (IS_ERR(audmux_clk)) {
-               dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
-                               PTR_ERR(audmux_clk));
-               audmux_clk = NULL;
-       }
-
-       if (of_id)
-               pdev->id_entry = of_id->data;
-       audmux_type = pdev->id_entry->driver_data;
-       if (audmux_type == IMX31_AUDMUX)
-               audmux_debugfs_init();
-
-       return 0;
-}
-
-static int __devexit imx_audmux_remove(struct platform_device *pdev)
-{
-       if (audmux_type == IMX31_AUDMUX)
-               audmux_debugfs_remove();
-       clk_put(audmux_clk);
-
-       return 0;
-}
-
-static struct platform_driver imx_audmux_driver = {
-       .probe          = imx_audmux_probe,
-       .remove         = __devexit_p(imx_audmux_remove),
-       .id_table       = imx_audmux_ids,
-       .driver = {
-               .name   = DRIVER_NAME,
-               .owner  = THIS_MODULE,
-               .of_match_table = imx_audmux_dt_ids,
-       }
-};
-
-static int __init imx_audmux_init(void)
-{
-       return platform_driver_register(&imx_audmux_driver);
-}
-subsys_initcall(imx_audmux_init);
-
-static void __exit imx_audmux_exit(void)
-{
-       platform_driver_unregister(&imx_audmux_driver);
-}
-module_exit(imx_audmux_exit);
-
-MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/sound/soc/imx/imx-audmux.h b/sound/soc/imx/imx-audmux.h
deleted file mode 100644 (file)
index 04ebbab..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __IMX_AUDMUX_H
-#define __IMX_AUDMUX_H
-
-#define MX27_AUDMUX_HPCR1_SSI0         0
-#define MX27_AUDMUX_HPCR2_SSI1         1
-#define MX27_AUDMUX_HPCR3_SSI_PINS_4   2
-#define MX27_AUDMUX_PPCR1_SSI_PINS_1   3
-#define MX27_AUDMUX_PPCR2_SSI_PINS_2   4
-#define MX27_AUDMUX_PPCR3_SSI_PINS_3   5
-
-#define MX31_AUDMUX_PORT1_SSI0         0
-#define MX31_AUDMUX_PORT2_SSI1         1
-#define MX31_AUDMUX_PORT3_SSI_PINS_3   2
-#define MX31_AUDMUX_PORT4_SSI_PINS_4   3
-#define MX31_AUDMUX_PORT5_SSI_PINS_5   4
-#define MX31_AUDMUX_PORT6_SSI_PINS_6   5
-
-#define MX51_AUDMUX_PORT1_SSI0         0
-#define MX51_AUDMUX_PORT2_SSI1         1
-#define MX51_AUDMUX_PORT3              2
-#define MX51_AUDMUX_PORT4              3
-#define MX51_AUDMUX_PORT5              4
-#define MX51_AUDMUX_PORT6              5
-#define MX51_AUDMUX_PORT7              6
-
-/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
-#define IMX_AUDMUX_V1_PCR_INMMASK(x)   ((x) & 0xff)
-#define IMX_AUDMUX_V1_PCR_INMEN                (1 << 8)
-#define IMX_AUDMUX_V1_PCR_TXRXEN       (1 << 10)
-#define IMX_AUDMUX_V1_PCR_SYN          (1 << 12)
-#define IMX_AUDMUX_V1_PCR_RXDSEL(x)    (((x) & 0x7) << 13)
-#define IMX_AUDMUX_V1_PCR_RFCSEL(x)    (((x) & 0xf) << 20)
-#define IMX_AUDMUX_V1_PCR_RCLKDIR      (1 << 24)
-#define IMX_AUDMUX_V1_PCR_RFSDIR       (1 << 25)
-#define IMX_AUDMUX_V1_PCR_TFCSEL(x)    (((x) & 0xf) << 26)
-#define IMX_AUDMUX_V1_PCR_TCLKDIR      (1 << 30)
-#define IMX_AUDMUX_V1_PCR_TFSDIR       (1 << 31)
-
-/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
-#define IMX_AUDMUX_V2_PTCR_TFSDIR      (1 << 31)
-#define IMX_AUDMUX_V2_PTCR_TFSEL(x)    (((x) & 0xf) << 27)
-#define IMX_AUDMUX_V2_PTCR_TCLKDIR     (1 << 26)
-#define IMX_AUDMUX_V2_PTCR_TCSEL(x)    (((x) & 0xf) << 22)
-#define IMX_AUDMUX_V2_PTCR_RFSDIR      (1 << 21)
-#define IMX_AUDMUX_V2_PTCR_RFSEL(x)    (((x) & 0xf) << 17)
-#define IMX_AUDMUX_V2_PTCR_RCLKDIR     (1 << 16)
-#define IMX_AUDMUX_V2_PTCR_RCSEL(x)    (((x) & 0xf) << 12)
-#define IMX_AUDMUX_V2_PTCR_SYN         (1 << 11)
-
-#define IMX_AUDMUX_V2_PDCR_RXDSEL(x)   (((x) & 0x7) << 13)
-#define IMX_AUDMUX_V2_PDCR_TXRXEN      (1 << 12)
-#define IMX_AUDMUX_V2_PDCR_MODE(x)     (((x) & 0x3) << 8)
-#define IMX_AUDMUX_V2_PDCR_INMMASK(x)  ((x) & 0xff)
-
-int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
-
-int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
-               unsigned int pdcr);
-
-#endif /* __IMX_AUDMUX_H */
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
deleted file mode 100644 (file)
index 6b818de..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * imx-pcm-dma-mx2.c  --  ALSA Soc Audio Layer
- *
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- *  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.
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dmaengine.h>
-#include <linux/types.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/dmaengine_pcm.h>
-
-#include <mach/dma.h>
-
-#include "imx-pcm.h"
-
-static bool filter(struct dma_chan *chan, void *param)
-{
-       if (!imx_dma_is_general_purpose(chan))
-               return false;
-
-       chan->private = param;
-
-       return true;
-}
-
-static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
-       struct imx_pcm_dma_params *dma_params;
-       struct dma_slave_config slave_config;
-       int ret;
-
-       dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
-       if (ret)
-               return ret;
-
-       slave_config.device_fc = false;
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               slave_config.dst_addr = dma_params->dma_addr;
-               slave_config.dst_maxburst = dma_params->burstsize;
-       } else {
-               slave_config.src_addr = dma_params->dma_addr;
-               slave_config.src_maxburst = dma_params->burstsize;
-       }
-
-       ret = dmaengine_slave_config(chan, &slave_config);
-       if (ret)
-               return ret;
-
-       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
-       return 0;
-}
-
-static struct snd_pcm_hardware snd_imx_hardware = {
-       .info = SNDRV_PCM_INFO_INTERLEAVED |
-               SNDRV_PCM_INFO_BLOCK_TRANSFER |
-               SNDRV_PCM_INFO_MMAP |
-               SNDRV_PCM_INFO_MMAP_VALID |
-               SNDRV_PCM_INFO_PAUSE |
-               SNDRV_PCM_INFO_RESUME,
-       .formats = SNDRV_PCM_FMTBIT_S16_LE,
-       .rate_min = 8000,
-       .channels_min = 2,
-       .channels_max = 2,
-       .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
-       .period_bytes_min = 128,
-       .period_bytes_max = 65535, /* Limited by SDMA engine */
-       .periods_min = 2,
-       .periods_max = 255,
-       .fifo_size = 0,
-};
-
-static int snd_imx_open(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params;
-       struct imx_dma_data *dma_data;
-       int ret;
-
-       snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
-
-       dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
-       dma_data->peripheral_type = IMX_DMATYPE_SSI;
-       dma_data->priority = DMA_PRIO_HIGH;
-       dma_data->dma_request = dma_params->dma;
-
-       ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
-       if (ret) {
-               kfree(dma_data);
-               return 0;
-       }
-
-       snd_dmaengine_pcm_set_data(substream, dma_data);
-
-       return 0;
-}
-
-static int snd_imx_close(struct snd_pcm_substream *substream)
-{
-       struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
-
-       snd_dmaengine_pcm_close(substream);
-       kfree(dma_data);
-
-       return 0;
-}
-
-static struct snd_pcm_ops imx_pcm_ops = {
-       .open           = snd_imx_open,
-       .close          = snd_imx_close,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = snd_imx_pcm_hw_params,
-       .trigger        = snd_dmaengine_pcm_trigger,
-       .pointer        = snd_dmaengine_pcm_pointer,
-       .mmap           = snd_imx_pcm_mmap,
-};
-
-static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
-       .ops            = &imx_pcm_ops,
-       .pcm_new        = imx_pcm_new,
-       .pcm_free       = imx_pcm_free,
-};
-
-static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
-{
-       return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
-}
-
-static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_platform(&pdev->dev);
-       return 0;
-}
-
-static struct platform_driver imx_pcm_driver = {
-       .driver = {
-                       .name = "imx-pcm-audio",
-                       .owner = THIS_MODULE,
-       },
-       .probe = imx_soc_platform_probe,
-       .remove = __devexit_p(imx_soc_platform_remove),
-};
-
-module_platform_driver(imx_pcm_driver);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-pcm-audio");
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
deleted file mode 100644 (file)
index 456b7d7..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * imx-pcm-fiq.c  --  ALSA Soc Audio Layer
- *
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- *  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.
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/fiq.h>
-
-#include <mach/ssi.h>
-
-#include "imx-ssi.h"
-
-struct imx_pcm_runtime_data {
-       int period;
-       int periods;
-       unsigned long offset;
-       unsigned long last_offset;
-       unsigned long size;
-       struct hrtimer hrt;
-       int poll_time_ns;
-       struct snd_pcm_substream *substream;
-       atomic_t running;
-};
-
-static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
-{
-       struct imx_pcm_runtime_data *iprtd =
-               container_of(hrt, struct imx_pcm_runtime_data, hrt);
-       struct snd_pcm_substream *substream = iprtd->substream;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct pt_regs regs;
-       unsigned long delta;
-
-       if (!atomic_read(&iprtd->running))
-               return HRTIMER_NORESTART;
-
-       get_fiq_regs(&regs);
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               iprtd->offset = regs.ARM_r8 & 0xffff;
-       else
-               iprtd->offset = regs.ARM_r9 & 0xffff;
-
-       /* How much data have we transferred since the last period report? */
-       if (iprtd->offset >= iprtd->last_offset)
-               delta = iprtd->offset - iprtd->last_offset;
-       else
-               delta = runtime->buffer_size + iprtd->offset
-                       - iprtd->last_offset;
-
-       /* If we've transferred at least a period then report it and
-        * reset our poll time */
-       if (delta >= iprtd->period) {
-               snd_pcm_period_elapsed(substream);
-               iprtd->last_offset = iprtd->offset;
-       }
-
-       hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
-
-       return HRTIMER_RESTART;
-}
-
-static struct fiq_handler fh = {
-       .name           = DRV_NAME,
-};
-
-static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
-       iprtd->size = params_buffer_bytes(params);
-       iprtd->periods = params_periods(params);
-       iprtd->period = params_period_bytes(params) ;
-       iprtd->offset = 0;
-       iprtd->last_offset = 0;
-       iprtd->poll_time_ns = 1000000000 / params_rate(params) *
-                               params_period_size(params);
-       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
-       return 0;
-}
-
-static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-       struct pt_regs regs;
-
-       get_fiq_regs(&regs);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               regs.ARM_r8 = (iprtd->period * iprtd->periods - 1) << 16;
-       else
-               regs.ARM_r9 = (iprtd->period * iprtd->periods - 1) << 16;
-
-       set_fiq_regs(&regs);
-
-       return 0;
-}
-
-static int fiq_enable;
-static int imx_pcm_fiq;
-
-static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-       case SNDRV_PCM_TRIGGER_RESUME:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               atomic_set(&iprtd->running, 1);
-               hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
-                     HRTIMER_MODE_REL);
-               if (++fiq_enable == 1)
-                       enable_fiq(imx_pcm_fiq);
-
-               break;
-
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               atomic_set(&iprtd->running, 0);
-
-               if (--fiq_enable == 0)
-                       disable_fiq(imx_pcm_fiq);
-
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
-       return bytes_to_frames(substream->runtime, iprtd->offset);
-}
-
-static struct snd_pcm_hardware snd_imx_hardware = {
-       .info = SNDRV_PCM_INFO_INTERLEAVED |
-               SNDRV_PCM_INFO_BLOCK_TRANSFER |
-               SNDRV_PCM_INFO_MMAP |
-               SNDRV_PCM_INFO_MMAP_VALID |
-               SNDRV_PCM_INFO_PAUSE |
-               SNDRV_PCM_INFO_RESUME,
-       .formats = SNDRV_PCM_FMTBIT_S16_LE,
-       .rate_min = 8000,
-       .channels_min = 2,
-       .channels_max = 2,
-       .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
-       .period_bytes_min = 128,
-       .period_bytes_max = 16 * 1024,
-       .periods_min = 4,
-       .periods_max = 255,
-       .fifo_size = 0,
-};
-
-static int snd_imx_open(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd;
-       int ret;
-
-       iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
-       if (iprtd == NULL)
-               return -ENOMEM;
-       runtime->private_data = iprtd;
-
-       iprtd->substream = substream;
-
-       atomic_set(&iprtd->running, 0);
-       hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-       iprtd->hrt.function = snd_hrtimer_callback;
-
-       ret = snd_pcm_hw_constraint_integer(substream->runtime,
-                       SNDRV_PCM_HW_PARAM_PERIODS);
-       if (ret < 0) {
-               kfree(iprtd);
-               return ret;
-       }
-
-       snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
-       return 0;
-}
-
-static int snd_imx_close(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
-       hrtimer_cancel(&iprtd->hrt);
-
-       kfree(iprtd);
-
-       return 0;
-}
-
-static struct snd_pcm_ops imx_pcm_ops = {
-       .open           = snd_imx_open,
-       .close          = snd_imx_close,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = snd_imx_pcm_hw_params,
-       .prepare        = snd_imx_pcm_prepare,
-       .trigger        = snd_imx_pcm_trigger,
-       .pointer        = snd_imx_pcm_pointer,
-       .mmap           = snd_imx_pcm_mmap,
-};
-
-static int ssi_irq = 0;
-
-static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_pcm *pcm = rtd->pcm;
-       struct snd_pcm_substream *substream;
-       int ret;
-
-       ret = imx_pcm_new(rtd);
-       if (ret)
-               return ret;
-
-       substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
-       if (substream) {
-               struct snd_dma_buffer *buf = &substream->dma_buffer;
-
-               imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
-       }
-
-       substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
-       if (substream) {
-               struct snd_dma_buffer *buf = &substream->dma_buffer;
-
-               imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
-       }
-
-       set_fiq_handler(&imx_ssi_fiq_start,
-               &imx_ssi_fiq_end - &imx_ssi_fiq_start);
-
-       return 0;
-}
-
-static void imx_pcm_fiq_free(struct snd_pcm *pcm)
-{
-       mxc_set_irq_fiq(ssi_irq, 0);
-       release_fiq(&fh);
-       imx_pcm_free(pcm);
-}
-
-static struct snd_soc_platform_driver imx_soc_platform_fiq = {
-       .ops            = &imx_pcm_ops,
-       .pcm_new        = imx_pcm_fiq_new,
-       .pcm_free       = imx_pcm_fiq_free,
-};
-
-static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
-{
-       struct imx_ssi *ssi = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = claim_fiq(&fh);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
-               return ret;
-       }
-
-       mxc_set_irq_fiq(ssi->irq, 1);
-       ssi_irq = ssi->irq;
-
-       imx_pcm_fiq = ssi->irq;
-
-       imx_ssi_fiq_base = (unsigned long)ssi->base;
-
-       ssi->dma_params_tx.burstsize = 4;
-       ssi->dma_params_rx.burstsize = 6;
-
-       ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
-       if (ret)
-               goto failed_register;
-
-       return 0;
-
-failed_register:
-       mxc_set_irq_fiq(ssi_irq, 0);
-       release_fiq(&fh);
-
-       return ret;
-}
-
-static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_platform(&pdev->dev);
-       return 0;
-}
-
-static struct platform_driver imx_pcm_driver = {
-       .driver = {
-                       .name = "imx-fiq-pcm-audio",
-                       .owner = THIS_MODULE,
-       },
-
-       .probe = imx_soc_platform_probe,
-       .remove = __devexit_p(imx_soc_platform_remove),
-};
-
-module_platform_driver(imx_pcm_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/imx/imx-pcm.c
deleted file mode 100644 (file)
index 93dc360..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * 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.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include "imx-pcm.h"
-
-int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
-               struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       int ret;
-
-       ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
-               runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
-
-       pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
-                       runtime->dma_area,
-                       runtime->dma_addr,
-                       runtime->dma_bytes);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
-
-static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-       size_t size = IMX_SSI_DMABUF_SIZE;
-
-       buf->dev.type = SNDRV_DMA_TYPE_DEV;
-       buf->dev.dev = pcm->card->dev;
-       buf->private_data = NULL;
-       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
-                                          &buf->addr, GFP_KERNEL);
-       if (!buf->area)
-               return -ENOMEM;
-       buf->bytes = size;
-
-       return 0;
-}
-
-static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
-
-int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       struct snd_pcm *pcm = rtd->pcm;
-       int ret = 0;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &imx_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
-               ret = imx_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_PLAYBACK);
-               if (ret)
-                       goto out;
-       }
-
-       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-               ret = imx_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_CAPTURE);
-               if (ret)
-                       goto out;
-       }
-
-out:
-       return ret;
-}
-EXPORT_SYMBOL_GPL(imx_pcm_new);
-
-void imx_pcm_free(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-
-       for (stream = 0; stream < 2; stream++) {
-               substream = pcm->streams[stream].substream;
-               if (!substream)
-                       continue;
-
-               buf = &substream->dma_buffer;
-               if (!buf->area)
-                       continue;
-
-               dma_free_writecombine(pcm->card->dev, buf->bytes,
-                                     buf->area, buf->addr);
-               buf->area = NULL;
-       }
-}
-EXPORT_SYMBOL_GPL(imx_pcm_free);
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h
deleted file mode 100644 (file)
index b5f5c3a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * 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.
- */
-
-#ifndef _IMX_PCM_H
-#define _IMX_PCM_H
-
-/*
- * Do not change this as the FIQ handler depends on this size
- */
-#define IMX_SSI_DMABUF_SIZE    (64 * 1024)
-
-struct imx_pcm_dma_params {
-       int dma;
-       unsigned long dma_addr;
-       int burstsize;
-};
-
-int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
-                    struct vm_area_struct *vma);
-int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
-void imx_pcm_free(struct snd_pcm *pcm);
-
-#endif /* _IMX_PCM_H */
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
deleted file mode 100644 (file)
index 4f81ed4..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * imx-ssi.c  --  ALSA Soc Audio Layer
- *
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- *  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.
- *
- *
- * The i.MX SSI core has some nasty limitations in AC97 mode. While most
- * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
- * one FIFO which combines all valid receive slots. We cannot even select
- * which slots we want to receive. The WM9712 with which this driver
- * was developed with always sends GPIO status data in slot 12 which
- * we receive in our (PCM-) data stream. The only chance we have is to
- * manually skip this data in the FIQ handler. With sampling rates different
- * from 48000Hz not every frame has valid receive data, so the ratio
- * between pcm data and GPIO status data changes. Our FIQ handler is not
- * able to handle this, hence this driver only works with 48000Hz sampling
- * rate.
- * Reading and writing AC97 registers is another challenge. The core
- * provides us status bits when the read register is updated with *another*
- * value. When we read the same register two times (and the register still
- * contains the same value) these status bits are not set. We work
- * around this by not polling these bits but only wait a fixed delay.
- * 
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <mach/ssi.h>
-#include <mach/hardware.h>
-
-#include "imx-ssi.h"
-
-#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
-
-/*
- * SSI Network Mode or TDM slots configuration.
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
-       unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
-       u32 sccr;
-
-       sccr = readl(ssi->base + SSI_STCCR);
-       sccr &= ~SSI_STCCR_DC_MASK;
-       sccr |= SSI_STCCR_DC(slots - 1);
-       writel(sccr, ssi->base + SSI_STCCR);
-
-       sccr = readl(ssi->base + SSI_SRCCR);
-       sccr &= ~SSI_STCCR_DC_MASK;
-       sccr |= SSI_STCCR_DC(slots - 1);
-       writel(sccr, ssi->base + SSI_SRCCR);
-
-       writel(tx_mask, ssi->base + SSI_STMSK);
-       writel(rx_mask, ssi->base + SSI_SRMSK);
-
-       return 0;
-}
-
-/*
- * SSI DAI format configuration.
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
-       u32 strcr = 0, scr;
-
-       scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
-
-       /* DAI mode */
-       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-       case SND_SOC_DAIFMT_I2S:
-               /* data on rising edge of bclk, frame low 1clk before data */
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
-               scr |= SSI_SCR_NET;
-               if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
-                       scr &= ~SSI_I2S_MODE_MASK;
-                       scr |= SSI_SCR_I2S_MODE_SLAVE;
-               }
-               break;
-       case SND_SOC_DAIFMT_LEFT_J:
-               /* data on rising edge of bclk, frame high with data */
-               strcr |= SSI_STCR_TXBIT0;
-               break;
-       case SND_SOC_DAIFMT_DSP_B:
-               /* data on rising edge of bclk, frame high with data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
-               break;
-       case SND_SOC_DAIFMT_DSP_A:
-               /* data on rising edge of bclk, frame high 1clk before data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
-               break;
-       }
-
-       /* DAI clock inversion */
-       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-       case SND_SOC_DAIFMT_IB_IF:
-               strcr |= SSI_STCR_TFSI;
-               strcr &= ~SSI_STCR_TSCKP;
-               break;
-       case SND_SOC_DAIFMT_IB_NF:
-               strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
-               break;
-       case SND_SOC_DAIFMT_NB_IF:
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
-               break;
-       case SND_SOC_DAIFMT_NB_NF:
-               strcr &= ~SSI_STCR_TFSI;
-               strcr |= SSI_STCR_TSCKP;
-               break;
-       }
-
-       /* DAI clock master masks */
-       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-       case SND_SOC_DAIFMT_CBM_CFM:
-               break;
-       default:
-               /* Master mode not implemented, needs handling of clocks. */
-               return -EINVAL;
-       }
-
-       strcr |= SSI_STCR_TFEN0;
-
-       if (ssi->flags & IMX_SSI_NET)
-               scr |= SSI_SCR_NET;
-       if (ssi->flags & IMX_SSI_SYN)
-               scr |= SSI_SCR_SYN;
-
-       writel(strcr, ssi->base + SSI_STCR);
-       writel(strcr, ssi->base + SSI_SRCR);
-       writel(scr, ssi->base + SSI_SCR);
-
-       return 0;
-}
-
-/*
- * SSI system clock configuration.
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
-                                 int clk_id, unsigned int freq, int dir)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
-       u32 scr;
-
-       scr = readl(ssi->base + SSI_SCR);
-
-       switch (clk_id) {
-       case IMX_SSP_SYS_CLK:
-               if (dir == SND_SOC_CLOCK_OUT)
-                       scr |= SSI_SCR_SYS_CLK_EN;
-               else
-                       scr &= ~SSI_SCR_SYS_CLK_EN;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       writel(scr, ssi->base + SSI_SCR);
-
-       return 0;
-}
-
-/*
- * SSI Clock dividers
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
-                                 int div_id, int div)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
-       u32 stccr, srccr;
-
-       stccr = readl(ssi->base + SSI_STCCR);
-       srccr = readl(ssi->base + SSI_SRCCR);
-
-       switch (div_id) {
-       case IMX_SSI_TX_DIV_2:
-               stccr &= ~SSI_STCCR_DIV2;
-               stccr |= div;
-               break;
-       case IMX_SSI_TX_DIV_PSR:
-               stccr &= ~SSI_STCCR_PSR;
-               stccr |= div;
-               break;
-       case IMX_SSI_TX_DIV_PM:
-               stccr &= ~0xff;
-               stccr |= SSI_STCCR_PM(div);
-               break;
-       case IMX_SSI_RX_DIV_2:
-               stccr &= ~SSI_STCCR_DIV2;
-               stccr |= div;
-               break;
-       case IMX_SSI_RX_DIV_PSR:
-               stccr &= ~SSI_STCCR_PSR;
-               stccr |= div;
-               break;
-       case IMX_SSI_RX_DIV_PM:
-               stccr &= ~0xff;
-               stccr |= SSI_STCCR_PM(div);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       writel(stccr, ssi->base + SSI_STCCR);
-       writel(srccr, ssi->base + SSI_SRCCR);
-
-       return 0;
-}
-
-static int imx_ssi_startup(struct snd_pcm_substream *substream,
-                          struct snd_soc_dai *cpu_dai)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
-       struct imx_pcm_dma_params *dma_data;
-
-       /* Tx/Rx config */
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dma_data = &ssi->dma_params_tx;
-       else
-               dma_data = &ssi->dma_params_rx;
-
-       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
-       return 0;
-}
-
-/*
- * Should only be called when port is inactive (i.e. SSIEN = 0),
- * although can be called multiple times by upper layers.
- */
-static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
-                            struct snd_pcm_hw_params *params,
-                            struct snd_soc_dai *cpu_dai)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
-       u32 reg, sccr;
-
-       /* Tx/Rx config */
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               reg = SSI_STCCR;
-       else
-               reg = SSI_SRCCR;
-
-       if (ssi->flags & IMX_SSI_SYN)
-               reg = SSI_STCCR;
-
-       sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
-
-       /* DAI data (word) size */
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S16_LE:
-               sccr |= SSI_SRCCR_WL(16);
-               break;
-       case SNDRV_PCM_FORMAT_S20_3LE:
-               sccr |= SSI_SRCCR_WL(20);
-               break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               sccr |= SSI_SRCCR_WL(24);
-               break;
-       }
-
-       writel(sccr, ssi->base + reg);
-
-       return 0;
-}
-
-static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
-               struct snd_soc_dai *dai)
-{
-       struct imx_ssi *ssi = snd_soc_dai_get_drvdata(dai);
-       unsigned int sier_bits, sier;
-       unsigned int scr;
-
-       scr = readl(ssi->base + SSI_SCR);
-       sier = readl(ssi->base + SSI_SIER);
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (ssi->flags & IMX_SSI_DMA)
-                       sier_bits = SSI_SIER_TDMAE;
-               else
-                       sier_bits = SSI_SIER_TIE | SSI_SIER_TFE0_EN;
-       } else {
-               if (ssi->flags & IMX_SSI_DMA)
-                       sier_bits = SSI_SIER_RDMAE;
-               else
-                       sier_bits = SSI_SIER_RIE | SSI_SIER_RFF0_EN;
-       }
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-       case SNDRV_PCM_TRIGGER_RESUME:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       scr |= SSI_SCR_TE;
-               else
-                       scr |= SSI_SCR_RE;
-               sier |= sier_bits;
-
-               if (++ssi->enabled == 1)
-                       scr |= SSI_SCR_SSIEN;
-
-               break;
-
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       scr &= ~SSI_SCR_TE;
-               else
-                       scr &= ~SSI_SCR_RE;
-               sier &= ~sier_bits;
-
-               if (--ssi->enabled == 0)
-                       scr &= ~SSI_SCR_SSIEN;
-
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (!(ssi->flags & IMX_SSI_USE_AC97))
-               /* rx/tx are always enabled to access ac97 registers */
-               writel(scr, ssi->base + SSI_SCR);
-
-       writel(sier, ssi->base + SSI_SIER);
-
-       return 0;
-}
-
-static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
-       .startup        = imx_ssi_startup,
-       .hw_params      = imx_ssi_hw_params,
-       .set_fmt        = imx_ssi_set_dai_fmt,
-       .set_clkdiv     = imx_ssi_set_dai_clkdiv,
-       .set_sysclk     = imx_ssi_set_dai_sysclk,
-       .set_tdm_slot   = imx_ssi_set_dai_tdm_slot,
-       .trigger        = imx_ssi_trigger,
-};
-
-static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
-{
-       struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
-       uint32_t val;
-
-       snd_soc_dai_set_drvdata(dai, ssi);
-
-       val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
-               SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
-       writel(val, ssi->base + SSI_SFCSR);
-
-       return 0;
-}
-
-static struct snd_soc_dai_driver imx_ssi_dai = {
-       .probe = imx_ssi_dai_probe,
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_96000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_8000_96000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,
-       },
-       .ops = &imx_ssi_pcm_dai_ops,
-};
-
-static struct snd_soc_dai_driver imx_ac97_dai = {
-       .probe = imx_ssi_dai_probe,
-       .ac97_control = 1,
-       .playback = {
-               .stream_name = "AC97 Playback",
-               .channels_min = 2,
-               .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,
-       },
-       .capture = {
-               .stream_name = "AC97 Capture",
-               .channels_min = 2,
-               .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,
-       },
-       .ops = &imx_ssi_pcm_dai_ops,
-};
-
-static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
-{
-       void __iomem *base = imx_ssi->base;
-
-       writel(0x0, base + SSI_SCR);
-       writel(0x0, base + SSI_STCR);
-       writel(0x0, base + SSI_SRCR);
-
-       writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);
-
-       writel(SSI_SFCSR_RFWM0(8) |
-               SSI_SFCSR_TFWM0(8) |
-               SSI_SFCSR_RFWM1(8) |
-               SSI_SFCSR_TFWM1(8), base + SSI_SFCSR);
-
-       writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);
-       writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);
-
-       writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);
-       writel(SSI_SOR_WAIT(3), base + SSI_SOR);
-
-       writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |
-                       SSI_SCR_TE | SSI_SCR_RE,
-                       base + SSI_SCR);
-
-       writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);
-       writel(0xff, base + SSI_SACCDIS);
-       writel(0x300, base + SSI_SACCEN);
-}
-
-static struct imx_ssi *ac97_ssi;
-
-static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
-               unsigned short val)
-{
-       struct imx_ssi *imx_ssi = ac97_ssi;
-       void __iomem *base = imx_ssi->base;
-       unsigned int lreg;
-       unsigned int lval;
-
-       if (reg > 0x7f)
-               return;
-
-       pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
-
-       lreg = reg <<  12;
-       writel(lreg, base + SSI_SACADD);
-
-       lval = val << 4;
-       writel(lval , base + SSI_SACDAT);
-
-       writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);
-       udelay(100);
-}
-
-static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,
-               unsigned short reg)
-{
-       struct imx_ssi *imx_ssi = ac97_ssi;
-       void __iomem *base = imx_ssi->base;
-
-       unsigned short val = -1;
-       unsigned int lreg;
-
-       lreg = (reg & 0x7f) <<  12 ;
-       writel(lreg, base + SSI_SACADD);
-       writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);
-
-       udelay(100);
-
-       val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;
-
-       pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
-
-       return val;
-}
-
-static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
-{
-       struct imx_ssi *imx_ssi = ac97_ssi;
-
-       if (imx_ssi->ac97_reset)
-               imx_ssi->ac97_reset(ac97);
-}
-
-static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
-{
-       struct imx_ssi *imx_ssi = ac97_ssi;
-
-       if (imx_ssi->ac97_warm_reset)
-               imx_ssi->ac97_warm_reset(ac97);
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
-       .read           = imx_ssi_ac97_read,
-       .write          = imx_ssi_ac97_write,
-       .reset          = imx_ssi_ac97_reset,
-       .warm_reset     = imx_ssi_ac97_warm_reset
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int imx_ssi_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       struct imx_ssi *ssi;
-       struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
-       int ret = 0;
-       struct snd_soc_dai_driver *dai;
-
-       ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
-       if (!ssi)
-               return -ENOMEM;
-       dev_set_drvdata(&pdev->dev, ssi);
-
-       if (pdata) {
-               ssi->ac97_reset = pdata->ac97_reset;
-               ssi->ac97_warm_reset = pdata->ac97_warm_reset;
-               ssi->flags = pdata->flags;
-       }
-
-       ssi->irq = platform_get_irq(pdev, 0);
-
-       ssi->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(ssi->clk)) {
-               ret = PTR_ERR(ssi->clk);
-               dev_err(&pdev->dev, "Cannot get the clock: %d\n",
-                       ret);
-               goto failed_clk;
-       }
-       clk_enable(ssi->clk);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               ret = -ENODEV;
-               goto failed_get_resource;
-       }
-
-       if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
-               dev_err(&pdev->dev, "request_mem_region failed\n");
-               ret = -EBUSY;
-               goto failed_get_resource;
-       }
-
-       ssi->base = ioremap(res->start, resource_size(res));
-       if (!ssi->base) {
-               dev_err(&pdev->dev, "ioremap failed\n");
-               ret = -ENODEV;
-               goto failed_ioremap;
-       }
-
-       if (ssi->flags & IMX_SSI_USE_AC97) {
-               if (ac97_ssi) {
-                       ret = -EBUSY;
-                       goto failed_ac97;
-               }
-               ac97_ssi = ssi;
-               setup_channel_to_ac97(ssi);
-               dai = &imx_ac97_dai;
-       } else
-               dai = &imx_ssi_dai;
-
-       writel(0x0, ssi->base + SSI_SIER);
-
-       ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
-       ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
-
-       ssi->dma_params_tx.burstsize = 6;
-       ssi->dma_params_rx.burstsize = 4;
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
-       if (res)
-               ssi->dma_params_tx.dma = res->start;
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
-       if (res)
-               ssi->dma_params_rx.dma = res->start;
-
-       platform_set_drvdata(pdev, ssi);
-
-       ret = snd_soc_register_dai(&pdev->dev, dai);
-       if (ret) {
-               dev_err(&pdev->dev, "register DAI failed\n");
-               goto failed_register;
-       }
-
-       ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev_fiq) {
-               ret = -ENOMEM;
-               goto failed_pdev_fiq_alloc;
-       }
-
-       platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
-       ret = platform_device_add(ssi->soc_platform_pdev_fiq);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform device\n");
-               goto failed_pdev_fiq_add;
-       }
-
-       ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev) {
-               ret = -ENOMEM;
-               goto failed_pdev_alloc;
-       }
-
-       platform_set_drvdata(ssi->soc_platform_pdev, ssi);
-       ret = platform_device_add(ssi->soc_platform_pdev);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform device\n");
-               goto failed_pdev_add;
-       }
-
-       return 0;
-
-failed_pdev_add:
-       platform_device_put(ssi->soc_platform_pdev);
-failed_pdev_alloc:
-       platform_device_del(ssi->soc_platform_pdev_fiq);
-failed_pdev_fiq_add:
-       platform_device_put(ssi->soc_platform_pdev_fiq);
-failed_pdev_fiq_alloc:
-       snd_soc_unregister_dai(&pdev->dev);
-failed_register:
-failed_ac97:
-       iounmap(ssi->base);
-failed_ioremap:
-       release_mem_region(res->start, resource_size(res));
-failed_get_resource:
-       clk_disable(ssi->clk);
-       clk_put(ssi->clk);
-failed_clk:
-       kfree(ssi);
-
-       return ret;
-}
-
-static int __devexit imx_ssi_remove(struct platform_device *pdev)
-{
-       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       struct imx_ssi *ssi = platform_get_drvdata(pdev);
-
-       platform_device_unregister(ssi->soc_platform_pdev);
-       platform_device_unregister(ssi->soc_platform_pdev_fiq);
-
-       snd_soc_unregister_dai(&pdev->dev);
-
-       if (ssi->flags & IMX_SSI_USE_AC97)
-               ac97_ssi = NULL;
-
-       iounmap(ssi->base);
-       release_mem_region(res->start, resource_size(res));
-       clk_disable(ssi->clk);
-       clk_put(ssi->clk);
-       kfree(ssi);
-
-       return 0;
-}
-
-static struct platform_driver imx_ssi_driver = {
-       .probe = imx_ssi_probe,
-       .remove = __devexit_p(imx_ssi_remove),
-
-       .driver = {
-               .name = "imx-ssi",
-               .owner = THIS_MODULE,
-       },
-};
-
-module_platform_driver(imx_ssi_driver);
-
-/* Module information */
-MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-ssi");
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
deleted file mode 100644 (file)
index 5744e86..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _IMX_SSI_H
-#define _IMX_SSI_H
-
-#define SSI_STX0       0x00
-#define SSI_STX1       0x04
-#define SSI_SRX0       0x08
-#define SSI_SRX1       0x0c
-
-#define SSI_SCR                0x10
-#define SSI_SCR_CLK_IST                (1 << 9)
-#define SSI_SCR_CLK_IST_SHIFT  9
-#define SSI_SCR_TCH_EN         (1 << 8)
-#define SSI_SCR_SYS_CLK_EN     (1 << 7)
-#define SSI_SCR_I2S_MODE_NORM  (0 << 5)
-#define SSI_SCR_I2S_MODE_MSTR  (1 << 5)
-#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
-#define SSI_I2S_MODE_MASK      (3 << 5)
-#define SSI_SCR_SYN            (1 << 4)
-#define SSI_SCR_NET            (1 << 3)
-#define SSI_SCR_RE             (1 << 2)
-#define SSI_SCR_TE             (1 << 1)
-#define SSI_SCR_SSIEN          (1 << 0)
-
-#define SSI_SISR       0x14
-#define SSI_SISR_MASK          ((1 << 19) - 1)
-#define SSI_SISR_CMDAU         (1 << 18)
-#define SSI_SISR_CMDDU         (1 << 17)
-#define SSI_SISR_RXT           (1 << 16)
-#define SSI_SISR_RDR1          (1 << 15)
-#define SSI_SISR_RDR0          (1 << 14)
-#define SSI_SISR_TDE1          (1 << 13)
-#define SSI_SISR_TDE0          (1 << 12)
-#define SSI_SISR_ROE1          (1 << 11)
-#define SSI_SISR_ROE0          (1 << 10)
-#define SSI_SISR_TUE1          (1 << 9)
-#define SSI_SISR_TUE0          (1 << 8)
-#define SSI_SISR_TFS           (1 << 7)
-#define SSI_SISR_RFS           (1 << 6)
-#define SSI_SISR_TLS           (1 << 5)
-#define SSI_SISR_RLS           (1 << 4)
-#define SSI_SISR_RFF1          (1 << 3)
-#define SSI_SISR_RFF0          (1 << 2)
-#define SSI_SISR_TFE1          (1 << 1)
-#define SSI_SISR_TFE0          (1 << 0)
-
-#define SSI_SIER       0x18
-#define SSI_SIER_RDMAE         (1 << 22)
-#define SSI_SIER_RIE           (1 << 21)
-#define SSI_SIER_TDMAE         (1 << 20)
-#define SSI_SIER_TIE           (1 << 19)
-#define SSI_SIER_CMDAU_EN      (1 << 18)
-#define SSI_SIER_CMDDU_EN      (1 << 17)
-#define SSI_SIER_RXT_EN                (1 << 16)
-#define SSI_SIER_RDR1_EN       (1 << 15)
-#define SSI_SIER_RDR0_EN       (1 << 14)
-#define SSI_SIER_TDE1_EN       (1 << 13)
-#define SSI_SIER_TDE0_EN       (1 << 12)
-#define SSI_SIER_ROE1_EN       (1 << 11)
-#define SSI_SIER_ROE0_EN       (1 << 10)
-#define SSI_SIER_TUE1_EN       (1 << 9)
-#define SSI_SIER_TUE0_EN       (1 << 8)
-#define SSI_SIER_TFS_EN                (1 << 7)
-#define SSI_SIER_RFS_EN                (1 << 6)
-#define SSI_SIER_TLS_EN                (1 << 5)
-#define SSI_SIER_RLS_EN                (1 << 4)
-#define SSI_SIER_RFF1_EN       (1 << 3)
-#define SSI_SIER_RFF0_EN       (1 << 2)
-#define SSI_SIER_TFE1_EN       (1 << 1)
-#define SSI_SIER_TFE0_EN       (1 << 0)
-
-#define SSI_STCR       0x1c
-#define SSI_STCR_TXBIT0                (1 << 9)
-#define SSI_STCR_TFEN1         (1 << 8)
-#define SSI_STCR_TFEN0         (1 << 7)
-#define SSI_FIFO_ENABLE_0_SHIFT 7
-#define SSI_STCR_TFDIR         (1 << 6)
-#define SSI_STCR_TXDIR         (1 << 5)
-#define SSI_STCR_TSHFD         (1 << 4)
-#define SSI_STCR_TSCKP         (1 << 3)
-#define SSI_STCR_TFSI          (1 << 2)
-#define SSI_STCR_TFSL          (1 << 1)
-#define SSI_STCR_TEFS          (1 << 0)
-
-#define SSI_SRCR       0x20
-#define SSI_SRCR_RXBIT0                (1 << 9)
-#define SSI_SRCR_RFEN1         (1 << 8)
-#define SSI_SRCR_RFEN0         (1 << 7)
-#define SSI_FIFO_ENABLE_0_SHIFT 7
-#define SSI_SRCR_RFDIR         (1 << 6)
-#define SSI_SRCR_RXDIR         (1 << 5)
-#define SSI_SRCR_RSHFD         (1 << 4)
-#define SSI_SRCR_RSCKP         (1 << 3)
-#define SSI_SRCR_RFSI          (1 << 2)
-#define SSI_SRCR_RFSL          (1 << 1)
-#define SSI_SRCR_REFS          (1 << 0)
-
-#define SSI_SRCCR              0x28
-#define SSI_SRCCR_DIV2         (1 << 18)
-#define SSI_SRCCR_PSR          (1 << 17)
-#define SSI_SRCCR_WL(x)                ((((x) - 2) >> 1) << 13)
-#define SSI_SRCCR_DC(x)                (((x) & 0x1f) << 8)
-#define SSI_SRCCR_PM(x)                (((x) & 0xff) << 0)
-#define SSI_SRCCR_WL_MASK      (0xf << 13)
-#define SSI_SRCCR_DC_MASK      (0x1f << 8)
-#define SSI_SRCCR_PM_MASK      (0xff << 0)
-
-#define SSI_STCCR              0x24
-#define SSI_STCCR_DIV2         (1 << 18)
-#define SSI_STCCR_PSR          (1 << 17)
-#define SSI_STCCR_WL(x)                ((((x) - 2) >> 1) << 13)
-#define SSI_STCCR_DC(x)                (((x) & 0x1f) << 8)
-#define SSI_STCCR_PM(x)                (((x) & 0xff) << 0)
-#define SSI_STCCR_WL_MASK      (0xf << 13)
-#define SSI_STCCR_DC_MASK      (0x1f << 8)
-#define SSI_STCCR_PM_MASK      (0xff << 0)
-
-#define SSI_SFCSR      0x2c
-#define SSI_SFCSR_RFCNT1(x)    (((x) & 0xf) << 28)
-#define SSI_RX_FIFO_1_COUNT_SHIFT 28
-#define SSI_SFCSR_TFCNT1(x)    (((x) & 0xf) << 24)
-#define SSI_TX_FIFO_1_COUNT_SHIFT 24
-#define SSI_SFCSR_RFWM1(x)     (((x) & 0xf) << 20)
-#define SSI_SFCSR_TFWM1(x)     (((x) & 0xf) << 16)
-#define SSI_SFCSR_RFCNT0(x)    (((x) & 0xf) << 12)
-#define SSI_RX_FIFO_0_COUNT_SHIFT 12
-#define SSI_SFCSR_TFCNT0(x)    (((x) & 0xf) <<  8)
-#define SSI_TX_FIFO_0_COUNT_SHIFT 8
-#define SSI_SFCSR_RFWM0(x)     (((x) & 0xf) <<  4)
-#define SSI_SFCSR_TFWM0(x)     (((x) & 0xf) <<  0)
-#define SSI_SFCSR_RFWM0_MASK   (0xf <<  4)
-#define SSI_SFCSR_TFWM0_MASK   (0xf <<  0)
-
-#define SSI_STR                0x30
-#define SSI_STR_TEST           (1 << 15)
-#define SSI_STR_RCK2TCK                (1 << 14)
-#define SSI_STR_RFS2TFS                (1 << 13)
-#define SSI_STR_RXSTATE(x)     (((x) & 0xf) << 8)
-#define SSI_STR_TXD2RXD                (1 <<  7)
-#define SSI_STR_TCK2RCK                (1 <<  6)
-#define SSI_STR_TFS2RFS                (1 <<  5)
-#define SSI_STR_TXSTATE(x)     (((x) & 0xf) << 0)
-
-#define SSI_SOR                0x34
-#define SSI_SOR_CLKOFF         (1 << 6)
-#define SSI_SOR_RX_CLR         (1 << 5)
-#define SSI_SOR_TX_CLR         (1 << 4)
-#define SSI_SOR_INIT           (1 << 3)
-#define SSI_SOR_WAIT(x)                (((x) & 0x3) << 1)
-#define SSI_SOR_WAIT_MASK      (0x3 << 1)
-#define SSI_SOR_SYNRST         (1 << 0)
-
-#define SSI_SACNT      0x38
-#define SSI_SACNT_FRDIV(x)     (((x) & 0x3f) << 5)
-#define SSI_SACNT_WR           (1 << 4)
-#define SSI_SACNT_RD           (1 << 3)
-#define SSI_SACNT_TIF          (1 << 2)
-#define SSI_SACNT_FV           (1 << 1)
-#define SSI_SACNT_AC97EN       (1 << 0)
-
-#define SSI_SACADD     0x3c
-#define SSI_SACDAT     0x40
-#define SSI_SATAG      0x44
-#define SSI_STMSK      0x48
-#define SSI_SRMSK      0x4c
-#define SSI_SACCST     0x50
-#define SSI_SACCEN     0x54
-#define SSI_SACCDIS    0x58
-
-/* SSI clock sources */
-#define IMX_SSP_SYS_CLK                0
-
-/* SSI audio dividers */
-#define IMX_SSI_TX_DIV_2       0
-#define IMX_SSI_TX_DIV_PSR     1
-#define IMX_SSI_TX_DIV_PM      2
-#define IMX_SSI_RX_DIV_2       3
-#define IMX_SSI_RX_DIV_PSR     4
-#define IMX_SSI_RX_DIV_PM      5
-
-#define DRV_NAME "imx-ssi"
-
-#include <linux/dmaengine.h>
-#include <mach/dma.h>
-#include "imx-pcm.h"
-
-struct imx_ssi {
-       struct platform_device *ac97_dev;
-
-       struct snd_soc_dai *imx_ac97;
-       struct clk *clk;
-       void __iomem *base;
-       int irq;
-       int fiq_enable;
-       unsigned int offset;
-
-       unsigned int flags;
-
-       void (*ac97_reset) (struct snd_ac97 *ac97);
-       void (*ac97_warm_reset)(struct snd_ac97 *ac97);
-
-       struct imx_pcm_dma_params       dma_params_rx;
-       struct imx_pcm_dma_params       dma_params_tx;
-
-       int enabled;
-
-       struct platform_device *soc_platform_pdev;
-       struct platform_device *soc_platform_pdev_fiq;
-};
-
-#endif /* _IMX_SSI_H */
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
deleted file mode 100644 (file)
index f6d04ad..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * mx27vis-aic32x4.c
- *
- * Copyright 2011 Vista Silicon S.L.
- *
- * Author: Javier Martin <javier.martin@vista-silicon.com>
- *
- * 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/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/tlv.h>
-#include <asm/mach-types.h>
-#include <mach/iomux-mx27.h>
-
-#include "../codecs/tlv320aic32x4.h"
-#include "imx-ssi.h"
-#include "imx-audmux.h"
-
-#define MX27VIS_AMP_GAIN       0
-#define MX27VIS_AMP_MUTE       1
-
-#define MX27VIS_PIN_G0         (GPIO_PORTF + 9)
-#define MX27VIS_PIN_G1         (GPIO_PORTF + 8)
-#define MX27VIS_PIN_SDL                (GPIO_PORTE + 5)
-#define MX27VIS_PIN_SDR                (GPIO_PORTF + 7)
-
-static int mx27vis_amp_gain;
-static int mx27vis_amp_mute;
-
-static const int mx27vis_amp_pins[] = {
-       MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
-       MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
-       MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
-       MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
-};
-
-static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
-                           struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       int ret;
-       u32 dai_format;
-
-       dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
-               SND_SOC_DAIFMT_CBM_CFM;
-
-       /* set codec DAI configuration */
-       snd_soc_dai_set_fmt(codec_dai, dai_format);
-
-       /* set cpu DAI configuration */
-       snd_soc_dai_set_fmt(cpu_dai, dai_format);
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0,
-                                    25000000, SND_SOC_CLOCK_OUT);
-       if (ret) {
-               pr_err("%s: failed setting codec sysclk\n", __func__);
-               return ret;
-       }
-
-       ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
-                               SND_SOC_CLOCK_IN);
-       if (ret) {
-               pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
-       .hw_params      = mx27vis_aic32x4_hw_params,
-};
-
-static int mx27vis_amp_set(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-{
-       struct soc_mixer_control *mc =
-               (struct soc_mixer_control *)kcontrol->private_value;
-       int value = ucontrol->value.integer.value[0];
-       unsigned int reg = mc->reg;
-       int max = mc->max;
-
-       if (value > max)
-               return -EINVAL;
-
-       switch (reg) {
-       case MX27VIS_AMP_GAIN:
-               gpio_set_value(MX27VIS_PIN_G0, value & 1);
-               gpio_set_value(MX27VIS_PIN_G1, value >> 1);
-               mx27vis_amp_gain = value;
-               break;
-       case MX27VIS_AMP_MUTE:
-               gpio_set_value(MX27VIS_PIN_SDL, value & 1);
-               gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
-               mx27vis_amp_mute = value;
-               break;
-       }
-       return 0;
-}
-
-static int mx27vis_amp_get(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-{
-       struct soc_mixer_control *mc =
-               (struct soc_mixer_control *)kcontrol->private_value;
-       unsigned int reg = mc->reg;
-
-       switch (reg) {
-       case MX27VIS_AMP_GAIN:
-               ucontrol->value.integer.value[0] = mx27vis_amp_gain;
-               break;
-       case MX27VIS_AMP_MUTE:
-               ucontrol->value.integer.value[0] = mx27vis_amp_mute;
-               break;
-       }
-       return 0;
-}
-
-/* From 6dB to 24dB in steps of 6dB */
-static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0);
-
-static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = {
-       SOC_DAPM_PIN_SWITCH("External Mic"),
-       SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0,
-                      mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv),
-       SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0,
-                      mx27vis_amp_get, mx27vis_amp_set),
-};
-
-static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
-       SND_SOC_DAPM_MIC("External Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
-       {"Mic Bias", NULL, "External Mic"},
-       {"IN1_R", NULL, "Mic Bias"},
-       {"IN2_R", NULL, "Mic Bias"},
-       {"IN3_R", NULL, "Mic Bias"},
-       {"IN1_L", NULL, "Mic Bias"},
-       {"IN2_L", NULL, "Mic Bias"},
-       {"IN3_L", NULL, "Mic Bias"},
-};
-
-static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
-       .name           = "tlv320aic32x4",
-       .stream_name    = "TLV320AIC32X4",
-       .codec_dai_name = "tlv320aic32x4-hifi",
-       .platform_name  = "imx-pcm-audio.0",
-       .codec_name     = "tlv320aic32x4.0-0018",
-       .cpu_dai_name   = "imx-ssi.0",
-       .ops            = &mx27vis_aic32x4_snd_ops,
-};
-
-static struct snd_soc_card mx27vis_aic32x4 = {
-       .name           = "visstrim_m10-audio",
-       .owner          = THIS_MODULE,
-       .dai_link       = &mx27vis_aic32x4_dai,
-       .num_links      = 1,
-       .controls       = mx27vis_aic32x4_controls,
-       .num_controls   = ARRAY_SIZE(mx27vis_aic32x4_controls),
-       .dapm_widgets   = aic32x4_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
-       .dapm_routes    = aic32x4_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
-};
-
-static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
-{
-       int ret;
-
-       mx27vis_aic32x4.dev = &pdev->dev;
-       ret = snd_soc_register_card(&mx27vis_aic32x4);
-       if (ret) {
-               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
-                       ret);
-               return ret;
-       }
-
-       /* Connect SSI0 as clock slave to SSI1 external pins */
-       imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-                       IMX_AUDMUX_V1_PCR_SYN |
-                       IMX_AUDMUX_V1_PCR_TFSDIR |
-                       IMX_AUDMUX_V1_PCR_TCLKDIR |
-                       IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
-                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
-       );
-       imx_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
-                       IMX_AUDMUX_V1_PCR_SYN |
-                       IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
-       );
-
-       ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
-                       ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
-       if (ret)
-               printk(KERN_ERR "ASoC: unable to setup gpios\n");
-
-       return ret;
-}
-
-static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_card(&mx27vis_aic32x4);
-
-       return 0;
-}
-
-static struct platform_driver mx27vis_aic32x4_audio_driver = {
-       .driver = {
-               .name = "mx27vis",
-               .owner = THIS_MODULE,
-       },
-       .probe = mx27vis_aic32x4_probe,
-       .remove = __devexit_p(mx27vis_aic32x4_remove),
-};
-
-module_platform_driver(mx27vis_aic32x4_audio_driver);
-
-MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
-MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mx27vis");
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
deleted file mode 100644 (file)
index f8da6dd..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * phycore-ac97.c  --  SoC audio for imx_phycore in AC97 mode
- *
- * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- *  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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-types.h>
-
-#include "imx-audmux.h"
-
-static struct snd_soc_card imx_phycore;
-
-static struct snd_soc_ops imx_phycore_hifi_ops = {
-};
-
-static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
-       {
-               .name           = "HiFi",
-               .stream_name    = "HiFi",
-               .codec_dai_name         = "wm9712-hifi",
-               .codec_name     = "wm9712-codec",
-               .cpu_dai_name   = "imx-ssi.0",
-               .platform_name  = "imx-fiq-pcm-audio.0",
-               .ops            = &imx_phycore_hifi_ops,
-       },
-};
-
-static struct snd_soc_card imx_phycore = {
-       .name           = "PhyCORE-ac97-audio",
-       .owner          = THIS_MODULE,
-       .dai_link       = imx_phycore_dai_ac97,
-       .num_links      = ARRAY_SIZE(imx_phycore_dai_ac97),
-};
-
-static struct platform_device *imx_phycore_snd_ac97_device;
-static struct platform_device *imx_phycore_snd_device;
-
-static int __init imx_phycore_init(void)
-{
-       int ret;
-
-       if (machine_is_pca100()) {
-               imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-                       IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-                       IMX_AUDMUX_V1_PCR_TFCSEL(3) |
-                       IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
-                       IMX_AUDMUX_V1_PCR_RXDSEL(3));
-               imx_audmux_v1_configure_port(3,
-                       IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-                       IMX_AUDMUX_V1_PCR_TFCSEL(0) |
-                       IMX_AUDMUX_V1_PCR_TFSDIR |
-                       IMX_AUDMUX_V1_PCR_RXDSEL(0));
-       } else if (machine_is_pcm043()) {
-               imx_audmux_v2_configure_port(3,
-                       IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
-                       IMX_AUDMUX_V2_PTCR_TFSEL(0) |
-                       IMX_AUDMUX_V2_PTCR_TFSDIR,
-                       IMX_AUDMUX_V2_PDCR_RXDSEL(0));
-               imx_audmux_v2_configure_port(0,
-                       IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
-                       IMX_AUDMUX_V2_PTCR_TCSEL(3) |
-                       IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
-                       IMX_AUDMUX_V2_PDCR_RXDSEL(3));
-       } else {
-               /* return happy. We might run on a totally different machine */
-               return 0;
-       }
-
-       imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
-       if (!imx_phycore_snd_ac97_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
-       ret = platform_device_add(imx_phycore_snd_ac97_device);
-       if (ret)
-               goto fail1;
-
-       imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
-       if (!imx_phycore_snd_device) {
-               ret = -ENOMEM;
-               goto fail2;
-       }
-       ret = platform_device_add(imx_phycore_snd_device);
-
-       if (ret) {
-               printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-               goto fail3;
-       }
-
-       return 0;
-
-fail3:
-       platform_device_put(imx_phycore_snd_device);
-fail2:
-       platform_device_del(imx_phycore_snd_ac97_device);
-fail1:
-       platform_device_put(imx_phycore_snd_ac97_device);
-       return ret;
-}
-
-static void __exit imx_phycore_exit(void)
-{
-       platform_device_unregister(imx_phycore_snd_device);
-       platform_device_unregister(imx_phycore_snd_ac97_device);
-}
-
-late_initcall(imx_phycore_init);
-module_exit(imx_phycore_exit);
-
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
deleted file mode 100644 (file)
index fe54a69..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- *  wm1133-ev1.c - Audio for WM1133-EV1 on i.MX31ADS
- *
- *  Copyright (c) 2010 Wolfson Microelectronics plc
- *  Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *  Based on an earlier driver for the same hardware by Liam Girdwood.
- *
- *  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.
- */
-
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "imx-ssi.h"
-#include "../codecs/wm8350.h"
-#include "imx-audmux.h"
-
-/* There is a silicon mic on the board optionally connected via a solder pad
- * SP1.  Define this to enable it.
- */
-#undef USE_SIMIC
-
-struct _wm8350_audio {
-       unsigned int channels;
-       snd_pcm_format_t format;
-       unsigned int rate;
-       unsigned int sysclk;
-       unsigned int bclkdiv;
-       unsigned int clkdiv;
-       unsigned int lr_rate;
-};
-
-/* in order of power consumption per rate (lowest first) */
-static const struct _wm8350_audio wm8350_audio[] = {
-       /* 16bit mono modes */
-       {1, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000 >> 1,
-        WM8350_BCLK_DIV_48, WM8350_DACDIV_3, 16,},
-
-       /* 16 bit stereo modes */
-       {2, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000,
-        WM8350_BCLK_DIV_48, WM8350_DACDIV_6, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 16000, 12288000,
-        WM8350_BCLK_DIV_24, WM8350_DACDIV_3, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 32000, 12288000,
-        WM8350_BCLK_DIV_12, WM8350_DACDIV_1_5, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 48000, 12288000,
-        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 96000, 24576000,
-        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 11025, 11289600,
-        WM8350_BCLK_DIV_32, WM8350_DACDIV_4, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 22050, 11289600,
-        WM8350_BCLK_DIV_16, WM8350_DACDIV_2, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 44100, 11289600,
-        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
-       {2, SNDRV_PCM_FORMAT_S16_LE, 88200, 22579200,
-        WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
-
-       /* 24bit stereo modes */
-       {2, SNDRV_PCM_FORMAT_S24_LE, 48000, 12288000,
-        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
-       {2, SNDRV_PCM_FORMAT_S24_LE, 96000, 24576000,
-        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
-       {2, SNDRV_PCM_FORMAT_S24_LE, 44100, 11289600,
-        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
-       {2, SNDRV_PCM_FORMAT_S24_LE, 88200, 22579200,
-        WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
-};
-
-static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       int i, found = 0;
-       snd_pcm_format_t format = params_format(params);
-       unsigned int rate = params_rate(params);
-       unsigned int channels = params_channels(params);
-       u32 dai_format;
-
-       /* find the correct audio parameters */
-       for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) {
-               if (rate == wm8350_audio[i].rate &&
-                   format == wm8350_audio[i].format &&
-                   channels == wm8350_audio[i].channels) {
-                       found = 1;
-                       break;
-               }
-       }
-       if (!found)
-               return -EINVAL;
-
-       /* codec FLL input is 14.75 MHz from MCLK */
-       snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk);
-
-       dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-               SND_SOC_DAIFMT_CBM_CFM;
-
-       /* set codec DAI configuration */
-       snd_soc_dai_set_fmt(codec_dai, dai_format);
-
-       /* set cpu DAI configuration */
-       snd_soc_dai_set_fmt(cpu_dai, dai_format);
-
-       /* TODO: The SSI driver should figure this out for us */
-       switch (channels) {
-       case 2:
-               snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
-               break;
-       case 1:
-               snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffe, 0xffffffe, 1, 0);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* set MCLK as the codec system clock for DAC and ADC */
-       snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_MCLK,
-                              wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
-
-       /* set codec BCLK division for sample rate */
-       snd_soc_dai_set_clkdiv(codec_dai, WM8350_BCLK_CLKDIV,
-                              wm8350_audio[i].bclkdiv);
-
-       /* DAI is synchronous and clocked with DAC LRCLK & ADC LRC */
-       snd_soc_dai_set_clkdiv(codec_dai,
-                              WM8350_DACLR_CLKDIV, wm8350_audio[i].lr_rate);
-       snd_soc_dai_set_clkdiv(codec_dai,
-                              WM8350_ADCLR_CLKDIV, wm8350_audio[i].lr_rate);
-
-       /* now configure DAC and ADC clocks */
-       snd_soc_dai_set_clkdiv(codec_dai,
-                              WM8350_DAC_CLKDIV, wm8350_audio[i].clkdiv);
-
-       snd_soc_dai_set_clkdiv(codec_dai,
-                              WM8350_ADC_CLKDIV, wm8350_audio[i].clkdiv);
-
-       return 0;
-}
-
-static struct snd_soc_ops wm1133_ev1_ops = {
-       .hw_params = wm1133_ev1_hw_params,
-};
-
-static const struct snd_soc_dapm_widget wm1133_ev1_widgets[] = {
-#ifdef USE_SIMIC
-       SND_SOC_DAPM_MIC("SiMIC", NULL),
-#endif
-       SND_SOC_DAPM_MIC("Mic1 Jack", NULL),
-       SND_SOC_DAPM_MIC("Mic2 Jack", NULL),
-       SND_SOC_DAPM_LINE("Line In Jack", NULL),
-       SND_SOC_DAPM_LINE("Line Out Jack", NULL),
-       SND_SOC_DAPM_HP("Headphone Jack", NULL),
-};
-
-/* imx32ads soc_card audio map */
-static const struct snd_soc_dapm_route wm1133_ev1_map[] = {
-
-#ifdef USE_SIMIC
-       /* SiMIC --> IN1LN (with automatic bias) via SP1 */
-       { "IN1LN", NULL, "Mic Bias" },
-       { "Mic Bias", NULL, "SiMIC" },
-#endif
-
-       /* Mic 1 Jack --> IN1LN and IN1LP (with automatic bias) */
-       { "IN1LN", NULL, "Mic Bias" },
-       { "IN1LP", NULL, "Mic1 Jack" },
-       { "Mic Bias", NULL, "Mic1 Jack" },
-
-       /* Mic 2 Jack --> IN1RN and IN1RP (with automatic bias) */
-       { "IN1RN", NULL, "Mic Bias" },
-       { "IN1RP", NULL, "Mic2 Jack" },
-       { "Mic Bias", NULL, "Mic2 Jack" },
-
-       /* Line in Jack --> AUX (L+R) */
-       { "IN3R", NULL, "Line In Jack" },
-       { "IN3L", NULL, "Line In Jack" },
-
-       /* Out1 --> Headphone Jack */
-       { "Headphone Jack", NULL, "OUT1R" },
-       { "Headphone Jack", NULL, "OUT1L" },
-
-       /* Out1 --> Line Out Jack */
-       { "Line Out Jack", NULL, "OUT2R" },
-       { "Line Out Jack", NULL, "OUT2L" },
-};
-
-static struct snd_soc_jack hp_jack;
-
-static struct snd_soc_jack_pin hp_jack_pins[] = {
-       { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE },
-};
-
-static struct snd_soc_jack mic_jack;
-
-static struct snd_soc_jack_pin mic_jack_pins[] = {
-       { .pin = "Mic1 Jack", .mask = SND_JACK_MICROPHONE },
-       { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
-};
-
-static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
-                                 ARRAY_SIZE(wm1133_ev1_widgets));
-
-       snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
-                               ARRAY_SIZE(wm1133_ev1_map));
-
-       /* Headphone jack detection */
-       snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
-       snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
-                             hp_jack_pins);
-       wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
-
-       /* Microphone jack detection */
-       snd_soc_jack_new(codec, "Microphone",
-                        SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
-       snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
-                             mic_jack_pins);
-       wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
-                              SND_JACK_BTN_0);
-
-       snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
-
-       return 0;
-}
-
-
-static struct snd_soc_dai_link wm1133_ev1_dai = {
-       .name = "WM1133-EV1",
-       .stream_name = "Audio",
-       .cpu_dai_name = "imx-ssi.0",
-       .codec_dai_name = "wm8350-hifi",
-       .platform_name = "imx-fiq-pcm-audio.0",
-       .codec_name = "wm8350-codec.0-0x1a",
-       .init = wm1133_ev1_init,
-       .ops = &wm1133_ev1_ops,
-       .symmetric_rates = 1,
-};
-
-static struct snd_soc_card wm1133_ev1 = {
-       .name = "WM1133-EV1",
-       .owner = THIS_MODULE,
-       .dai_link = &wm1133_ev1_dai,
-       .num_links = 1,
-};
-
-static struct platform_device *wm1133_ev1_snd_device;
-
-static int __init wm1133_ev1_audio_init(void)
-{
-       int ret;
-       unsigned int ptcr, pdcr;
-
-       /* SSI0 mastered by port 5 */
-       ptcr = IMX_AUDMUX_V2_PTCR_SYN |
-               IMX_AUDMUX_V2_PTCR_TFSDIR |
-               IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
-               IMX_AUDMUX_V2_PTCR_TCLKDIR |
-               IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
-       pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
-       imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
-
-       ptcr = IMX_AUDMUX_V2_PTCR_SYN;
-       pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
-       imx_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
-
-       wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!wm1133_ev1_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1);
-       ret = platform_device_add(wm1133_ev1_snd_device);
-
-       if (ret)
-               platform_device_put(wm1133_ev1_snd_device);
-
-       return ret;
-}
-module_init(wm1133_ev1_audio_init);
-
-static void __exit wm1133_ev1_audio_exit(void)
-{
-       platform_device_unregister(wm1133_ev1_snd_device);
-}
-module_exit(wm1133_ev1_audio_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("Audio for WM1133-EV1 on i.MX31ADS");
-MODULE_LICENSE("GPL");