Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into next/boards
The asoc branch that was already merged into v3.4 contains some board-level changes that conflict with patches we already have here, so pull in that branch to resolve the conflicts. Conflicts: arch/arm/mach-imx/mach-imx27_visstrim_m10.c arch/arm/mach-omap2/board-omap4panda.c Signed-off-by: Arnd Bergmann <arnd@arndb.de> [olof: Amended fix for mismerge as reported by Kevin Hilman] Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
a754a87ce8
214 changed files with 14178 additions and 6320 deletions
24
Documentation/devicetree/bindings/sound/alc5632.txt
Normal file
24
Documentation/devicetree/bindings/sound/alc5632.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
ALC5632 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "realtek,alc5632"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
- gpio-controller : Indicates this device is a GPIO controller.
|
||||
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters (currently unused).
|
||||
|
||||
Example:
|
||||
|
||||
alc5632: alc5632@1e {
|
||||
compatible = "realtek,alc5632";
|
||||
reg = <0x1a>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
13
Documentation/devicetree/bindings/sound/imx-audmux.txt
Normal file
13
Documentation/devicetree/bindings/sound/imx-audmux.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
Freescale Digital Audio Mux (AUDMUX) device
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,imx21-audmux" for AUDMUX version firstly used on i.MX21,
|
||||
or "fsl,imx31-audmux" for the version firstly used on i.MX31.
|
||||
- reg : Should contain AUDMUX registers location and length
|
||||
|
||||
Example:
|
||||
|
||||
audmux@021d8000 {
|
||||
compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
|
||||
reg = <0x021d8000 0x4000>;
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
NVIDIA Tegra audio complex
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra-audio-alc5632"
|
||||
- nvidia,model : The user-visible name of this sound complex.
|
||||
- nvidia,audio-routing : A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the connection's sink,
|
||||
the second being the connection's source. Valid names for sources and
|
||||
sinks are the ALC5632's pins:
|
||||
|
||||
ALC5632 pins:
|
||||
|
||||
* SPK_OUTP
|
||||
* SPK_OUTN
|
||||
* HP_OUT_L
|
||||
* HP_OUT_R
|
||||
* AUX_OUT_P
|
||||
* AUX_OUT_N
|
||||
* LINE_IN_L
|
||||
* LINE_IN_R
|
||||
* PHONE_P
|
||||
* PHONE_N
|
||||
* MIC1_P
|
||||
* MIC1_N
|
||||
* MIC2_P
|
||||
* MIC2_N
|
||||
* MICBIAS1
|
||||
* DMICDAT
|
||||
|
||||
Board connectors:
|
||||
|
||||
* Headset Stereophone
|
||||
* Int Spk
|
||||
* Headset Mic
|
||||
* Digital Mic
|
||||
|
||||
- nvidia,i2s-controller : The phandle of the Tegra I2S controller
|
||||
- nvidia,audio-codec : The phandle of the ALC5632 audio codec
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "nvidia,tegra-audio-alc5632-paz00",
|
||||
"nvidia,tegra-audio-alc5632";
|
||||
|
||||
nvidia,model = "Compal PAZ00";
|
||||
|
||||
nvidia,audio-routing =
|
||||
"Int Spk", "SPK_OUTP",
|
||||
"Int Spk", "SPK_OUTN",
|
||||
"Headset Mic","MICBIAS1",
|
||||
"MIC1_N", "Headset Mic",
|
||||
"MIC1_P", "Headset Mic",
|
||||
"Headset Stereophone", "HP_OUT_R",
|
||||
"Headset Stereophone", "HP_OUT_L";
|
||||
|
||||
nvidia,i2s-controller = <&tegra_i2s1>;
|
||||
nvidia,audio-codec = <&alc5632>;
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* Initial development of this code was funded by
|
||||
* Phytec Messtechnik GmbH, http://www.phytec.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <mach/audmux.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
static void __iomem *audmux_base;
|
||||
|
||||
static unsigned char port_mapping[] = {
|
||||
0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
|
||||
};
|
||||
|
||||
int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
|
||||
{
|
||||
if (!audmux_base) {
|
||||
printk("%s: not configured\n", __func__);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
if (port >= ARRAY_SIZE(port_mapping))
|
||||
return -EINVAL;
|
||||
|
||||
writel(pcr, audmux_base + port_mapping[port]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
|
||||
|
||||
static int mxc_audmux_v1_init(void)
|
||||
{
|
||||
#ifdef CONFIG_MACH_MX21
|
||||
if (cpu_is_mx21())
|
||||
audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_MACH_MX27
|
||||
if (cpu_is_mx27())
|
||||
audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
|
||||
else
|
||||
#endif
|
||||
(void)0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
postcore_initcall(mxc_audmux_v1_init);
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef __MACH_AUDMUX_H
|
||||
#define __MACH_AUDMUX_H
|
||||
|
||||
#define MX27_AUDMUX_HPCR1_SSI0 0
|
||||
#define MX27_AUDMUX_HPCR2_SSI1 1
|
||||
#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
|
||||
#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
|
||||
#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
|
||||
#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
|
||||
|
||||
#define MX31_AUDMUX_PORT1_SSI0 0
|
||||
#define MX31_AUDMUX_PORT2_SSI1 1
|
||||
#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
|
||||
#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
|
||||
#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
|
||||
#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
|
||||
|
||||
#define MX51_AUDMUX_PORT1_SSI0 0
|
||||
#define MX51_AUDMUX_PORT2_SSI1 1
|
||||
#define MX51_AUDMUX_PORT3 2
|
||||
#define MX51_AUDMUX_PORT4 3
|
||||
#define MX51_AUDMUX_PORT5 4
|
||||
#define MX51_AUDMUX_PORT6 5
|
||||
#define MX51_AUDMUX_PORT7 6
|
||||
|
||||
/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
|
||||
#define MXC_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
|
||||
#define MXC_AUDMUX_V1_PCR_INMEN (1 << 8)
|
||||
#define MXC_AUDMUX_V1_PCR_TXRXEN (1 << 10)
|
||||
#define MXC_AUDMUX_V1_PCR_SYN (1 << 12)
|
||||
#define MXC_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
|
||||
#define MXC_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
|
||||
#define MXC_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
|
||||
#define MXC_AUDMUX_V1_PCR_RFSDIR (1 << 25)
|
||||
#define MXC_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
|
||||
#define MXC_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
|
||||
#define MXC_AUDMUX_V1_PCR_TFSDIR (1 << 31)
|
||||
|
||||
/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
|
||||
#define MXC_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
|
||||
#define MXC_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
|
||||
#define MXC_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
|
||||
#define MXC_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
|
||||
#define MXC_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
|
||||
#define MXC_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
|
||||
#define MXC_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
|
||||
#define MXC_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
|
||||
#define MXC_AUDMUX_V2_PTCR_SYN (1 << 11)
|
||||
|
||||
#define MXC_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
|
||||
#define MXC_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
|
||||
#define MXC_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
|
||||
#define MXC_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
|
||||
|
||||
int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
|
||||
|
||||
int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
|
||||
unsigned int pdcr);
|
||||
|
||||
#endif /* __MACH_AUDMUX_H */
|
|
@ -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];
|
||||
|
||||
|
|
49
include/linux/platform_data/omap-abe-twl6040.h
Normal file
49
include/linux/platform_data/omap-abe-twl6040.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* omap-abe-twl6040.h - ASoC machine driver OMAP4+ devices, header.
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _OMAP_ABE_TWL6040_H_
|
||||
#define _OMAP_ABE_TWL6040_H_
|
||||
|
||||
/* To select if only one channel is connected in a stereo port */
|
||||
#define ABE_TWL6040_LEFT (1 << 0)
|
||||
#define ABE_TWL6040_RIGHT (1 << 1)
|
||||
|
||||
struct omap_abe_twl6040_data {
|
||||
char *card_name;
|
||||
/* Feature flags for connected audio pins */
|
||||
u8 has_hs;
|
||||
u8 has_hf;
|
||||
bool has_ep;
|
||||
u8 has_aux;
|
||||
u8 has_vibra;
|
||||
bool has_dmic;
|
||||
bool has_hsmic;
|
||||
bool has_mainmic;
|
||||
bool has_submic;
|
||||
u8 has_afm;
|
||||
/* Other features */
|
||||
bool jack_detection; /* board can detect jack events */
|
||||
int mclk_freq; /* MCLK frequency speed for twl6040 */
|
||||
};
|
||||
|
||||
#endif /* _OMAP_ABE_TWL6040_H_ */
|
|
@ -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 */
|
||||
|
|
49
include/sound/dmaengine_pcm.h
Normal file
49
include/sound/dmaengine_pcm.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2012, Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __SOUND_DMAENGINE_PCM_H__
|
||||
#define __SOUND_DMAENGINE_PCM_H__
|
||||
|
||||
#include <sound/pcm.h>
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
/**
|
||||
* snd_pcm_substream_to_dma_direction - Get dma_transfer_direction for a PCM
|
||||
* substream
|
||||
* @substream: PCM substream
|
||||
*/
|
||||
static inline enum dma_transfer_direction
|
||||
snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return DMA_MEM_TO_DEV;
|
||||
else
|
||||
return DMA_DEV_TO_MEM;
|
||||
}
|
||||
|
||||
void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data);
|
||||
void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream);
|
||||
|
||||
int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
|
||||
const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
|
||||
int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
|
||||
snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
|
||||
|
||||
int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
|
||||
dma_filter_fn filter_fn, void *filter_data);
|
||||
int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
|
||||
|
||||
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
|
||||
|
||||
#endif
|
24
include/sound/max9768.h
Normal file
24
include/sound/max9768.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Platform data for MAX9768
|
||||
* Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
|
||||
* same licence as the driver
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_MAX9768_PDATA_H__
|
||||
#define __SOUND_MAX9768_PDATA_H__
|
||||
|
||||
/**
|
||||
* struct max9768_pdata - optional platform specific MAX9768 configuration
|
||||
* @shdn_gpio: GPIO to SHDN pin. If not valid, pin must be hardwired HIGH
|
||||
* @mute_gpio: GPIO to MUTE pin. If not valid, control for mute won't be added
|
||||
* @flags: configuration flags, e.g. set classic PWM mode (check datasheet
|
||||
* regarding "filterless modulation" which is default).
|
||||
*/
|
||||
struct max9768_pdata {
|
||||
int shdn_gpio;
|
||||
int mute_gpio;
|
||||
unsigned flags;
|
||||
#define MAX9768_FLAG_CLASSIC_PWM (1 << 0)
|
||||
};
|
||||
|
||||
#endif /* __SOUND_MAX9768_PDATA_H__*/
|
|
@ -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;
|
||||
|
|
41
include/sound/wm2200.h
Normal file
41
include/sound/wm2200.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* linux/sound/wm2200.h -- Platform data for WM2200
|
||||
*
|
||||
* Copyright 2012 Wolfson Microelectronics. PLC.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_WM2200_H
|
||||
#define __LINUX_SND_WM2200_H
|
||||
|
||||
#define WM2200_GPIO_SET 0x10000
|
||||
|
||||
enum wm2200_in_mode {
|
||||
WM2200_IN_SE = 0,
|
||||
WM2200_IN_DIFF = 1,
|
||||
WM2200_IN_DMIC = 2,
|
||||
};
|
||||
|
||||
enum wm2200_dmic_sup {
|
||||
WM2200_DMIC_SUP_MICVDD = 0,
|
||||
WM2200_DMIC_SUP_MICBIAS1 = 1,
|
||||
WM2200_DMIC_SUP_MICBIAS2 = 2,
|
||||
};
|
||||
|
||||
struct wm2200_pdata {
|
||||
int reset; /** GPIO controlling /RESET, if any */
|
||||
int ldo_ena; /** GPIO controlling LODENA, if any */
|
||||
int irq_flags;
|
||||
|
||||
int gpio_defaults[4];
|
||||
|
||||
enum wm2200_in_mode in_mode[3];
|
||||
enum wm2200_dmic_sup dmic_sup[3];
|
||||
|
||||
int micbias_cfg[2]; /** Register value to configure MICBIAS */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -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"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
|
||||
snd-soc-core-objs += soc-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;
|
||||
int ret;
|
||||
|
||||
codec->control_data = ak4104->control_data;
|
||||
|
||||
/* 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;
|
||||
snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
|
||||
AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
|
|
@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
|
|||
/* -16.5db min scale, 1.5db steps, no mute */
|
||||
static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
|
||||
static const unsigned int boost_tlv[] = {
|
||||
TLV_DB_RANGE_HEAD(3),
|
||||
0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
|
||||
1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
|
||||
2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
|
||||
1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
|
||||
};
|
||||
/* 0db min scale, 6 db steps, no mute */
|
||||
static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
|
||||
/* 0db min scalem 0.75db steps, no mute */
|
||||
static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);
|
||||
|
||||
static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
|
||||
/* left starts at bit 8, right at bit 0 */
|
||||
|
@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = {
|
|||
ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
|
||||
SOC_SINGLE_TLV("Voice DAC Playback Volume",
|
||||
ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
|
||||
SOC_SINGLE_TLV("Phone Capture Volume",
|
||||
SOC_SINGLE("Voice DAC Playback Switch",
|
||||
ALC5632_VOICE_DAC_VOL, 12, 1, 1),
|
||||
SOC_SINGLE_TLV("Phone Playback Volume",
|
||||
ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
|
||||
SOC_DOUBLE_TLV("LineIn Capture Volume",
|
||||
SOC_DOUBLE_TLV("LineIn Playback Volume",
|
||||
ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
|
||||
SOC_DOUBLE_TLV("Master Playback Volume",
|
||||
ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
|
||||
SOC_DOUBLE("Master Playback Switch",
|
||||
ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
|
||||
SOC_SINGLE_TLV("Mic1 Capture Volume",
|
||||
SOC_SINGLE_TLV("Mic1 Playback Volume",
|
||||
ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
|
||||
SOC_SINGLE_TLV("Mic2 Capture Volume",
|
||||
SOC_SINGLE_TLV("Mic2 Playback Volume",
|
||||
ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
|
||||
SOC_DOUBLE_TLV("Rec Capture Volume",
|
||||
ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
|
||||
SOC_SINGLE_TLV("Mic 1 Boost Volume",
|
||||
ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv),
|
||||
ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),
|
||||
SOC_SINGLE_TLV("Mic 2 Boost Volume",
|
||||
ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv),
|
||||
SOC_SINGLE_TLV("Digital Boost Volume",
|
||||
ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),
|
||||
SOC_SINGLE_TLV("DMIC Boost Capture Volume",
|
||||
ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
|
||||
SOC_SINGLE("DMIC En Capture Switch",
|
||||
ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),
|
||||
SOC_SINGLE("DMIC PreFilter Capture Switch",
|
||||
ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
|
|||
|
||||
/* Left Record Mixer */
|
||||
static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
|
||||
SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
|
||||
SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
|
||||
SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
|
||||
SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
|
||||
SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
|
||||
SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
|
||||
SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
|
||||
SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
|
||||
SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
|
||||
SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
|
||||
SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
|
||||
SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
|
||||
SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
|
||||
};
|
||||
|
||||
/* Right Record Mixer */
|
||||
static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
|
||||
SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
|
||||
SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
|
||||
SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
|
||||
SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
|
||||
SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
|
||||
SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
|
||||
SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
|
||||
SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
|
||||
SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
|
||||
SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
|
||||
SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
|
||||
SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
|
||||
SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
|
||||
};
|
||||
|
||||
static const char *alc5632_spk_n_sour_sel[] = {
|
||||
/* Dmic Mixer */
|
||||
static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),
|
||||
};
|
||||
static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),
|
||||
};
|
||||
|
||||
static const char * const alc5632_spk_n_sour_sel[] = {
|
||||
"RN/-R", "RP/+R", "LN/-R", "Mute"};
|
||||
static const char *alc5632_hpl_out_input_sel[] = {
|
||||
static const char * const alc5632_hpl_out_input_sel[] = {
|
||||
"Vmid", "HP Left Mix"};
|
||||
static const char *alc5632_hpr_out_input_sel[] = {
|
||||
static const char * const alc5632_hpr_out_input_sel[] = {
|
||||
"Vmid", "HP Right Mix"};
|
||||
static const char *alc5632_spkout_input_sel[] = {
|
||||
static const char * const alc5632_spkout_input_sel[] = {
|
||||
"Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
|
||||
static const char *alc5632_aux_out_input_sel[] = {
|
||||
static const char * const alc5632_aux_out_input_sel[] = {
|
||||
"Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
|
||||
static const char * const alc5632_adcr_func_sel[] = {
|
||||
"Stereo ADC", "Voice ADC"};
|
||||
static const char * const alc5632_i2s_out_sel[] = {
|
||||
"ADC LR", "Voice Stereo Digital"};
|
||||
|
||||
/* auxout output mux */
|
||||
static const struct soc_enum alc5632_aux_out_input_enum =
|
||||
|
@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum =
|
|||
static const struct snd_kcontrol_new alc5632_amp_mux_controls =
|
||||
SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
|
||||
|
||||
/* ADC output select */
|
||||
static const struct soc_enum alc5632_adcr_func_enum =
|
||||
SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel);
|
||||
static const struct snd_kcontrol_new alc5632_adcr_func_controls =
|
||||
SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
|
||||
|
||||
/* I2S out select */
|
||||
static const struct soc_enum alc5632_i2s_out_enum =
|
||||
SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel);
|
||||
static const struct snd_kcontrol_new alc5632_i2s_out_controls =
|
||||
SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
|
||||
/* Muxes */
|
||||
|
@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
|
|||
&alc5632_hpr_out_mux_controls),
|
||||
SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
|
||||
&alc5632_spkoutn_mux_controls),
|
||||
SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
|
||||
&alc5632_adcr_func_controls),
|
||||
SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,
|
||||
&alc5632_i2s_out_controls),
|
||||
|
||||
/* output mixers */
|
||||
SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
|
||||
|
@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
|
|||
SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
|
||||
&alc5632_speaker_mixer_controls[0],
|
||||
ARRAY_SIZE(alc5632_speaker_mixer_controls)),
|
||||
SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,
|
||||
&alc5632_dmicl_mixer_controls[0],
|
||||
ARRAY_SIZE(alc5632_dmicl_mixer_controls)),
|
||||
SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,
|
||||
&alc5632_dmicr_mixer_controls[0],
|
||||
ARRAY_SIZE(alc5632_dmicr_mixer_controls)),
|
||||
|
||||
/* input mixers */
|
||||
SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
|
||||
|
@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
|
|||
&alc5632_captureR_mixer_controls[0],
|
||||
ARRAY_SIZE(alc5632_captureR_mixer_controls)),
|
||||
|
||||
SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback",
|
||||
ALC5632_PWR_MANAG_ADD2, 9, 0),
|
||||
SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback",
|
||||
ALC5632_PWR_MANAG_ADD2, 8, 0),
|
||||
SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),
|
||||
SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),
|
||||
SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),
|
||||
SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),
|
||||
SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),
|
||||
|
||||
SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER("DAC Right Channel",
|
||||
ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture",
|
||||
ALC5632_PWR_MANAG_ADD2, 7, 0),
|
||||
SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
|
||||
ALC5632_PWR_MANAG_ADD2, 6, 0),
|
||||
SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
|
||||
|
@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"),
|
|||
SND_SOC_DAPM_OUTPUT("HPR"),
|
||||
SND_SOC_DAPM_OUTPUT("SPKOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("SPKOUTN"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("LINEINL"),
|
||||
SND_SOC_DAPM_INPUT("LINEINR"),
|
||||
SND_SOC_DAPM_INPUT("PHONEP"),
|
||||
SND_SOC_DAPM_INPUT("PHONEN"),
|
||||
SND_SOC_DAPM_INPUT("DMICDAT"),
|
||||
SND_SOC_DAPM_INPUT("MIC1"),
|
||||
SND_SOC_DAPM_INPUT("MIC2"),
|
||||
SND_SOC_DAPM_VMID("Vmid"),
|
||||
|
@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"),
|
|||
|
||||
|
||||
static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
|
||||
/* Playback streams */
|
||||
{"Left DAC", NULL, "AIFRXL"},
|
||||
{"Right DAC", NULL, "AIFRXR"},
|
||||
|
||||
/* virtual mixer - mixes left & right channels */
|
||||
{"I2S Mix", NULL, "Left DAC"},
|
||||
{"I2S Mix", NULL, "Right DAC"},
|
||||
|
@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
|
|||
{"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
|
||||
{"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
|
||||
{"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
|
||||
|
||||
{"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"},
|
||||
{"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
|
||||
{"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
|
||||
{"HPOut Mix", NULL, "HP Mix"},
|
||||
{"HPOut Mix", NULL, "HPR Mix"},
|
||||
{"HPOut Mix", NULL, "HPL Mix"},
|
||||
|
||||
/* speaker mixer */
|
||||
{"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
|
||||
|
@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
|
|||
{"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
|
||||
{"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
|
||||
{"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
|
||||
|
||||
|
||||
{"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"},
|
||||
|
||||
/* mono mixer */
|
||||
{"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
|
||||
{"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
|
||||
{"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
|
||||
{"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
|
||||
{"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
|
||||
{"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
|
||||
{"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
|
||||
{"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"},
|
||||
|
||||
/* Left record mixer */
|
||||
{"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
|
||||
{"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"},
|
||||
{"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
|
||||
{"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
|
||||
{"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
|
||||
{"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
|
||||
{"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
|
||||
{"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},
|
||||
{"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},
|
||||
{"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},
|
||||
{"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},
|
||||
{"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},
|
||||
{"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},
|
||||
{"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},
|
||||
|
||||
/*Right record mixer */
|
||||
{"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
|
||||
{"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"},
|
||||
{"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
|
||||
{"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
|
||||
{"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
|
||||
{"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
|
||||
{"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
|
||||
{"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},
|
||||
{"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},
|
||||
{"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},
|
||||
{"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},
|
||||
{"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},
|
||||
{"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},
|
||||
{"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},
|
||||
|
||||
/* headphone left mux */
|
||||
{"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
|
||||
|
@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
|
|||
|
||||
/* left ADC */
|
||||
{"Left ADC", NULL, "Left Capture Mix"},
|
||||
{"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},
|
||||
{"Left ADC", NULL, "DMICL Mix"},
|
||||
{"ADCLR", NULL, "Left ADC"},
|
||||
|
||||
/* right ADC */
|
||||
{"Right ADC", NULL, "Right Capture Mix"},
|
||||
{"Right ADC", NULL, "Right Capture Mix"},
|
||||
{"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},
|
||||
{"Right ADC", NULL, "DMICR Mix"},
|
||||
{"ADCR Mux", "Stereo ADC", "Right ADC"},
|
||||
{"ADCR Mux", "Voice ADC", "Right ADC"},
|
||||
{"ADCLR", NULL, "ADCR Mux"},
|
||||
{"VAIFTX", NULL, "ADCR Mux"},
|
||||
|
||||
/* Digital I2S out */
|
||||
{"I2SOut Mux", "ADC LR", "ADCLR"},
|
||||
{"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},
|
||||
{"AIFTXL", NULL, "I2SOut Mux"},
|
||||
{"AIFTXR", NULL, "I2SOut Mux"},
|
||||
|
||||
/* Voice Mix */
|
||||
{"Voice DAC", NULL, "VAIFRX"},
|
||||
{"Voice Mix", NULL, "Voice DAC"},
|
||||
|
||||
/* Speaker Output */
|
||||
{"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
|
||||
{"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
|
||||
{"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
|
||||
|
@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
|||
struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (freq) {
|
||||
case 4096000:
|
||||
case 8192000:
|
||||
case 11289600:
|
||||
case 12288000:
|
||||
|
@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
|
|||
|
||||
switch (alc5632->id) {
|
||||
case 0x5c:
|
||||
snd_soc_add_controls(codec, alc5632_vol_snd_controls,
|
||||
snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
|
||||
ARRAY_SIZE(alc5632_vol_snd_controls));
|
||||
break;
|
||||
default:
|
||||
|
@ -1109,7 +1184,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int alc5632_i2c_remove(struct i2c_client *client)
|
||||
static __devexit int alc5632_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
|
|
|
@ -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;
|
||||
|
|
247
sound/soc/codecs/max9768.c
Normal file
247
sound/soc/codecs/max9768.c
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* MAX9768 AMP driver
|
||||
*
|
||||
* Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/max9768.h>
|
||||
|
||||
/* "Registers" */
|
||||
#define MAX9768_VOL 0
|
||||
#define MAX9768_CTRL 3
|
||||
|
||||
/* Commands */
|
||||
#define MAX9768_CTRL_PWM 0x15
|
||||
#define MAX9768_CTRL_FILTERLESS 0x16
|
||||
|
||||
struct max9768 {
|
||||
struct regmap *regmap;
|
||||
int mute_gpio;
|
||||
int shdn_gpio;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
static struct reg_default max9768_default_regs[] = {
|
||||
{ 0, 0 },
|
||||
{ 3, MAX9768_CTRL_FILTERLESS},
|
||||
};
|
||||
|
||||
static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
|
||||
int val = gpio_get_value_cansleep(max9768->mute_gpio);
|
||||
|
||||
ucontrol->value.integer.value[0] = !val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned int volume_tlv[] = {
|
||||
TLV_DB_RANGE_HEAD(43),
|
||||
0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
|
||||
1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
|
||||
2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
|
||||
3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
|
||||
4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
|
||||
5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
|
||||
6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
|
||||
7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
|
||||
8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
|
||||
9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
|
||||
10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
|
||||
11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
|
||||
12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
|
||||
13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
|
||||
14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
|
||||
15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
|
||||
18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
|
||||
19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
|
||||
20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
|
||||
21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
|
||||
22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
|
||||
23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
|
||||
24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
|
||||
25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
|
||||
26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
|
||||
27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
|
||||
28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
|
||||
31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
|
||||
32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
|
||||
35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
|
||||
38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
|
||||
40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
|
||||
41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
|
||||
42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
|
||||
43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
|
||||
44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
|
||||
45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
|
||||
46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
|
||||
47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
|
||||
51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
|
||||
58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
|
||||
59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
|
||||
63, 63, TLV_DB_SCALE_ITEM(950, 0, 0),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new max9768_volume[] = {
|
||||
SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new max9768_mute[] = {
|
||||
SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
|
||||
};
|
||||
|
||||
static int max9768_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
codec->control_data = max9768->regmap;
|
||||
ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
|
||||
ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (gpio_is_valid(max9768->mute_gpio)) {
|
||||
ret = snd_soc_add_codec_controls(codec, max9768_mute,
|
||||
ARRAY_SIZE(max9768_mute));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver max9768_codec_driver = {
|
||||
.probe = max9768_probe,
|
||||
.controls = max9768_volume,
|
||||
.num_controls = ARRAY_SIZE(max9768_volume),
|
||||
};
|
||||
|
||||
static const struct regmap_config max9768_i2c_regmap_config = {
|
||||
.reg_bits = 2,
|
||||
.val_bits = 6,
|
||||
.max_register = 3,
|
||||
.reg_defaults = max9768_default_regs,
|
||||
.num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int __devinit max9768_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct max9768 *max9768;
|
||||
struct max9768_pdata *pdata = client->dev.platform_data;
|
||||
int err;
|
||||
|
||||
max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
|
||||
if (!max9768)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pdata) {
|
||||
/* Mute on powerup to avoid clicks */
|
||||
err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute");
|
||||
max9768->mute_gpio = err ?: pdata->mute_gpio;
|
||||
|
||||
/* Activate chip by releasing shutdown, enables I2C */
|
||||
err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown");
|
||||
max9768->shdn_gpio = err ?: pdata->shdn_gpio;
|
||||
|
||||
max9768->flags = pdata->flags;
|
||||
} else {
|
||||
max9768->shdn_gpio = -EINVAL;
|
||||
max9768->mute_gpio = -EINVAL;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, max9768);
|
||||
|
||||
max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
|
||||
if (IS_ERR(max9768->regmap)) {
|
||||
err = PTR_ERR(max9768->regmap);
|
||||
goto err_gpio_free;
|
||||
}
|
||||
|
||||
err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
|
||||
if (err)
|
||||
goto err_regmap_free;
|
||||
|
||||
return 0;
|
||||
|
||||
err_regmap_free:
|
||||
regmap_exit(max9768->regmap);
|
||||
err_gpio_free:
|
||||
if (gpio_is_valid(max9768->shdn_gpio))
|
||||
gpio_free(max9768->shdn_gpio);
|
||||
if (gpio_is_valid(max9768->mute_gpio))
|
||||
gpio_free(max9768->mute_gpio);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit max9768_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct max9768 *max9768 = i2c_get_clientdata(client);
|
||||
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
regmap_exit(max9768->regmap);
|
||||
|
||||
if (gpio_is_valid(max9768->shdn_gpio))
|
||||
gpio_free(max9768->shdn_gpio);
|
||||
if (gpio_is_valid(max9768->mute_gpio))
|
||||
gpio_free(max9768->mute_gpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id max9768_i2c_id[] = {
|
||||
{ "max9768", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
|
||||
|
||||
static struct i2c_driver max9768_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max9768",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = max9768_i2c_probe,
|
||||
.remove = __devexit_p(max9768_i2c_remove),
|
||||
.id_table = max9768_i2c_id,
|
||||
};
|
||||
module_i2c_driver(max9768_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
|
||||
MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -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,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue