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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPVgcKAAoJEBus8iNuMP3dk6gQAJuddZ0luBse1NUf7NIGfKV6 ZQJUWEjoAS3BLLQ4OMQF9QAd5PUQQzFG0VIjKrLVzomyTmxXOjhyM33HccWsHYsF fUOdpQTcj5FNOoalYbEMY5ELIp/+Q2KV5MnyjcOSS2Um6/WJGU1CZwO7DOEB3WHl XfoayQ9zZnvftEvweJqOepo6WrfJIVL65u2jxLyWDIqb3jyUQT2PYB3JrNenIXYQ ISI99NMqaQW1fq8v21aWgzO+jo4Jh7n6A2b6ZbbEM5ojQOBIScYX4Vk9+Qht4EbV r6nxNOvytmWBru7HHw1AGcnsBb1WUY7V1c2myvpEr98YWxDWoWEp7pgWyiaLsBRP DDzVlEmWD9248pn/sKUCxQe+cLgG6gWz46YXYFqNdBT/Q5hBcEBoB2o9dEeyFfLT l+XpSDve8kT3QaDz5rvzYRHji97uHG0vE8s6WU0PJYtf2/u0Jzf5ZKrJMU//lojE q3EySKAC1hy2KtSU4G4p13sh5dbzLfBt6UYSxHk0GYnRZG6k/VSXQGznBVcjHK93 +95CharGOB179k6n5S/HTSBeXPn/EeB977uysurvE1VVc14QE0fsoKCbrBWov4vB W3+DTqWScHdVtp9gUzJFMJ6Cmupc4rG1PN1xDLguZ8h8TCRvxHRTx3zmsO/Jkna4 crf42gOFThah4nOmqr72 =0lYr -----END PGP SIGNATURE----- Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into topic/asoc 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.
This commit is contained in:
Коммит
303076342b
|
@ -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>;
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
|
@ -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 */
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
wm8994->jackdet_mode = mode;
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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),
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8,19 +8,32 @@ menuconfig SND_IMX_SOC
|
|||
|
||||
if SND_IMX_SOC
|
||||
|
||||
config SND_MXC_SOC_FIQ
|
||||
select FIQ
|
||||
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.
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
int int_port = 0, ext_port;
|
||||
|
||||
if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd()
|
||||
&& !machine_is_eukrea_cpuimx35sd()
|
||||
&& !machine_is_eukrea_cpuimx51sd())
|
||||
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)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
|
@ -15,20 +17,25 @@
|
|||
* 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/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 <mach/audmux.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "imx-audmux.h"
|
||||
|
||||
#define DRIVER_NAME "imx-audmux"
|
||||
|
||||
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)
|
||||
#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;
|
||||
|
@ -75,8 +82,8 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
|
|||
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));
|
||||
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);
|
||||
|
@ -84,7 +91,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
|
|||
ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
|
||||
pdcr, ptcr);
|
||||
|
||||
if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR)
|
||||
if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
|
||||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"TxFS output from %s, ",
|
||||
audmux_port_string((ptcr >> 27) & 0x7));
|
||||
|
@ -92,7 +99,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
|
|||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"TxFS input, ");
|
||||
|
||||
if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR)
|
||||
if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
|
||||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"TxClk output from %s",
|
||||
audmux_port_string((ptcr >> 22) & 0x7));
|
||||
|
@ -102,11 +109,11 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
|
|||
|
||||
ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
|
||||
|
||||
if (ptcr & MXC_AUDMUX_V2_PTCR_SYN) {
|
||||
if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
|
||||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"Port is symmetric");
|
||||
} else {
|
||||
if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR)
|
||||
if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
|
||||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"RxFS output from %s, ",
|
||||
audmux_port_string((ptcr >> 17) & 0x7));
|
||||
|
@ -114,7 +121,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
|
|||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"RxFS input, ");
|
||||
|
||||
if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR)
|
||||
if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
|
||||
ret += snprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"RxClk output from %s",
|
||||
audmux_port_string((ptcr >> 12) & 0x7));
|
||||
|
@ -140,7 +147,7 @@ static const struct file_operations audmux_debugfs_fops = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static void audmux_debugfs_init(void)
|
||||
static void __init audmux_debugfs_init(void)
|
||||
{
|
||||
int i;
|
||||
char buf[20];
|
||||
|
@ -159,61 +166,149 @@ static void audmux_debugfs_init(void)
|
|||
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
|
||||
|
||||
int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
|
||||
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 + MXC_AUDMUX_V2_PTCR(port));
|
||||
writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
|
||||
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(mxc_audmux_v2_configure_port);
|
||||
EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
|
||||
|
||||
static int mxc_audmux_v2_init(void)
|
||||
static int __init imx_audmux_probe(struct platform_device *pdev)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
audmux_debugfs_init();
|
||||
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;
|
||||
}
|
||||
|
||||
postcore_initcall(mxc_audmux_v2_init);
|
||||
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);
|
|
@ -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 */
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
|
@ -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 */
|
|
@ -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);
|
||||
|
|
|
@ -187,12 +187,7 @@
|
|||
|
||||
#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 */
|
||||
|
|
|
@ -32,11 +32,11 @@
|
|||
#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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -21,10 +21,9 @@
|
|||
#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 = 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 = 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;
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче