Commit a754a87c authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Olof Johansson

Merge tag 'asoc-3.4' of...

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: default avatarArnd Bergmann <arnd@arndb.de>
[olof: Amended fix for mismerge as reported by Kevin Hilman]
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 70688056 22f8d055
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>;
};
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>;
};
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>;
};
......@@ -34,6 +34,7 @@ picochip Picochip Ltd
powervr Imagination Technologies
qcom Qualcomm, Inc.
ramtron Ramtron International
realtek Realtek Semiconductor Corp.
samsung Samsung Semiconductor
sbs Smart Battery System
schindler Schindler
......
......@@ -271,3 +271,6 @@ IOMAP
pcim_iounmap()
pcim_iomap_table() : array of mapped addresses indexed by BAR
pcim_iomap_regions() : do request_region() and iomap() on multiple BARs
REGULATOR
devm_regulator_get()
......@@ -783,23 +783,12 @@ void __init ep93xx_register_i2s(void)
#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
EP93XX_SYSCON_I2SCLKDIV_SPOL)
int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
int ep93xx_i2s_acquire(void)
{
unsigned val;
/* Sanity check */
if (i2s_pins & ~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);
ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97,
EP93XX_SYSCON_DEVCFG_I2S_MASK);
/*
* 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 &= ~EP93XX_I2SCLKDIV_MASK;
val |= i2s_config;
val |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
return 0;
......
......@@ -59,7 +59,7 @@ void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
void ep93xx_keypad_release_gpio(struct platform_device *pdev);
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_register_ac97(void);
......
......@@ -46,7 +46,6 @@ config SOC_IMX21
bool
select MACH_MX21
select CPU_ARM926T
select ARCH_MXC_AUDMUX_V1
select IMX_HAVE_DMA_V1
select IMX_HAVE_IOMUX_V1
select MXC_AVIC
......@@ -55,7 +54,6 @@ config SOC_IMX25
bool
select ARCH_MX25
select CPU_ARM926T
select ARCH_MXC_AUDMUX_V2
select ARCH_MXC_IOMUX_V3
select MXC_AVIC
......@@ -63,7 +61,6 @@ config SOC_IMX27
bool
select MACH_MX27
select CPU_ARM926T
select ARCH_MXC_AUDMUX_V1
select IMX_HAVE_DMA_V1
select IMX_HAVE_IOMUX_V1
select MXC_AVIC
......@@ -72,7 +69,6 @@ config SOC_IMX31
bool
select CPU_V6
select IMX_HAVE_PLATFORM_MXC_RNGA
select ARCH_MXC_AUDMUX_V2
select MXC_AVIC
select SMP_ON_UP if SMP
......@@ -80,7 +76,6 @@ config SOC_IMX35
bool
select CPU_V6
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
select HAVE_EPIT
select MXC_AVIC
select SMP_ON_UP if SMP
......@@ -89,7 +84,6 @@ config SOC_IMX5
select CPU_V7
select MXC_TZIC
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
select ARCH_HAS_CPUFREQ
select ARCH_MX5
bool
......
......@@ -32,7 +32,6 @@
#include <mach/common.h>
#include <mach/iomux-mx27.h>
#include <mach/hardware.h>
#include <mach/audmux.h>
#include "devices-imx27.h"
......@@ -306,25 +305,6 @@ void __init eukrea_mbimx27_baseboard_init(void)
mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
|| defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
/* SSI unit master I2S codec connected to SSI_PINS_4*/
mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
MXC_AUDMUX_V1_PCR_SYN |
MXC_AUDMUX_V1_PCR_TFSDIR |
MXC_AUDMUX_V1_PCR_TCLKDIR |
MXC_AUDMUX_V1_PCR_RFSDIR |
MXC_AUDMUX_V1_PCR_RCLKDIR |
MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
);
mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
MXC_AUDMUX_V1_PCR_SYN |
MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
);
#endif
imx27_add_imx_uart1(&uart_pdata);
imx27_add_imx_uart2(&uart_pdata);
#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
......
......@@ -37,7 +37,6 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx51.h>
#include <mach/audmux.h>
#include "devices-imx51.h"
......
......@@ -31,7 +31,6 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/mx25.h>
#include <mach/audmux.h>
#include "devices-imx25.h"
......@@ -241,22 +240,6 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
ARRAY_SIZE(eukrea_mbimxsd_pads)))
printk(KERN_ERR "error setting mbimxsd pads !\n");
#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
/* SSI unit master I2S codec connected to SSI_AUD5*/
mxc_audmux_v2_configure_port(0,
MXC_AUDMUX_V2_PTCR_SYN |
MXC_AUDMUX_V2_PTCR_TFSDIR |
MXC_AUDMUX_V2_PTCR_TFSEL(4) |
MXC_AUDMUX_V2_PTCR_TCLKDIR |
MXC_AUDMUX_V2_PTCR_TCSEL(4),
MXC_AUDMUX_V2_PDCR_RXDSEL(4)
);
mxc_audmux_v2_configure_port(4,
MXC_AUDMUX_V2_PTCR_SYN,
MXC_AUDMUX_V2_PDCR_RXDSEL(0)
);
#endif
imx25_add_imx_uart1(&uart_pdata);
imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
......
......@@ -38,7 +38,6 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/iomux-mx35.h>
#include <mach/audmux.h>
#include "devices-imx35.h"
......@@ -252,22 +251,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
ARRAY_SIZE(eukrea_mbimxsd_pads)))
printk(KERN_ERR "error setting mbimxsd pads !\n");
#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
/* SSI unit master I2S codec connected to SSI_AUD4 */
mxc_audmux_v2_configure_port(0,
MXC_AUDMUX_V2_PTCR_SYN |
MXC_AUDMUX_V2_PTCR_TFSDIR |
MXC_AUDMUX_V2_PTCR_TFSEL(3) |
MXC_AUDMUX_V2_PTCR_TCLKDIR |
MXC_AUDMUX_V2_PTCR_TCSEL(3),
MXC_AUDMUX_V2_PDCR_RXDSEL(3)
);
mxc_audmux_v2_configure_port(3,
MXC_AUDMUX_V2_PTCR_SYN,
MXC_AUDMUX_V2_PDCR_RXDSEL(0)
);
#endif
imx35_add_imx_uart1(&uart_pdata);
imx35_add_ipu_core(&mx3_ipu_data);
imx35_add_mx3_sdc_fb(&mx3fb_pdata);
......
......@@ -393,6 +393,7 @@ static void __init visstrim_m10_board_init(void)
imx27_add_fec(NULL);
imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
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,
&iclink_tvp5150, sizeof(iclink_tvp5150));
gpio_led_register_device(0, &visstrim_m10_led_data);
......
......@@ -36,7 +36,6 @@
#include <mach/hardware.h>
#include <mach/iomux-mx27.h>
#include <asm/mach/time.h>
#include <mach/audmux.h>
#include <mach/irqs.h>
#include <mach/ulpi.h>
......@@ -359,18 +358,6 @@ static void __init pca100_init(void)
imx27_soc_init();
/* SSI unit */
mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
MXC_AUDMUX_V1_PCR_TFCSEL(3) |
MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
MXC_AUDMUX_V1_PCR_RXDSEL(3));
mxc_audmux_v1_configure_port(3,
MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
MXC_AUDMUX_V1_PCR_TFCSEL(0) |
MXC_AUDMUX_V1_PCR_TFSDIR |
MXC_AUDMUX_V1_PCR_RXDSEL(0));
ret = mxc_gpio_setup_multiple_pins(pca100_pins,
ARRAY_SIZE(pca100_pins), "PCA100");
if (ret)
......
......@@ -37,7 +37,6 @@
#include <mach/common.h>
#include <mach/iomux-mx35.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
#include "devices-imx35.h"
......@@ -362,18 +361,6 @@ static void __init pcm043_init(void)
mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
mxc_audmux_v2_configure_port(3,
MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
MXC_AUDMUX_V2_PTCR_TFSEL(0) |
MXC_AUDMUX_V2_PTCR_TFSDIR,
MXC_AUDMUX_V2_PDCR_RXDSEL(0));
mxc_audmux_v2_configure_port(0,
MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
MXC_AUDMUX_V2_PTCR_TCSEL(3) |
MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
MXC_AUDMUX_V2_PDCR_RXDSEL(3));
imx35_add_fec(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
imx35_add_imx2_wdt(NULL);
......
......@@ -75,6 +75,10 @@ void __init mx21_init_irq(void)
mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
}
static const struct resource imx21_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX21_AUDMUX_BASE_ADDR, SZ_4K),
};
void __init imx21_soc_init(void)
{
mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
......@@ -85,4 +89,6 @@ void __init imx21_soc_init(void)
mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
imx_add_imx_dma();
platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
ARRAY_SIZE(imx21_audmux_res));
}
......@@ -83,6 +83,10 @@ static struct sdma_platform_data imx25_sdma_pdata __initdata = {
.script_addrs = &imx25_sdma_script,
};
static const struct resource imx25_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX25_AUDMUX_BASE_ADDR, SZ_16K),
};
void __init imx25_soc_init(void)
{
/* i.mx25 has the i.mx31 type gpio */
......@@ -93,4 +97,7 @@ void __init imx25_soc_init(void)
/* i.mx25 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
/* i.mx25 has the i.mx31 type audmux */
platform_device_register_simple("imx31-audmux", 0, imx25_audmux_res,
ARRAY_SIZE(imx25_audmux_res));
}
......@@ -75,6 +75,10 @@ void __init mx27_init_irq(void)
mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
}
static const struct resource imx27_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX27_AUDMUX_BASE_ADDR, SZ_4K),
};
void __init imx27_soc_init(void)
{
/* i.mx27 has the i.mx21 type gpio */
......@@ -86,4 +90,7 @@ void __init imx27_soc_init(void)
mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
imx_add_imx_dma();
/* imx27 has the imx21 type audmux */
platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
ARRAY_SIZE(imx27_audmux_res));
}
......@@ -156,6 +156,10 @@ static struct sdma_platform_data imx31_sdma_pdata __initdata = {
.script_addrs = &imx31_to2_sdma_script,
};
static const struct resource imx31_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX31_AUDMUX_BASE_ADDR, SZ_16K),
};
void __init imx31_soc_init(void)
{
int to_version = mx31_revision() >> 4;
......@@ -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);
platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
ARRAY_SIZE(imx31_audmux_res));
}
#endif /* ifdef CONFIG_SOC_IMX31 */
......@@ -239,6 +245,10 @@ static struct sdma_platform_data imx35_sdma_pdata __initdata = {
.script_addrs = &imx35_to2_sdma_script,
};
static const struct resource imx35_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX35_AUDMUX_BASE_ADDR, SZ_16K),
};
void __init imx35_soc_init(void)
{
int to_version = mx35_revision() >> 4;
......@@ -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);
/* 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 */
......@@ -164,6 +164,18 @@ static struct sdma_platform_data imx53_sdma_pdata __initdata = {
.script_addrs = &imx53_sdma_script,
};
static const struct resource imx50_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX50_AUDMUX_BASE_ADDR, SZ_16K),
};
static const struct resource imx51_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX51_AUDMUX_BASE_ADDR, SZ_16K),
};
static const struct resource imx53_audmux_res[] __initconst = {
DEFINE_RES_MEM(MX53_AUDMUX_BASE_ADDR, SZ_16K),
};
void __init imx50_soc_init(void)
{
/* i.mx50 has the i.mx31 type gpio */
......@@ -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", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
/* i.mx50 has the i.mx31 type audmux */
platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
ARRAY_SIZE(imx50_audmux_res));
}
void __init imx51_soc_init(void)
......@@ -185,6 +201,9 @@ void __init imx51_soc_init(void)
/* i.mx51 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
/* i.mx51 has the i.mx31 type audmux */
platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res,
ARRAY_SIZE(imx51_audmux_res));
}
void __init imx53_soc_init(void)
......@@ -200,4 +219,7 @@ void __init imx53_soc_init(void)
/* i.mx53 has the i.mx35 type sdma */
imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
/* i.mx53 has the i.mx31 type audmux */
platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
ARRAY_SIZE(imx53_audmux_res));
}
......@@ -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 __init sd_uart_selection(char *str)
......@@ -172,6 +177,7 @@ static void __init openrd_init(void)
kirkwood_i2c_init();
if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
platform_device_register(&openrd_client_audio_device);
i2c_register_board_info(0, i2c_board_info,
ARRAY_SIZE(i2c_board_info));
kirkwood_audio_init();
......
......@@ -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 = {
MPP0_NF_IO2,
MPP1_SPI_MOSI,
......@@ -179,6 +184,7 @@ static void __init hp_t5325_init(void)
kirkwood_sata_init(&hp_t5325_sata_data);
kirkwood_ehci_init();
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));
kirkwood_audio_init();
......
......@@ -41,6 +41,7 @@
#include <video/omap-panel-nokia-dsi.h>
#include <video/omap-panel-picodlp.h>
#include <linux/wl12xx.h>
#include <linux/platform_data/omap-abe-twl6040.h>
#include "mux.h"
#include "hsmmc.h"
......@@ -381,12 +382,40 @@ static struct platform_device sdp4430_dmic_codec = {
.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 = {
&sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
&sdp4430_leds_pwm,
&sdp4430_vbat,
&sdp4430_dmic_codec,
&sdp4430_abe_audio,
};
static struct omap_musb_board_data musb_board_data = {
......
......@@ -28,6 +28,7 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
#include <linux/wl12xx.h>
#include <linux/platform_data/omap-abe-twl6040.h>
#include <mach/hardware.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 = {
.name = "btwilink",
.id = -1,
......@@ -99,6 +124,7 @@ static struct platform_device btwilink_device = {
static struct platform_device *panda_devices[] __initdata = {
&leds_gpio,
&wl1271_device,
&panda_abe_audio,
&btwilink_device,
};
......@@ -258,8 +284,25 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
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 */
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
......@@ -491,6 +534,20 @@ void omap4_panda_display_init(void)
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)
{
int package = OMAP_PACKAGE_CBS;
......@@ -504,6 +561,7 @@ static void __init omap4_panda_init(void)
if (ret)
pr_err("error setting wl12xx data: %d\n", ret);
omap4_panda_init_rev();
omap4_panda_i2c_init();
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
platform_device_register(&omap_vwlan_device);
......
......@@ -120,6 +120,7 @@ static struct wm8962_pdata wm8962_pdata __initdata = {
0x8000 | WM8962_GPIO_FN_DMICDAT,
WM8962_GPIO_FN_IRQ, /* Open drain mode */
},
.in4_dc_measure = true,
};
static struct wm9081_pdata wm9081_pdata __initdata = {
......
......@@ -737,26 +737,18 @@ static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
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 = {
.porta_flags = SH_FSI_BRS_INV,
.portb_flags = SH_FSI_BRS_INV |
SH_FSI_BRM_INV |
SH_FSI_LRS_INV |
SH_FSI_FMT_SPDIF,
.set_rate = fsi_set_rate,
.port_a = {
.flags = SH_FSI_BRS_INV,
.set_rate = fsi_ak4642_set_rate,
},
.port_b = {
.flags = SH_FSI_BRS_INV |
SH_FSI_BRM_INV |
SH_FSI_LRS_INV |
SH_FSI_FMT_SPDIF,
.set_rate = fsi_hdmi_set_rate,
},
};
static struct resource fsi_resources[] = {
......
......@@ -860,7 +860,7 @@ static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
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 *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 ret;
/* FSIA is slave mode. nothing to do here */
if (is_porta)
return 0;
/* clock start */
switch (rate) {
case 44100:
......@@ -916,14 +912,16 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
}
static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV,
.portb_flags = SH_FSI_BRS_INV |
.port_a = {
.flags = SH_FSI_BRS_INV,
},
.port_b = {
.flags = SH_FSI_BRS_INV |
SH_FSI_BRM_INV |
SH_FSI_LRS_INV |
SH_FSI_FMT_SPDIF,
.set_rate = fsi_set_rate,
.set_rate = fsi_b_set_rate,
}
};
static struct resource fsi_resources[] = {
......
......@@ -88,12 +88,6 @@ config IMX_HAVE_IOMUX_V1
config ARCH_MXC_IOMUX_V3
bool
config ARCH_MXC_AUDMUX_V1
bool
config ARCH_MXC_AUDMUX_V2
bool
config IRAM_ALLOC
bool
select GENERIC_ALLOCATOR
......
......@@ -14,8 +14,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
ifdef CONFIG_SND_IMX_SOC
......
/*
* 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);
......@@ -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 = {
&jz4740_udc_device,
......@@ -434,6 +439,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&qi_lb60_gpio_keys,
&qi_lb60_pwm_beeper,
&qi_lb60_charger_device,
&qi_lb60_audio_device,
};
static void __init board_gpio_setup(void)
......
......@@ -769,7 +769,9 @@ static struct platform_device camera_devices[] = {
/* FSI */
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[] = {
......
......@@ -278,7 +278,9 @@ static struct platform_device ceu1_device = {
/* FSI */
/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
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[] = {
......
......@@ -75,6 +75,9 @@ struct regmap {
const void *reg_defaults_raw;
void *cache;
bool cache_dirty;
struct reg_default *patch;
int patch_regs;
};
struct regcache_ops {
......
......@@ -268,6 +268,17 @@ int regcache_sync(struct regmap *map)
map->cache_ops->name);
name = map->cache_ops->name;
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)
goto out;
if (map->cache_ops->sync) {
......
......@@ -672,6 +672,79 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
}
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)
{
regmap_debugfs_initcall();
......
......@@ -1320,6 +1320,40 @@ struct regulator *regulator_get(struct device *dev, const char *id)
}
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.
* @dev: device for regulator "consumer"
......@@ -1387,6 +1421,34 @@ void regulator_put(struct regulator *regulator)
}
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)
{
if (!rdev->constraints)
......@@ -2401,6 +2463,52 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
}
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)
{
struct regulator_bulk_data *bulk = data;
......
......@@ -185,6 +185,9 @@ struct wm8994_pdata {
unsigned int jd_scthr: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 */
int micbias[2];
......
/**
* 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_ */
......@@ -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,
unsigned int mask, unsigned int val,
bool *change);
int regmap_get_val_bytes(struct regmap *map);
int regcache_sync(struct regmap *map);
void regcache_cache_only(struct regmap *map, bool enable);
void regcache_cache_bypass(struct regmap *map, bool enable);
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.
*
......
......@@ -132,9 +132,12 @@ struct regulator_bulk_data {
/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,
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,
const char *id);
void regulator_put(struct regulator *regulator);
void devm_regulator_free(struct regulator *regulator);
/* regulator output control and status */
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,
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,
struct regulator_bulk_data *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;
}
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)
{
}
......
......@@ -40,7 +40,7 @@ struct snd_kcontrol_new {
snd_ctl_elem_iface_t iface; /* interface identifier */
unsigned int device; /* device/client 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 access; /* access rights */
unsigned int count; /* count of same elements */
......
/*
* 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
/*
* 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__*/
......@@ -454,6 +454,7 @@ struct snd_pcm {
void *private_data;
void (*private_free) (struct snd_pcm *pcm);
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)
struct snd_pcm_oss oss;
#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 playback_count, int capture_count,
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_notify(struct snd_pcm_notify *notify, int nfree);
......
......@@ -72,10 +72,16 @@
#define SH_FSI_BPFMD_32 (5 << 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 {
unsigned long porta_flags;
unsigned long portb_flags;
int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
struct sh_fsi_port_info port_a;
struct sh_fsi_port_info port_b;
};
/*
......
......@@ -17,6 +17,7 @@
#include <linux/list.h>
struct snd_pcm_substream;
struct snd_soc_dapm_widget;
/*
* DAI hardware audio formats.
......@@ -238,6 +239,9 @@ struct snd_soc_dai {
unsigned char pop_wait:1;
unsigned char probed:1;
struct snd_soc_dapm_widget *playback_widget;
struct snd_soc_dapm_widget *capture_widget;
/* DAI DMA data */
void *playback_dma_data;
void *capture_dma_data;
......@@ -246,10 +250,9 @@ struct snd_soc_dai {
unsigned int rate;
/* parent platform/codec */
union {
struct snd_soc_platform *platform;
struct snd_soc_codec *codec;
};
struct snd_soc_platform *platform;
struct snd_soc_codec *codec;
struct snd_soc_card *card;
struct list_head list;
......
......@@ -243,6 +243,10 @@
{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .event = wevent, \
.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 */
#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,
struct snd_kcontrol *kcontrol, int event);
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
/* dapm controls */
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);
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
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,
const struct snd_soc_dapm_widget *widget,
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 */
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);
/* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
const char *stream, int event);
int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
struct snd_soc_dai *dai, int event);
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 */
int snd_soc_dapm_sys_add(struct device *dev);
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_post, /* machine specific post widget - exec last */
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_out, /* audio interface output */
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 */
struct snd_soc_dapm_path {
char *name;
char *long_name;
const char *name;
const char *long_name;
/* source (input) and sink (output) widgets */
struct snd_soc_dapm_widget *source;
......@@ -458,13 +473,15 @@ struct snd_soc_dapm_path {
/* dapm widget */
struct snd_soc_dapm_widget {
enum snd_soc_dapm_type id;
char *name; /* widget name */
char *sname; /* stream name */
const char *name; /* widget name */
const char *sname; /* stream name */
struct snd_soc_codec *codec;
struct snd_soc_platform *platform;
struct list_head list;
struct snd_soc_dapm_context *dapm;
void *priv; /* widget specific data */
/* dapm control */
short reg; /* negative reg = no direct dapm */
unsigned char shift; /* bits to shift */
......
......@@ -185,6 +185,20 @@
.rreg = xreg_right, .shift = xshift, \
.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
......@@ -366,12 +380,16 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
*Controls
*/
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);
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);
int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
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,
struct snd_ctl_elem_info *uinfo);
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);
int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
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
......@@ -505,6 +530,7 @@ struct snd_soc_pcm_stream {
unsigned int rate_max; /* max rate */
unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */
unsigned int sig_bits; /* number of bits of content */
};
/* SoC audio ops */
......@@ -559,6 +585,7 @@ struct snd_soc_codec {
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
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_sync; /* Cache needs to be synced to hardware */
......@@ -637,6 +664,8 @@ struct snd_soc_codec_driver {
/* codec stream completion 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 */
int probe_order;
int remove_order;
......@@ -689,6 +718,7 @@ struct snd_soc_platform {
int id;
struct device *dev;
struct snd_soc_platform_driver *driver;
struct mutex mutex;
unsigned int suspended:1; /* platform is suspended */
unsigned int probed:1;
......@@ -698,6 +728,11 @@ struct snd_soc_platform {
struct list_head card_list;
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 {
......@@ -875,6 +910,12 @@ struct soc_mixer_control {
unsigned int reg, rreg, shift, rshift, invert;
};
struct soc_bytes {
int base;
int num_regs;
u32 mask;
};
/* enumerated kcontrol */
struct soc_enum {
unsigned short reg;
......
/*
* 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
......@@ -49,6 +49,12 @@ struct wm8962_pdata {
bool irq_active_low;
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
......@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
pstr->stream = stream;
pstr->pcm = pcm;
pstr->substream_count = substream_count;
if (substream_count > 0) {
if (substream_count > 0 && !pcm->internal) {
err = snd_pcm_stream_proc_init(pstr);
if (err < 0) {
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;
else
prev->next = substream;
err = snd_pcm_substream_proc_init(substream);
if (err < 0) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
if (prev == NULL)
pstr->substream = NULL;
else
prev->next = NULL;
kfree(substream);
return err;
if (!pcm->internal) {
err = snd_pcm_substream_proc_init(substream);
if (err < 0) {
snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
if (prev == NULL)
pstr->substream = NULL;
else
prev->next = NULL;
kfree(substream);
return err;
}
}
substream->group = &substream->self_group;
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);
/**
* 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)
static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count, bool internal,
struct snd_pcm **rpcm)
{
struct snd_pcm *pcm;
int err;
......@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
}
pcm->card = card;
pcm->device = device;
pcm->internal = internal;
if (id)
strlcpy(pcm->id, id, sizeof(pcm->id));
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;
}
/**
* 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);
/**
* 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)
{
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++) {
int devtype = -1;
if (pcm->streams[cidx].substream == NULL)
if (pcm->streams[cidx].substream == NULL || pcm->internal)
continue;
switch (cidx) {
case SNDRV_PCM_STREAM_PLAYBACK:
......
......@@ -25,6 +25,9 @@ if SND_SOC
config SND_SOC_AC97_BUS
bool
config SND_SOC_DMAENGINE_PCM
bool
# All the supported SoCs
source "sound/soc/atmel/Kconfig"
source "sound/soc/au1x/Kconfig"
......
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-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) += codecs/
obj-$(CONFIG_SND_SOC) += atmel/
......
......@@ -362,7 +362,7 @@ static struct snd_pcm_ops atmel_pcm_ops = {
/*--------------------------------------------------------------------------*\
* 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)
{
......@@ -373,7 +373,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
if (!card->dev->dma_mask)
card->dev->dma_mask = &atmel_pcm_dmamask;
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) {
ret = atmel_pcm_preallocate_dma_buffer(pcm,
......
......@@ -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_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
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 */
err =
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),
};
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, "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_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, "Line In");
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",
.codec_name = "tlv320aic23-codec.0-001a",
.init = afeb9260_tlv320aic23_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &afeb9260_ops,
};
......@@ -138,6 +112,11 @@ static struct snd_soc_card snd_soc_machine_afeb9260 = {
.owner = THIS_MODULE,
.dai_link = &afeb9260_dai,
.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;
......
......@@ -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_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};
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 */
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,
};
#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[] = {
{
.name = "ad1836",
......@@ -77,6 +68,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
.platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.4",
.ops = &bf5xx_ad1836_ops,
.dai_fmt = BF5XX_AD1836_DAIFMT,
},
{
.name = "ad1836",
......@@ -86,6 +78,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
.platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.4",
.ops = &bf5xx_ad1836_ops,
.dai_fmt = BF5XX_AD1836_DAIFMT,
},
};
......
......@@ -60,18 +60,6 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
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 */
ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
SND_SOC_CLOCK_IN);
......@@ -92,6 +80,9 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
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 = {
.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",
.codec_name = "spi0.5",
.ops = &bf5xx_ad193x_ops,
.dai_fmt = BF5XX_AD193X_DAIFMT,
},
{
.name = "ad193x",
......@@ -114,6 +106,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
.platform_name = "bfin-tdm-pcm-audio",
.codec_name = "spi0.5",
.ops = &bf5xx_ad193x_ops,
.dai_fmt = BF5XX_AD193X_DAIFMT,
},
};
......
......@@ -145,29 +145,8 @@ static int bf5xx_probe(struct snd_soc_card *card)
return 0;
}
static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *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,
};
#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
SND_SOC_DAIFMT_CBM_CFM)
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",
.platform_name = "bfin-i2s-pcm-audio",
.codec_name = "ad73311",
.ops = &bf5xx_ad73311_ops,
.dai_fmt = BF5XX_AD7311_DAI_FMT,
},
{
.name = "ad73311",
......@@ -186,7 +165,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
.codec_dai_name = "ad73311-hifi",
.platform_name = "bfin-i2s-pcm-audio",
.codec_name = "ad73311",
.ops = &bf5xx_ad73311_ops,
.dai_fmt = BF5XX_AD7311_DAI_FMT,
},
};
......
......@@ -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_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned int clk = 0;
int ret = 0;
......@@ -75,21 +74,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
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,
SND_SOC_CLOCK_IN);
if (ret < 0)
......@@ -102,6 +86,10 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
.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[] = {
{
.name = "ssm2602",
......
......@@ -67,21 +67,10 @@ static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
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)) {
case 48000:
case 8000:
......@@ -143,6 +132,8 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
.codec_name = "adau1373.0-001a",
.ops = &bfin_eval_adau1373_ops,
.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 = {
......
......@@ -37,20 +37,9 @@ static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
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,
SND_SOC_CLOCK_IN);
......@@ -61,6 +50,9 @@ static struct snd_soc_ops bfin_eval_adau1701_ops = {
.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[] = {
{
.name = "adau1701",
......@@ -70,6 +62,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
.platform_name = "bfin-i2s-pcm-audio",
.codec_name = "adau1701.0-0034",
.ops = &bfin_eval_adau1701_ops,
.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
},
{
.name = "adau1701",
......@@ -79,6 +72,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
.platform_name = "bfin-i2s-pcm-audio",
.codec_name = "adau1701.0-0034",
.ops = &bfin_eval_adau1701_ops,
.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
},
};
......
......@@ -34,20 +34,9 @@ static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
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,
27000000, params_rate(params) * 256);
if (ret)
......@@ -88,6 +77,8 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
.platform_name = "bfin-i2s-pcm-audio",
.init = bfin_eval_adav80x_codec_init,
.ops = &bfin_eval_adav80x_ops,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
},
};
......
......@@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX98088 if I2C
select SND_SOC_MAX98095 if I2C
select SND_SOC_MAX9850 if I2C
select SND_SOC_MAX9768 if I2C
select SND_SOC_MAX9877 if I2C
select SND_SOC_PCM3008
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_WM1250_EV1 if I2C
select SND_SOC_WM2000 if I2C
select SND_SOC_WM2200 if I2C
select SND_SOC_WM5100 if I2C
select SND_SOC_WM8350 if MFD_WM8350
select SND_SOC_WM8400 if MFD_WM8400
......@@ -292,6 +294,9 @@ config SND_SOC_WM1250_EV1
config SND_SOC_WM2000
tristate
config SND_SOC_WM2200
tristate
config SND_SOC_WM5100
tristate
......@@ -425,6 +430,9 @@ config SND_SOC_WM9713
config SND_SOC_LM4857
tristate
config SND_SOC_MAX9768
tristate
config SND_SOC_MAX9877
tristate
......
......@@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o
snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o
snd-soc-max9768-objs := max9768.o
snd-soc-max98088-objs := max98088.o
snd-soc-max98095-objs := max98095.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-wm1250-ev1-objs := wm1250-ev1.o
snd-soc-wm2000-objs := wm2000.o
snd-soc-wm2200-objs := wm2200.o
snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
snd-soc-wm8350-objs := wm8350.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_LM4857) += snd-soc-lm4857.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_MAX98095) += snd-soc-max98095.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_WM1250_EV1) += snd-soc-wm1250-ev1.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_WM8350) += snd-soc-wm8350.o
obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
......
......@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
if (ad1836->type == AD1836) {
/* left/right diff:PGA/MUX */
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));
if (ret)
return ret;
......@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
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)
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)
return ret;
......
......@@ -228,7 +228,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
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));
return 0;
......
......@@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec)
return ret;
}
codec->dapm.idle_bias_off = true;
if (pdata) {
if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
return -EINVAL;
......@@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
pdata->drc_setting[i]);
}
snd_soc_add_controls(codec, adau1373_drc_controls,
snd_soc_add_codec_controls(codec, adau1373_drc_controls,
pdata->num_drc);
val = 0;
......@@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
}
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));
}
......@@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
.suspend = adau1373_suspend,
.resume = adau1373_resume,
.set_bias_level = adau1373_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
.reg_cache_default = adau1373_default_regs,
.reg_word_size = sizeof(uint8_t),
......
......@@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec)
{
int ret;
codec->dapm.idle_bias_off = 1;
codec->control_data = to_i2c_client(codec->dev);
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 = {
.probe = adau1701_probe,
.set_bias_level = adau1701_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ADAU1701_NUM_REGS,
.reg_word_size = sizeof(u16),
......
......@@ -46,75 +46,15 @@
#define DRV_NAME "ak4104-codec"
struct ak4104_private {
enum snd_soc_control_type control_type;
void *control_data;
struct regmap *regmap;
};
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,
unsigned int format)
{
struct snd_soc_codec *codec = codec_dai->codec;
int val = 0;
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
if (val < 0)
return val;
val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1);
int ret;
/* set DAI format */
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)
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,
......@@ -148,7 +94,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
/* set the IEC958 bits: consumer mode, no copyright bit */
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;
......@@ -167,7 +113,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
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 = {
......@@ -192,67 +138,57 @@ static struct snd_soc_dai_driver ak4104_dai = {
static int ak4104_probe(struct snd_soc_codec *codec)
{
struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
int ret, val;
codec->control_data = ak4104->control_data;
int ret;
/* read all regs and fill the cache */
ret = ak4104_fill_cache(codec);
if (ret < 0) {
dev_err(codec->dev, "failed to fill register cache\n");
codec->control_data = ak4104->regmap;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret != 0)
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 */
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
if (ret < 0)
return ret;
/* enable transmitter */
val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
val |= AK4104_TX_TXE;
ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
ret = snd_soc_update_bits(codec, AK4104_REG_TX,
AK4104_TX_TXE, AK4104_TX_TXE);
if (ret < 0)
return ret;
dev_info(codec->dev, "SPI device initialized\n");
return 0;
}
static int ak4104_remove(struct snd_soc_codec *codec)
{
int val, ret;
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
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);
snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
return ret;
return 0;
}
static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
.probe = ak4104_probe,
.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)
{
struct ak4104_private *ak4104;
unsigned int val;
int ret;
spi->bits_per_word = 8;
......@@ -266,17 +202,41 @@ static int ak4104_spi_probe(struct spi_device *spi)
if (ak4104 == NULL)
return -ENOMEM;
ak4104->control_data = spi;
ak4104->control_type = SND_SOC_SPI;
ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap);
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);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_device_ak4104, &ak4104_dai, 1);
if (ret != 0)
goto err;
return 0;
err:
regmap_exit(ak4104->regmap);
return ret;
}
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);
return 0;
}
......@@ -290,17 +250,7 @@ static struct spi_driver ak4104_spi_driver = {
.remove = __devexit_p(ak4104_spi_remove),
};
static int __init ak4104_init(void)
{
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_spi_driver(ak4104_spi_driver);
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");
......
......@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
......@@ -27,24 +28,43 @@
#include "ak4535.h"
#define AK4535_VERSION "0.3"
/* codec private data */
struct ak4535_priv {
struct regmap *regmap;
unsigned int sysclk;
enum snd_soc_control_type control_type;
};
/*
* ak4535 register cache
*/
static const u8 ak4535_reg[AK4535_CACHEREGNUM] = {
0x00, 0x80, 0x00, 0x03,
0x02, 0x00, 0x11, 0x01,
0x00, 0x40, 0x36, 0x10,
0x00, 0x00, 0x57, 0x00,
static const struct reg_default ak4535_reg_defaults[] = {
{ 0, 0x00 },
{ 1, 0x80 },
{ 2, 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_out[] = {"(L + R)/2", "Hi-Z"};
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);
int ret;
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
codec->control_data = ak4535->regmap;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
......@@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec)
/* power on device */
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));
return 0;
}
......@@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec)
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 = {
.probe = ak4535_probe,
.remove = ak4535_remove,
.suspend = ak4535_suspend,
.resume = ak4535_resume,
.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,
.num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
.dapm_routes = 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,
const struct i2c_device_id *id)
{
......@@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
if (ak4535 == NULL)
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);
ak4535->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_ak4535, &ak4535_dai, 1);
if (ret != 0)
regmap_exit(ak4535->regmap);
return ret;
}
static __devexit int ak4535_i2c_remove(struct i2c_client *client)
{
struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev);
regmap_exit(ak4535->regmap);
return 0;
}
......@@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
static struct i2c_driver ak4535_i2c_driver = {
.driver = {
.name = "ak4535-codec",
.name = "ak4535",
.owner = THIS_MODULE,
},
.probe = ak4535_i2c_probe,
.remove = __devexit_p(ak4535_i2c_remove),
.id_table = ak4535_i2c_id,
};
#endif
static int __init ak4535_modinit(void)
{
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_i2c_driver(ak4535_i2c_driver);
MODULE_DESCRIPTION("Soc AK4535 driver");
MODULE_AUTHOR("Richard Purdie");
......
......@@ -34,6 +34,4 @@
#define AK4535_VOL 0xe
#define AK4535_STATUS 0xf
#define AK4535_CACHEREGNUM 0x10
#endif
......@@ -477,7 +477,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
return ret;
}
snd_soc_add_controls(codec, ak4642_snd_controls,
snd_soc_add_codec_controls(codec, ak4642_snd_controls,
ARRAY_SIZE(ak4642_snd_controls));
ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
......
......@@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec)
return ret;
}
snd_soc_add_controls(codec, ak4671_snd_controls,
snd_soc_add_codec_controls(codec, ak4671_snd_controls,
ARRAY_SIZE(ak4671_snd_controls));
ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
......
......@@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec)
switch (alc5623->id) {
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));
break;
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));
break;
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));
break;
default:
return -EINVAL;
}
snd_soc_add_controls(codec, alc5623_snd_controls,
snd_soc_add_codec_controls(codec, alc5623_snd_controls,
ARRAY_SIZE(alc5623_snd_controls));
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
* 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)
{
struct alc5623_platform_data *pdata;
......@@ -1059,7 +1059,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
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);
return 0;
......
This diff is collapsed.
......@@ -51,6 +51,7 @@
#define ALC5632_ADC_REC_MONOMIX (1 << 0)
#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 : */
/* same remark as for reg 2 line vs speaker */
#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */
......
......@@ -38,8 +38,6 @@
#include <sound/soc.h>
#include <sound/initval.h>
#include <mach/dm365.h>
static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
unsigned int reg)
{
......@@ -159,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
codec->control_data = davinci_vc;
/* Set controls */
snd_soc_add_controls(codec, cq93vc_snd_controls,
snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
ARRAY_SIZE(cq93vc_snd_controls));
/* Off, with power on */
......
......@@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec)
}
/* 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));
if (ret < 0) {
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 = {
.driver = {
.name = "cs4270-codec",
.name = "cs4270",
.owner = THIS_MODULE,
},
.id_table = cs4270_id,
......
......@@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
/* Power-up sequence requires 85 uS */
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));
}
......
......@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <sound/pcm.h>
......@@ -626,41 +627,82 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = {
/* Codec private data */
struct da7210_priv {
enum snd_soc_control_type control_type;
struct regmap *regmap;
};
/*
* Register cache
*/
static const u8 da7210_reg[] = {
0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
0x00, /* R88 */
static struct reg_default da7210_reg_defaults[] = {
{ 0x01, 0x11 },
{ 0x03, 0x00 },
{ 0x04, 0x00 },
{ 0x05, 0x00 },
{ 0x06, 0x00 },
{ 0x07, 0x00 },
{ 0x08, 0x00 },
{ 0x09, 0x00 },
{ 0x0a, 0x00 },
{ 0x0b, 0x00 },
{ 0x0c, 0x00 },
{ 0x0d, 0x00 },
{ 0x0e, 0x00 },
{ 0x0f, 0x08 },
{ 0x10, 0x00 },
{ 0x11, 0x00 },
{ 0x12, 0x00 },
{ 0x13, 0x00 },
{ 0x14, 0x08 },
{ 0x15, 0x10 },
{ 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)
{
switch (reg) {
case DA7210_STATUS:
return 1;
return true;
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);
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) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", 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);
/* As suggested by Dialog */
snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
snd_soc_write(codec, DA7210_A_PLL1, 0x01);
snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C);
snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
/* unlock */
regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
/* re-lock */
regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
/* Activate all enabled subsystem */
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 = {
.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,
.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),
};
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)
static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
......@@ -1027,16 +1079,34 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
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,
&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;
}
static int __devexit da7210_i2c_remove(struct i2c_client *client)
{
struct da7210_priv *da7210 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev);
regmap_exit(da7210->regmap);
return 0;
}
......
......@@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec)
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));
if (ret)
return ret;
......
/*
* 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");
......@@ -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.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)
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);
snd_soc_add_controls(codec, max98088_snd_controls,
snd_soc_add_codec_controls(codec, max98088_snd_controls,
ARRAY_SIZE(max98088_snd_controls));
err_access:
......
......@@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = {
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));
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.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)
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.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)
dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
}
......
......@@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = {
/* This function is called from ASoC machine driver */
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));
}
EXPORT_SYMBOL_GPL(max9877_add_controls);
......
......@@ -227,7 +227,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
};
/* 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", "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;
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,
......@@ -1353,15 +1353,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
if (ret)
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);
return 0;
......@@ -1402,6 +1393,12 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
.reg_cache_step = 2,
.reg_cache_default = sgtl5000_regs,
.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,
......
......@@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
{
pr_debug("codec_probe called\n");
codec->dapm.idle_bias_off = 1;
/* PCM interface config
* This sets the pcm rx slot conguration to max 6 slots
* 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_SSR3, 0x40);
snd_soc_add_controls(codec, sn95031_snd_controls,
snd_soc_add_codec_controls(codec, sn95031_snd_controls,
ARRAY_SIZE(sn95031_snd_controls));
return 0;
......@@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = {
.read = sn95031_read,
.write = sn95031_write,
.set_bias_level = sn95031_set_vaud_bias,
.idle_bias_off = true,
.dapm_widgets = sn95031_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
.dapm_routes = sn95031_audio_map,
......
......@@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, SSM2602_ROUT1V,
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));
if (ret)
return ret;
......
......@@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
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));
return 0;
......
......@@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
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));
return 0;
......
......@@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
/* register controls */
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));
WARN_ON(err < 0);
......
......@@ -671,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
}
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));
aic32x4_add_widgets(codec);
......
......@@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
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) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
......@@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
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,
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);
}
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_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);
aic3x->codec = codec;
codec->dapm.idle_bias_off = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
if (ret != 0) {
......@@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec)
(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));
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);
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 = {
.set_bias_level = aic3x_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(aic3x_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = aic3x_reg,
......
......@@ -212,9 +212,6 @@
/* Default input volume */
#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 */
/* 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_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 */
......@@ -806,8 +806,6 @@ static int dac33_startup(struct snd_pcm_substream *substream,
/* Stream started, save the substream pointer */
dac33->substream = substream;
snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
return 0;
}
......@@ -1397,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
codec->control_data = dac33->control_data;
codec->hw_write = (hw_write_t) i2c_master_send;
codec->dapm.idle_bias_off = 1;
dac33->codec = codec;
/* 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 */
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));
err_power:
......@@ -1478,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
.read = dac33_read_reg_cache,
.write = dac33_write_locked,
.set_bias_level = dac33_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = ARRAY_SIZE(dac33_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = dac33_reg,
......@@ -1515,7 +1513,9 @@ static struct snd_soc_dai_driver dac33_dai = {
.channels_min = 2,
.channels_max = 2,
.rates = DAC33_RATES,
.formats = DAC33_FORMATS,},
.formats = DAC33_FORMATS,
.sig_bits = 24,
},
.ops = &dac33_dai_ops,
};
......
......@@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
data = i2c_get_clientdata(tpa6130a2_client);
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));
else
return snd_soc_add_controls(codec, tpa6130a2_controls,
return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
ARRAY_SIZE(tpa6130a2_controls));
}
EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
......
......@@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
unsigned short mask, bitmask;
if (twl4030->configured) {
printk(KERN_ERR "twl4030 operation mode cannot be "
"changed on-the-fly\n");
dev_err(codec->dev,
"operation mode cannot be changed on-the-fly\n");
return -EBUSY;
}
......@@ -1689,7 +1689,6 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = rtd->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) {
twl4030->slave_substream = substream;
/* 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;
break;
default:
printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
params_rate(params));
return -EINVAL;
}
......@@ -1818,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
format |= TWL4030_DATA_WIDTH_32S_24W;
break;
default:
printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
dev_err(codec->dev, "%s: unknown format %d\n", __func__,
params_format(params));
return -EINVAL;
}
......@@ -1868,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
case 38400000:
break;
default:
dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
return -EINVAL;
}
if ((freq / 1000) != twl4030->sysclk) {
dev_err(codec->dev,
"Mismatch in APLL mclk: %u (configured: %u)\n",
"Mismatch in HFCLKIN: %u (configured: %u)\n",
freq, twl4030->sysclk * 1000);
return -EINVAL;
}
......@@ -1984,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
* not available.
*/
if (twl4030->sysclk != 26000) {
dev_err(codec->dev, "The board is configured for %u Hz, while"
"the Voice interface needs 26MHz APLL mclk\n",
twl4030->sysclk * 1000);
dev_err(codec->dev,
"%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
__func__, twl4030->sysclk);
return -EINVAL;
}
......@@ -1997,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
& TWL4030_OPT_MODE;
if (mode != TWL4030_OPTION_2) {
printk(KERN_ERR "TWL4030 voice startup: "
"the codec mode is not option2\n");
dev_err(codec->dev, "%s: the codec mode is not option2\n",
__func__);
return -EINVAL;
}
......@@ -2039,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
mode |= TWL4030_SEL_16K;
break;
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));
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);
if (freq != 26000000) {
dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
"interface needs 26MHz APLL mclk\n", freq);
dev_err(codec->dev,
"%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
__func__, freq / 1000);
return -EINVAL;
}
if ((freq / 1000) != twl4030->sysclk) {
dev_err(codec->dev,
"Mismatch in APLL mclk: %u (configured: %u)\n",
"Mismatch in HFCLKIN: %u (configured: %u)\n",
freq, twl4030->sysclk * 1000);
return -EINVAL;
}
......@@ -2175,13 +2175,15 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
.channels_min = 2,
.channels_max = 4,
.rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
.formats = TWL4030_FORMATS,},
.formats = TWL4030_FORMATS,
.sig_bits = 24,},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 4,
.rates = TWL4030_RATES,
.formats = TWL4030_FORMATS,},
.formats = TWL4030_FORMATS,
.sig_bits = 24,},
.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);
if (twl4030 == NULL) {
printk("Can not allocate memroy\n");
dev_err(codec->dev, "Can not allocate memory\n");
return -ENOMEM;
}
snd_soc_codec_set_drvdata(codec, twl4030);
/* Set the defaults, and power up the codec */
twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
codec->dapm.idle_bias_off = 1;
twl4030_init_chip(codec);
......@@ -2252,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
.read = twl4030_read_reg_cache,
.write = twl4030_write,
.set_bias_level = twl4030_set_bias_level,
.idle_bias_off = true,
.reg_cache_size = sizeof(twl4030_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = twl4030_reg,
......
......@@ -1052,6 +1052,19 @@ int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
}
EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
{
struct twl6040 *twl6040 = codec->control_data;
if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2)
/* For ES under ES_1.3 HS step is 2 mV */
return 2;
else
/* For ES_1.3 HS step is 1 mV */
return 1;
}
EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size);
static const struct snd_kcontrol_new twl6040_snd_controls[] = {
/* Capture gains */
SOC_DOUBLE_TLV("Capture Preamplifier Volume",
......@@ -1125,14 +1138,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
TWL6040_REG_MICRCTL, 2, 0),
/* Microphone bias */
SND_SOC_DAPM_MICBIAS("Headset Mic Bias",
TWL6040_REG_AMICBCTL, 0, 0),
SND_SOC_DAPM_MICBIAS("Main Mic Bias",
TWL6040_REG_AMICBCTL, 4, 0),
SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias",
TWL6040_REG_DMICBCTL, 0, 0),
SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias",
TWL6040_REG_DMICBCTL, 4, 0),
SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
TWL6040_REG_AMICBCTL, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Main Mic Bias",
TWL6040_REG_AMICBCTL, 4, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
TWL6040_REG_DMICBCTL, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
/* DACs */
SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
......@@ -1527,7 +1540,6 @@ static int twl6040_probe(struct snd_soc_codec *codec)
priv->codec = codec;
codec->control_data = dev_get_drvdata(codec->dev->parent);
codec->ignore_pmdown_time = 1;
if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
priv->hs_left_step = pdata->hs_left_step;
......@@ -1613,6 +1625,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
.reg_cache_size = ARRAY_SIZE(twl6040_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = twl6040_reg,
.ignore_pmdown_time = true,
.controls = twl6040_snd_controls,
.num_controls = ARRAY_SIZE(twl6040_snd_controls),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment