Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound...
authorTakashi Iwai <tiwai@suse.de>
Tue, 6 Mar 2012 13:04:16 +0000 (14:04 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 6 Mar 2012 13:04:16 +0000 (14:04 +0100)
A few more ASoC updates, the main one is the move of the audmux driver
from arch/arm into sound/soc.  There's also some general driver specific
tweaks and fixes.

36 files changed:
Documentation/devicetree/bindings/sound/imx-audmux.txt [new file with mode: 0644]
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
arch/arm/mach-imx/eukrea_mbimxsd-baseboard.c
arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
arch/arm/mach-imx/mach-pca100.c
arch/arm/mach-imx/mach-pcm043.c
arch/arm/mach-imx/mm-imx21.c
arch/arm/mach-imx/mm-imx25.c
arch/arm/mach-imx/mm-imx27.c
arch/arm/mach-imx/mm-imx3.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/plat-mxc/Kconfig
arch/arm/plat-mxc/Makefile
arch/arm/plat-mxc/audmux-v1.c [deleted file]
arch/arm/plat-mxc/audmux-v2.c [deleted file]
arch/arm/plat-mxc/include/mach/audmux.h [deleted file]
sound/soc/codecs/wm8804.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8994.h
sound/soc/imx/Kconfig
sound/soc/imx/Makefile
sound/soc/imx/eukrea-tlv320.c
sound/soc/imx/imx-audmux.c [new file with mode: 0644]
sound/soc/imx/imx-audmux.h [new file with mode: 0644]
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-pcm.c [new file with mode: 0644]
sound/soc/imx/imx-pcm.h [new file with mode: 0644]
sound/soc/imx/imx-ssi.c
sound/soc/imx/imx-ssi.h
sound/soc/imx/mx27vis-aic32x4.c
sound/soc/imx/phycore-ac97.c
sound/soc/imx/wm1133-ev1.c
sound/soc/soc-dapm.c

diff --git a/Documentation/devicetree/bindings/sound/imx-audmux.txt b/Documentation/devicetree/bindings/sound/imx-audmux.txt
new file mode 100644 (file)
index 0000000..215aa98
--- /dev/null
@@ -0,0 +1,13 @@
+Freescale Digital Audio Mux (AUDMUX) device
+
+Required properties:
+- compatible : "fsl,imx21-audmux" for AUDMUX version firstly used on i.MX21,
+  or "fsl,imx31-audmux" for the version firstly used on i.MX31.
+- reg : Should contain AUDMUX registers location and length
+
+Example:
+
+audmux@021d8000 {
+       compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
+       reg = <0x021d8000 0x4000>;
+};
index 4defb97bbfc866400fe57fe4c5178a778c30a91f..3919fba52ac80c30196eb1abe5bc152b7edd0f0b 100644 (file)
@@ -46,7 +46,6 @@ config SOC_IMX21
        bool
        select MACH_MX21
        select CPU_ARM926T
-       select ARCH_MXC_AUDMUX_V1
        select IMX_HAVE_DMA_V1
        select IMX_HAVE_IOMUX_V1
        select MXC_AVIC
@@ -55,7 +54,6 @@ config SOC_IMX25
        bool
        select ARCH_MX25
        select CPU_ARM926T
-       select ARCH_MXC_AUDMUX_V2
        select ARCH_MXC_IOMUX_V3
        select MXC_AVIC
 
@@ -63,7 +61,6 @@ config SOC_IMX27
        bool
        select MACH_MX27
        select CPU_ARM926T
-       select ARCH_MXC_AUDMUX_V1
        select IMX_HAVE_DMA_V1
        select IMX_HAVE_IOMUX_V1
        select MXC_AVIC
@@ -72,7 +69,6 @@ config SOC_IMX31
        bool
        select CPU_V6
        select IMX_HAVE_PLATFORM_MXC_RNGA
-       select ARCH_MXC_AUDMUX_V2
        select MXC_AVIC
        select SMP_ON_UP if SMP
 
@@ -80,7 +76,6 @@ config SOC_IMX35
        bool
        select CPU_V6
        select ARCH_MXC_IOMUX_V3
-       select ARCH_MXC_AUDMUX_V2
        select HAVE_EPIT
        select MXC_AVIC
        select SMP_ON_UP if SMP
@@ -89,7 +84,6 @@ config SOC_IMX5
        select CPU_V7
        select MXC_TZIC
        select ARCH_MXC_IOMUX_V3
-       select ARCH_MXC_AUDMUX_V2
        select ARCH_HAS_CPUFREQ
        select ARCH_MX5
        bool
index 5db3e1463af7714bff06e8b17f526804148e89b0..5f2f91d1798b6470e2ef9ab5fd88ca22deadafcd 100644 (file)
@@ -32,7 +32,6 @@
 #include <mach/common.h>
 #include <mach/iomux-mx27.h>
 #include <mach/hardware.h>
-#include <mach/audmux.h>
 
 #include "devices-imx27.h"
 
@@ -306,25 +305,6 @@ void __init eukrea_mbimx27_baseboard_init(void)
        mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
                ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
 
-#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
-       || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
-       /* SSI unit master I2S codec connected to SSI_PINS_4*/
-       mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-                       MXC_AUDMUX_V1_PCR_SYN |
-                       MXC_AUDMUX_V1_PCR_TFSDIR |
-                       MXC_AUDMUX_V1_PCR_TCLKDIR |
-                       MXC_AUDMUX_V1_PCR_RFSDIR |
-                       MXC_AUDMUX_V1_PCR_RCLKDIR |
-                       MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
-                       MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
-                       MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
-       );
-       mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
-                       MXC_AUDMUX_V1_PCR_SYN |
-                       MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
-       );
-#endif
-
        imx27_add_imx_uart1(&uart_pdata);
        imx27_add_imx_uart2(&uart_pdata);
 #if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
index d817fc80b986c8231da7df66dea5231f6211f4b5..aaa592fdb9ce38b84e70985a9e1496cae0c9496b 100644 (file)
@@ -37,7 +37,6 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-mx51.h>
-#include <mach/audmux.h>
 
 #include "devices-imx51.h"
 
index 66e8726253faa5370dd23443110b472b7671ba13..2cf603e11c4f36786f06299b00cc8ffd9e7f4125 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/mx25.h>
-#include <mach/audmux.h>
 
 #include "devices-imx25.h"
 
@@ -241,22 +240,6 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
                        ARRAY_SIZE(eukrea_mbimxsd_pads)))
                printk(KERN_ERR "error setting mbimxsd pads !\n");
 
-#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
-       /* SSI unit master I2S codec connected to SSI_AUD5*/
-       mxc_audmux_v2_configure_port(0,
-                       MXC_AUDMUX_V2_PTCR_SYN |
-                       MXC_AUDMUX_V2_PTCR_TFSDIR |
-                       MXC_AUDMUX_V2_PTCR_TFSEL(4) |
-                       MXC_AUDMUX_V2_PTCR_TCLKDIR |
-                       MXC_AUDMUX_V2_PTCR_TCSEL(4),
-                       MXC_AUDMUX_V2_PDCR_RXDSEL(4)
-       );
-       mxc_audmux_v2_configure_port(4,
-                       MXC_AUDMUX_V2_PTCR_SYN,
-                       MXC_AUDMUX_V2_PDCR_RXDSEL(0)
-       );
-#endif
-
        imx25_add_imx_uart1(&uart_pdata);
        imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
        imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
index 0f0af02b31821528185ff69401784a76c9e0efe6..fd8bf8a425a7a49c0daa7f90bb185c22f2ba2e7c 100644 (file)
@@ -38,7 +38,6 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-mx35.h>
-#include <mach/audmux.h>
 
 #include "devices-imx35.h"
 
@@ -252,22 +251,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
                        ARRAY_SIZE(eukrea_mbimxsd_pads)))
                printk(KERN_ERR "error setting mbimxsd pads !\n");
 
-#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
-       /* SSI unit master I2S codec connected to SSI_AUD4 */
-       mxc_audmux_v2_configure_port(0,
-                       MXC_AUDMUX_V2_PTCR_SYN |
-                       MXC_AUDMUX_V2_PTCR_TFSDIR |
-                       MXC_AUDMUX_V2_PTCR_TFSEL(3) |
-                       MXC_AUDMUX_V2_PTCR_TCLKDIR |
-                       MXC_AUDMUX_V2_PTCR_TCSEL(3),
-                       MXC_AUDMUX_V2_PDCR_RXDSEL(3)
-       );
-       mxc_audmux_v2_configure_port(3,
-                       MXC_AUDMUX_V2_PTCR_SYN,
-                       MXC_AUDMUX_V2_PDCR_RXDSEL(0)
-       );
-#endif
-
        imx35_add_imx_uart1(&uart_pdata);
        imx35_add_ipu_core(&mx3_ipu_data);
        imx35_add_mx3_sdc_fb(&mx3fb_pdata);
index d3b9c6b5edde091d56f3196be79a5cf245410137..541152e450c420bbf2cd65ca6061bee935957191 100644 (file)
@@ -36,7 +36,6 @@
 #include <mach/hardware.h>
 #include <mach/iomux-mx27.h>
 #include <asm/mach/time.h>
-#include <mach/audmux.h>
 #include <mach/irqs.h>
 #include <mach/ulpi.h>
 
@@ -359,18 +358,6 @@ static void __init pca100_init(void)
 
        imx27_soc_init();
 
-       /* SSI unit */
-       mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-                                 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-                                 MXC_AUDMUX_V1_PCR_TFCSEL(3) |
-                                 MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
-                                 MXC_AUDMUX_V1_PCR_RXDSEL(3));
-       mxc_audmux_v1_configure_port(3,
-                                 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-                                 MXC_AUDMUX_V1_PCR_TFCSEL(0) |
-                                 MXC_AUDMUX_V1_PCR_TFSDIR |
-                                 MXC_AUDMUX_V1_PCR_RXDSEL(0));
-
        ret = mxc_gpio_setup_multiple_pins(pca100_pins,
                        ARRAY_SIZE(pca100_pins), "PCA100");
        if (ret)
index 06dc106519aec6f8826b1589b3c765cad148bfc5..237474fcca23eb352bacc211d1173fd7f21d0ac7 100644 (file)
@@ -37,7 +37,6 @@
 #include <mach/common.h>
 #include <mach/iomux-mx35.h>
 #include <mach/ulpi.h>
-#include <mach/audmux.h>
 
 #include "devices-imx35.h"
 
@@ -362,18 +361,6 @@ static void __init pcm043_init(void)
 
        mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
 
-       mxc_audmux_v2_configure_port(3,
-                       MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
-                       MXC_AUDMUX_V2_PTCR_TFSEL(0) |
-                       MXC_AUDMUX_V2_PTCR_TFSDIR,
-                       MXC_AUDMUX_V2_PDCR_RXDSEL(0));
-
-       mxc_audmux_v2_configure_port(0,
-                       MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
-                       MXC_AUDMUX_V2_PTCR_TCSEL(3) |
-                       MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
-                       MXC_AUDMUX_V2_PDCR_RXDSEL(3));
-
        imx35_add_fec(NULL);
        platform_add_devices(devices, ARRAY_SIZE(devices));
        imx35_add_imx2_wdt(NULL);
index 3f05dfebacc9f7c2bb7df18c0646b7a775100097..14d540edfd1e6d9817ecf0f624de8d710b6dfa4d 100644 (file)
@@ -75,6 +75,10 @@ void __init mx21_init_irq(void)
        mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
 }
 
+static const struct resource imx21_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX21_AUDMUX_BASE_ADDR, SZ_4K),
+};
+
 void __init imx21_soc_init(void)
 {
        mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
@@ -85,4 +89,6 @@ void __init imx21_soc_init(void)
        mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 
        imx_add_imx_dma();
+       platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
+                                       ARRAY_SIZE(imx21_audmux_res));
 }
index cc4d152bd9bd9342d1c0ff53e6b9cfd0a52c9a90..153b457acdc02db153b520540093860dd768df14 100644 (file)
@@ -83,6 +83,10 @@ static struct sdma_platform_data imx25_sdma_pdata __initdata = {
        .script_addrs = &imx25_sdma_script,
 };
 
+static const struct resource imx25_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX25_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx25_soc_init(void)
 {
        /* i.mx25 has the i.mx31 type gpio */
@@ -93,4 +97,7 @@ void __init imx25_soc_init(void)
 
        /* i.mx25 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
+       /* i.mx25 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx25_audmux_res,
+                                       ARRAY_SIZE(imx25_audmux_res));
 }
index 96dd1f5ea7bddc32d8745b7447b56cf20402640e..8cb3f5e3e56901b04228408407f2d7ecb34bee7d 100644 (file)
@@ -75,6 +75,10 @@ void __init mx27_init_irq(void)
        mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
 }
 
+static const struct resource imx27_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX27_AUDMUX_BASE_ADDR, SZ_4K),
+};
+
 void __init imx27_soc_init(void)
 {
        /* i.mx27 has the i.mx21 type gpio */
@@ -86,4 +90,7 @@ void __init imx27_soc_init(void)
        mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
 
        imx_add_imx_dma();
+       /* imx27 has the imx21 type audmux */
+       platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
+                                       ARRAY_SIZE(imx27_audmux_res));
 }
index 31807d2a8b7bf1a65d57c8f4cb748bb9e6697934..2530c151b7b3d5aa50a1731c9ceaf1a3cc949ab8 100644 (file)
@@ -158,6 +158,10 @@ static struct sdma_platform_data imx31_sdma_pdata __initdata = {
        .script_addrs = &imx31_to2_sdma_script,
 };
 
+static const struct resource imx31_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX31_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx31_soc_init(void)
 {
        int to_version = mx31_revision() >> 4;
@@ -175,6 +179,8 @@ void __init imx31_soc_init(void)
        }
 
        imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
+       platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
+                                       ARRAY_SIZE(imx31_audmux_res));
 }
 #endif /* ifdef CONFIG_SOC_IMX31 */
 
@@ -241,6 +247,10 @@ static struct sdma_platform_data imx35_sdma_pdata __initdata = {
        .script_addrs = &imx35_to2_sdma_script,
 };
 
+static const struct resource imx35_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX35_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx35_soc_init(void)
 {
        int to_version = mx35_revision() >> 4;
@@ -259,5 +269,8 @@ void __init imx35_soc_init(void)
        }
 
        imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
+       /* i.mx35 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res,
+                                       ARRAY_SIZE(imx35_audmux_res));
 }
 #endif /* ifdef CONFIG_SOC_IMX35 */
index bc17dfea38170872c24216165715e8af60144feb..90d7880bb372a95a7ae5b0f57f897311215dbaf8 100644 (file)
@@ -170,6 +170,18 @@ static struct sdma_platform_data imx53_sdma_pdata __initdata = {
        .script_addrs = &imx53_sdma_script,
 };
 
+static const struct resource imx50_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX50_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
+static const struct resource imx51_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX51_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
+static const struct resource imx53_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX53_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx50_soc_init(void)
 {
        /* i.mx50 has the i.mx31 type gpio */
@@ -179,6 +191,10 @@ void __init imx50_soc_init(void)
        mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
        mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
        mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+
+       /* i.mx50 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
+                                       ARRAY_SIZE(imx50_audmux_res));
 }
 
 void __init imx51_soc_init(void)
@@ -191,6 +207,9 @@ void __init imx51_soc_init(void)
 
        /* i.mx51 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
+       /* i.mx51 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res,
+                                       ARRAY_SIZE(imx51_audmux_res));
 }
 
 void __init imx53_soc_init(void)
@@ -206,4 +225,7 @@ void __init imx53_soc_init(void)
 
        /* i.mx53 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
+       /* i.mx53 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
+                                       ARRAY_SIZE(imx53_audmux_res));
 }
index dcebb1230f7fd3cd6f6e492c97507a483dcef3b8..c722f9ce691827e8924674119b75708ba7ea6428 100644 (file)
@@ -88,12 +88,6 @@ config IMX_HAVE_IOMUX_V1
 config ARCH_MXC_IOMUX_V3
        bool
 
-config ARCH_MXC_AUDMUX_V1
-       bool
-
-config ARCH_MXC_AUDMUX_V2
-       bool
-
 config IRAM_ALLOC
        bool
        select GENERIC_ALLOCATOR
index 076db84f3e3183a47096cded0ac90abf50aa23b4..e81290c27c655bdf4ab5f4d58a61ee41cc8013e9 100644 (file)
@@ -14,8 +14,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
 obj-$(CONFIG_MXC_PWM)  += pwm.o
 obj-$(CONFIG_MXC_ULPI) += ulpi.o
 obj-$(CONFIG_MXC_USE_EPIT) += epit.o
-obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
-obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpufreq.o
 ifdef CONFIG_SND_IMX_SOC
diff --git a/arch/arm/plat-mxc/audmux-v1.c b/arch/arm/plat-mxc/audmux-v1.c
deleted file mode 100644 (file)
index 1180bef..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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/module.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <mach/audmux.h>
-#include <mach/hardware.h>
-
-static void __iomem *audmux_base;
-
-static unsigned char port_mapping[] = {
-       0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
-};
-
-int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
-{
-       if (!audmux_base) {
-               printk("%s: not configured\n", __func__);
-               return -ENOSYS;
-       }
-
-       if (port >= ARRAY_SIZE(port_mapping))
-               return -EINVAL;
-
-       writel(pcr, audmux_base + port_mapping[port]);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
-
-static int mxc_audmux_v1_init(void)
-{
-#ifdef CONFIG_MACH_MX21
-       if (cpu_is_mx21())
-               audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
-       else
-#endif
-#ifdef CONFIG_MACH_MX27
-       if (cpu_is_mx27())
-               audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
-       else
-#endif
-               (void)0;
-       
-       return 0;
-}
-
-postcore_initcall(mxc_audmux_v1_init);
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
deleted file mode 100644 (file)
index 8cced35..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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/module.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <mach/audmux.h>
-#include <mach/hardware.h>
-
-static struct clk *audmux_clk;
-static void __iomem *audmux_base;
-
-#define MXC_AUDMUX_V2_PTCR(x)          ((x) * 8)
-#define MXC_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_enable(audmux_clk);
-
-       ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
-       pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
-
-       if (audmux_clk)
-               clk_disable(audmux_clk);
-
-       ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
-                      pdcr, ptcr);
-
-       if (ptcr & MXC_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 & MXC_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 & MXC_AUDMUX_V2_PTCR_SYN) {
-               ret += snprintf(buf + ret, PAGE_SIZE - ret,
-                               "Port is symmetric");
-       } else {
-               if (ptcr & MXC_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 & MXC_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 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);
-       }
-}
-#else
-static inline void audmux_debugfs_init(void)
-{
-}
-#endif
-
-int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
-               unsigned int pdcr)
-{
-       if (!audmux_base)
-               return -ENOSYS;
-
-       if (audmux_clk)
-               clk_enable(audmux_clk);
-
-       writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
-       writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
-
-       if (audmux_clk)
-               clk_disable(audmux_clk);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port);
-
-static int mxc_audmux_v2_init(void)
-{
-       int ret;
-       if (cpu_is_mx51()) {
-               audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx31()) {
-               audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx35()) {
-               audmux_clk = clk_get(NULL, "audmux");
-               if (IS_ERR(audmux_clk)) {
-                       ret = PTR_ERR(audmux_clk);
-                       printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
-                                       ret);
-                       return ret;
-               }
-               audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx25()) {
-               audmux_clk = clk_get(NULL, "audmux");
-               if (IS_ERR(audmux_clk)) {
-                       ret = PTR_ERR(audmux_clk);
-                       printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
-                                       ret);
-                       return ret;
-               }
-               audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
-       }
-
-       audmux_debugfs_init();
-
-       return 0;
-}
-
-postcore_initcall(mxc_audmux_v2_init);
diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h
deleted file mode 100644 (file)
index 6fda788..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __MACH_AUDMUX_H
-#define __MACH_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 MXC_AUDMUX_V1_PCR_INMMASK(x)   ((x) & 0xff)
-#define MXC_AUDMUX_V1_PCR_INMEN                (1 << 8)
-#define MXC_AUDMUX_V1_PCR_TXRXEN       (1 << 10)
-#define MXC_AUDMUX_V1_PCR_SYN          (1 << 12)
-#define MXC_AUDMUX_V1_PCR_RXDSEL(x)    (((x) & 0x7) << 13)
-#define MXC_AUDMUX_V1_PCR_RFCSEL(x)    (((x) & 0xf) << 20)
-#define MXC_AUDMUX_V1_PCR_RCLKDIR      (1 << 24)
-#define MXC_AUDMUX_V1_PCR_RFSDIR       (1 << 25)
-#define MXC_AUDMUX_V1_PCR_TFCSEL(x)    (((x) & 0xf) << 26)
-#define MXC_AUDMUX_V1_PCR_TCLKDIR      (1 << 30)
-#define MXC_AUDMUX_V1_PCR_TFSDIR       (1 << 31)
-
-/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
-#define MXC_AUDMUX_V2_PTCR_TFSDIR      (1 << 31)
-#define MXC_AUDMUX_V2_PTCR_TFSEL(x)    (((x) & 0xf) << 27)
-#define MXC_AUDMUX_V2_PTCR_TCLKDIR     (1 << 26)
-#define MXC_AUDMUX_V2_PTCR_TCSEL(x)    (((x) & 0xf) << 22)
-#define MXC_AUDMUX_V2_PTCR_RFSDIR      (1 << 21)
-#define MXC_AUDMUX_V2_PTCR_RFSEL(x)    (((x) & 0xf) << 17)
-#define MXC_AUDMUX_V2_PTCR_RCLKDIR     (1 << 16)
-#define MXC_AUDMUX_V2_PTCR_RCSEL(x)    (((x) & 0xf) << 12)
-#define MXC_AUDMUX_V2_PTCR_SYN         (1 << 11)
-
-#define MXC_AUDMUX_V2_PDCR_RXDSEL(x)   (((x) & 0x7) << 13)
-#define MXC_AUDMUX_V2_PDCR_TXRXEN      (1 << 12)
-#define MXC_AUDMUX_V2_PDCR_MODE(x)     (((x) & 0x3) << 8)
-#define MXC_AUDMUX_V2_PDCR_INMMASK(x)  ((x) & 0xff)
-
-int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
-
-int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
-               unsigned int pdcr);
-
-#endif /* __MACH_AUDMUX_H */
index 7ee8dcf1fe32c7e7848cf3d2f4fde78f7f668c7e..6bd1b767b138881eecb66451d9b468309b650d29 100644 (file)
@@ -755,6 +755,12 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
        if (!wm8804)
                return -ENOMEM;
 
+       wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config);
+       if (IS_ERR(wm8804->regmap)) {
+               ret = PTR_ERR(wm8804->regmap);
+               return ret;
+       }
+
        i2c_set_clientdata(i2c, wm8804);
 
        ret = snd_soc_register_codec(&i2c->dev,
index 445d2090661cea83d7b2fc780cc39fcf861e5956..5bcb350bacc1db320afef47680fb92c17ae0596a 100644 (file)
@@ -116,11 +116,11 @@ static struct reg_default wm8962_reg[] = {
        { 1, 0x049F },   /* R1     - Right Input volume */
        { 2, 0x0000 },   /* R2     - HPOUTL volume */
        { 3, 0x0000 },   /* R3     - HPOUTR volume */
-       { 4, 0x0020 },   /* R4     - Clocking1 */
+
        { 5, 0x0018 },   /* R5     - ADC & DAC Control 1 */
        { 6, 0x2008 },   /* R6     - ADC & DAC Control 2 */
        { 7, 0x000A },   /* R7     - Audio Interface 0 */
-       { 8, 0x01E4 },   /* R8     - Clocking2 */
+
        { 9, 0x0300 },   /* R9     - Audio Interface 1 */
        { 10, 0x00C0 },  /* R10    - Left DAC volume */
        { 11, 0x00C0 },  /* R11    - Right DAC volume */
@@ -129,7 +129,7 @@ static struct reg_default wm8962_reg[] = {
        { 15, 0x6243 },   /* R15    - Software Reset */
 
        { 17, 0x007B },   /* R17    - ALC1 */
-       { 18, 0x0000 },   /* R18    - ALC2 */
+
        { 19, 0x1C32 },   /* R19    - ALC3 */
        { 20, 0x3200 },   /* R20    - Noise Gate */
        { 21, 0x00C0 },   /* R21    - Left ADC volume */
@@ -153,10 +153,6 @@ static struct reg_default wm8962_reg[] = {
        { 40, 0x0000 },   /* R40    - SPKOUTL volume */
        { 41, 0x0000 },   /* R41    - SPKOUTR volume */
 
-       { 47, 0x0000 },   /* R47    - Thermal Shutdown Status */
-       { 48, 0x8027 },   /* R48    - Additional Control (4) */
-       { 49, 0x0010 },   /* R49    - Class D Control 1 */
-
        { 51, 0x0003 },   /* R51    - Class D Control 2 */
 
        { 56, 0x0506 },   /* R56    - Clocking 4 */
@@ -168,8 +164,6 @@ static struct reg_default wm8962_reg[] = {
 
        { 64, 0x0810 },   /* R64    - DC Servo 4 */
 
-       { 66, 0x0000 },   /* R66    - DC Servo 6 */
-
        { 68, 0x001B },   /* R68    - Analogue PGA Bias */
        { 69, 0x0000 },   /* R69    - Analogue HP 0 */
 
@@ -302,9 +296,6 @@ static struct reg_default wm8962_reg[] = {
        { 516, 0x8100 },   /* R516   - GPIO 5 */
        { 517, 0x8100 },   /* R517   - GPIO 6 */
 
-       { 560, 0x0000 },   /* R560   - Interrupt Status 1 */
-       { 561, 0x0000 },   /* R561   - Interrupt Status 2 */
-
        { 568, 0x0030 },   /* R568   - Interrupt Status 1 Mask */
        { 569, 0xFFED },   /* R569   - Interrupt Status 2 Mask */
 
@@ -316,8 +307,6 @@ static struct reg_default wm8962_reg[] = {
 
        { 768, 0x1C00 },   /* R768   - DSP2 Power Management */
 
-       { 1037, 0x0000 },   /* R1037  - DSP2_ExecControl */
-
        { 8192, 0x0000 },   /* R8192  - DSP2 Instruction RAM 0 */
 
        { 9216, 0x0030 },   /* R9216  - DSP2 Address RAM 2 */
@@ -3673,7 +3662,6 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
                                ret);
        }
 
-       pm_runtime_set_active(&i2c->dev);
        pm_runtime_enable(&i2c->dev);
        pm_request_idle(&i2c->dev);
 
index 2417ef9316ed70a92b29e350f26dd44e85b8a028..bc12d097ef0dbbc5b383d04970eaba80792e1bae 100644 (file)
@@ -685,8 +685,6 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
 static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-       u16 old = snd_soc_read(codec, WM8994_ANTIPOP_2)
-               & WM1811_JACKDET_MODE_MASK;
 
        if (!wm8994->jackdet || !wm8994->jack_cb)
                return;
@@ -694,28 +692,17 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
        if (wm8994->active_refcount)
                mode = WM1811_JACKDET_MODE_AUDIO;
 
-       if (mode == old)
+       if (mode == wm8994->jackdet_mode)
                return;
 
-       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                           WM1811_JACKDET_MODE_MASK, mode);
-
-       switch (mode) {
-       case WM1811_JACKDET_MODE_MIC:
-       case WM1811_JACKDET_MODE_AUDIO:
-               switch (old) {
-               case WM1811_JACKDET_MODE_MIC:
-               case WM1811_JACKDET_MODE_AUDIO:
-                       break;
-               default:
-                       msleep(2);
-                       break;
-               }
+       wm8994->jackdet_mode = mode;
 
-       default:
-               break;
-       }
+       /* Always use audio mode to detect while the system is active */
+       if (mode != WM1811_JACKDET_MODE_NONE)
+               mode = WM1811_JACKDET_MODE_AUDIO;
 
+       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                           WM1811_JACKDET_MODE_MASK, mode);
 }
 
 static void active_reference(struct snd_soc_codec *codec)
@@ -2749,7 +2736,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm8994_suspend(struct snd_soc_codec *codec)
+static int wm8994_codec_suspend(struct snd_soc_codec *codec)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        struct wm8994 *control = wm8994->wm8994;
@@ -2783,7 +2770,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int wm8994_resume(struct snd_soc_codec *codec)
+static int wm8994_codec_resume(struct snd_soc_codec *codec)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        struct wm8994 *control = wm8994->wm8994;
@@ -2842,8 +2829,8 @@ static int wm8994_resume(struct snd_soc_codec *codec)
        return 0;
 }
 #else
-#define wm8994_suspend NULL
-#define wm8994_resume NULL
+#define wm8994_codec_suspend NULL
+#define wm8994_codec_resume NULL
 #endif
 
 static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
@@ -3955,8 +3942,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
        .probe =        wm8994_codec_probe,
        .remove =       wm8994_codec_remove,
-       .suspend =      wm8994_suspend,
-       .resume =       wm8994_resume,
+       .suspend =      wm8994_codec_suspend,
+       .resume =       wm8994_codec_resume,
        .set_bias_level = wm8994_set_bias_level,
 };
 
@@ -3983,11 +3970,43 @@ static int __devexit wm8994_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int wm8994_suspend(struct device *dev)
+{
+       struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
+
+       /* Drop down to power saving mode when system is suspended */
+       if (wm8994->jackdet && !wm8994->active_refcount)
+               regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
+                                  WM1811_JACKDET_MODE_MASK,
+                                  wm8994->jackdet_mode);
+
+       return 0;
+}
+
+static int wm8994_resume(struct device *dev)
+{
+       struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
+
+       if (wm8994->jackdet && wm8994->jack_cb)
+               regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
+                                  WM1811_JACKDET_MODE_MASK,
+                                  WM1811_JACKDET_MODE_AUDIO);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops wm8994_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume)
+};
+
 static struct platform_driver wm8994_codec_driver = {
        .driver = {
-                  .name = "wm8994-codec",
-                  .owner = THIS_MODULE,
-                  },
+               .name = "wm8994-codec",
+               .owner = THIS_MODULE,
+               .pm = &wm8994_pm_ops,
+       },
        .probe = wm8994_probe,
        .remove = __devexit_p(wm8994_remove),
 };
index f996d14766d9dafda74cebd88ad02154133061b5..2f4d2d12a4528017a3efef8878fc429a955bdeef 100644 (file)
@@ -122,6 +122,7 @@ struct wm8994_priv {
        bool jack_mic;
        int btn_mask;
        bool jackdet;
+       int jackdet_mode;
 
        wm8958_micdet_cb jack_cb;
        void *jack_cb_data;
index aa4294bf49b28bac9d26f90522bb5b39fe60cddc..810acaa0900955f0a24b3b99089356ec413a01e8 100644 (file)
@@ -8,19 +8,32 @@ menuconfig SND_IMX_SOC
 
 if SND_IMX_SOC
 
+config SND_SOC_IMX_SSI
+       tristate
+
+config SND_SOC_IMX_PCM
+       tristate
+
 config SND_MXC_SOC_FIQ
-       select 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.
@@ -30,6 +43,8 @@ config SND_SOC_MX27VIS_AIC32X4
        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.
@@ -40,6 +55,8 @@ config SND_SOC_PHYCORE_AC97
        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
@@ -53,6 +70,8 @@ config SND_SOC_EUKREA_TLV320
        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
index d6d609ba7e24afa539e0cc9804caee1a43026379..f5db3e92d0d11e5527087932a03380aa93b3a9f5 100644 (file)
@@ -1,11 +1,14 @@
 # i.MX Platform Support
-snd-soc-imx-objs := imx-ssi.o
-snd-soc-imx-fiq-objs := imx-pcm-fiq.o
-snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o
+snd-soc-imx-ssi-objs := imx-ssi.o
+snd-soc-imx-audmux-objs := imx-audmux.o
 
-obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
-obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o
-obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.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
index 1c1fdd10f73f6b39e39f01a318d3df3bc6ad74f5..7d4475cfdb242bf6da4a74393a45c7b80b053d33 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "../codecs/tlv320aic23.h"
 #include "imx-ssi.h"
+#include "imx-audmux.h"
 
 #define CODEC_CLOCK 12000000
 
@@ -97,12 +98,43 @@ static struct platform_device *eukrea_tlv320_snd_device;
 static int __init eukrea_tlv320_init(void)
 {
        int ret;
-
-       if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd()
-               && !machine_is_eukrea_cpuimx35sd()
-               && !machine_is_eukrea_cpuimx51sd())
+       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)
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/imx/imx-audmux.c
new file mode 100644 (file)
index 0000000..b83699d
--- /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_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(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 __exit 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_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(audmux_clk);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
+
+static int __init 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 __exit 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         = __exit_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
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 */
index 471e2218c971c948e89e213496f2d622294bff3c..e43c8fa2788b34062b5601066b112c6c667e5c67 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <mach/dma.h>
 
-#include "imx-ssi.h"
+#include "imx-pcm.h"
 
 static bool filter(struct dma_chan *chan, void *param)
 {
diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/imx/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/imx/imx-pcm.h b/sound/soc/imx/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 */
index 25c623115a9f61337ba3ba93b52667ac271d8f07..9203cdd0a154b6d138d25aa1fc96d0ba6da1fa31 100644 (file)
@@ -363,94 +363,6 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
        .trigger        = imx_ssi_trigger,
 };
 
-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);
-
 static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
 {
        struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
index 1072dfb53e4772f306c9dfcb38262e6c02c8d62c..5744e86ca8781537dce529523bb58a37b35e5293 100644 (file)
 
 #include <linux/dmaengine.h>
 #include <mach/dma.h>
-
-struct imx_pcm_dma_params {
-       int dma;
-       unsigned long dma_addr;
-       int burstsize;
-};
+#include "imx-pcm.h"
 
 struct imx_ssi {
        struct platform_device *ac97_dev;
@@ -218,13 +213,4 @@ struct imx_ssi {
        struct platform_device *soc_platform_pdev_fiq;
 };
 
-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);
-
-/*
- * Do not change this as the FIQ handler depends on this size
- */
-#define IMX_SSI_DMABUF_SIZE    (64 * 1024)
-
 #endif /* _IMX_SSI_H */
index 155899c08c0c4c15ddcdf5fe3e6874463c6cb578..976f857151f08b43d8b0e485d3f012112a98ee55 100644 (file)
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
 #include <asm/mach-types.h>
-#include <mach/audmux.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
@@ -207,16 +207,16 @@ static int __init mx27vis_aic32x4_init(void)
        }
 
        /* Connect SSI0 as clock slave to SSI1 external pins */
-       mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-                       MXC_AUDMUX_V1_PCR_SYN |
-                       MXC_AUDMUX_V1_PCR_TFSDIR |
-                       MXC_AUDMUX_V1_PCR_TCLKDIR |
-                       MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
-                       MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
+       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)
        );
-       mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
-                       MXC_AUDMUX_V1_PCR_SYN |
-                       MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+       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,
index 6ac12111de6a4ad108be9a0d39684389cc8b3c49..f8da6dd115ed1c292d66fe0d7bee395ba849f2f7 100644 (file)
@@ -19,6 +19,8 @@
 #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 = {
@@ -50,9 +52,32 @@ static int __init imx_phycore_init(void)
 {
        int ret;
 
-       if (!machine_is_pcm043() && !machine_is_pca100())
+       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)
index 37480c90e9979265e43171326d4bfab6310d25f5..fe54a69073e5cca05920b9d9b1864f916b261696 100644 (file)
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
-#include <mach/audmux.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.
@@ -268,17 +267,17 @@ static int __init wm1133_ev1_audio_init(void)
        unsigned int ptcr, pdcr;
 
        /* SSI0 mastered by port 5 */
-       ptcr = MXC_AUDMUX_V2_PTCR_SYN |
-               MXC_AUDMUX_V2_PTCR_TFSDIR |
-               MXC_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
-               MXC_AUDMUX_V2_PTCR_TCLKDIR |
-               MXC_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
-       pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
-       mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
-
-       ptcr = MXC_AUDMUX_V2_PTCR_SYN;
-       pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
-       mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
+       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)
index c9b088dab1cf4cad72d0ef2248deff11391b203b..a4d4aa1e6c496615f3b78890bcbb0aee9fa9ed8c 100644 (file)
@@ -1569,8 +1569,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
        out = is_connected_output_ep(w);
        dapm_clear_walk(w->dapm);
 
-       ret = snprintf(buf, PAGE_SIZE, "%s: %s  in %d out %d",
-                      w->name, w->power ? "On" : "Off", in, out);
+       ret = snprintf(buf, PAGE_SIZE, "%s: %s%s  in %d out %d",
+                      w->name, w->power ? "On" : "Off",
+                      w->force ? " (forced)" : "", in, out);
 
        if (w->reg >= 0)
                ret += snprintf(buf + ret, PAGE_SIZE - ret,