dect
/
linux-2.6
Archived
13
0
Fork 0

Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into next/boards

The asoc branch that was already merged into v3.4 contains some
board-level changes that conflict with patches we already have
here, so pull in that branch to resolve the conflicts.

Conflicts:
	arch/arm/mach-imx/mach-imx27_visstrim_m10.c
	arch/arm/mach-omap2/board-omap4panda.c

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
[olof: Amended fix for mismerge as reported by Kevin Hilman]
Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Arnd Bergmann 2012-03-24 11:33:59 +00:00 committed by Olof Johansson
commit a754a87ce8
214 changed files with 14178 additions and 6320 deletions

View File

@ -0,0 +1,24 @@
ALC5632 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "realtek,alc5632"
- reg : the I2C address of the device.
- gpio-controller : Indicates this device is a GPIO controller.
- #gpio-cells : Should be two. The first cell is the pin number and the
second cell is used to specify optional parameters (currently unused).
Example:
alc5632: alc5632@1e {
compatible = "realtek,alc5632";
reg = <0x1a>;
gpio-controller;
#gpio-cells = <2>;
};

View File

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

View File

@ -0,0 +1,59 @@
NVIDIA Tegra audio complex
Required properties:
- compatible : "nvidia,tegra-audio-alc5632"
- nvidia,model : The user-visible name of this sound complex.
- nvidia,audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
the second being the connection's source. Valid names for sources and
sinks are the ALC5632's pins:
ALC5632 pins:
* SPK_OUTP
* SPK_OUTN
* HP_OUT_L
* HP_OUT_R
* AUX_OUT_P
* AUX_OUT_N
* LINE_IN_L
* LINE_IN_R
* PHONE_P
* PHONE_N
* MIC1_P
* MIC1_N
* MIC2_P
* MIC2_N
* MICBIAS1
* DMICDAT
Board connectors:
* Headset Stereophone
* Int Spk
* Headset Mic
* Digital Mic
- nvidia,i2s-controller : The phandle of the Tegra I2S controller
- nvidia,audio-codec : The phandle of the ALC5632 audio codec
Example:
sound {
compatible = "nvidia,tegra-audio-alc5632-paz00",
"nvidia,tegra-audio-alc5632";
nvidia,model = "Compal PAZ00";
nvidia,audio-routing =
"Int Spk", "SPK_OUTP",
"Int Spk", "SPK_OUTN",
"Headset Mic","MICBIAS1",
"MIC1_N", "Headset Mic",
"MIC1_P", "Headset Mic",
"Headset Stereophone", "HP_OUT_R",
"Headset Stereophone", "HP_OUT_L";
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&alc5632>;
};

View File

@ -34,6 +34,7 @@ picochip Picochip Ltd
powervr Imagination Technologies powervr Imagination Technologies
qcom Qualcomm, Inc. qcom Qualcomm, Inc.
ramtron Ramtron International ramtron Ramtron International
realtek Realtek Semiconductor Corp.
samsung Samsung Semiconductor samsung Samsung Semiconductor
sbs Smart Battery System sbs Smart Battery System
schindler Schindler schindler Schindler

View File

@ -271,3 +271,6 @@ IOMAP
pcim_iounmap() pcim_iounmap()
pcim_iomap_table() : array of mapped addresses indexed by BAR pcim_iomap_table() : array of mapped addresses indexed by BAR
pcim_iomap_regions() : do request_region() and iomap() on multiple BARs pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
REGULATOR
devm_regulator_get()

View File

@ -783,23 +783,12 @@ void __init ep93xx_register_i2s(void)
#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \ #define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
EP93XX_SYSCON_I2SCLKDIV_SPOL) EP93XX_SYSCON_I2SCLKDIV_SPOL)
int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config) int ep93xx_i2s_acquire(void)
{ {
unsigned val; unsigned val;
/* Sanity check */ ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97,
if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK) EP93XX_SYSCON_DEVCFG_I2S_MASK);
return -EINVAL;
if (i2s_config & ~EP93XX_I2SCLKDIV_MASK)
return -EINVAL;
/* Must have only one of I2SONSSP/I2SONAC97 set */
if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) ==
(i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97))
return -EINVAL;
ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
ep93xx_devcfg_set_bits(i2s_pins);
/* /*
* This is potentially racy with the clock api for i2s_mclk, sclk and * This is potentially racy with the clock api for i2s_mclk, sclk and
@ -809,7 +798,7 @@ int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
*/ */
val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV); val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
val &= ~EP93XX_I2SCLKDIV_MASK; val &= ~EP93XX_I2SCLKDIV_MASK;
val |= i2s_config; val |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV); ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
return 0; return 0;

View File

@ -59,7 +59,7 @@ void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
int ep93xx_keypad_acquire_gpio(struct platform_device *pdev); int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
void ep93xx_keypad_release_gpio(struct platform_device *pdev); void ep93xx_keypad_release_gpio(struct platform_device *pdev);
void ep93xx_register_i2s(void); void ep93xx_register_i2s(void);
int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config); int ep93xx_i2s_acquire(void);
void ep93xx_i2s_release(void); void ep93xx_i2s_release(void);
void ep93xx_register_ac97(void); void ep93xx_register_ac97(void);

View File

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

View File

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

View File

@ -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"

View File

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

View File

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

View File

@ -393,6 +393,7 @@ static void __init visstrim_m10_board_init(void)
imx27_add_fec(NULL); imx27_add_fec(NULL);
imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0);
platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0, platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
&iclink_tvp5150, sizeof(iclink_tvp5150)); &iclink_tvp5150, sizeof(iclink_tvp5150));
gpio_led_register_device(0, &visstrim_m10_led_data); gpio_led_register_device(0, &visstrim_m10_led_data);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -156,6 +156,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;
@ -173,6 +177,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 */
@ -239,6 +245,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;
@ -257,5 +267,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 */

View File

@ -164,6 +164,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 */
@ -173,6 +185,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)
@ -185,6 +201,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)
@ -200,4 +219,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));
} }

View File

@ -83,6 +83,11 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
}, },
}; };
static struct platform_device openrd_client_audio_device = {
.name = "openrd-client-audio",
.id = -1,
};
static int __initdata uart1; static int __initdata uart1;
static int __init sd_uart_selection(char *str) static int __init sd_uart_selection(char *str)
@ -172,6 +177,7 @@ static void __init openrd_init(void)
kirkwood_i2c_init(); kirkwood_i2c_init();
if (machine_is_openrd_client() || machine_is_openrd_ultimate()) { if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
platform_device_register(&openrd_client_audio_device);
i2c_register_board_info(0, i2c_board_info, i2c_register_board_info(0, i2c_board_info,
ARRAY_SIZE(i2c_board_info)); ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init(); kirkwood_audio_init();

View File

@ -106,6 +106,11 @@ static struct platform_device hp_t5325_button_device = {
} }
}; };
static struct platform_device hp_t5325_audio_device = {
.name = "t5325-audio",
.id = -1,
};
static unsigned int hp_t5325_mpp_config[] __initdata = { static unsigned int hp_t5325_mpp_config[] __initdata = {
MPP0_NF_IO2, MPP0_NF_IO2,
MPP1_SPI_MOSI, MPP1_SPI_MOSI,
@ -179,6 +184,7 @@ static void __init hp_t5325_init(void)
kirkwood_sata_init(&hp_t5325_sata_data); kirkwood_sata_init(&hp_t5325_sata_data);
kirkwood_ehci_init(); kirkwood_ehci_init();
platform_device_register(&hp_t5325_button_device); platform_device_register(&hp_t5325_button_device);
platform_device_register(&hp_t5325_audio_device);
i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info)); i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init(); kirkwood_audio_init();

View File

@ -41,6 +41,7 @@
#include <video/omap-panel-nokia-dsi.h> #include <video/omap-panel-nokia-dsi.h>
#include <video/omap-panel-picodlp.h> #include <video/omap-panel-picodlp.h>
#include <linux/wl12xx.h> #include <linux/wl12xx.h>
#include <linux/platform_data/omap-abe-twl6040.h>
#include "mux.h" #include "mux.h"
#include "hsmmc.h" #include "hsmmc.h"
@ -381,12 +382,40 @@ static struct platform_device sdp4430_dmic_codec = {
.id = -1, .id = -1,
}; };
static struct omap_abe_twl6040_data sdp4430_abe_audio_data = {
.card_name = "SDP4430",
.has_hs = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
.has_hf = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
.has_ep = 1,
.has_aux = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
.has_vibra = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
.has_dmic = 1,
.has_hsmic = 1,
.has_mainmic = 1,
.has_submic = 1,
.has_afm = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
.jack_detection = 1,
/* MCLK input is 38.4MHz */
.mclk_freq = 38400000,
};
static struct platform_device sdp4430_abe_audio = {
.name = "omap-abe-twl6040",
.id = -1,
.dev = {
.platform_data = &sdp4430_abe_audio_data,
},
};
static struct platform_device *sdp4430_devices[] __initdata = { static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_gpio_keys_device, &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio, &sdp4430_leds_gpio,
&sdp4430_leds_pwm, &sdp4430_leds_pwm,
&sdp4430_vbat, &sdp4430_vbat,
&sdp4430_dmic_codec, &sdp4430_dmic_codec,
&sdp4430_abe_audio,
}; };
static struct omap_musb_board_data musb_board_data = { static struct omap_musb_board_data musb_board_data = {

View File

@ -28,6 +28,7 @@
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h> #include <linux/regulator/fixed.h>
#include <linux/wl12xx.h> #include <linux/wl12xx.h>
#include <linux/platform_data/omap-abe-twl6040.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
@ -91,6 +92,30 @@ static struct platform_device leds_gpio = {
}, },
}; };
static struct omap_abe_twl6040_data panda_abe_audio_data = {
/* Audio out */
.has_hs = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
/* HandsFree through expasion connector */
.has_hf = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
/* PandaBoard: FM TX, PandaBoardES: can be connected to audio out */
.has_aux = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
/* PandaBoard: FM RX, PandaBoardES: audio in */
.has_afm = ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
/* No jack detection. */
.jack_detection = 0,
/* MCLK input is 38.4MHz */
.mclk_freq = 38400000,
};
static struct platform_device panda_abe_audio = {
.name = "omap-abe-twl6040",
.id = -1,
.dev = {
.platform_data = &panda_abe_audio_data,
},
};
static struct platform_device btwilink_device = { static struct platform_device btwilink_device = {
.name = "btwilink", .name = "btwilink",
.id = -1, .id = -1,
@ -99,6 +124,7 @@ static struct platform_device btwilink_device = {
static struct platform_device *panda_devices[] __initdata = { static struct platform_device *panda_devices[] __initdata = {
&leds_gpio, &leds_gpio,
&wl1271_device, &wl1271_device,
&panda_abe_audio,
&btwilink_device, &btwilink_device,
}; };
@ -258,8 +284,25 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
return 0; return 0;
} }
static struct twl4030_codec_data twl6040_codec = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
.hf_left_step = 0x1d,
.hf_right_step = 0x1d,
};
static struct twl4030_audio_data twl6040_audio = {
.codec = &twl6040_codec,
.audpwron_gpio = 127,
.naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
};
/* Panda board uses the common PMIC configuration */ /* Panda board uses the common PMIC configuration */
static struct twl4030_platform_data omap4_panda_twldata; static struct twl4030_platform_data omap4_panda_twldata = {
.audio = &twl6040_audio,
};
/* /*
* Display monitor features are burnt in their EEPROM as EDID data. The EEPROM * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
@ -491,6 +534,20 @@ void omap4_panda_display_init(void)
omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
} }
static void omap4_panda_init_rev(void)
{
if (cpu_is_omap4430()) {
/* PandaBoard 4430 */
/* ASoC audio configuration */
panda_abe_audio_data.card_name = "PandaBoard";
panda_abe_audio_data.has_hsmic = 1;
} else {
/* PandaBoard ES */
/* ASoC audio configuration */
panda_abe_audio_data.card_name = "PandaBoardES";
}
}
static void __init omap4_panda_init(void) static void __init omap4_panda_init(void)
{ {
int package = OMAP_PACKAGE_CBS; int package = OMAP_PACKAGE_CBS;
@ -504,6 +561,7 @@ static void __init omap4_panda_init(void)
if (ret) if (ret)
pr_err("error setting wl12xx data: %d\n", ret); pr_err("error setting wl12xx data: %d\n", ret);
omap4_panda_init_rev();
omap4_panda_i2c_init(); omap4_panda_i2c_init();
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
platform_device_register(&omap_vwlan_device); platform_device_register(&omap_vwlan_device);

View File

@ -120,6 +120,7 @@ static struct wm8962_pdata wm8962_pdata __initdata = {
0x8000 | WM8962_GPIO_FN_DMICDAT, 0x8000 | WM8962_GPIO_FN_DMICDAT,
WM8962_GPIO_FN_IRQ, /* Open drain mode */ WM8962_GPIO_FN_IRQ, /* Open drain mode */
}, },
.in4_dc_measure = true,
}; };
static struct wm9081_pdata wm9081_pdata __initdata = { static struct wm9081_pdata wm9081_pdata __initdata = {

View File

@ -737,26 +737,18 @@ fsi_set_rate_end:
return ret; return ret;
} }
static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
{
int ret;
if (is_porta)
ret = fsi_ak4642_set_rate(dev, rate, enable);
else
ret = fsi_hdmi_set_rate(dev, rate, enable);
return ret;
}
static struct sh_fsi_platform_info fsi_info = { static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV, .port_a = {
.flags = SH_FSI_BRS_INV,
.portb_flags = SH_FSI_BRS_INV | .set_rate = fsi_ak4642_set_rate,
SH_FSI_BRM_INV | },
SH_FSI_LRS_INV | .port_b = {
SH_FSI_FMT_SPDIF, .flags = SH_FSI_BRS_INV |
.set_rate = fsi_set_rate, SH_FSI_BRM_INV |
SH_FSI_LRS_INV |
SH_FSI_FMT_SPDIF,
.set_rate = fsi_hdmi_set_rate,
},
}; };
static struct resource fsi_resources[] = { static struct resource fsi_resources[] = {

View File

@ -860,7 +860,7 @@ static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
return clk_enable(clk); return clk_enable(clk);
} }
static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) static int fsi_b_set_rate(struct device *dev, int rate, int enable)
{ {
struct clk *fsib_clk; struct clk *fsib_clk;
struct clk *fdiv_clk = &sh7372_fsidivb_clk; struct clk *fdiv_clk = &sh7372_fsidivb_clk;
@ -869,10 +869,6 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
int ackmd_bpfmd; int ackmd_bpfmd;
int ret; int ret;
/* FSIA is slave mode. nothing to do here */
if (is_porta)
return 0;
/* clock start */ /* clock start */
switch (rate) { switch (rate) {
case 44100: case 44100:
@ -916,14 +912,16 @@ fsi_set_rate_end:
} }
static struct sh_fsi_platform_info fsi_info = { static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV, .port_a = {
.flags = SH_FSI_BRS_INV,
.portb_flags = SH_FSI_BRS_INV | },
.port_b = {
.flags = SH_FSI_BRS_INV |
SH_FSI_BRM_INV | SH_FSI_BRM_INV |
SH_FSI_LRS_INV | SH_FSI_LRS_INV |
SH_FSI_FMT_SPDIF, SH_FSI_FMT_SPDIF,
.set_rate = fsi_b_set_rate,
.set_rate = fsi_set_rate, }
}; };
static struct resource fsi_resources[] = { static struct resource fsi_resources[] = {

View File

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

View File

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

View File

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

View File

@ -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 */

View File

@ -418,6 +418,11 @@ static struct platform_device qi_lb60_charger_device = {
}, },
}; };
/* audio */
static struct platform_device qi_lb60_audio_device = {
.name = "qi-lb60-audio",
.id = -1,
};
static struct platform_device *jz_platform_devices[] __initdata = { static struct platform_device *jz_platform_devices[] __initdata = {
&jz4740_udc_device, &jz4740_udc_device,
@ -434,6 +439,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&qi_lb60_gpio_keys, &qi_lb60_gpio_keys,
&qi_lb60_pwm_beeper, &qi_lb60_pwm_beeper,
&qi_lb60_charger_device, &qi_lb60_charger_device,
&qi_lb60_audio_device,
}; };
static void __init board_gpio_setup(void) static void __init board_gpio_setup(void)

View File

@ -769,7 +769,9 @@ static struct platform_device camera_devices[] = {
/* FSI */ /* FSI */
static struct sh_fsi_platform_info fsi_info = { static struct sh_fsi_platform_info fsi_info = {
.portb_flags = SH_FSI_BRS_INV, .port_b = {
.flags = SH_FSI_BRS_INV,
},
}; };
static struct resource fsi_resources[] = { static struct resource fsi_resources[] = {

View File

@ -278,7 +278,9 @@ static struct platform_device ceu1_device = {
/* FSI */ /* FSI */
/* change J20, J21, J22 pin to 1-2 connection to use slave mode */ /* change J20, J21, J22 pin to 1-2 connection to use slave mode */
static struct sh_fsi_platform_info fsi_info = { static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV, .port_a = {
.flags = SH_FSI_BRS_INV,
},
}; };
static struct resource fsi_resources[] = { static struct resource fsi_resources[] = {

View File

@ -75,6 +75,9 @@ struct regmap {
const void *reg_defaults_raw; const void *reg_defaults_raw;
void *cache; void *cache;
bool cache_dirty; bool cache_dirty;
struct reg_default *patch;
int patch_regs;
}; };
struct regcache_ops { struct regcache_ops {

View File

@ -268,6 +268,17 @@ int regcache_sync(struct regmap *map)
map->cache_ops->name); map->cache_ops->name);
name = map->cache_ops->name; name = map->cache_ops->name;
trace_regcache_sync(map->dev, name, "start"); trace_regcache_sync(map->dev, name, "start");
/* Apply any patch first */
for (i = 0; i < map->patch_regs; i++) {
ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
if (ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
map->patch[i].reg, map->patch[i].def, ret);
goto out;
}
}
if (!map->cache_dirty) if (!map->cache_dirty)
goto out; goto out;
if (map->cache_ops->sync) { if (map->cache_ops->sync) {

View File

@ -672,6 +672,79 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
} }
EXPORT_SYMBOL_GPL(regmap_update_bits_check); EXPORT_SYMBOL_GPL(regmap_update_bits_check);
/**
* regmap_register_patch: Register and apply register updates to be applied
* on device initialistion
*
* @map: Register map to apply updates to.
* @regs: Values to update.
* @num_regs: Number of entries in regs.
*
* Register a set of register updates to be applied to the device
* whenever the device registers are synchronised with the cache and
* apply them immediately. Typically this is used to apply
* corrections to be applied to the device defaults on startup, such
* as the updates some vendors provide to undocumented registers.
*/
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
int num_regs)
{
int i, ret;
bool bypass;
/* If needed the implementation can be extended to support this */
if (map->patch)
return -EBUSY;
mutex_lock(&map->lock);
bypass = map->cache_bypass;
map->cache_bypass = true;
/* Write out first; it's useful to apply even if we fail later. */
for (i = 0; i < num_regs; i++) {
ret = _regmap_write(map, regs[i].reg, regs[i].def);
if (ret != 0) {
dev_err(map->dev, "Failed to write %x = %x: %d\n",
regs[i].reg, regs[i].def, ret);
goto out;
}
}
map->patch = kcalloc(sizeof(struct reg_default), num_regs, GFP_KERNEL);
if (map->patch != NULL) {
memcpy(map->patch, regs,
num_regs * sizeof(struct reg_default));
map->patch_regs = num_regs;
} else {
ret = -ENOMEM;
}
out:
map->cache_bypass = bypass;
mutex_unlock(&map->lock);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_register_patch);
/*
* regmap_get_val_bytes(): Report the size of a register value
*
* Report the size of a register value, mainly intended to for use by
* generic infrastructure built on top of regmap.
*/
int regmap_get_val_bytes(struct regmap *map)
{
if (map->format.format_write)
return -EINVAL;
return map->format.val_bytes;
}
EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
static int __init regmap_initcall(void) static int __init regmap_initcall(void)
{ {
regmap_debugfs_initcall(); regmap_debugfs_initcall();

View File

@ -1320,6 +1320,40 @@ struct regulator *regulator_get(struct device *dev, const char *id)
} }
EXPORT_SYMBOL_GPL(regulator_get); EXPORT_SYMBOL_GPL(regulator_get);
static void devm_regulator_release(struct device *dev, void *res)
{
regulator_put(*(struct regulator **)res);
}
/**
* devm_regulator_get - Resource managed regulator_get()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get(). Regulators returned from this function are
* automatically regulator_put() on driver detach. See regulator_get() for more
* information.
*/
struct regulator *devm_regulator_get(struct device *dev, const char *id)
{
struct regulator **ptr, *regulator;
ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
regulator = regulator_get(dev, id);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return regulator;
}
EXPORT_SYMBOL_GPL(devm_regulator_get);
/** /**
* regulator_get_exclusive - obtain exclusive access to a regulator. * regulator_get_exclusive - obtain exclusive access to a regulator.
* @dev: device for regulator "consumer" * @dev: device for regulator "consumer"
@ -1387,6 +1421,34 @@ void regulator_put(struct regulator *regulator)
} }
EXPORT_SYMBOL_GPL(regulator_put); EXPORT_SYMBOL_GPL(regulator_put);
static int devm_regulator_match(struct device *dev, void *res, void *data)
{
struct regulator **r = res;
if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}
return *r == data;
}
/**
* devm_regulator_put - Resource managed regulator_put()
* @regulator: regulator to free
*
* Deallocate a regulator allocated with devm_regulator_get(). Normally
* this function will not need to be called and the resource management
* code will ensure that the resource is freed.
*/
void devm_regulator_put(struct regulator *regulator)
{
int rc;
rc = devres_destroy(regulator->dev, devm_regulator_release,
devm_regulator_match, regulator);
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_regulator_put);
static int _regulator_can_change_status(struct regulator_dev *rdev) static int _regulator_can_change_status(struct regulator_dev *rdev)
{ {
if (!rdev->constraints) if (!rdev->constraints)
@ -2401,6 +2463,52 @@ err:
} }
EXPORT_SYMBOL_GPL(regulator_bulk_get); EXPORT_SYMBOL_GPL(regulator_bulk_get);
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
* @dev: Device to supply
* @num_consumers: Number of consumers to register
* @consumers: Configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation with management, the regulators will
* automatically be freed when the device is unbound. If any of the
* regulators cannot be acquired then any regulators that were
* allocated will be freed before returning to the caller.
*/
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
int i;
int ret;
for (i = 0; i < num_consumers; i++)
consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = devm_regulator_get(dev,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n",
consumers[i].supply, ret);
consumers[i].consumer = NULL;
goto err;
}
}
return 0;
err:
for (i = 0; i < num_consumers && consumers[i].consumer; i++)
devm_regulator_put(consumers[i].consumer);
return ret;
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
{ {
struct regulator_bulk_data *bulk = data; struct regulator_bulk_data *bulk = data;

View File

@ -185,6 +185,9 @@ struct wm8994_pdata {
unsigned int jd_scthr:2; unsigned int jd_scthr:2;
unsigned int jd_thr:2; unsigned int jd_thr:2;
/* Configure WM1811 jack detection for use with external capacitor */
unsigned int jd_ext_cap:1;
/* WM8958 microphone bias configuration */ /* WM8958 microphone bias configuration */
int micbias[2]; int micbias[2];

View File

@ -0,0 +1,49 @@
/**
* omap-abe-twl6040.h - ASoC machine driver OMAP4+ devices, header.
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
* All rights reserved.
*
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef _OMAP_ABE_TWL6040_H_
#define _OMAP_ABE_TWL6040_H_
/* To select if only one channel is connected in a stereo port */
#define ABE_TWL6040_LEFT (1 << 0)
#define ABE_TWL6040_RIGHT (1 << 1)
struct omap_abe_twl6040_data {
char *card_name;
/* Feature flags for connected audio pins */
u8 has_hs;
u8 has_hf;
bool has_ep;
u8 has_aux;
u8 has_vibra;
bool has_dmic;
bool has_hsmic;
bool has_mainmic;
bool has_submic;
u8 has_afm;
/* Other features */
bool jack_detection; /* board can detect jack events */
int mclk_freq; /* MCLK frequency speed for twl6040 */
};
#endif /* _OMAP_ABE_TWL6040_H_ */

View File

@ -143,12 +143,16 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
int regmap_update_bits_check(struct regmap *map, unsigned int reg, int regmap_update_bits_check(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val, unsigned int mask, unsigned int val,
bool *change); bool *change);
int regmap_get_val_bytes(struct regmap *map);
int regcache_sync(struct regmap *map); int regcache_sync(struct regmap *map);
void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_only(struct regmap *map, bool enable);
void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable);
void regcache_mark_dirty(struct regmap *map); void regcache_mark_dirty(struct regmap *map);
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
int num_regs);
/** /**
* Description of an IRQ for the generic regmap irq_chip. * Description of an IRQ for the generic regmap irq_chip.
* *

View File

@ -132,9 +132,12 @@ struct regulator_bulk_data {
/* regulator get and put */ /* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev, struct regulator *__must_check regulator_get(struct device *dev,
const char *id); const char *id);
struct regulator *__must_check devm_regulator_get(struct device *dev,
const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev, struct regulator *__must_check regulator_get_exclusive(struct device *dev,
const char *id); const char *id);
void regulator_put(struct regulator *regulator); void regulator_put(struct regulator *regulator);
void devm_regulator_free(struct regulator *regulator);
/* regulator output control and status */ /* regulator output control and status */
int regulator_enable(struct regulator *regulator); int regulator_enable(struct regulator *regulator);
@ -145,6 +148,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms);
int regulator_bulk_get(struct device *dev, int num_consumers, int regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers); struct regulator_bulk_data *consumers);
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers);
int regulator_bulk_enable(int num_consumers, int regulator_bulk_enable(int num_consumers,
struct regulator_bulk_data *consumers); struct regulator_bulk_data *consumers);
int regulator_bulk_disable(int num_consumers, int regulator_bulk_disable(int num_consumers,
@ -200,6 +205,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
*/ */
return NULL; return NULL;
} }
static inline struct regulator *__must_check
devm_regulator_get(struct device *dev, const char *id)
{
return NULL;
}
static inline void regulator_put(struct regulator *regulator) static inline void regulator_put(struct regulator *regulator)
{ {
} }

View File

@ -40,7 +40,7 @@ struct snd_kcontrol_new {
snd_ctl_elem_iface_t iface; /* interface identifier */ snd_ctl_elem_iface_t iface; /* interface identifier */
unsigned int device; /* device/client number */ unsigned int device; /* device/client number */
unsigned int subdevice; /* subdevice (substream) number */ unsigned int subdevice; /* subdevice (substream) number */
unsigned char *name; /* ASCII name of item */ const unsigned char *name; /* ASCII name of item */
unsigned int index; /* index of item */ unsigned int index; /* index of item */
unsigned int access; /* access rights */ unsigned int access; /* access rights */
unsigned int count; /* count of same elements */ unsigned int count; /* count of same elements */

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2012, Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __SOUND_DMAENGINE_PCM_H__
#define __SOUND_DMAENGINE_PCM_H__
#include <sound/pcm.h>
#include <linux/dmaengine.h>
/**
* snd_pcm_substream_to_dma_direction - Get dma_transfer_direction for a PCM
* substream
* @substream: PCM substream
*/
static inline enum dma_transfer_direction
snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
{
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return DMA_MEM_TO_DEV;
else
return DMA_DEV_TO_MEM;
}
void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data);
void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream);
int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
dma_filter_fn filter_fn, void *filter_data);
int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
#endif

24
include/sound/max9768.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Platform data for MAX9768
* Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
* same licence as the driver
*/
#ifndef __SOUND_MAX9768_PDATA_H__
#define __SOUND_MAX9768_PDATA_H__
/**
* struct max9768_pdata - optional platform specific MAX9768 configuration
* @shdn_gpio: GPIO to SHDN pin. If not valid, pin must be hardwired HIGH
* @mute_gpio: GPIO to MUTE pin. If not valid, control for mute won't be added
* @flags: configuration flags, e.g. set classic PWM mode (check datasheet
* regarding "filterless modulation" which is default).
*/
struct max9768_pdata {
int shdn_gpio;
int mute_gpio;
unsigned flags;
#define MAX9768_FLAG_CLASSIC_PWM (1 << 0)
};
#endif /* __SOUND_MAX9768_PDATA_H__*/

View File

@ -454,6 +454,7 @@ struct snd_pcm {
void *private_data; void *private_data;
void (*private_free) (struct snd_pcm *pcm); void (*private_free) (struct snd_pcm *pcm);
struct device *dev; /* actual hw device this belongs to */ struct device *dev; /* actual hw device this belongs to */
bool internal; /* pcm is for internal use only */
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
struct snd_pcm_oss oss; struct snd_pcm_oss oss;
#endif #endif
@ -475,6 +476,9 @@ extern const struct file_operations snd_pcm_f_ops[2];
int snd_pcm_new(struct snd_card *card, const char *id, int device, int snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count, int playback_count, int capture_count,
struct snd_pcm **rpcm); struct snd_pcm **rpcm);
int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm **rpcm);
int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count); int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree); int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);

View File

@ -72,10 +72,16 @@
#define SH_FSI_BPFMD_32 (5 << 4) #define SH_FSI_BPFMD_32 (5 << 4)
#define SH_FSI_BPFMD_16 (6 << 4) #define SH_FSI_BPFMD_16 (6 << 4)
struct sh_fsi_port_info {
unsigned long flags;
int tx_id;
int rx_id;
int (*set_rate)(struct device *dev, int rate, int enable);
};
struct sh_fsi_platform_info { struct sh_fsi_platform_info {
unsigned long porta_flags; struct sh_fsi_port_info port_a;
unsigned long portb_flags; struct sh_fsi_port_info port_b;
int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
}; };
/* /*

View File

@ -17,6 +17,7 @@
#include <linux/list.h> #include <linux/list.h>
struct snd_pcm_substream; struct snd_pcm_substream;
struct snd_soc_dapm_widget;
/* /*
* DAI hardware audio formats. * DAI hardware audio formats.
@ -238,6 +239,9 @@ struct snd_soc_dai {
unsigned char pop_wait:1; unsigned char pop_wait:1;
unsigned char probed:1; unsigned char probed:1;
struct snd_soc_dapm_widget *playback_widget;
struct snd_soc_dapm_widget *capture_widget;
/* DAI DMA data */ /* DAI DMA data */
void *playback_dma_data; void *playback_dma_data;
void *capture_dma_data; void *capture_dma_data;
@ -246,10 +250,9 @@ struct snd_soc_dai {
unsigned int rate; unsigned int rate;
/* parent platform/codec */ /* parent platform/codec */
union { struct snd_soc_platform *platform;
struct snd_soc_platform *platform; struct snd_soc_codec *codec;
struct snd_soc_codec *codec;
};
struct snd_soc_card *card; struct snd_soc_card *card;
struct list_head list; struct list_head list;

View File

@ -243,6 +243,10 @@
{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \ { .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .event = wevent, \ .shift = wshift, .invert = winvert, .event = wevent, \
.event_flags = wflags} .event_flags = wflags}
#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay) \
{ .id = snd_soc_dapm_regulator_supply, .name = wname, \
.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
/* dapm kcontrol types */ /* dapm kcontrol types */
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
@ -322,6 +326,8 @@ struct snd_soc_dapm_context;
int dapm_reg_event(struct snd_soc_dapm_widget *w, int dapm_reg_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event); struct snd_kcontrol *kcontrol, int event);
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
/* dapm controls */ /* dapm controls */
int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
@ -346,11 +352,12 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol); struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uncontrol); struct snd_ctl_elem_value *uncontrol);
int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget, const struct snd_soc_dapm_widget *widget,
int num); int num);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
/* dapm path setup */ /* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm); int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
@ -361,10 +368,16 @@ int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num); const struct snd_soc_dapm_route *route, int num);
/* dapm events */ /* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
const char *stream, int event); struct snd_soc_dai *dai, int event);
void snd_soc_dapm_shutdown(struct snd_soc_card *card); void snd_soc_dapm_shutdown(struct snd_soc_card *card);
/* external DAPM widget events */
int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *kcontrol, int connect);
int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e);
/* dapm sys fs - used by the core */ /* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev); int snd_soc_dapm_sys_add(struct device *dev);
void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
@ -411,9 +424,11 @@ enum snd_soc_dapm_type {
snd_soc_dapm_pre, /* machine specific pre widget - exec first */ snd_soc_dapm_pre, /* machine specific pre widget - exec first */
snd_soc_dapm_post, /* machine specific post widget - exec last */ snd_soc_dapm_post, /* machine specific post widget - exec last */
snd_soc_dapm_supply, /* power/clock supply */ snd_soc_dapm_supply, /* power/clock supply */
snd_soc_dapm_regulator_supply, /* external regulator */
snd_soc_dapm_aif_in, /* audio interface input */ snd_soc_dapm_aif_in, /* audio interface input */
snd_soc_dapm_aif_out, /* audio interface output */ snd_soc_dapm_aif_out, /* audio interface output */
snd_soc_dapm_siggen, /* signal generator */ snd_soc_dapm_siggen, /* signal generator */
snd_soc_dapm_dai, /* link to DAI structure */
}; };
/* /*
@ -434,8 +449,8 @@ struct snd_soc_dapm_route {
/* dapm audio path between two widgets */ /* dapm audio path between two widgets */
struct snd_soc_dapm_path { struct snd_soc_dapm_path {
char *name; const char *name;
char *long_name; const char *long_name;
/* source (input) and sink (output) widgets */ /* source (input) and sink (output) widgets */
struct snd_soc_dapm_widget *source; struct snd_soc_dapm_widget *source;
@ -458,13 +473,15 @@ struct snd_soc_dapm_path {
/* dapm widget */ /* dapm widget */
struct snd_soc_dapm_widget { struct snd_soc_dapm_widget {
enum snd_soc_dapm_type id; enum snd_soc_dapm_type id;
char *name; /* widget name */ const char *name; /* widget name */
char *sname; /* stream name */ const char *sname; /* stream name */
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct snd_soc_platform *platform; struct snd_soc_platform *platform;
struct list_head list; struct list_head list;
struct snd_soc_dapm_context *dapm; struct snd_soc_dapm_context *dapm;
void *priv; /* widget specific data */
/* dapm control */ /* dapm control */
short reg; /* negative reg = no direct dapm */ short reg; /* negative reg = no direct dapm */
unsigned char shift; /* bits to shift */ unsigned char shift; /* bits to shift */

View File

@ -185,6 +185,20 @@
.rreg = xreg_right, .shift = xshift, \ .rreg = xreg_right, .shift = xshift, \
.min = xmin, .max = xmax} } .min = xmin, .max = xmax} }
#define SND_SOC_BYTES(xname, xbase, xregs) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
.put = snd_soc_bytes_put, .private_value = \
((unsigned long)&(struct soc_bytes) \
{.base = xbase, .num_regs = xregs }) }
#define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
.put = snd_soc_bytes_put, .private_value = \
((unsigned long)&(struct soc_bytes) \
{.base = xbase, .num_regs = xregs, \
.mask = xmask }) }
/* /*
* Simplified versions of above macros, declaring a struct and calculating * Simplified versions of above macros, declaring a struct and calculating
@ -366,12 +380,16 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
*Controls *Controls
*/ */
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
void *data, char *long_name, void *data, const char *long_name,
const char *prefix); const char *prefix);
int snd_soc_add_controls(struct snd_soc_codec *codec, int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
const struct snd_kcontrol_new *controls, int num_controls); const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_add_platform_controls(struct snd_soc_platform *platform, int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
const struct snd_kcontrol_new *controls, int num_controls); const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo); struct snd_ctl_elem_info *uinfo);
int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
@ -409,6 +427,13 @@ int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol); struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol, int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol); struct snd_ctl_elem_value *ucontrol);
int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
/** /**
* struct snd_soc_reg_access - Describes whether a given register is * struct snd_soc_reg_access - Describes whether a given register is
@ -505,6 +530,7 @@ struct snd_soc_pcm_stream {
unsigned int rate_max; /* max rate */ unsigned int rate_max; /* max rate */
unsigned int channels_min; /* min channels */ unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */ unsigned int channels_max; /* max channels */
unsigned int sig_bits; /* number of bits of content */
}; };
/* SoC audio ops */ /* SoC audio ops */
@ -559,6 +585,7 @@ struct snd_soc_codec {
unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */ unsigned int sysfs_registered:1; /* codec has been sysfs registered */
unsigned int cache_init:1; /* codec cache has been initialized */ unsigned int cache_init:1; /* codec cache has been initialized */
unsigned int using_regmap:1; /* using regmap access */
u32 cache_only; /* Suppress writes to hardware */ u32 cache_only; /* Suppress writes to hardware */
u32 cache_sync; /* Cache needs to be synced to hardware */ u32 cache_sync; /* Cache needs to be synced to hardware */
@ -637,6 +664,8 @@ struct snd_soc_codec_driver {
/* codec stream completion event */ /* codec stream completion event */
int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */
/* probe ordering - for components with runtime dependencies */ /* probe ordering - for components with runtime dependencies */
int probe_order; int probe_order;
int remove_order; int remove_order;
@ -689,6 +718,7 @@ struct snd_soc_platform {
int id; int id;
struct device *dev; struct device *dev;
struct snd_soc_platform_driver *driver; struct snd_soc_platform_driver *driver;
struct mutex mutex;
unsigned int suspended:1; /* platform is suspended */ unsigned int suspended:1; /* platform is suspended */
unsigned int probed:1; unsigned int probed:1;
@ -698,6 +728,11 @@ struct snd_soc_platform {
struct list_head card_list; struct list_head card_list;
struct snd_soc_dapm_context dapm; struct snd_soc_dapm_context dapm;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_platform_root;
struct dentry *debugfs_dapm;
#endif
}; };
struct snd_soc_dai_link { struct snd_soc_dai_link {
@ -875,6 +910,12 @@ struct soc_mixer_control {
unsigned int reg, rreg, shift, rshift, invert; unsigned int reg, rreg, shift, rshift, invert;
}; };
struct soc_bytes {
int base;
int num_regs;
u32 mask;
};
/* enumerated kcontrol */ /* enumerated kcontrol */
struct soc_enum { struct soc_enum {
unsigned short reg; unsigned short reg;

41
include/sound/wm2200.h Normal file
View File

@ -0,0 +1,41 @@
/*
* linux/sound/wm2200.h -- Platform data for WM2200
*
* Copyright 2012 Wolfson Microelectronics. PLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_SND_WM2200_H
#define __LINUX_SND_WM2200_H
#define WM2200_GPIO_SET 0x10000
enum wm2200_in_mode {
WM2200_IN_SE = 0,
WM2200_IN_DIFF = 1,
WM2200_IN_DMIC = 2,
};
enum wm2200_dmic_sup {
WM2200_DMIC_SUP_MICVDD = 0,
WM2200_DMIC_SUP_MICBIAS1 = 1,
WM2200_DMIC_SUP_MICBIAS2 = 2,
};
struct wm2200_pdata {
int reset; /** GPIO controlling /RESET, if any */
int ldo_ena; /** GPIO controlling LODENA, if any */
int irq_flags;
int gpio_defaults[4];
enum wm2200_in_mode in_mode[3];
enum wm2200_dmic_sup dmic_sup[3];
int micbias_cfg[2]; /** Register value to configure MICBIAS */
};
#endif

View File

@ -49,6 +49,12 @@ struct wm8962_pdata {
bool irq_active_low; bool irq_active_low;
bool spk_mono; /* Speaker outputs tied together as mono */ bool spk_mono; /* Speaker outputs tied together as mono */
/**
* This flag should be set if one or both IN4 inputs is wired
* in a DC measurement configuration.
*/
bool in4_dc_measure;
}; };
#endif #endif

View File

@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
pstr->stream = stream; pstr->stream = stream;
pstr->pcm = pcm; pstr->pcm = pcm;
pstr->substream_count = substream_count; pstr->substream_count = substream_count;
if (substream_count > 0) { if (substream_count > 0 && !pcm->internal) {
err = snd_pcm_stream_proc_init(pstr); err = snd_pcm_stream_proc_init(pstr);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
@ -674,15 +674,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
pstr->substream = substream; pstr->substream = substream;
else else
prev->next = substream; prev->next = substream;
err = snd_pcm_substream_proc_init(substream);
if (err < 0) { if (!pcm->internal) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); err = snd_pcm_substream_proc_init(substream);
if (prev == NULL) if (err < 0) {
pstr->substream = NULL; snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
else if (prev == NULL)
prev->next = NULL; pstr->substream = NULL;
kfree(substream); else
return err; prev->next = NULL;
kfree(substream);
return err;
}
} }
substream->group = &substream->self_group; substream->group = &substream->self_group;
spin_lock_init(&substream->self_group.lock); spin_lock_init(&substream->self_group.lock);
@ -696,25 +699,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
EXPORT_SYMBOL(snd_pcm_new_stream); EXPORT_SYMBOL(snd_pcm_new_stream);
/** static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
* snd_pcm_new - create a new PCM instance int playback_count, int capture_count, bool internal,
* @card: the card instance struct snd_pcm **rpcm)
* @id: the id string
* @device: the device index (zero based)
* @playback_count: the number of substreams for playback
* @capture_count: the number of substreams for capture
* @rpcm: the pointer to store the new pcm instance
*
* Creates a new PCM instance.
*
* The pcm operators have to be set afterwards to the new instance
* via snd_pcm_set_ops().
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm ** rpcm)
{ {
struct snd_pcm *pcm; struct snd_pcm *pcm;
int err; int err;
@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
} }
pcm->card = card; pcm->card = card;
pcm->device = device; pcm->device = device;
pcm->internal = internal;
if (id) if (id)
strlcpy(pcm->id, id, sizeof(pcm->id)); strlcpy(pcm->id, id, sizeof(pcm->id));
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
@ -756,8 +744,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
return 0; return 0;
} }
/**
* snd_pcm_new - create a new PCM instance
* @card: the card instance
* @id: the id string
* @device: the device index (zero based)
* @playback_count: the number of substreams for playback
* @capture_count: the number of substreams for capture
* @rpcm: the pointer to store the new pcm instance
*
* Creates a new PCM instance.
*
* The pcm operators have to be set afterwards to the new instance
* via snd_pcm_set_ops().
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count, struct snd_pcm **rpcm)
{
return _snd_pcm_new(card, id, device, playback_count, capture_count,
false, rpcm);
}
EXPORT_SYMBOL(snd_pcm_new); EXPORT_SYMBOL(snd_pcm_new);
/**
* snd_pcm_new_internal - create a new internal PCM instance
* @card: the card instance
* @id: the id string
* @device: the device index (zero based - shared with normal PCMs)
* @playback_count: the number of substreams for playback
* @capture_count: the number of substreams for capture
* @rpcm: the pointer to store the new pcm instance
*
* Creates a new internal PCM instance with no userspace device or procfs
* entries. This is used by ASoC Back End PCMs in order to create a PCM that
* will only be used internally by kernel drivers. i.e. it cannot be opened
* by userspace. It provides existing ASoC components drivers with a substream
* and access to any private data.
*
* The pcm operators have to be set afterwards to the new instance
* via snd_pcm_set_ops().
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm **rpcm)
{
return _snd_pcm_new(card, id, device, playback_count, capture_count,
true, rpcm);
}
EXPORT_SYMBOL(snd_pcm_new_internal);
static void snd_pcm_free_stream(struct snd_pcm_str * pstr) static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
{ {
struct snd_pcm_substream *substream, *substream_next; struct snd_pcm_substream *substream, *substream_next;
@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
} }
for (cidx = 0; cidx < 2; cidx++) { for (cidx = 0; cidx < 2; cidx++) {
int devtype = -1; int devtype = -1;
if (pcm->streams[cidx].substream == NULL) if (pcm->streams[cidx].substream == NULL || pcm->internal)
continue; continue;
switch (cidx) { switch (cidx) {
case SNDRV_PCM_STREAM_PLAYBACK: case SNDRV_PCM_STREAM_PLAYBACK:

View File

@ -25,6 +25,9 @@ if SND_SOC
config SND_SOC_AC97_BUS config SND_SOC_AC97_BUS
bool bool
config SND_SOC_DMAENGINE_PCM
bool
# All the supported SoCs # All the supported SoCs
source "sound/soc/atmel/Kconfig" source "sound/soc/atmel/Kconfig"
source "sound/soc/au1x/Kconfig" source "sound/soc/au1x/Kconfig"

View File

@ -1,6 +1,9 @@
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
snd-soc-core-objs += soc-pcm.o soc-io.o snd-soc-core-objs += soc-pcm.o soc-io.o
snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o
obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += codecs/
obj-$(CONFIG_SND_SOC) += atmel/ obj-$(CONFIG_SND_SOC) += atmel/

View File

@ -362,7 +362,7 @@ static struct snd_pcm_ops atmel_pcm_ops = {
/*--------------------------------------------------------------------------*\ /*--------------------------------------------------------------------------*\
* ASoC platform driver * ASoC platform driver
\*--------------------------------------------------------------------------*/ \*--------------------------------------------------------------------------*/
static u64 atmel_pcm_dmamask = 0xffffffff; static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
{ {
@ -373,7 +373,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
if (!card->dev->dma_mask) if (!card->dev->dma_mask)
card->dev->dma_mask = &atmel_pcm_dmamask; card->dev->dma_mask = &atmel_pcm_dmamask;
if (!card->dev->coherent_dma_mask) if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff; card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = atmel_pcm_preallocate_dma_buffer(pcm, ret = atmel_pcm_preallocate_dma_buffer(pcm,

View File

@ -46,29 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int err; int err;
/* Set codec DAI configuration */
err = snd_soc_dai_set_fmt(codec_dai,
SND_SOC_DAIFMT_I2S|
SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBM_CFM);
if (err < 0) {
printk(KERN_ERR "can't set codec DAI configuration\n");
return err;
}
/* Set cpu DAI configuration */
err = snd_soc_dai_set_fmt(cpu_dai,
SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBM_CFM);
if (err < 0) {
printk(KERN_ERR "can't set cpu DAI configuration\n");
return err;
}
/* Set the codec system clock for DAC and ADC */ /* Set the codec system clock for DAC and ADC */
err = err =
snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
@ -91,7 +70,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
SND_SOC_DAPM_MIC("Mic Jack", NULL), SND_SOC_DAPM_MIC("Mic Jack", NULL),
}; };
static const struct snd_soc_dapm_route audio_map[] = { static const struct snd_soc_dapm_route afeb9260_audio_map[] = {
{"Headphone Jack", NULL, "LHPOUT"}, {"Headphone Jack", NULL, "LHPOUT"},
{"Headphone Jack", NULL, "RHPOUT"}, {"Headphone Jack", NULL, "RHPOUT"},
@ -106,13 +85,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = &codec->dapm;
/* Add afeb9260 specific widgets */
snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up afeb9260 specific audio path audio_map */
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
snd_soc_dapm_enable_pin(dapm, "Line In"); snd_soc_dapm_enable_pin(dapm, "Line In");
snd_soc_dapm_enable_pin(dapm, "Mic Jack"); snd_soc_dapm_enable_pin(dapm, "Mic Jack");
@ -129,6 +101,8 @@ static struct snd_soc_dai_link afeb9260_dai = {
.platform_name = "atmel_pcm-audio", .platform_name = "atmel_pcm-audio",
.codec_name = "tlv320aic23-codec.0-001a", .codec_name = "tlv320aic23-codec.0-001a",
.init = afeb9260_tlv320aic23_init, .init = afeb9260_tlv320aic23_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &afeb9260_ops, .ops = &afeb9260_ops,
}; };
@ -138,6 +112,11 @@ static struct snd_soc_card snd_soc_machine_afeb9260 = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.dai_link = &afeb9260_dai, .dai_link = &afeb9260_dai,
.num_links = 1, .num_links = 1,
.dapm_widgets = tlv320aic23_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
.dapm_routes = afeb9260_audio_map,
.num_dapm_routes = ARRAY_SIZE(afeb9260_audio_map),
}; };
static struct platform_device *afeb9260_snd_device; static struct platform_device *afeb9260_snd_device;

View File

@ -40,20 +40,8 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
int ret = 0; int ret = 0;
/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
/* set cpu DAI channel mapping */ /* set cpu DAI channel mapping */
ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
@ -68,6 +56,9 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
.hw_params = bf5xx_ad1836_hw_params, .hw_params = bf5xx_ad1836_hw_params,
}; };
#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
SND_SOC_DAIFMT_CBM_CFM)
static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
{ {
.name = "ad1836", .name = "ad1836",
@ -77,6 +68,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
.platform_name = "bfin-tdm-pcm-audio", .platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.4", .codec_name = "spi0.4",
.ops = &bf5xx_ad1836_ops, .ops = &bf5xx_ad1836_ops,
.dai_fmt = BF5XX_AD1836_DAIFMT,
}, },
{ {
.name = "ad1836", .name = "ad1836",
@ -86,6 +78,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
.platform_name = "bfin-tdm-pcm-audio", .platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.4", .codec_name = "spi0.4",
.ops = &bf5xx_ad1836_ops, .ops = &bf5xx_ad1836_ops,
.dai_fmt = BF5XX_AD1836_DAIFMT,
}, },
}; };

View File

@ -60,18 +60,6 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
break; break;
} }
/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
/* set the codec system clock for DAC and ADC */ /* set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
@ -92,6 +80,9 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
SND_SOC_DAIFMT_CBM_CFM)
static struct snd_soc_ops bf5xx_ad193x_ops = { static struct snd_soc_ops bf5xx_ad193x_ops = {
.hw_params = bf5xx_ad193x_hw_params, .hw_params = bf5xx_ad193x_hw_params,
}; };
@ -105,6 +96,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
.platform_name = "bfin-tdm-pcm-audio", .platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.5", .codec_name = "spi0.5",
.ops = &bf5xx_ad193x_ops, .ops = &bf5xx_ad193x_ops,
.dai_fmt = BF5XX_AD193X_DAIFMT,
}, },
{ {
.name = "ad193x", .name = "ad193x",
@ -114,6 +106,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
.platform_name = "bfin-tdm-pcm-audio", .platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.5", .codec_name = "spi0.5",
.ops = &bf5xx_ad193x_ops, .ops = &bf5xx_ad193x_ops,
.dai_fmt = BF5XX_AD193X_DAIFMT,
}, },
}; };

View File

@ -145,29 +145,8 @@ static int bf5xx_probe(struct snd_soc_card *card)
return 0; return 0;
} }
static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, #define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
struct snd_pcm_hw_params *params) SND_SOC_DAIFMT_CBM_CFM)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
params_format(params));
/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
return 0;
}
static struct snd_soc_ops bf5xx_ad73311_ops = {
.hw_params = bf5xx_ad73311_hw_params,
};
static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
{ {
@ -177,7 +156,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
.codec_dai_name = "ad73311-hifi", .codec_dai_name = "ad73311-hifi",
.platform_name = "bfin-i2s-pcm-audio", .platform_name = "bfin-i2s-pcm-audio",
.codec_name = "ad73311", .codec_name = "ad73311",
.ops = &bf5xx_ad73311_ops, .dai_fmt = BF5XX_AD7311_DAI_FMT,
}, },
{ {
.name = "ad73311", .name = "ad73311",
@ -186,7 +165,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
.codec_dai_name = "ad73311-hifi", .codec_dai_name = "ad73311-hifi",
.platform_name = "bfin-i2s-pcm-audio", .platform_name = "bfin-i2s-pcm-audio",
.codec_name = "ad73311", .codec_name = "ad73311",
.ops = &bf5xx_ad73311_ops, .dai_fmt = BF5XX_AD7311_DAI_FMT,
}, },
}; };

View File

@ -49,7 +49,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned int clk = 0; unsigned int clk = 0;
int ret = 0; int ret = 0;
@ -75,21 +74,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
break; break;
} }
/*
* CODEC is master for BCLK and LRC in this configuration.
*/
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;
ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk, ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
if (ret < 0) if (ret < 0)
@ -102,6 +86,10 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
.hw_params = bf5xx_ssm2602_hw_params, .hw_params = bf5xx_ssm2602_hw_params,
}; };
/* CODEC is master for BCLK and LRC in this configuration. */
#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
SND_SOC_DAIFMT_CBM_CFM)
static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
{ {
.name = "ssm2602", .name = "ssm2602",

View File

@ -67,21 +67,10 @@ static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret; int ret;
int pll_rate; int pll_rate;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
switch (params_rate(params)) { switch (params_rate(params)) {
case 48000: case 48000:
case 8000: case 8000:
@ -143,6 +132,8 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
.codec_name = "adau1373.0-001a", .codec_name = "adau1373.0-001a",
.ops = &bfin_eval_adau1373_ops, .ops = &bfin_eval_adau1373_ops,
.init = bfin_eval_adau1373_codec_init, .init = bfin_eval_adau1373_codec_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
}; };
static struct snd_soc_card bfin_eval_adau1373 = { static struct snd_soc_card bfin_eval_adau1373 = {

View File

@ -37,20 +37,9 @@ static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret; int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000, ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
@ -61,6 +50,9 @@ static struct snd_soc_ops bfin_eval_adau1701_ops = {
.hw_params = bfin_eval_adau1701_hw_params, .hw_params = bfin_eval_adau1701_hw_params,
}; };
#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
{ {
.name = "adau1701", .name = "adau1701",
@ -70,6 +62,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
.platform_name = "bfin-i2s-pcm-audio", .platform_name = "bfin-i2s-pcm-audio",
.codec_name = "adau1701.0-0034", .codec_name = "adau1701.0-0034",
.ops = &bfin_eval_adau1701_ops, .ops = &bfin_eval_adau1701_ops,
.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
}, },
{ {
.name = "adau1701", .name = "adau1701",
@ -79,6 +72,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
.platform_name = "bfin-i2s-pcm-audio", .platform_name = "bfin-i2s-pcm-audio",
.codec_name = "adau1701.0-0034", .codec_name = "adau1701.0-0034",
.ops = &bfin_eval_adau1701_ops, .ops = &bfin_eval_adau1701_ops,
.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
}, },
}; };

View File

@ -34,20 +34,9 @@ static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret; int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL, ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
27000000, params_rate(params) * 256); 27000000, params_rate(params) * 256);
if (ret) if (ret)
@ -88,6 +77,8 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
.platform_name = "bfin-i2s-pcm-audio", .platform_name = "bfin-i2s-pcm-audio",
.init = bfin_eval_adav80x_codec_init, .init = bfin_eval_adav80x_codec_init,
.ops = &bfin_eval_adav80x_ops, .ops = &bfin_eval_adav80x_ops,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
}, },
}; };

View File

@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX98088 if I2C select SND_SOC_MAX98088 if I2C
select SND_SOC_MAX98095 if I2C select SND_SOC_MAX98095 if I2C
select SND_SOC_MAX9850 if I2C select SND_SOC_MAX9850 if I2C
select SND_SOC_MAX9768 if I2C
select SND_SOC_MAX9877 if I2C select SND_SOC_MAX9877 if I2C
select SND_SOC_PCM3008 select SND_SOC_PCM3008
select SND_SOC_RT5631 if I2C select SND_SOC_RT5631 if I2C
@ -62,6 +63,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WL1273 if MFD_WL1273_CORE select SND_SOC_WL1273 if MFD_WL1273_CORE
select SND_SOC_WM1250_EV1 if I2C select SND_SOC_WM1250_EV1 if I2C
select SND_SOC_WM2000 if I2C select SND_SOC_WM2000 if I2C
select SND_SOC_WM2200 if I2C
select SND_SOC_WM5100 if I2C select SND_SOC_WM5100 if I2C
select SND_SOC_WM8350 if MFD_WM8350 select SND_SOC_WM8350 if MFD_WM8350
select SND_SOC_WM8400 if MFD_WM8400 select SND_SOC_WM8400 if MFD_WM8400
@ -292,6 +294,9 @@ config SND_SOC_WM1250_EV1
config SND_SOC_WM2000 config SND_SOC_WM2000
tristate tristate
config SND_SOC_WM2200
tristate
config SND_SOC_WM5100 config SND_SOC_WM5100
tristate tristate
@ -425,6 +430,9 @@ config SND_SOC_WM9713
config SND_SOC_LM4857 config SND_SOC_LM4857
tristate tristate
config SND_SOC_MAX9768
tristate
config SND_SOC_MAX9877 config SND_SOC_MAX9877
tristate tristate

View File

@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o
snd-soc-jz4740-codec-objs := jz4740.o snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-l3-objs := l3.o snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o snd-soc-lm4857-objs := lm4857.o
snd-soc-max9768-objs := max9768.o
snd-soc-max98088-objs := max98088.o snd-soc-max98088-objs := max98088.o
snd-soc-max98095-objs := max98095.o snd-soc-max98095-objs := max98095.o
snd-soc-max9850-objs := max9850.o snd-soc-max9850-objs := max9850.o
@ -51,6 +52,7 @@ snd-soc-uda1380-objs := uda1380.o
snd-soc-wl1273-objs := wl1273.o snd-soc-wl1273-objs := wl1273.o
snd-soc-wm1250-ev1-objs := wm1250-ev1.o snd-soc-wm1250-ev1-objs := wm1250-ev1.o
snd-soc-wm2000-objs := wm2000.o snd-soc-wm2000-objs := wm2000.o
snd-soc-wm2200-objs := wm2200.o
snd-soc-wm5100-objs := wm5100.o wm5100-tables.o snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
snd-soc-wm8350-objs := wm8350.o snd-soc-wm8350-objs := wm8350.o
snd-soc-wm8400-objs := wm8400.o snd-soc-wm8400-objs := wm8400.o
@ -129,6 +131,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
@ -153,6 +156,7 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o

View File

@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
if (ad1836->type == AD1836) { if (ad1836->type == AD1836) {
/* left/right diff:PGA/MUX */ /* left/right diff:PGA/MUX */
snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
ret = snd_soc_add_controls(codec, ad1836_controls, ret = snd_soc_add_codec_controls(codec, ad1836_controls,
ARRAY_SIZE(ad1836_controls)); ARRAY_SIZE(ad1836_controls));
if (ret) if (ret)
return ret; return ret;
@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
} }
ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2); ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs); ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
if (ret) if (ret)
return ret; return ret;

View File

@ -228,7 +228,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
snd_soc_add_controls(codec, ad1980_snd_ac97_controls, snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls,
ARRAY_SIZE(ad1980_snd_ac97_controls)); ARRAY_SIZE(ad1980_snd_ac97_controls));
return 0; return 0;

View File

@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec)
return ret; return ret;
} }
codec->dapm.idle_bias_off = true;
if (pdata) { if (pdata) {
if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
return -EINVAL; return -EINVAL;
@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
pdata->drc_setting[i]); pdata->drc_setting[i]);
} }
snd_soc_add_controls(codec, adau1373_drc_controls, snd_soc_add_codec_controls(codec, adau1373_drc_controls,
pdata->num_drc); pdata->num_drc);
val = 0; val = 0;
@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
} }
if (!lineout_differential) { if (!lineout_differential) {
snd_soc_add_controls(codec, adau1373_lineout2_controls, snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
ARRAY_SIZE(adau1373_lineout2_controls)); ARRAY_SIZE(adau1373_lineout2_controls));
} }
@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
.suspend = adau1373_suspend, .suspend = adau1373_suspend,
.resume = adau1373_resume, .resume = adau1373_resume,
.set_bias_level = adau1373_set_bias_level, .set_bias_level = adau1373_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(adau1373_default_regs), .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
.reg_cache_default = adau1373_default_regs, .reg_cache_default = adau1373_default_regs,
.reg_word_size = sizeof(uint8_t), .reg_word_size = sizeof(uint8_t),

View File

@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec)
{ {
int ret; int ret;
codec->dapm.idle_bias_off = 1;
codec->control_data = to_i2c_client(codec->dev); codec->control_data = to_i2c_client(codec->dev);
ret = adau1701_load_firmware(codec); ret = adau1701_load_firmware(codec);
@ -473,6 +472,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver adau1701_codec_drv = { static struct snd_soc_codec_driver adau1701_codec_drv = {
.probe = adau1701_probe, .probe = adau1701_probe,
.set_bias_level = adau1701_set_bias_level, .set_bias_level = adau1701_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ADAU1701_NUM_REGS, .reg_cache_size = ADAU1701_NUM_REGS,
.reg_word_size = sizeof(u16), .reg_word_size = sizeof(u16),

View File

@ -46,75 +46,15 @@
#define DRV_NAME "ak4104-codec" #define DRV_NAME "ak4104-codec"
struct ak4104_private { struct ak4104_private {
enum snd_soc_control_type control_type; struct regmap *regmap;
void *control_data;
}; };
static int ak4104_fill_cache(struct snd_soc_codec *codec)
{
int i;
u8 *reg_cache = codec->reg_cache;
struct spi_device *spi = codec->control_data;
for (i = 0; i < codec->driver->reg_cache_size; i++) {
int ret = spi_w8r8(spi, i | AK4104_READ);
if (ret < 0) {
dev_err(&spi->dev, "SPI write failure\n");
return ret;
}
reg_cache[i] = ret;
}
return 0;
}
static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg)
{
u8 *reg_cache = codec->reg_cache;
if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
return reg_cache[reg];
}
static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
u8 *cache = codec->reg_cache;
struct spi_device *spi = codec->control_data;
if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
/* only write to the hardware if value has changed */
if (cache[reg] != value) {
u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
if (spi_write(spi, tmp, sizeof(tmp))) {
dev_err(&spi->dev, "SPI write failed\n");
return -EIO;
}
cache[reg] = value;
}
return 0;
}
static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int format) unsigned int format)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
int val = 0; int val = 0;
int ret;
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
if (val < 0)
return val;
val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1);
/* set DAI format */ /* set DAI format */
switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@ -135,7 +75,13 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
return -EINVAL; return -EINVAL;
return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1,
val);
if (ret < 0)
return ret;
return 0;
} }
static int ak4104_hw_params(struct snd_pcm_substream *substream, static int ak4104_hw_params(struct snd_pcm_substream *substream,
@ -148,7 +94,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
/* set the IEC958 bits: consumer mode, no copyright bit */ /* set the IEC958 bits: consumer mode, no copyright bit */
val |= IEC958_AES0_CON_NOT_COPYRIGHT; val |= IEC958_AES0_CON_NOT_COPYRIGHT;
ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val); snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val);
val = 0; val = 0;
@ -167,7 +113,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
} }
return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val);
} }
static const struct snd_soc_dai_ops ak4101_dai_ops = { static const struct snd_soc_dai_ops ak4101_dai_ops = {
@ -192,67 +138,57 @@ static struct snd_soc_dai_driver ak4104_dai = {
static int ak4104_probe(struct snd_soc_codec *codec) static int ak4104_probe(struct snd_soc_codec *codec)
{ {
struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
int ret, val; int ret;
codec->control_data = ak4104->control_data; codec->control_data = ak4104->regmap;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
/* read all regs and fill the cache */ if (ret != 0)
ret = ak4104_fill_cache(codec);
if (ret < 0) {
dev_err(codec->dev, "failed to fill register cache\n");
return ret; return ret;
}
/* read the 'reserved' register - according to the datasheet, it
* should contain 0x5b. Not a good way to verify the presence of
* the device, but there is no hardware ID register. */
if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
AK4104_RESERVED_VAL)
return -ENODEV;
/* set power-up and non-reset bits */ /* set power-up and non-reset bits */
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
if (ret < 0) if (ret < 0)
return ret; return ret;
/* enable transmitter */ /* enable transmitter */
val = ak4104_read_reg_cache(codec, AK4104_REG_TX); ret = snd_soc_update_bits(codec, AK4104_REG_TX,
val |= AK4104_TX_TXE; AK4104_TX_TXE, AK4104_TX_TXE);
ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
if (ret < 0) if (ret < 0)
return ret; return ret;
dev_info(codec->dev, "SPI device initialized\n");
return 0; return 0;
} }
static int ak4104_remove(struct snd_soc_codec *codec) static int ak4104_remove(struct snd_soc_codec *codec)
{ {
int val, ret; snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); return 0;
if (val < 0)
return val;
/* clear power-up and non-reset bits */
val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
return ret;
} }
static struct snd_soc_codec_driver soc_codec_device_ak4104 = { static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
.probe = ak4104_probe, .probe = ak4104_probe,
.remove = ak4104_remove, .remove = ak4104_remove,
.reg_cache_size = AK4104_NUM_REGS, };
.reg_word_size = sizeof(u8),
static const struct regmap_config ak4104_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AK4104_NUM_REGS - 1,
.read_flag_mask = AK4104_READ,
.write_flag_mask = AK4104_WRITE,
.cache_type = REGCACHE_RBTREE,
}; };
static int ak4104_spi_probe(struct spi_device *spi) static int ak4104_spi_probe(struct spi_device *spi)
{ {
struct ak4104_private *ak4104; struct ak4104_private *ak4104;
unsigned int val;
int ret; int ret;
spi->bits_per_word = 8; spi->bits_per_word = 8;
@ -266,17 +202,41 @@ static int ak4104_spi_probe(struct spi_device *spi)
if (ak4104 == NULL) if (ak4104 == NULL)
return -ENOMEM; return -ENOMEM;
ak4104->control_data = spi; ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap);
ak4104->control_type = SND_SOC_SPI; if (IS_ERR(ak4104->regmap)) {
ret = PTR_ERR(ak4104->regmap);
return ret;
}
/* read the 'reserved' register - according to the datasheet, it
* should contain 0x5b. Not a good way to verify the presence of
* the device, but there is no hardware ID register. */
ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val);
if (ret != 0)
goto err;
if (val != AK4104_RESERVED_VAL) {
ret = -ENODEV;
goto err;
}
spi_set_drvdata(spi, ak4104); spi_set_drvdata(spi, ak4104);
ret = snd_soc_register_codec(&spi->dev, ret = snd_soc_register_codec(&spi->dev,
&soc_codec_device_ak4104, &ak4104_dai, 1); &soc_codec_device_ak4104, &ak4104_dai, 1);
if (ret != 0)
goto err;
return 0;
err:
regmap_exit(ak4104->regmap);
return ret; return ret;
} }
static int __devexit ak4104_spi_remove(struct spi_device *spi) static int __devexit ak4104_spi_remove(struct spi_device *spi)
{ {
struct ak4104_private *ak4101 = spi_get_drvdata(spi);
regmap_exit(ak4101->regmap);
snd_soc_unregister_codec(&spi->dev); snd_soc_unregister_codec(&spi->dev);
return 0; return 0;
} }
@ -290,17 +250,7 @@ static struct spi_driver ak4104_spi_driver = {
.remove = __devexit_p(ak4104_spi_remove), .remove = __devexit_p(ak4104_spi_remove),
}; };
static int __init ak4104_init(void) module_spi_driver(ak4104_spi_driver);
{
return spi_register_driver(&ak4104_spi_driver);
}
module_init(ak4104_init);
static void __exit ak4104_exit(void)
{
spi_unregister_driver(&ak4104_spi_driver);
}
module_exit(ak4104_exit);
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");

View File

@ -18,6 +18,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
@ -27,24 +28,43 @@
#include "ak4535.h" #include "ak4535.h"
#define AK4535_VERSION "0.3"
/* codec private data */ /* codec private data */
struct ak4535_priv { struct ak4535_priv {
struct regmap *regmap;
unsigned int sysclk; unsigned int sysclk;
enum snd_soc_control_type control_type;
}; };
/* /*
* ak4535 register cache * ak4535 register cache
*/ */
static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { static const struct reg_default ak4535_reg_defaults[] = {
0x00, 0x80, 0x00, 0x03, { 0, 0x00 },
0x02, 0x00, 0x11, 0x01, { 1, 0x80 },
0x00, 0x40, 0x36, 0x10, { 2, 0x00 },
0x00, 0x00, 0x57, 0x00, { 3, 0x03 },
{ 4, 0x02 },
{ 5, 0x00 },
{ 6, 0x11 },
{ 7, 0x01 },
{ 8, 0x00 },
{ 9, 0x40 },
{ 10, 0x36 },
{ 11, 0x10 },
{ 12, 0x00 },
{ 13, 0x00 },
{ 14, 0x57 },
}; };
static bool ak4535_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case AK4535_STATUS:
return true;
default:
return false;
}
}
static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec)
struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); codec->control_data = ak4535->regmap;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
if (ret < 0) { if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret; return ret;
@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec)
/* power on device */ /* power on device */
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_add_controls(codec, ak4535_snd_controls, snd_soc_add_codec_controls(codec, ak4535_snd_controls,
ARRAY_SIZE(ak4535_snd_controls)); ARRAY_SIZE(ak4535_snd_controls));
return 0; return 0;
} }
@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec)
return 0; return 0;
} }
static const struct regmap_config ak4535_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AK4535_STATUS,
.volatile_reg = ak4535_volatile,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = ak4535_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
};
static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
.probe = ak4535_probe, .probe = ak4535_probe,
.remove = ak4535_remove, .remove = ak4535_remove,
.suspend = ak4535_suspend, .suspend = ak4535_suspend,
.resume = ak4535_resume, .resume = ak4535_resume,
.set_bias_level = ak4535_set_bias_level, .set_bias_level = ak4535_set_bias_level,
.reg_cache_size = ARRAY_SIZE(ak4535_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = ak4535_reg,
.dapm_widgets = ak4535_dapm_widgets, .dapm_widgets = ak4535_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
.dapm_routes = ak4535_audio_map, .dapm_routes = ak4535_audio_map,
.num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
}; };
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
if (ak4535 == NULL) if (ak4535 == NULL)
return -ENOMEM; return -ENOMEM;
ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
if (IS_ERR(ak4535->regmap)) {
ret = PTR_ERR(ak4535->regmap);
dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
return ret;
}
i2c_set_clientdata(i2c, ak4535); i2c_set_clientdata(i2c, ak4535);
ak4535->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev, ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_ak4535, &ak4535_dai, 1); &soc_codec_dev_ak4535, &ak4535_dai, 1);
if (ret != 0)
regmap_exit(ak4535->regmap);
return ret; return ret;
} }
static __devexit int ak4535_i2c_remove(struct i2c_client *client) static __devexit int ak4535_i2c_remove(struct i2c_client *client)
{ {
struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);
regmap_exit(ak4535->regmap);
return 0; return 0;
} }
@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
static struct i2c_driver ak4535_i2c_driver = { static struct i2c_driver ak4535_i2c_driver = {
.driver = { .driver = {
.name = "ak4535-codec", .name = "ak4535",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = ak4535_i2c_probe, .probe = ak4535_i2c_probe,
.remove = __devexit_p(ak4535_i2c_remove), .remove = __devexit_p(ak4535_i2c_remove),
.id_table = ak4535_i2c_id, .id_table = ak4535_i2c_id,
}; };
#endif
static int __init ak4535_modinit(void) module_i2c_driver(ak4535_i2c_driver);
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&ak4535_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
ret);
}
#endif
return ret;
}
module_init(ak4535_modinit);
static void __exit ak4535_exit(void)
{
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&ak4535_i2c_driver);
#endif
}
module_exit(ak4535_exit);
MODULE_DESCRIPTION("Soc AK4535 driver"); MODULE_DESCRIPTION("Soc AK4535 driver");
MODULE_AUTHOR("Richard Purdie"); MODULE_AUTHOR("Richard Purdie");

View File

@ -34,6 +34,4 @@
#define AK4535_VOL 0xe #define AK4535_VOL 0xe
#define AK4535_STATUS 0xf #define AK4535_STATUS 0xf
#define AK4535_CACHEREGNUM 0x10
#endif #endif

View File

@ -477,7 +477,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
return ret; return ret;
} }
snd_soc_add_controls(codec, ak4642_snd_controls, snd_soc_add_codec_controls(codec, ak4642_snd_controls,
ARRAY_SIZE(ak4642_snd_controls)); ARRAY_SIZE(ak4642_snd_controls));
ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

View File

@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec)
return ret; return ret;
} }
snd_soc_add_controls(codec, ak4671_snd_controls, snd_soc_add_codec_controls(codec, ak4671_snd_controls,
ARRAY_SIZE(ak4671_snd_controls)); ARRAY_SIZE(ak4671_snd_controls));
ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

View File

@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec)
switch (alc5623->id) { switch (alc5623->id) {
case 0x21: case 0x21:
snd_soc_add_controls(codec, alc5621_vol_snd_controls, snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
ARRAY_SIZE(alc5621_vol_snd_controls)); ARRAY_SIZE(alc5621_vol_snd_controls));
break; break;
case 0x22: case 0x22:
snd_soc_add_controls(codec, alc5622_vol_snd_controls, snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
ARRAY_SIZE(alc5622_vol_snd_controls)); ARRAY_SIZE(alc5622_vol_snd_controls));
break; break;
case 0x23: case 0x23:
snd_soc_add_controls(codec, alc5623_vol_snd_controls, snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
ARRAY_SIZE(alc5623_vol_snd_controls)); ARRAY_SIZE(alc5623_vol_snd_controls));
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
snd_soc_add_controls(codec, alc5623_snd_controls, snd_soc_add_codec_controls(codec, alc5623_snd_controls,
ARRAY_SIZE(alc5623_snd_controls)); ARRAY_SIZE(alc5623_snd_controls));
snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
@ -992,7 +992,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
* low = 0x1a * low = 0x1a
* high = 0x1b * high = 0x1b
*/ */
static int alc5623_i2c_probe(struct i2c_client *client, static __devinit int alc5623_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct alc5623_platform_data *pdata; struct alc5623_platform_data *pdata;
@ -1059,7 +1059,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
return ret; return ret;
} }
static int alc5623_i2c_remove(struct i2c_client *client) static __devexit int alc5623_i2c_remove(struct i2c_client *client)
{ {
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);
return 0; return 0;

View File

@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
/* -16.5db min scale, 1.5db steps, no mute */ /* -16.5db min scale, 1.5db steps, no mute */
static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
static const unsigned int boost_tlv[] = { static const unsigned int boost_tlv[] = {
TLV_DB_RANGE_HEAD(3), TLV_DB_RANGE_HEAD(2),
0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
}; };
/* 0db min scale, 6 db steps, no mute */ /* 0db min scale, 6 db steps, no mute */
static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
/* 0db min scalem 0.75db steps, no mute */ /* 0db min scalem 0.75db steps, no mute */
static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0); static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);
static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
/* left starts at bit 8, right at bit 0 */ /* left starts at bit 8, right at bit 0 */
@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = {
ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
SOC_SINGLE_TLV("Voice DAC Playback Volume", SOC_SINGLE_TLV("Voice DAC Playback Volume",
ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
SOC_SINGLE_TLV("Phone Capture Volume", SOC_SINGLE("Voice DAC Playback Switch",
ALC5632_VOICE_DAC_VOL, 12, 1, 1),
SOC_SINGLE_TLV("Phone Playback Volume",
ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
SOC_DOUBLE_TLV("LineIn Capture Volume", SOC_DOUBLE_TLV("LineIn Playback Volume",
ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
SOC_DOUBLE_TLV("Master Playback Volume", SOC_DOUBLE_TLV("Master Playback Volume",
ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
SOC_DOUBLE("Master Playback Switch", SOC_DOUBLE("Master Playback Switch",
ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
SOC_SINGLE_TLV("Mic1 Capture Volume", SOC_SINGLE_TLV("Mic1 Playback Volume",
ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
SOC_SINGLE_TLV("Mic2 Capture Volume", SOC_SINGLE_TLV("Mic2 Playback Volume",
ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
SOC_DOUBLE_TLV("Rec Capture Volume", SOC_DOUBLE_TLV("Rec Capture Volume",
ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
SOC_SINGLE_TLV("Mic 1 Boost Volume", SOC_SINGLE_TLV("Mic 1 Boost Volume",
ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv), ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),
SOC_SINGLE_TLV("Mic 2 Boost Volume", SOC_SINGLE_TLV("Mic 2 Boost Volume",
ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv), ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),
SOC_SINGLE_TLV("Digital Boost Volume", SOC_SINGLE_TLV("DMIC Boost Capture Volume",
ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
SOC_SINGLE("DMIC En Capture Switch",
ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),
SOC_SINGLE("DMIC PreFilter Capture Switch",
ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),
}; };
/* /*
@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
/* Left Record Mixer */ /* Left Record Mixer */
static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
}; };
/* Right Record Mixer */ /* Right Record Mixer */
static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
}; };
static const char *alc5632_spk_n_sour_sel[] = { /* Dmic Mixer */
static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {
SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),
};
static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {
SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),
};
static const char * const alc5632_spk_n_sour_sel[] = {
"RN/-R", "RP/+R", "LN/-R", "Mute"}; "RN/-R", "RP/+R", "LN/-R", "Mute"};
static const char *alc5632_hpl_out_input_sel[] = { static const char * const alc5632_hpl_out_input_sel[] = {
"Vmid", "HP Left Mix"}; "Vmid", "HP Left Mix"};
static const char *alc5632_hpr_out_input_sel[] = { static const char * const alc5632_hpr_out_input_sel[] = {
"Vmid", "HP Right Mix"}; "Vmid", "HP Right Mix"};
static const char *alc5632_spkout_input_sel[] = { static const char * const alc5632_spkout_input_sel[] = {
"Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
static const char *alc5632_aux_out_input_sel[] = { static const char * const alc5632_aux_out_input_sel[] = {
"Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
static const char * const alc5632_adcr_func_sel[] = {
"Stereo ADC", "Voice ADC"};
static const char * const alc5632_i2s_out_sel[] = {
"ADC LR", "Voice Stereo Digital"};
/* auxout output mux */ /* auxout output mux */
static const struct soc_enum alc5632_aux_out_input_enum = static const struct soc_enum alc5632_aux_out_input_enum =
@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum =
static const struct snd_kcontrol_new alc5632_amp_mux_controls = static const struct snd_kcontrol_new alc5632_amp_mux_controls =
SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
/* ADC output select */
static const struct soc_enum alc5632_adcr_func_enum =
SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel);
static const struct snd_kcontrol_new alc5632_adcr_func_controls =
SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
/* I2S out select */
static const struct soc_enum alc5632_i2s_out_enum =
SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel);
static const struct snd_kcontrol_new alc5632_i2s_out_controls =
SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
/* Muxes */ /* Muxes */
@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
&alc5632_hpr_out_mux_controls), &alc5632_hpr_out_mux_controls),
SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
&alc5632_spkoutn_mux_controls), &alc5632_spkoutn_mux_controls),
SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
&alc5632_adcr_func_controls),
SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,
&alc5632_i2s_out_controls),
/* output mixers */ /* output mixers */
SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
&alc5632_speaker_mixer_controls[0], &alc5632_speaker_mixer_controls[0],
ARRAY_SIZE(alc5632_speaker_mixer_controls)), ARRAY_SIZE(alc5632_speaker_mixer_controls)),
SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,
&alc5632_dmicl_mixer_controls[0],
ARRAY_SIZE(alc5632_dmicl_mixer_controls)),
SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,
&alc5632_dmicr_mixer_controls[0],
ARRAY_SIZE(alc5632_dmicr_mixer_controls)),
/* input mixers */ /* input mixers */
SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
&alc5632_captureR_mixer_controls[0], &alc5632_captureR_mixer_controls[0],
ARRAY_SIZE(alc5632_captureR_mixer_controls)), ARRAY_SIZE(alc5632_captureR_mixer_controls)),
SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback", SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
ALC5632_PWR_MANAG_ADD2, 9, 0), SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback", SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
ALC5632_PWR_MANAG_ADD2, 8, 0), SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),
SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),
SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),
SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),
SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),
SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
SND_SOC_DAPM_MIXER("DAC Right Channel", SND_SOC_DAPM_MIXER("DAC Right Channel",
ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
ALC5632_PWR_MANAG_ADD2, 7, 0), SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
ALC5632_PWR_MANAG_ADD2, 6, 0),
SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"),
SND_SOC_DAPM_OUTPUT("HPR"), SND_SOC_DAPM_OUTPUT("HPR"),
SND_SOC_DAPM_OUTPUT("SPKOUT"), SND_SOC_DAPM_OUTPUT("SPKOUT"),
SND_SOC_DAPM_OUTPUT("SPKOUTN"), SND_SOC_DAPM_OUTPUT("SPKOUTN"),
SND_SOC_DAPM_INPUT("LINEINL"), SND_SOC_DAPM_INPUT("LINEINL"),
SND_SOC_DAPM_INPUT("LINEINR"), SND_SOC_DAPM_INPUT("LINEINR"),
SND_SOC_DAPM_INPUT("PHONEP"), SND_SOC_DAPM_INPUT("PHONEP"),
SND_SOC_DAPM_INPUT("PHONEN"), SND_SOC_DAPM_INPUT("PHONEN"),
SND_SOC_DAPM_INPUT("DMICDAT"),
SND_SOC_DAPM_INPUT("MIC1"), SND_SOC_DAPM_INPUT("MIC1"),
SND_SOC_DAPM_INPUT("MIC2"), SND_SOC_DAPM_INPUT("MIC2"),
SND_SOC_DAPM_VMID("Vmid"), SND_SOC_DAPM_VMID("Vmid"),
@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"),
static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
/* Playback streams */
{"Left DAC", NULL, "AIFRXL"},
{"Right DAC", NULL, "AIFRXR"},
/* virtual mixer - mixes left & right channels */ /* virtual mixer - mixes left & right channels */
{"I2S Mix", NULL, "Left DAC"}, {"I2S Mix", NULL, "Left DAC"},
{"I2S Mix", NULL, "Right DAC"}, {"I2S Mix", NULL, "Right DAC"},
@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
{"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
{"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
{"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
{"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"},
{"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
{"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
{"HPOut Mix", NULL, "HP Mix"},
{"HPOut Mix", NULL, "HPR Mix"},
{"HPOut Mix", NULL, "HPL Mix"},
/* speaker mixer */ /* speaker mixer */
{"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
{"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
{"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
{"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
{"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"},
/* mono mixer */ /* mono mixer */
{"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
{"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
{"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
{"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
{"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
{"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
{"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
{"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"},
/* Left record mixer */ /* Left record mixer */
{"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},
{"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"}, {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},
{"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},
{"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},
{"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},
{"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},
{"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},
/*Right record mixer */ /*Right record mixer */
{"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},
{"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"}, {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},
{"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},
{"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},
{"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},
{"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},
{"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},
/* headphone left mux */ /* headphone left mux */
{"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
/* left ADC */ /* left ADC */
{"Left ADC", NULL, "Left Capture Mix"}, {"Left ADC", NULL, "Left Capture Mix"},
{"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},
{"Left ADC", NULL, "DMICL Mix"},
{"ADCLR", NULL, "Left ADC"},
/* right ADC */ /* right ADC */
{"Right ADC", NULL, "Right Capture Mix"}, {"Right ADC", NULL, "Right Capture Mix"},
{"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},
{"Right ADC", NULL, "DMICR Mix"},
{"ADCR Mux", "Stereo ADC", "Right ADC"},
{"ADCR Mux", "Voice ADC", "Right ADC"},
{"ADCLR", NULL, "ADCR Mux"},
{"VAIFTX", NULL, "ADCR Mux"},
/* Digital I2S out */
{"I2SOut Mux", "ADC LR", "ADCLR"},
{"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},
{"AIFTXL", NULL, "I2SOut Mux"},
{"AIFTXR", NULL, "I2SOut Mux"},
/* Voice Mix */
{"Voice DAC", NULL, "VAIFRX"},
{"Voice Mix", NULL, "Voice DAC"},
/* Speaker Output */
{"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
{"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
{"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
switch (freq) { switch (freq) {
case 4096000:
case 8192000: case 8192000:
case 11289600: case 11289600:
case 12288000: case 12288000:
@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
switch (alc5632->id) { switch (alc5632->id) {
case 0x5c: case 0x5c:
snd_soc_add_controls(codec, alc5632_vol_snd_controls, snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
ARRAY_SIZE(alc5632_vol_snd_controls)); ARRAY_SIZE(alc5632_vol_snd_controls));
break; break;
default: default:
@ -1109,7 +1184,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
return ret; return ret;
} }
static int alc5632_i2c_remove(struct i2c_client *client) static __devexit int alc5632_i2c_remove(struct i2c_client *client)
{ {
struct alc5632_priv *alc5632 = i2c_get_clientdata(client); struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);

View File

@ -51,6 +51,7 @@
#define ALC5632_ADC_REC_MONOMIX (1 << 0) #define ALC5632_ADC_REC_MONOMIX (1 << 0)
#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ #define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */
#define ALC5632_I2S_OUT_CTL 0x1A /* undocumented reg. found in path scheme */
/* ALC5632_OUTPUT_MIXER_CTRL : */ /* ALC5632_OUTPUT_MIXER_CTRL : */
/* same remark as for reg 2 line vs speaker */ /* same remark as for reg 2 line vs speaker */
#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ #define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */

View File

@ -38,8 +38,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/initval.h> #include <sound/initval.h>
#include <mach/dm365.h>
static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
unsigned int reg) unsigned int reg)
{ {
@ -159,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
codec->control_data = davinci_vc; codec->control_data = davinci_vc;
/* Set controls */ /* Set controls */
snd_soc_add_controls(codec, cq93vc_snd_controls, snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
ARRAY_SIZE(cq93vc_snd_controls)); ARRAY_SIZE(cq93vc_snd_controls));
/* Off, with power on */ /* Off, with power on */

View File

@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec)
} }
/* Add the non-DAPM controls */ /* Add the non-DAPM controls */
ret = snd_soc_add_controls(codec, cs4270_snd_controls, ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
ARRAY_SIZE(cs4270_snd_controls)); ARRAY_SIZE(cs4270_snd_controls));
if (ret < 0) { if (ret < 0) {
dev_err(codec->dev, "failed to add controls\n"); dev_err(codec->dev, "failed to add controls\n");
@ -715,7 +715,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
*/ */
static struct i2c_driver cs4270_i2c_driver = { static struct i2c_driver cs4270_i2c_driver = {
.driver = { .driver = {
.name = "cs4270-codec", .name = "cs4270",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.id_table = cs4270_id, .id_table = cs4270_id,

View File

@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
/* Power-up sequence requires 85 uS */ /* Power-up sequence requires 85 uS */
udelay(85); udelay(85);
return snd_soc_add_controls(codec, cs4271_snd_controls, return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
ARRAY_SIZE(cs4271_snd_controls)); ARRAY_SIZE(cs4271_snd_controls));
} }

View File

@ -17,6 +17,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <sound/pcm.h> #include <sound/pcm.h>
@ -626,41 +627,82 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = {
/* Codec private data */ /* Codec private data */
struct da7210_priv { struct da7210_priv {
enum snd_soc_control_type control_type; struct regmap *regmap;
}; };
/* static struct reg_default da7210_reg_defaults[] = {
* Register cache { 0x01, 0x11 },
*/ { 0x03, 0x00 },
static const u8 da7210_reg[] = { { 0x04, 0x00 },
0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */ { 0x05, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */ { 0x06, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */ { 0x07, 0x00 },
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */ { 0x08, 0x00 },
0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */ { 0x09, 0x00 },
0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */ { 0x0a, 0x00 },
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */ { 0x0b, 0x00 },
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */ { 0x0c, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */ { 0x0d, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */ { 0x0e, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */ { 0x0f, 0x08 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */ { 0x10, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */ { 0x11, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */ { 0x12, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */ { 0x13, 0x00 },
0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */ { 0x14, 0x08 },
0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */ { 0x15, 0x10 },
0x00, /* R88 */ { 0x16, 0x10 },
{ 0x17, 0x54 },
{ 0x18, 0x40 },
{ 0x19, 0x00 },
{ 0x1a, 0x00 },
{ 0x1b, 0x00 },
{ 0x1c, 0x00 },
{ 0x1d, 0x00 },
{ 0x1e, 0x00 },
{ 0x1f, 0x00 },
{ 0x20, 0x00 },
{ 0x21, 0x00 },
{ 0x22, 0x00 },
{ 0x23, 0x02 },
{ 0x24, 0x00 },
{ 0x25, 0x76 },
{ 0x26, 0x00 },
{ 0x27, 0x00 },
{ 0x28, 0x04 },
{ 0x29, 0x00 },
{ 0x2a, 0x00 },
{ 0x2b, 0x30 },
{ 0x2c, 0x2A },
{ 0x83, 0x00 },
{ 0x84, 0x00 },
{ 0x85, 0x00 },
{ 0x86, 0x00 },
{ 0x87, 0x00 },
{ 0x88, 0x00 },
}; };
static int da7210_volatile_register(struct snd_soc_codec *codec, static bool da7210_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case DA7210_A_HID_UNLOCK:
case DA7210_A_TEST_UNLOCK:
case DA7210_A_PLL1:
case DA7210_A_CP_MODE:
return false;
default:
return true;
}
}
static bool da7210_volatile_register(struct device *dev,
unsigned int reg) unsigned int reg)
{ {
switch (reg) { switch (reg) {
case DA7210_STATUS: case DA7210_STATUS:
return 1; return true;
default: default:
return 0; return false;
} }
} }
@ -866,7 +908,8 @@ static int da7210_probe(struct snd_soc_codec *codec)
dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type); codec->control_data = da7210->regmap;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) { if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret; return ret;
@ -983,12 +1026,14 @@ static int da7210_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
/* As suggested by Dialog */ /* As suggested by Dialog */
snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ /* unlock */
snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
snd_soc_write(codec, DA7210_A_PLL1, 0x01); regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C); regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00); /* re-lock */
regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
/* Activate all enabled subsystem */ /* Activate all enabled subsystem */
snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
@ -1000,10 +1045,6 @@ static int da7210_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_da7210 = { static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
.probe = da7210_probe, .probe = da7210_probe,
.reg_cache_size = ARRAY_SIZE(da7210_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = da7210_reg,
.volatile_register = da7210_volatile_register,
.controls = da7210_snd_controls, .controls = da7210_snd_controls,
.num_controls = ARRAY_SIZE(da7210_snd_controls), .num_controls = ARRAY_SIZE(da7210_snd_controls),
@ -1014,6 +1055,17 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
.num_dapm_routes = ARRAY_SIZE(da7210_audio_map), .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
}; };
static struct regmap_config da7210_regmap = {
.reg_bits = 8,
.val_bits = 8,
.reg_defaults = da7210_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
.volatile_reg = da7210_volatile_register,
.readable_reg = da7210_readable_register,
.cache_type = REGCACHE_RBTREE,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int __devinit da7210_i2c_probe(struct i2c_client *i2c, static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
@ -1027,16 +1079,34 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
return -ENOMEM; return -ENOMEM;
i2c_set_clientdata(i2c, da7210); i2c_set_clientdata(i2c, da7210);
da7210->control_type = SND_SOC_I2C;
da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap);
if (IS_ERR(da7210->regmap)) {
ret = PTR_ERR(da7210->regmap);
dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
return ret;
}
ret = snd_soc_register_codec(&i2c->dev, ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_da7210, &da7210_dai, 1); &soc_codec_dev_da7210, &da7210_dai, 1);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
goto err_regmap;
}
return ret;
err_regmap:
regmap_exit(da7210->regmap);
return ret; return ret;
} }
static int __devexit da7210_i2c_remove(struct i2c_client *client) static int __devexit da7210_i2c_remove(struct i2c_client *client)
{ {
struct da7210_priv *da7210 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);
regmap_exit(da7210->regmap);
return 0; return 0;
} }

View File

@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec)
codec->control_data = lm4857->i2c; codec->control_data = lm4857->i2c;
ret = snd_soc_add_controls(codec, lm4857_controls, ret = snd_soc_add_codec_controls(codec, lm4857_controls,
ARRAY_SIZE(lm4857_controls)); ARRAY_SIZE(lm4857_controls));
if (ret) if (ret)
return ret; return ret;

247
sound/soc/codecs/max9768.c Normal file
View File

@ -0,0 +1,247 @@
/*
* MAX9768 AMP driver
*
* Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
*
* 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; version 2 of the License.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/max9768.h>
/* "Registers" */
#define MAX9768_VOL 0
#define MAX9768_CTRL 3
/* Commands */
#define MAX9768_CTRL_PWM 0x15
#define MAX9768_CTRL_FILTERLESS 0x16
struct max9768 {
struct regmap *regmap;
int mute_gpio;
int shdn_gpio;
u32 flags;
};
static struct reg_default max9768_default_regs[] = {
{ 0, 0 },
{ 3, MAX9768_CTRL_FILTERLESS},
};
static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
int val = gpio_get_value_cansleep(max9768->mute_gpio);
ucontrol->value.integer.value[0] = !val;
return 0;
}
static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
return 0;
}
static const unsigned int volume_tlv[] = {
TLV_DB_RANGE_HEAD(43),
0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
63, 63, TLV_DB_SCALE_ITEM(950, 0, 0),
};
static const struct snd_kcontrol_new max9768_volume[] = {
SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
};
static const struct snd_kcontrol_new max9768_mute[] = {
SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
};
static int max9768_probe(struct snd_soc_codec *codec)
{
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
int ret;
codec->control_data = max9768->regmap;
ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
if (ret)
return ret;
if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
if (ret)
return ret;
}
if (gpio_is_valid(max9768->mute_gpio)) {
ret = snd_soc_add_codec_controls(codec, max9768_mute,
ARRAY_SIZE(max9768_mute));
if (ret)
return ret;
}
return 0;
}
static struct snd_soc_codec_driver max9768_codec_driver = {
.probe = max9768_probe,
.controls = max9768_volume,
.num_controls = ARRAY_SIZE(max9768_volume),
};
static const struct regmap_config max9768_i2c_regmap_config = {
.reg_bits = 2,
.val_bits = 6,
.max_register = 3,
.reg_defaults = max9768_default_regs,
.num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
.cache_type = REGCACHE_RBTREE,
};
static int __devinit max9768_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max9768 *max9768;
struct max9768_pdata *pdata = client->dev.platform_data;
int err;
max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
if (!max9768)
return -ENOMEM;
if (pdata) {
/* Mute on powerup to avoid clicks */
err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute");
max9768->mute_gpio = err ?: pdata->mute_gpio;
/* Activate chip by releasing shutdown, enables I2C */
err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown");
max9768->shdn_gpio = err ?: pdata->shdn_gpio;
max9768->flags = pdata->flags;
} else {
max9768->shdn_gpio = -EINVAL;
max9768->mute_gpio = -EINVAL;
}
i2c_set_clientdata(client, max9768);
max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
if (IS_ERR(max9768->regmap)) {
err = PTR_ERR(max9768->regmap);
goto err_gpio_free;
}
err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
if (err)
goto err_regmap_free;
return 0;
err_regmap_free:
regmap_exit(max9768->regmap);
err_gpio_free:
if (gpio_is_valid(max9768->shdn_gpio))
gpio_free(max9768->shdn_gpio);
if (gpio_is_valid(max9768->mute_gpio))
gpio_free(max9768->mute_gpio);
return err;
}
static int __devexit max9768_i2c_remove(struct i2c_client *client)
{
struct max9768 *max9768 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev);
regmap_exit(max9768->regmap);
if (gpio_is_valid(max9768->shdn_gpio))
gpio_free(max9768->shdn_gpio);
if (gpio_is_valid(max9768->mute_gpio))
gpio_free(max9768->mute_gpio);
return 0;
}
static const struct i2c_device_id max9768_i2c_id[] = {
{ "max9768", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
static struct i2c_driver max9768_i2c_driver = {
.driver = {
.name = "max9768",
.owner = THIS_MODULE,
},
.probe = max9768_i2c_probe,
.remove = __devexit_p(max9768_i2c_remove),
.id_table = max9768_i2c_id,
};
module_i2c_driver(max9768_i2c_driver);
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
MODULE_LICENSE("GPL v2");

View File

@ -1908,7 +1908,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
max98088->eq_enum.texts = max98088->eq_texts; max98088->eq_enum.texts = max98088->eq_texts;
max98088->eq_enum.max = max98088->eq_textcnt; max98088->eq_enum.max = max98088->eq_textcnt;
ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
if (ret != 0) if (ret != 0)
dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
} }
@ -2030,7 +2030,7 @@ static int max98088_probe(struct snd_soc_codec *codec)
max98088_handle_pdata(codec); max98088_handle_pdata(codec);
snd_soc_add_controls(codec, max98088_snd_controls, snd_soc_add_codec_controls(codec, max98088_snd_controls,
ARRAY_SIZE(max98088_snd_controls)); ARRAY_SIZE(max98088_snd_controls));
err_access: err_access:

View File

@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = {
static int max98095_add_widgets(struct snd_soc_codec *codec) static int max98095_add_widgets(struct snd_soc_codec *codec)
{ {
snd_soc_add_controls(codec, max98095_snd_controls, snd_soc_add_codec_controls(codec, max98095_snd_controls,
ARRAY_SIZE(max98095_snd_controls)); ARRAY_SIZE(max98095_snd_controls));
return 0; return 0;
@ -1984,7 +1984,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
max98095->eq_enum.texts = max98095->eq_texts; max98095->eq_enum.texts = max98095->eq_texts;
max98095->eq_enum.max = max98095->eq_textcnt; max98095->eq_enum.max = max98095->eq_textcnt;
ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
if (ret != 0) if (ret != 0)
dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
} }
@ -2139,7 +2139,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
max98095->bq_enum.texts = max98095->bq_texts; max98095->bq_enum.texts = max98095->bq_texts;
max98095->bq_enum.max = max98095->bq_textcnt; max98095->bq_enum.max = max98095->bq_textcnt;
ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
if (ret != 0) if (ret != 0)
dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret); dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
} }

View File

@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = {
/* This function is called from ASoC machine driver */ /* This function is called from ASoC machine driver */
int max9877_add_controls(struct snd_soc_codec *codec) int max9877_add_controls(struct snd_soc_codec *codec)
{ {
return snd_soc_add_controls(codec, max9877_controls, return snd_soc_add_codec_controls(codec, max9877_controls,
ARRAY_SIZE(max9877_controls)); ARRAY_SIZE(max9877_controls));
} }
EXPORT_SYMBOL_GPL(max9877_add_controls); EXPORT_SYMBOL_GPL(max9877_add_controls);

View File

@ -227,7 +227,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
}; };
/* routes for sgtl5000 */ /* routes for sgtl5000 */
static const struct snd_soc_dapm_route audio_map[] = { static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
{"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
{"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
@ -1248,7 +1248,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
} }
rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
dev_info(codec->dev, "sgtl5000 revision %d\n", rev); dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev);
/* /*
* workaround for revision 0x11 and later, * workaround for revision 0x11 and later,
@ -1353,15 +1353,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
if (ret) if (ret)
goto err; goto err;
snd_soc_add_controls(codec, sgtl5000_snd_controls,
ARRAY_SIZE(sgtl5000_snd_controls));
snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
ARRAY_SIZE(sgtl5000_dapm_widgets));
snd_soc_dapm_add_routes(&codec->dapm, audio_map,
ARRAY_SIZE(audio_map));
snd_soc_dapm_new_widgets(&codec->dapm); snd_soc_dapm_new_widgets(&codec->dapm);
return 0; return 0;
@ -1402,6 +1393,12 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
.reg_cache_step = 2, .reg_cache_step = 2,
.reg_cache_default = sgtl5000_regs, .reg_cache_default = sgtl5000_regs,
.volatile_register = sgtl5000_volatile_register, .volatile_register = sgtl5000_volatile_register,
.controls = sgtl5000_snd_controls,
.num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
.dapm_widgets = sgtl5000_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets),
.dapm_routes = sgtl5000_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
}; };
static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,

View File

@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
{ {
pr_debug("codec_probe called\n"); pr_debug("codec_probe called\n");
codec->dapm.idle_bias_off = 1;
/* PCM interface config /* PCM interface config
* This sets the pcm rx slot conguration to max 6 slots * This sets the pcm rx slot conguration to max 6 slots
* for max 4 dais (2 stereo and 2 mono) * for max 4 dais (2 stereo and 2 mono)
@ -871,7 +869,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
snd_soc_write(codec, SN95031_SSR2, 0x10); snd_soc_write(codec, SN95031_SSR2, 0x10);
snd_soc_write(codec, SN95031_SSR3, 0x40); snd_soc_write(codec, SN95031_SSR3, 0x40);
snd_soc_add_controls(codec, sn95031_snd_controls, snd_soc_add_codec_controls(codec, sn95031_snd_controls,
ARRAY_SIZE(sn95031_snd_controls)); ARRAY_SIZE(sn95031_snd_controls));
return 0; return 0;
@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = {
.read = sn95031_read, .read = sn95031_read,
.write = sn95031_write, .write = sn95031_write,
.set_bias_level = sn95031_set_vaud_bias, .set_bias_level = sn95031_set_vaud_bias,
.idle_bias_off = true,
.dapm_widgets = sn95031_dapm_widgets, .dapm_widgets = sn95031_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
.dapm_routes = sn95031_audio_map, .dapm_routes = sn95031_audio_map,

View File

@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, SSM2602_ROUT1V, snd_soc_update_bits(codec, SSM2602_ROUT1V,
ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
ret = snd_soc_add_controls(codec, ssm2602_snd_controls, ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
ARRAY_SIZE(ssm2602_snd_controls)); ARRAY_SIZE(ssm2602_snd_controls));
if (ret) if (ret)
return ret; return ret;

View File

@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_add_controls(codec, stac9766_snd_ac97_controls, snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
ARRAY_SIZE(stac9766_snd_ac97_controls)); ARRAY_SIZE(stac9766_snd_ac97_controls));
return 0; return 0;

View File

@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
snd_soc_add_controls(codec, tlv320aic23_snd_controls, snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls,
ARRAY_SIZE(tlv320aic23_snd_controls)); ARRAY_SIZE(tlv320aic23_snd_controls));
return 0; return 0;

View File

@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
/* register controls */ /* register controls */
dev_dbg(codec->dev, "Registering controls\n"); dev_dbg(codec->dev, "Registering controls\n");
err = snd_soc_add_controls(codec, aic26_snd_controls, err = snd_soc_add_codec_controls(codec, aic26_snd_controls,
ARRAY_SIZE(aic26_snd_controls)); ARRAY_SIZE(aic26_snd_controls));
WARN_ON(err < 0); WARN_ON(err < 0);

View File

@ -671,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
} }
aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_add_controls(codec, aic32x4_snd_controls, snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
ARRAY_SIZE(aic32x4_snd_controls)); ARRAY_SIZE(aic32x4_snd_controls));
aic32x4_add_widgets(codec); aic32x4_add_widgets(codec);

View File

@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
0x00, 0x00, 0x02, /* 100 */ 0x00, 0x00, 0x02, /* 100 */
}; };
/*
* read from the aic3x register space. Only use for this function is if
* wanting to read volatile bits from those registers that has both read-only
* and read/write bits. All other cases should use snd_soc_read.
*/
static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
u8 *value)
{
u8 *cache = codec->reg_cache;
if (codec->cache_only)
return -EINVAL;
if (reg >= AIC3X_CACHEREGNUM)
return -1;
codec->cache_bypass = 1;
*value = snd_soc_read(codec, reg);
codec->cache_bypass = 0;
cache[reg] = *value;
return 0;
}
#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \ .info = snd_soc_info_volsw, \
@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
return 0; return 0;
} }
void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
{
u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
u8 bit = gpio ? 3: 0;
u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
snd_soc_write(codec, reg, val | (!!state << bit));
}
EXPORT_SYMBOL_GPL(aic3x_set_gpio);
int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
{
u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
u8 val = 0, bit = gpio ? 2 : 1;
aic3x_read(codec, reg, &val);
return (val >> bit) & 1;
}
EXPORT_SYMBOL_GPL(aic3x_get_gpio);
void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
int headset_debounce, int button_debounce) int headset_debounce, int button_debounce)
{ {
@ -1221,23 +1178,6 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
} }
EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
int aic3x_headset_detected(struct snd_soc_codec *codec)
{
u8 val = 0;
aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
return (val >> 4) & 1;
}
EXPORT_SYMBOL_GPL(aic3x_headset_detected);
int aic3x_button_pressed(struct snd_soc_codec *codec)
{
u8 val = 0;
aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
return (val >> 5) & 1;
}
EXPORT_SYMBOL_GPL(aic3x_button_pressed);
#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
@ -1377,7 +1317,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
INIT_LIST_HEAD(&aic3x->list); INIT_LIST_HEAD(&aic3x->list);
aic3x->codec = codec; aic3x->codec = codec;
codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
if (ret != 0) { if (ret != 0) {
@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec)
(aic3x->setup->gpio_func[1] & 0xf) << 4); (aic3x->setup->gpio_func[1] & 0xf) << 4);
} }
snd_soc_add_controls(codec, aic3x_snd_controls, snd_soc_add_codec_controls(codec, aic3x_snd_controls,
ARRAY_SIZE(aic3x_snd_controls)); ARRAY_SIZE(aic3x_snd_controls));
if (aic3x->model == AIC3X_MODEL_3007) if (aic3x->model == AIC3X_MODEL_3007)
snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
aic3x_add_widgets(codec); aic3x_add_widgets(codec);
list_add(&aic3x->list, &reset_list); list_add(&aic3x->list, &reset_list);
@ -1471,6 +1410,7 @@ static int aic3x_remove(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_aic3x = { static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
.set_bias_level = aic3x_set_bias_level, .set_bias_level = aic3x_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(aic3x_reg), .reg_cache_size = ARRAY_SIZE(aic3x_reg),
.reg_word_size = sizeof(u8), .reg_word_size = sizeof(u8),
.reg_cache_default = aic3x_reg, .reg_cache_default = aic3x_reg,

View File

@ -212,9 +212,6 @@
/* Default input volume */ /* Default input volume */
#define DEFAULT_GAIN 0x20 #define DEFAULT_GAIN 0x20
void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
/* headset detection / button API */ /* headset detection / button API */
/* The AIC3x supports detection of stereo headsets (GND + left + right signal) /* The AIC3x supports detection of stereo headsets (GND + left + right signal)
@ -252,10 +249,4 @@ enum {
#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 #define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
#define AIC3X_BUTTON_DEBOUNCE_MASK 3 #define AIC3X_BUTTON_DEBOUNCE_MASK 3
/* see the enums above for valid parameters to this function */
void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
int headset_debounce, int button_debounce);
int aic3x_headset_detected(struct snd_soc_codec *codec);
int aic3x_button_pressed(struct snd_soc_codec *codec);
#endif /* _AIC3X_H */ #endif /* _AIC3X_H */

View File

@ -806,8 +806,6 @@ static int dac33_startup(struct snd_pcm_substream *substream,
/* Stream started, save the substream pointer */ /* Stream started, save the substream pointer */
dac33->substream = substream; dac33->substream = substream;
snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
return 0; return 0;
} }
@ -1397,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
codec->control_data = dac33->control_data; codec->control_data = dac33->control_data;
codec->hw_write = (hw_write_t) i2c_master_send; codec->hw_write = (hw_write_t) i2c_master_send;
codec->dapm.idle_bias_off = 1;
dac33->codec = codec; dac33->codec = codec;
/* Read the tlv320dac33 ID registers */ /* Read the tlv320dac33 ID registers */
@ -1440,7 +1437,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
/* Only add the FIFO controls, if we have valid IRQ number */ /* Only add the FIFO controls, if we have valid IRQ number */
if (dac33->irq >= 0) if (dac33->irq >= 0)
snd_soc_add_controls(codec, dac33_mode_snd_controls, snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
ARRAY_SIZE(dac33_mode_snd_controls)); ARRAY_SIZE(dac33_mode_snd_controls));
err_power: err_power:
@ -1478,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
.read = dac33_read_reg_cache, .read = dac33_read_reg_cache,
.write = dac33_write_locked, .write = dac33_write_locked,
.set_bias_level = dac33_set_bias_level, .set_bias_level = dac33_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(dac33_reg), .reg_cache_size = ARRAY_SIZE(dac33_reg),
.reg_word_size = sizeof(u8), .reg_word_size = sizeof(u8),
.reg_cache_default = dac33_reg, .reg_cache_default = dac33_reg,
@ -1515,7 +1513,9 @@ static struct snd_soc_dai_driver dac33_dai = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.rates = DAC33_RATES, .rates = DAC33_RATES,
.formats = DAC33_FORMATS,}, .formats = DAC33_FORMATS,
.sig_bits = 24,
},
.ops = &dac33_dai_ops, .ops = &dac33_dai_ops,
}; };

View File

@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
data = i2c_get_clientdata(tpa6130a2_client); data = i2c_get_clientdata(tpa6130a2_client);
if (data->id == TPA6140A2) if (data->id == TPA6140A2)
return snd_soc_add_controls(codec, tpa6140a2_controls, return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
ARRAY_SIZE(tpa6140a2_controls)); ARRAY_SIZE(tpa6140a2_controls));
else else
return snd_soc_add_controls(codec, tpa6130a2_controls, return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
ARRAY_SIZE(tpa6130a2_controls)); ARRAY_SIZE(tpa6130a2_controls));
} }
EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);

View File

@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
unsigned short mask, bitmask; unsigned short mask, bitmask;
if (twl4030->configured) { if (twl4030->configured) {
printk(KERN_ERR "twl4030 operation mode cannot be " dev_err(codec->dev,
"changed on-the-fly\n"); "operation mode cannot be changed on-the-fly\n");
return -EBUSY; return -EBUSY;
} }
@ -1689,7 +1689,6 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
if (twl4030->master_substream) { if (twl4030->master_substream) {
twl4030->slave_substream = substream; twl4030->slave_substream = substream;
/* The DAI has one configuration for playback and capture, so /* The DAI has one configuration for playback and capture, so
@ -1801,7 +1800,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
mode |= TWL4030_APLL_RATE_96000; mode |= TWL4030_APLL_RATE_96000;
break; break;
default: default:
printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n", dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
params_rate(params)); params_rate(params));
return -EINVAL; return -EINVAL;
} }
@ -1818,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
format |= TWL4030_DATA_WIDTH_32S_24W; format |= TWL4030_DATA_WIDTH_32S_24W;
break; break;
default: default:
printk(KERN_ERR "TWL4030 hw params: unknown format %d\n", dev_err(codec->dev, "%s: unknown format %d\n", __func__,
params_format(params)); params_format(params));
return -EINVAL; return -EINVAL;
} }
@ -1868,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
case 38400000: case 38400000:
break; break;
default: default:
dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq); dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
return -EINVAL; return -EINVAL;
} }
if ((freq / 1000) != twl4030->sysclk) { if ((freq / 1000) != twl4030->sysclk) {
dev_err(codec->dev, dev_err(codec->dev,
"Mismatch in APLL mclk: %u (configured: %u)\n", "Mismatch in HFCLKIN: %u (configured: %u)\n",
freq, twl4030->sysclk * 1000); freq, twl4030->sysclk * 1000);
return -EINVAL; return -EINVAL;
} }
@ -1984,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
* not available. * not available.
*/ */
if (twl4030->sysclk != 26000) { if (twl4030->sysclk != 26000) {
dev_err(codec->dev, "The board is configured for %u Hz, while" dev_err(codec->dev,
"the Voice interface needs 26MHz APLL mclk\n", "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
twl4030->sysclk * 1000); __func__, twl4030->sysclk);
return -EINVAL; return -EINVAL;
} }
@ -1997,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
& TWL4030_OPT_MODE; & TWL4030_OPT_MODE;
if (mode != TWL4030_OPTION_2) { if (mode != TWL4030_OPTION_2) {
printk(KERN_ERR "TWL4030 voice startup: " dev_err(codec->dev, "%s: the codec mode is not option2\n",
"the codec mode is not option2\n"); __func__);
return -EINVAL; return -EINVAL;
} }
@ -2039,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
mode |= TWL4030_SEL_16K; mode |= TWL4030_SEL_16K;
break; break;
default: default:
printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
params_rate(params)); params_rate(params));
return -EINVAL; return -EINVAL;
} }
@ -2068,13 +2067,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
if (freq != 26000000) { if (freq != 26000000) {
dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" dev_err(codec->dev,
"interface needs 26MHz APLL mclk\n", freq); "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
__func__, freq / 1000);
return -EINVAL; return -EINVAL;
} }
if ((freq / 1000) != twl4030->sysclk) { if ((freq / 1000) != twl4030->sysclk) {
dev_err(codec->dev, dev_err(codec->dev,
"Mismatch in APLL mclk: %u (configured: %u)\n", "Mismatch in HFCLKIN: %u (configured: %u)\n",
freq, twl4030->sysclk * 1000); freq, twl4030->sysclk * 1000);
return -EINVAL; return -EINVAL;
} }
@ -2175,13 +2175,15 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
.channels_min = 2, .channels_min = 2,
.channels_max = 4, .channels_max = 4,
.rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
.formats = TWL4030_FORMATS,}, .formats = TWL4030_FORMATS,
.sig_bits = 24,},
.capture = { .capture = {
.stream_name = "Capture", .stream_name = "Capture",
.channels_min = 2, .channels_min = 2,
.channels_max = 4, .channels_max = 4,
.rates = TWL4030_RATES, .rates = TWL4030_RATES,
.formats = TWL4030_FORMATS,}, .formats = TWL4030_FORMATS,
.sig_bits = 24,},
.ops = &twl4030_dai_hifi_ops, .ops = &twl4030_dai_hifi_ops,
}, },
{ {
@ -2220,13 +2222,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
if (twl4030 == NULL) { if (twl4030 == NULL) {
printk("Can not allocate memroy\n"); dev_err(codec->dev, "Can not allocate memory\n");
return -ENOMEM; return -ENOMEM;
} }
snd_soc_codec_set_drvdata(codec, twl4030); snd_soc_codec_set_drvdata(codec, twl4030);
/* Set the defaults, and power up the codec */ /* Set the defaults, and power up the codec */
twl4030->sysclk = twl4030_audio_get_mclk() / 1000; twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
codec->dapm.idle_bias_off = 1;
twl4030_init_chip(codec); twl4030_init_chip(codec);
@ -2252,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
.read = twl4030_read_reg_cache, .read = twl4030_read_reg_cache,
.write = twl4030_write, .write = twl4030_write,
.set_bias_level = twl4030_set_bias_level, .set_bias_level = twl4030_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = sizeof(twl4030_reg), .reg_cache_size = sizeof(twl4030_reg),
.reg_word_size = sizeof(u8), .reg_word_size = sizeof(u8),
.reg_cache_default = twl4030_reg, .reg_cache_default = twl4030_reg,

Some files were not shown because too many files have changed in this diff Show More