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:
Takashi Iwai 2012-03-06 14:04:16 +01:00
Родитель 650d6e25cd 9d5ef2663f
Коммит 303076342b
35 изменённых файлов: 580 добавлений и 448 удалений

Просмотреть файл

@ -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 bool
select MACH_MX21 select MACH_MX21
select CPU_ARM926T select CPU_ARM926T
select ARCH_MXC_AUDMUX_V1
select IMX_HAVE_DMA_V1 select IMX_HAVE_DMA_V1
select IMX_HAVE_IOMUX_V1 select IMX_HAVE_IOMUX_V1
select MXC_AVIC select MXC_AVIC
@ -55,7 +54,6 @@ config SOC_IMX25
bool bool
select ARCH_MX25 select ARCH_MX25
select CPU_ARM926T select CPU_ARM926T
select ARCH_MXC_AUDMUX_V2
select ARCH_MXC_IOMUX_V3 select ARCH_MXC_IOMUX_V3
select MXC_AVIC select MXC_AVIC
@ -63,7 +61,6 @@ config SOC_IMX27
bool bool
select MACH_MX27 select MACH_MX27
select CPU_ARM926T select CPU_ARM926T
select ARCH_MXC_AUDMUX_V1
select IMX_HAVE_DMA_V1 select IMX_HAVE_DMA_V1
select IMX_HAVE_IOMUX_V1 select IMX_HAVE_IOMUX_V1
select MXC_AVIC select MXC_AVIC
@ -72,7 +69,6 @@ config SOC_IMX31
bool bool
select CPU_V6 select CPU_V6
select IMX_HAVE_PLATFORM_MXC_RNGA select IMX_HAVE_PLATFORM_MXC_RNGA
select ARCH_MXC_AUDMUX_V2
select MXC_AVIC select MXC_AVIC
select SMP_ON_UP if SMP select SMP_ON_UP if SMP
@ -80,7 +76,6 @@ config SOC_IMX35
bool bool
select CPU_V6 select CPU_V6
select ARCH_MXC_IOMUX_V3 select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
select HAVE_EPIT select HAVE_EPIT
select MXC_AVIC select MXC_AVIC
select SMP_ON_UP if SMP select SMP_ON_UP if SMP
@ -89,7 +84,6 @@ config SOC_IMX5
select CPU_V7 select CPU_V7
select MXC_TZIC select MXC_TZIC
select ARCH_MXC_IOMUX_V3 select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
select ARCH_MX5 select ARCH_MX5
bool bool

Просмотреть файл

@ -32,7 +32,6 @@
#include <mach/common.h> #include <mach/common.h>
#include <mach/iomux-mx27.h> #include <mach/iomux-mx27.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/audmux.h>
#include "devices-imx27.h" #include "devices-imx27.h"
@ -306,25 +305,6 @@ void __init eukrea_mbimx27_baseboard_init(void)
mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins, mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27"); 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_uart1(&uart_pdata);
imx27_add_imx_uart2(&uart_pdata); imx27_add_imx_uart2(&uart_pdata);
#if !defined(MACH_EUKREA_CPUIMX27_USEUART4) #if !defined(MACH_EUKREA_CPUIMX27_USEUART4)

Просмотреть файл

@ -37,7 +37,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/iomux-mx51.h> #include <mach/iomux-mx51.h>
#include <mach/audmux.h>
#include "devices-imx51.h" #include "devices-imx51.h"

Просмотреть файл

@ -31,7 +31,6 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <mach/mx25.h> #include <mach/mx25.h>
#include <mach/audmux.h>
#include "devices-imx25.h" #include "devices-imx25.h"
@ -241,22 +240,6 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
ARRAY_SIZE(eukrea_mbimxsd_pads))) ARRAY_SIZE(eukrea_mbimxsd_pads)))
printk(KERN_ERR "error setting mbimxsd pads !\n"); 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_uart1(&uart_pdata);
imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata); imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);

Просмотреть файл

@ -38,7 +38,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/iomux-mx35.h> #include <mach/iomux-mx35.h>
#include <mach/audmux.h>
#include "devices-imx35.h" #include "devices-imx35.h"
@ -252,22 +251,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
ARRAY_SIZE(eukrea_mbimxsd_pads))) ARRAY_SIZE(eukrea_mbimxsd_pads)))
printk(KERN_ERR "error setting mbimxsd pads !\n"); 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_imx_uart1(&uart_pdata);
imx35_add_ipu_core(&mx3_ipu_data); imx35_add_ipu_core(&mx3_ipu_data);
imx35_add_mx3_sdc_fb(&mx3fb_pdata); imx35_add_mx3_sdc_fb(&mx3fb_pdata);

Просмотреть файл

@ -36,7 +36,6 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/iomux-mx27.h> #include <mach/iomux-mx27.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <mach/audmux.h>
#include <mach/irqs.h> #include <mach/irqs.h>
#include <mach/ulpi.h> #include <mach/ulpi.h>
@ -359,18 +358,6 @@ static void __init pca100_init(void)
imx27_soc_init(); 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, ret = mxc_gpio_setup_multiple_pins(pca100_pins,
ARRAY_SIZE(pca100_pins), "PCA100"); ARRAY_SIZE(pca100_pins), "PCA100");
if (ret) if (ret)

Просмотреть файл

@ -37,7 +37,6 @@
#include <mach/common.h> #include <mach/common.h>
#include <mach/iomux-mx35.h> #include <mach/iomux-mx35.h>
#include <mach/ulpi.h> #include <mach/ulpi.h>
#include <mach/audmux.h>
#include "devices-imx35.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_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); imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx2_wdt(NULL); 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)); 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) void __init imx21_soc_init(void)
{ {
mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); 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); mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
imx_add_imx_dma(); 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, .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) void __init imx25_soc_init(void)
{ {
/* i.mx25 has the i.mx31 type gpio */ /* 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 */ /* i.mx25 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata); 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)); 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) void __init imx27_soc_init(void)
{ {
/* i.mx27 has the i.mx21 type gpio */ /* 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); mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
imx_add_imx_dma(); 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, .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) void __init imx31_soc_init(void)
{ {
int to_version = mx31_revision() >> 4; 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); 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 */ #endif /* ifdef CONFIG_SOC_IMX31 */
@ -241,6 +247,10 @@ static struct sdma_platform_data imx35_sdma_pdata __initdata = {
.script_addrs = &imx35_to2_sdma_script, .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) void __init imx35_soc_init(void)
{ {
int to_version = mx35_revision() >> 4; 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); 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 */ #endif /* ifdef CONFIG_SOC_IMX35 */

Просмотреть файл

@ -170,6 +170,18 @@ static struct sdma_platform_data imx53_sdma_pdata __initdata = {
.script_addrs = &imx53_sdma_script, .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) void __init imx50_soc_init(void)
{ {
/* i.mx50 has the i.mx31 type gpio */ /* 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", 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", 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); 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) void __init imx51_soc_init(void)
@ -191,6 +207,9 @@ void __init imx51_soc_init(void)
/* i.mx51 has the i.mx35 type sdma */ /* i.mx51 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); 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) void __init imx53_soc_init(void)
@ -206,4 +225,7 @@ void __init imx53_soc_init(void)
/* i.mx53 has the i.mx35 type sdma */ /* i.mx53 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata); 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 config ARCH_MXC_IOMUX_V3
bool bool
config ARCH_MXC_AUDMUX_V1
bool
config ARCH_MXC_AUDMUX_V2
bool
config IRAM_ALLOC config IRAM_ALLOC
bool bool
select GENERIC_ALLOCATOR select GENERIC_ALLOCATOR

Просмотреть файл

@ -14,8 +14,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
obj-$(CONFIG_MXC_PWM) += pwm.o obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_ULPI) += ulpi.o
obj-$(CONFIG_MXC_USE_EPIT) += epit.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_MXC_DEBUG_BOARD) += 3ds_debugboard.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
ifdef CONFIG_SND_IMX_SOC 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) if (!wm8804)
return -ENOMEM; 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); i2c_set_clientdata(i2c, wm8804);
ret = snd_soc_register_codec(&i2c->dev, ret = snd_soc_register_codec(&i2c->dev,

Просмотреть файл

@ -116,11 +116,11 @@ static struct reg_default wm8962_reg[] = {
{ 1, 0x049F }, /* R1 - Right Input volume */ { 1, 0x049F }, /* R1 - Right Input volume */
{ 2, 0x0000 }, /* R2 - HPOUTL volume */ { 2, 0x0000 }, /* R2 - HPOUTL volume */
{ 3, 0x0000 }, /* R3 - HPOUTR volume */ { 3, 0x0000 }, /* R3 - HPOUTR volume */
{ 4, 0x0020 }, /* R4 - Clocking1 */
{ 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */
{ 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */
{ 7, 0x000A }, /* R7 - Audio Interface 0 */ { 7, 0x000A }, /* R7 - Audio Interface 0 */
{ 8, 0x01E4 }, /* R8 - Clocking2 */
{ 9, 0x0300 }, /* R9 - Audio Interface 1 */ { 9, 0x0300 }, /* R9 - Audio Interface 1 */
{ 10, 0x00C0 }, /* R10 - Left DAC volume */ { 10, 0x00C0 }, /* R10 - Left DAC volume */
{ 11, 0x00C0 }, /* R11 - Right DAC volume */ { 11, 0x00C0 }, /* R11 - Right DAC volume */
@ -129,7 +129,7 @@ static struct reg_default wm8962_reg[] = {
{ 15, 0x6243 }, /* R15 - Software Reset */ { 15, 0x6243 }, /* R15 - Software Reset */
{ 17, 0x007B }, /* R17 - ALC1 */ { 17, 0x007B }, /* R17 - ALC1 */
{ 18, 0x0000 }, /* R18 - ALC2 */
{ 19, 0x1C32 }, /* R19 - ALC3 */ { 19, 0x1C32 }, /* R19 - ALC3 */
{ 20, 0x3200 }, /* R20 - Noise Gate */ { 20, 0x3200 }, /* R20 - Noise Gate */
{ 21, 0x00C0 }, /* R21 - Left ADC volume */ { 21, 0x00C0 }, /* R21 - Left ADC volume */
@ -153,10 +153,6 @@ static struct reg_default wm8962_reg[] = {
{ 40, 0x0000 }, /* R40 - SPKOUTL volume */ { 40, 0x0000 }, /* R40 - SPKOUTL volume */
{ 41, 0x0000 }, /* R41 - SPKOUTR 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 */ { 51, 0x0003 }, /* R51 - Class D Control 2 */
{ 56, 0x0506 }, /* R56 - Clocking 4 */ { 56, 0x0506 }, /* R56 - Clocking 4 */
@ -168,8 +164,6 @@ static struct reg_default wm8962_reg[] = {
{ 64, 0x0810 }, /* R64 - DC Servo 4 */ { 64, 0x0810 }, /* R64 - DC Servo 4 */
{ 66, 0x0000 }, /* R66 - DC Servo 6 */
{ 68, 0x001B }, /* R68 - Analogue PGA Bias */ { 68, 0x001B }, /* R68 - Analogue PGA Bias */
{ 69, 0x0000 }, /* R69 - Analogue HP 0 */ { 69, 0x0000 }, /* R69 - Analogue HP 0 */
@ -302,9 +296,6 @@ static struct reg_default wm8962_reg[] = {
{ 516, 0x8100 }, /* R516 - GPIO 5 */ { 516, 0x8100 }, /* R516 - GPIO 5 */
{ 517, 0x8100 }, /* R517 - GPIO 6 */ { 517, 0x8100 }, /* R517 - GPIO 6 */
{ 560, 0x0000 }, /* R560 - Interrupt Status 1 */
{ 561, 0x0000 }, /* R561 - Interrupt Status 2 */
{ 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */ { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */
{ 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */ { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */
@ -316,8 +307,6 @@ static struct reg_default wm8962_reg[] = {
{ 768, 0x1C00 }, /* R768 - DSP2 Power Management */ { 768, 0x1C00 }, /* R768 - DSP2 Power Management */
{ 1037, 0x0000 }, /* R1037 - DSP2_ExecControl */
{ 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */
{ 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */ { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */
@ -3673,7 +3662,6 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
ret); ret);
} }
pm_runtime_set_active(&i2c->dev);
pm_runtime_enable(&i2c->dev); pm_runtime_enable(&i2c->dev);
pm_request_idle(&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) static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
{ {
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 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) if (!wm8994->jackdet || !wm8994->jack_cb)
return; return;
@ -694,28 +692,17 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
if (wm8994->active_refcount) if (wm8994->active_refcount)
mode = WM1811_JACKDET_MODE_AUDIO; mode = WM1811_JACKDET_MODE_AUDIO;
if (mode == old) if (mode == wm8994->jackdet_mode)
return; 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, snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM1811_JACKDET_MODE_MASK, mode); 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) static void active_reference(struct snd_soc_codec *codec)
@ -2749,7 +2736,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
}; };
#ifdef CONFIG_PM #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_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = wm8994->wm8994; struct wm8994 *control = wm8994->wm8994;
@ -2783,7 +2770,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec)
return 0; 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_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = wm8994->wm8994; struct wm8994 *control = wm8994->wm8994;
@ -2842,8 +2829,8 @@ static int wm8994_resume(struct snd_soc_codec *codec)
return 0; return 0;
} }
#else #else
#define wm8994_suspend NULL #define wm8994_codec_suspend NULL
#define wm8994_resume NULL #define wm8994_codec_resume NULL
#endif #endif
static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) 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 = { static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
.probe = wm8994_codec_probe, .probe = wm8994_codec_probe,
.remove = wm8994_codec_remove, .remove = wm8994_codec_remove,
.suspend = wm8994_suspend, .suspend = wm8994_codec_suspend,
.resume = wm8994_resume, .resume = wm8994_codec_resume,
.set_bias_level = wm8994_set_bias_level, .set_bias_level = wm8994_set_bias_level,
}; };
@ -3983,11 +3970,43 @@ static int __devexit wm8994_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver wm8994_codec_driver = {
.driver = { .driver = {
.name = "wm8994-codec", .name = "wm8994-codec",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, .pm = &wm8994_pm_ops,
},
.probe = wm8994_probe, .probe = wm8994_probe,
.remove = __devexit_p(wm8994_remove), .remove = __devexit_p(wm8994_remove),
}; };

Просмотреть файл

@ -122,6 +122,7 @@ struct wm8994_priv {
bool jack_mic; bool jack_mic;
int btn_mask; int btn_mask;
bool jackdet; bool jackdet;
int jackdet_mode;
wm8958_micdet_cb jack_cb; wm8958_micdet_cb jack_cb;
void *jack_cb_data; void *jack_cb_data;

Просмотреть файл

@ -8,19 +8,32 @@ menuconfig SND_IMX_SOC
if SND_IMX_SOC if SND_IMX_SOC
config SND_MXC_SOC_FIQ config SND_SOC_IMX_SSI
select FIQ
tristate 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 config SND_MXC_SOC_MX2
select SND_SOC_DMAENGINE_PCM select SND_SOC_DMAENGINE_PCM
tristate tristate
select SND_SOC_IMX_PCM
config SND_SOC_IMX_AUDMUX
tristate
config SND_MXC_SOC_WM1133_EV1 config SND_MXC_SOC_WM1133_EV1
tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
select SND_SOC_WM8350 select SND_SOC_WM8350
select SND_MXC_SOC_FIQ select SND_MXC_SOC_FIQ
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_SSI
help help
Enable support for audio on the i.MX31ADS with the WM1133-EV1 Enable support for audio on the i.MX31ADS with the WM1133-EV1
PMIC board with WM8835x fitted. PMIC board with WM8835x fitted.
@ -30,6 +43,8 @@ config SND_SOC_MX27VIS_AIC32X4
depends on MACH_IMX27_VISSTRIM_M10 && I2C depends on MACH_IMX27_VISSTRIM_M10 && I2C
select SND_SOC_TLV320AIC32X4 select SND_SOC_TLV320AIC32X4
select SND_MXC_SOC_MX2 select SND_MXC_SOC_MX2
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_SSI
help help
Say Y if you want to add support for SoC audio on Visstrim SM10 Say Y if you want to add support for SoC audio on Visstrim SM10
board with TLV320AIC32X4 codec. board with TLV320AIC32X4 codec.
@ -40,6 +55,8 @@ config SND_SOC_PHYCORE_AC97
select SND_SOC_AC97_BUS select SND_SOC_AC97_BUS
select SND_SOC_WM9712 select SND_SOC_WM9712
select SND_MXC_SOC_FIQ select SND_MXC_SOC_FIQ
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_SSI
help help
Say Y if you want to add support for SoC audio on Phytec phyCORE Say Y if you want to add support for SoC audio on Phytec phyCORE
and phyCARD boards in AC97 mode and phyCARD boards in AC97 mode
@ -53,6 +70,8 @@ config SND_SOC_EUKREA_TLV320
depends on I2C depends on I2C
select SND_SOC_TLV320AIC23 select SND_SOC_TLV320AIC23
select SND_MXC_SOC_FIQ select SND_MXC_SOC_FIQ
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_SSI
help help
Enable I2S based access to the TLV320AIC23B codec attached Enable I2S based access to the TLV320AIC23B codec attached
to the SSI interface to the SSI interface

Просмотреть файл

@ -1,11 +1,14 @@
# i.MX Platform Support # i.MX Platform Support
snd-soc-imx-objs := imx-ssi.o snd-soc-imx-ssi-objs := imx-ssi.o
snd-soc-imx-fiq-objs := imx-pcm-fiq.o snd-soc-imx-audmux-objs := imx-audmux.o
snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o
obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.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 # i.MX Machine Support
snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o

Просмотреть файл

@ -26,6 +26,7 @@
#include "../codecs/tlv320aic23.h" #include "../codecs/tlv320aic23.h"
#include "imx-ssi.h" #include "imx-ssi.h"
#include "imx-audmux.h"
#define CODEC_CLOCK 12000000 #define CODEC_CLOCK 12000000
@ -97,12 +98,43 @@ static struct platform_device *eukrea_tlv320_snd_device;
static int __init eukrea_tlv320_init(void) static int __init eukrea_tlv320_init(void)
{ {
int ret; int ret;
int int_port = 0, ext_port;
if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd() if (machine_is_eukrea_cpuimx27()) {
&& !machine_is_eukrea_cpuimx35sd() imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
&& !machine_is_eukrea_cpuimx51sd()) 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 happy. We might run on a totally different machine */
return 0; return 0;
}
eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1); eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
if (!eukrea_tlv320_snd_device) 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> * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
* *
* Initial development of this code was funded by * Initial development of this code was funded by
@ -15,20 +17,25 @@
* GNU General Public License for more details. * 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/clk.h>
#include <linux/debugfs.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 <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 struct clk *audmux_clk;
static void __iomem *audmux_base; static void __iomem *audmux_base;
#define MXC_AUDMUX_V2_PTCR(x) ((x) * 8) #define IMX_AUDMUX_V2_PTCR(x) ((x) * 8)
#define MXC_AUDMUX_V2_PDCR(x) ((x) * 8 + 4) #define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static struct dentry *audmux_debugfs_root; 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) if (audmux_clk)
clk_enable(audmux_clk); clk_enable(audmux_clk);
ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port)); ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port)); pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
if (audmux_clk) if (audmux_clk)
clk_disable(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", ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
pdcr, ptcr); pdcr, ptcr);
if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR) if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"TxFS output from %s, ", "TxFS output from %s, ",
audmux_port_string((ptcr >> 27) & 0x7)); 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, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"TxFS input, "); "TxFS input, ");
if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR) if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"TxClk output from %s", "TxClk output from %s",
audmux_port_string((ptcr >> 22) & 0x7)); 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"); 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, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"Port is symmetric"); "Port is symmetric");
} else { } else {
if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR) if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"RxFS output from %s, ", "RxFS output from %s, ",
audmux_port_string((ptcr >> 17) & 0x7)); 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, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"RxFS input, "); "RxFS input, ");
if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR) if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,
"RxClk output from %s", "RxClk output from %s",
audmux_port_string((ptcr >> 12) & 0x7)); audmux_port_string((ptcr >> 12) & 0x7));
@ -140,7 +147,7 @@ static const struct file_operations audmux_debugfs_fops = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static void audmux_debugfs_init(void) static void __init audmux_debugfs_init(void)
{ {
int i; int i;
char buf[20]; char buf[20];
@ -159,61 +166,149 @@ static void audmux_debugfs_init(void)
i); i);
} }
} }
static void __exit audmux_debugfs_remove(void)
{
debugfs_remove_recursive(audmux_debugfs_root);
}
#else #else
static inline void audmux_debugfs_init(void) static inline void audmux_debugfs_init(void)
{ {
} }
static inline void audmux_debugfs_remove(void)
{
}
#endif #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) unsigned int pdcr)
{ {
if (audmux_type != IMX31_AUDMUX)
return -EINVAL;
if (!audmux_base) if (!audmux_base)
return -ENOSYS; return -ENOSYS;
if (audmux_clk) if (audmux_clk)
clk_enable(audmux_clk); clk_enable(audmux_clk);
writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port)); writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port)); writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
if (audmux_clk) if (audmux_clk)
clk_disable(audmux_clk); clk_disable(audmux_clk);
return 0; 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; struct resource *res;
if (cpu_is_mx51()) { const struct of_device_id *of_id =
audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR); of_match_device(imx_audmux_dt_ids, &pdev->dev);
} else if (cpu_is_mx31()) {
audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
} else if (cpu_is_mx35()) { audmux_base = devm_request_and_ioremap(&pdev->dev, res);
audmux_clk = clk_get(NULL, "audmux"); if (!audmux_base)
if (IS_ERR(audmux_clk)) { return -EADDRNOTAVAIL;
ret = PTR_ERR(audmux_clk);
printk(KERN_ERR "%s: cannot get clock: %d\n", __func__, audmux_clk = clk_get(&pdev->dev, "audmux");
ret); if (IS_ERR(audmux_clk)) {
return ret; dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
} PTR_ERR(audmux_clk));
audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR); audmux_clk = NULL;
} 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(); 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; 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 <mach/dma.h>
#include "imx-ssi.h" #include "imx-pcm.h"
static bool filter(struct dma_chan *chan, void *param) static bool filter(struct dma_chan *chan, void *param)
{ {

105
sound/soc/imx/imx-pcm.c Normal file
Просмотреть файл

@ -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);

32
sound/soc/imx/imx-pcm.h Normal file
Просмотреть файл

@ -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, .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) static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
{ {
struct imx_ssi *ssi = dev_get_drvdata(dai->dev); struct imx_ssi *ssi = dev_get_drvdata(dai->dev);

Просмотреть файл

@ -187,12 +187,7 @@
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <mach/dma.h> #include <mach/dma.h>
#include "imx-pcm.h"
struct imx_pcm_dma_params {
int dma;
unsigned long dma_addr;
int burstsize;
};
struct imx_ssi { struct imx_ssi {
struct platform_device *ac97_dev; struct platform_device *ac97_dev;
@ -218,13 +213,4 @@ struct imx_ssi {
struct platform_device *soc_platform_pdev_fiq; 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 */ #endif /* _IMX_SSI_H */

Просмотреть файл

@ -32,11 +32,11 @@
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
#include <sound/tlv.h> #include <sound/tlv.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/audmux.h>
#include <mach/iomux-mx27.h> #include <mach/iomux-mx27.h>
#include "../codecs/tlv320aic32x4.h" #include "../codecs/tlv320aic32x4.h"
#include "imx-ssi.h" #include "imx-ssi.h"
#include "imx-audmux.h"
#define MX27VIS_AMP_GAIN 0 #define MX27VIS_AMP_GAIN 0
#define MX27VIS_AMP_MUTE 1 #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 */ /* Connect SSI0 as clock slave to SSI1 external pins */
mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
MXC_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_SYN |
MXC_AUDMUX_V1_PCR_TFSDIR | IMX_AUDMUX_V1_PCR_TFSDIR |
MXC_AUDMUX_V1_PCR_TCLKDIR | IMX_AUDMUX_V1_PCR_TCLKDIR |
MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) | IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
MXC_AUDMUX_V1_PCR_RXDSEL(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, imx_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
MXC_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_SYN |
MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
); );
ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins, ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,

Просмотреть файл

@ -19,6 +19,8 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "imx-audmux.h"
static struct snd_soc_card imx_phycore; static struct snd_soc_card imx_phycore;
static struct snd_soc_ops imx_phycore_hifi_ops = { static struct snd_soc_ops imx_phycore_hifi_ops = {
@ -50,9 +52,32 @@ static int __init imx_phycore_init(void)
{ {
int ret; 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 happy. We might run on a totally different machine */
return 0; return 0;
}
imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1); imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
if (!imx_phycore_snd_ac97_device) if (!imx_phycore_snd_ac97_device)

Просмотреть файл

@ -21,10 +21,9 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <mach/audmux.h>
#include "imx-ssi.h" #include "imx-ssi.h"
#include "../codecs/wm8350.h" #include "../codecs/wm8350.h"
#include "imx-audmux.h"
/* There is a silicon mic on the board optionally connected via a solder pad /* There is a silicon mic on the board optionally connected via a solder pad
* SP1. Define this to enable it. * SP1. Define this to enable it.
@ -268,17 +267,17 @@ static int __init wm1133_ev1_audio_init(void)
unsigned int ptcr, pdcr; unsigned int ptcr, pdcr;
/* SSI0 mastered by port 5 */ /* SSI0 mastered by port 5 */
ptcr = MXC_AUDMUX_V2_PTCR_SYN | ptcr = IMX_AUDMUX_V2_PTCR_SYN |
MXC_AUDMUX_V2_PTCR_TFSDIR | IMX_AUDMUX_V2_PTCR_TFSDIR |
MXC_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) | IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
MXC_AUDMUX_V2_PTCR_TCLKDIR | IMX_AUDMUX_V2_PTCR_TCLKDIR |
MXC_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr); imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
ptcr = MXC_AUDMUX_V2_PTCR_SYN; ptcr = IMX_AUDMUX_V2_PTCR_SYN;
pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0); pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr); imx_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1); wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
if (!wm1133_ev1_snd_device) 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); out = is_connected_output_ep(w);
dapm_clear_walk(w->dapm); dapm_clear_walk(w->dapm);
ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
w->name, w->power ? "On" : "Off", in, out); w->name, w->power ? "On" : "Off",
w->force ? " (forced)" : "", in, out);
if (w->reg >= 0) if (w->reg >= 0)
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += snprintf(buf + ret, PAGE_SIZE - ret,