Merge branch 'topic/multi-component' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into for-2.6.37
This commit is contained in:
commit
cf7af01aa7
|
@ -295,6 +295,18 @@ static void davinci_init_wdt(void)
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
struct platform_device davinci_pcm_device = {
|
||||
.name = "davinci-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static void davinci_init_pcm(void)
|
||||
{
|
||||
platform_device_register(&davinci_pcm_device);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
struct davinci_timer_instance davinci_timer_instance[2] = {
|
||||
{
|
||||
.base = DAVINCI_TIMER0_BASE,
|
||||
|
@ -315,6 +327,7 @@ static int __init davinci_init_devices(void)
|
|||
/* please keep these calls, and their implementations above,
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
davinci_init_pcm();
|
||||
davinci_init_wdt();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -732,9 +732,15 @@ static struct platform_device ep93xx_i2s_device = {
|
|||
.resource = ep93xx_i2s_resource,
|
||||
};
|
||||
|
||||
static struct platform_device ep93xx_pcm_device = {
|
||||
.name = "ep93xx-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
void __init ep93xx_register_i2s(void)
|
||||
{
|
||||
platform_device_register(&ep93xx_i2s_device);
|
||||
platform_device_register(&ep93xx_pcm_device);
|
||||
}
|
||||
|
||||
#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \
|
||||
|
|
|
@ -896,10 +896,16 @@ static struct platform_device kirkwood_i2s_device = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct platform_device kirkwood_pcm_device = {
|
||||
.name = "kirkwood-pcm",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
void __init kirkwood_audio_init(void)
|
||||
{
|
||||
kirkwood_clk_ctrl |= CGC_AUDIO;
|
||||
platform_device_register(&kirkwood_i2s_device);
|
||||
platform_device_register(&kirkwood_pcm_device);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
|
@ -653,8 +653,8 @@ static struct clk_lookup lookups[] = {
|
|||
_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
|
||||
_REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
|
||||
_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
|
||||
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
|
||||
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
|
||||
_REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk)
|
||||
_REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk)
|
||||
_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
|
||||
_REGISTER_CLOCK(NULL, "vpu", vpu_clk)
|
||||
_REGISTER_CLOCK(NULL, "dma", dma_clk)
|
||||
|
|
|
@ -415,7 +415,7 @@ struct platform_device mxc_usbh2 = {
|
|||
}; \
|
||||
\
|
||||
struct platform_device imx_ssi_device ## n = { \
|
||||
.name = "imx-ssi", \
|
||||
.name = "imx-ssi-dai", \
|
||||
.id = n, \
|
||||
.num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
|
||||
.resource = imx_ssi_resources ## n, \
|
||||
|
|
|
@ -558,8 +558,8 @@ static struct clk_lookup lookups[] = {
|
|||
_REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
|
||||
_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
|
||||
_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
|
||||
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
|
||||
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
|
||||
_REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk)
|
||||
_REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk)
|
||||
_REGISTER_CLOCK(NULL, "firi", firi_clk)
|
||||
_REGISTER_CLOCK(NULL, "ata", ata_clk)
|
||||
_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
|
||||
|
|
|
@ -464,8 +464,8 @@ static struct clk_lookup lookups[] = {
|
|||
_REGISTER_CLOCK(NULL, "sdma", sdma_clk)
|
||||
_REGISTER_CLOCK(NULL, "spba", spba_clk)
|
||||
_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
|
||||
_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
|
||||
_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
|
||||
_REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk)
|
||||
_REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk)
|
||||
_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
|
||||
_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
|
||||
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
|
||||
|
|
|
@ -562,14 +562,14 @@ static struct resource imx_ssi_resources1[] = {
|
|||
};
|
||||
|
||||
struct platform_device imx_ssi_device0 = {
|
||||
.name = "imx-ssi",
|
||||
.name = "imx-ssi-dai",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(imx_ssi_resources0),
|
||||
.resource = imx_ssi_resources0,
|
||||
};
|
||||
|
||||
struct platform_device imx_ssi_device1 = {
|
||||
.name = "imx-ssi",
|
||||
.name = "imx-ssi-dai",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(imx_ssi_resources1),
|
||||
.resource = imx_ssi_resources1,
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <mach/gpio.h>
|
||||
#include <plat/mmc.h>
|
||||
#include <plat/omap7xx.h>
|
||||
#include <plat/mcbsp.h>
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -267,6 +268,30 @@ static inline void omap_init_sti(void)
|
|||
static inline void omap_init_sti(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
|
||||
|
||||
static struct platform_device omap_pcm = {
|
||||
.name = "omap-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(1);
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(2);
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(3);
|
||||
|
||||
static void omap_init_audio(void)
|
||||
{
|
||||
platform_device_register(&omap_mcbsp1);
|
||||
platform_device_register(&omap_mcbsp2);
|
||||
if (!cpu_is_omap7xx())
|
||||
platform_device_register(&omap_mcbsp3);
|
||||
platform_device_register(&omap_pcm);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void omap_init_audio(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -299,6 +324,7 @@ static int __init omap1_init_devices(void)
|
|||
omap_init_rtc();
|
||||
omap_init_spi100k();
|
||||
omap_init_sti();
|
||||
omap_init_audio();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/usb/musb.h>
|
||||
#include <sound/tlv320aic3x.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
@ -612,11 +613,25 @@ static int n8x0_menelaus_late_init(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct aic3x_setup_data n810_aic33_setup = {
|
||||
.gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
|
||||
.gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
|
||||
};
|
||||
|
||||
static struct aic3x_pdata n810_aic33_data = {
|
||||
.setup = &n810_aic33_setup,
|
||||
.gpio_reset = -1,
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("menelaus", 0x72),
|
||||
.irq = INT_24XX_SYS_NIRQ,
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("tlv320aic3x", 0x1b),
|
||||
.platform_data = &n810_aic33_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct menelaus_platform_data n8x0_menelaus_platform_data = {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <sound/tlv320aic3x.h>
|
||||
|
||||
#include <plat/mcspi.h>
|
||||
#include <plat/mux.h>
|
||||
|
@ -686,7 +687,6 @@ static struct twl4030_power_data rx51_t2scripts_data __initdata = {
|
|||
};
|
||||
|
||||
|
||||
|
||||
static struct twl4030_platform_data rx51_twldata __initdata = {
|
||||
.irq_base = TWL4030_IRQ_BASE,
|
||||
.irq_end = TWL4030_IRQ_END,
|
||||
|
@ -716,9 +716,21 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Audio setup data */
|
||||
static struct aic3x_setup_data rx51_aic34_setup = {
|
||||
.gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
|
||||
.gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
|
||||
};
|
||||
|
||||
static struct aic3x_pdata rx51_aic34_data = {
|
||||
.setup = &rx51_aic34_setup,
|
||||
.gpio_reset = 60,
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("tlv320aic3x", 0x18),
|
||||
.platform_data = &rx51_aic34_data,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -34,8 +35,11 @@ static void __init omap_zoom2_init_irq(void)
|
|||
omap_gpio_init();
|
||||
}
|
||||
|
||||
/* REVISIT: These audio entries can be removed once MFD code is merged */
|
||||
#if 0
|
||||
/* EXTMUTE callback function */
|
||||
void zoom2_set_hs_extmute(int mute)
|
||||
{
|
||||
gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
|
||||
}
|
||||
|
||||
static struct twl4030_madc_platform_data zoom2_madc_data = {
|
||||
.irq_line = 1,
|
||||
|
@ -43,6 +47,9 @@ static struct twl4030_madc_platform_data zoom2_madc_data = {
|
|||
|
||||
static struct twl4030_codec_audio_data zoom2_audio_data = {
|
||||
.audio_mclk = 26000000,
|
||||
.ramp_delay_value = 3, /* 161 ms */
|
||||
.hs_extmute = 1,
|
||||
.set_hs_extmute = zoom2_set_hs_extmute,
|
||||
};
|
||||
|
||||
static struct twl4030_codec_data zoom2_codec_data = {
|
||||
|
@ -64,10 +71,24 @@ static struct twl4030_platform_data zoom2_twldata = {
|
|||
.vmmc1 = &zoom2_vmmc1,
|
||||
.vmmc2 = &zoom2_vmmc2,
|
||||
.vsim = &zoom2_vsim,
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("twl4030", 0x48),
|
||||
.flags = I2C_CLIENT_WAKE,
|
||||
.irq = INT_34XX_SYS_NIRQ,
|
||||
.platform_data = &zoom2_twldata,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init omap3_zoom2_i2c_init(void)
|
||||
{
|
||||
omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo,
|
||||
ARRAY_SIZE(zoom2_i2c_boardinfo));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_OMAP_MUX
|
||||
static struct omap_board_mux board_mux[] __initdata = {
|
||||
|
@ -81,6 +102,7 @@ static void __init omap_zoom2_init(void)
|
|||
{
|
||||
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
||||
zoom_peripherals_init();
|
||||
omap3_zoom2_i2c_init();
|
||||
zoom_debugboard_init();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <mach/gpio.h>
|
||||
#include <plat/mmc.h>
|
||||
#include <plat/dma.h>
|
||||
#include <plat/mcbsp.h>
|
||||
|
||||
#include "mux.h"
|
||||
|
||||
|
@ -289,6 +290,43 @@ static inline void omap_init_sti(void)
|
|||
static inline void omap_init_sti(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
|
||||
|
||||
static struct platform_device omap_pcm = {
|
||||
.name = "omap-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* OMAP2420 has 2 McBSP ports
|
||||
* OMAP2430 has 5 McBSP ports
|
||||
* OMAP3 has 5 McBSP ports
|
||||
* OMAP4 has 4 McBSP ports
|
||||
*/
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(1);
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(2);
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(3);
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(4);
|
||||
OMAP_MCBSP_PLATFORM_DEVICE(5);
|
||||
|
||||
static void omap_init_audio(void)
|
||||
{
|
||||
platform_device_register(&omap_mcbsp1);
|
||||
platform_device_register(&omap_mcbsp2);
|
||||
if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
|
||||
platform_device_register(&omap_mcbsp3);
|
||||
platform_device_register(&omap_mcbsp4);
|
||||
}
|
||||
if (cpu_is_omap243x() || cpu_is_omap34xx())
|
||||
platform_device_register(&omap_mcbsp5);
|
||||
|
||||
platform_device_register(&omap_pcm);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void omap_init_audio(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
|
||||
|
||||
#include <plat/mcspi.h>
|
||||
|
@ -901,6 +939,7 @@ static int __init omap2_init_devices(void)
|
|||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_hsmmc_reset();
|
||||
omap_init_audio();
|
||||
omap_init_camera();
|
||||
omap_init_mbox();
|
||||
omap_init_mcspi();
|
||||
|
|
|
@ -3,3 +3,5 @@
|
|||
*/
|
||||
extern int __init zoom_debugboard_init(void);
|
||||
extern void __init zoom_peripherals_init(void);
|
||||
|
||||
#define ZOOM2_HEADSET_EXTMUTE_GPIO 153
|
||||
|
|
|
@ -340,6 +340,31 @@ struct platform_device pxa_device_i2s = {
|
|||
.num_resources = ARRAY_SIZE(pxai2s_resources),
|
||||
};
|
||||
|
||||
struct platform_device pxa_device_asoc_ssp1 = {
|
||||
.name = "pxa-ssp-dai",
|
||||
.id = 0,
|
||||
};
|
||||
|
||||
struct platform_device pxa_device_asoc_ssp2= {
|
||||
.name = "pxa-ssp-dai",
|
||||
.id = 1,
|
||||
};
|
||||
|
||||
struct platform_device pxa_device_asoc_ssp3 = {
|
||||
.name = "pxa-ssp-dai",
|
||||
.id = 2,
|
||||
};
|
||||
|
||||
struct platform_device pxa_device_asoc_ssp4 = {
|
||||
.name = "pxa-ssp-dai",
|
||||
.id = 3,
|
||||
};
|
||||
|
||||
struct platform_device pxa_device_asoc_platform = {
|
||||
.name = "pxa-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static u64 pxaficp_dmamask = ~(u32)0;
|
||||
|
||||
struct platform_device pxa_device_ficp = {
|
||||
|
|
|
@ -37,4 +37,10 @@ extern struct platform_device pxa3xx_device_i2c_power;
|
|||
|
||||
extern struct platform_device pxa3xx_device_gcu;
|
||||
|
||||
extern struct platform_device pxa_device_asoc_platform;
|
||||
extern struct platform_device pxa_device_asoc_ssp1;
|
||||
extern struct platform_device pxa_device_asoc_ssp2;
|
||||
extern struct platform_device pxa_device_asoc_ssp3;
|
||||
extern struct platform_device pxa_device_asoc_ssp4;
|
||||
|
||||
void __init pxa_register_device(struct platform_device *dev, void *data);
|
||||
|
|
|
@ -384,6 +384,10 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
|
|||
static struct platform_device *devices[] __initdata = {
|
||||
&pxa27x_device_udc,
|
||||
&pxa_device_i2s,
|
||||
&pxa_device_asoc_ssp1,
|
||||
&pxa_device_asoc_ssp2,
|
||||
&pxa_device_asoc_ssp3,
|
||||
&pxa_device_asoc_platform,
|
||||
&sa1100_device_rtc,
|
||||
&pxa_device_rtc,
|
||||
&pxa27x_device_ssp1,
|
||||
|
|
|
@ -597,6 +597,11 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
|
|||
static struct platform_device *devices[] __initdata = {
|
||||
&pxa27x_device_udc,
|
||||
&pxa_device_i2s,
|
||||
&pxa_device_asoc_ssp1,
|
||||
&pxa_device_asoc_ssp2,
|
||||
&pxa_device_asoc_ssp3,
|
||||
&pxa_device_asoc_ssp4,
|
||||
&pxa_device_asoc_platform,
|
||||
&sa1100_device_rtc,
|
||||
&pxa_device_rtc,
|
||||
&pxa27x_device_ssp1,
|
||||
|
|
|
@ -45,6 +45,16 @@ int wm9713_irq;
|
|||
int lcd_id;
|
||||
int lcd_orientation;
|
||||
|
||||
struct platform_device pxa_device_wm9713_audio = {
|
||||
.name = "wm9713-codec",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static void __init zylonite_init_wm9713_audio(void)
|
||||
{
|
||||
platform_device_register(&pxa_device_wm9713_audio);
|
||||
}
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = ZYLONITE_ETH_PHYS + 0x300,
|
||||
|
@ -408,6 +418,7 @@ static void __init zylonite_init(void)
|
|||
zylonite_init_nand();
|
||||
zylonite_init_leds();
|
||||
zylonite_init_ohci();
|
||||
zylonite_init_wm9713_audio();
|
||||
}
|
||||
|
||||
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
|
||||
|
|
|
@ -333,3 +333,16 @@ void __init s3c64xx_ac97_setup_gpio(int num)
|
|||
else
|
||||
s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
|
||||
}
|
||||
|
||||
static u64 s3c_device_audio_dmamask = 0xffffffffUL;
|
||||
|
||||
struct platform_device s3c_device_pcm = {
|
||||
.name = "s3c24xx-pcm-audio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &s3c_device_audio_dmamask,
|
||||
.coherent_dma_mask = 0xffffffffUL
|
||||
}
|
||||
};
|
||||
EXPORT_SYMBOL(s3c_device_pcm);
|
||||
|
||||
|
|
|
@ -256,6 +256,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
|
|||
&s3c_device_fb,
|
||||
&s3c_device_ohci,
|
||||
&s3c_device_usb_hsotg,
|
||||
&s3c_device_pcm,
|
||||
&s3c64xx_device_iisv4,
|
||||
|
||||
#ifdef CONFIG_REGULATOR
|
||||
|
|
|
@ -49,9 +49,9 @@ static const char *audmux_port_string(int port)
|
|||
{
|
||||
switch (port) {
|
||||
case MX31_AUDMUX_PORT1_SSI0:
|
||||
return "imx-ssi.0";
|
||||
return "imx-ssi-dai.0";
|
||||
case MX31_AUDMUX_PORT2_SSI1:
|
||||
return "imx-ssi.1";
|
||||
return "imx-ssi-dai.1";
|
||||
case MX31_AUDMUX_PORT3_SSI_PINS_3:
|
||||
return "SSI3";
|
||||
case MX31_AUDMUX_PORT4_SSI_PINS_4:
|
||||
|
|
|
@ -30,6 +30,13 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <plat/clock.h>
|
||||
|
||||
/* macro for building platform_device for McBSP ports */
|
||||
#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \
|
||||
static struct platform_device omap_mcbsp##port_nr = { \
|
||||
.name = "omap-mcbsp-dai", \
|
||||
.id = OMAP_MCBSP##port_nr, \
|
||||
}
|
||||
|
||||
#define OMAP7XX_MCBSP1_BASE 0xfffb1000
|
||||
#define OMAP7XX_MCBSP2_BASE 0xfffb1800
|
||||
|
||||
|
|
|
@ -481,7 +481,7 @@ static struct resource s3c_ac97_resource[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static u64 s3c_device_ac97_dmamask = 0xffffffffUL;
|
||||
static u64 s3c_device_audio_dmamask = 0xffffffffUL;
|
||||
|
||||
struct platform_device s3c_device_ac97 = {
|
||||
.name = "s3c-ac97",
|
||||
|
@ -489,11 +489,37 @@ struct platform_device s3c_device_ac97 = {
|
|||
.num_resources = ARRAY_SIZE(s3c_ac97_resource),
|
||||
.resource = s3c_ac97_resource,
|
||||
.dev = {
|
||||
.dma_mask = &s3c_device_ac97_dmamask,
|
||||
.dma_mask = &s3c_device_audio_dmamask,
|
||||
.coherent_dma_mask = 0xffffffffUL
|
||||
}
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(s3c_device_ac97);
|
||||
|
||||
/* ASoC PCM DMA */
|
||||
|
||||
struct platform_device s3c_device_pcm = {
|
||||
.name = "s3c24xx-pcm-audio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &s3c_device_audio_dmamask,
|
||||
.coherent_dma_mask = 0xffffffffUL
|
||||
}
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(s3c_device_pcm);
|
||||
|
||||
/* ASoC I2S */
|
||||
|
||||
struct platform_device s3c2412_device_iis = {
|
||||
.name = "s3c2412-iis",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &s3c_device_audio_dmamask,
|
||||
.coherent_dma_mask = 0xffffffffUL
|
||||
}
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(s3c2412_device_iis);
|
||||
|
||||
#endif // CONFIG_CPU_S32440
|
||||
|
|
|
@ -32,6 +32,8 @@ extern struct platform_device s3c64xx_device_iisv4;
|
|||
extern struct platform_device s3c64xx_device_spi0;
|
||||
extern struct platform_device s3c64xx_device_spi1;
|
||||
|
||||
extern struct platform_device s3c_device_pcm;
|
||||
|
||||
extern struct platform_device s3c64xx_device_pcm0;
|
||||
extern struct platform_device s3c64xx_device_pcm1;
|
||||
|
||||
|
|
|
@ -286,6 +286,7 @@
|
|||
|
||||
ssi@16100 {
|
||||
compatible = "fsl,mpc8610-ssi";
|
||||
status = "disabled";
|
||||
cell-index = <1>;
|
||||
reg = <0x16100 0x100>;
|
||||
interrupt-parent = <&mpic>;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* MPC86xx Internal Memory Map
|
||||
* Freecale 85xx and 86xx Global Utilties register set
|
||||
*
|
||||
* Authors: Jeff Brown
|
||||
* Timur Tabi <timur@freescale.com>
|
||||
|
@ -10,73 +10,112 @@
|
|||
* 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 header file defines structures for various 86xx SOC devices that are
|
||||
* used by multiple source files.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_POWERPC_IMMAP_86XX_H__
|
||||
#define __ASM_POWERPC_IMMAP_86XX_H__
|
||||
#ifndef __ASM_POWERPC_FSL_GUTS_H__
|
||||
#define __ASM_POWERPC_FSL_GUTS_H__
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Global Utility Registers */
|
||||
struct ccsr_guts {
|
||||
/*
|
||||
* These #ifdefs are safe because it's not possible to build a kernel that
|
||||
* runs on e500 and e600 cores.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_PPC_85xx) && !defined(CONFIG_PPC_86xx)
|
||||
#error Only 85xx and 86xx SOCs are supported
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Global Utility Registers.
|
||||
*
|
||||
* Not all registers defined in this structure are available on all chips, so
|
||||
* you are expected to know whether a given register actually exists on your
|
||||
* chip before you access it.
|
||||
*
|
||||
* Also, some registers are similar on different chips but have slightly
|
||||
* different names. In these cases, one name is chosen to avoid extraneous
|
||||
* #ifdefs.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_85xx
|
||||
struct ccsr_guts_85xx {
|
||||
#else
|
||||
struct ccsr_guts_86xx {
|
||||
#endif
|
||||
__be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
|
||||
__be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
|
||||
__be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
|
||||
__be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
|
||||
__be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
|
||||
u8 res1[0x20 - 0x14];
|
||||
__be32 pordevsr2; /* 0x.0014 - POR device status register 2 */
|
||||
u8 res018[0x20 - 0x18];
|
||||
__be32 porcir; /* 0x.0020 - POR Configuration Information Register */
|
||||
u8 res2[0x30 - 0x24];
|
||||
u8 res024[0x30 - 0x24];
|
||||
__be32 gpiocr; /* 0x.0030 - GPIO Control Register */
|
||||
u8 res3[0x40 - 0x34];
|
||||
u8 res034[0x40 - 0x34];
|
||||
__be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
|
||||
u8 res4[0x50 - 0x44];
|
||||
u8 res044[0x50 - 0x44];
|
||||
__be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
|
||||
u8 res5[0x60 - 0x54];
|
||||
u8 res054[0x60 - 0x54];
|
||||
__be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
|
||||
u8 res6[0x70 - 0x64];
|
||||
__be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */
|
||||
__be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
|
||||
u8 res06c[0x70 - 0x6c];
|
||||
__be32 devdisr; /* 0x.0070 - Device Disable Control */
|
||||
__be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
|
||||
u8 res7[0x80 - 0x78];
|
||||
u8 res078[0x7c - 0x78];
|
||||
__be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
|
||||
__be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
|
||||
u8 res8[0x90 - 0x84];
|
||||
__be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */
|
||||
__be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */
|
||||
__be32 pmcdr; /* 0x.008c - 4Power management clock disable register */
|
||||
__be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
|
||||
__be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
|
||||
u8 res9[0xA0 - 0x98];
|
||||
__be32 ectrstcr; /* 0x.0098 - Exception reset control register */
|
||||
__be32 autorstsr; /* 0x.009c - Automatic reset status register */
|
||||
__be32 pvr; /* 0x.00a0 - Processor Version Register */
|
||||
__be32 svr; /* 0x.00a4 - System Version Register */
|
||||
u8 res10[0xB0 - 0xA8];
|
||||
u8 res0a8[0xb0 - 0xa8];
|
||||
__be32 rstcr; /* 0x.00b0 - Reset Control Register */
|
||||
u8 res11[0xC0 - 0xB4];
|
||||
u8 res0b4[0xc0 - 0xb4];
|
||||
#ifdef CONFIG_PPC_85xx
|
||||
__be32 iovselsr; /* 0x.00c0 - I/O voltage select status register */
|
||||
#else
|
||||
__be32 elbcvselcr; /* 0x.00c0 - eLBC Voltage Select Ctrl Reg */
|
||||
u8 res12[0x800 - 0xC4];
|
||||
#endif
|
||||
u8 res0c4[0x224 - 0xc4];
|
||||
__be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
|
||||
__be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
|
||||
u8 res22c[0x800 - 0x22c];
|
||||
__be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
|
||||
u8 res13[0x900 - 0x804];
|
||||
u8 res804[0x900 - 0x804];
|
||||
__be32 ircr; /* 0x.0900 - Infrared Control Register */
|
||||
u8 res14[0x908 - 0x904];
|
||||
u8 res904[0x908 - 0x904];
|
||||
__be32 dmacr; /* 0x.0908 - DMA Control Register */
|
||||
u8 res15[0x914 - 0x90C];
|
||||
u8 res90c[0x914 - 0x90c];
|
||||
__be32 elbccr; /* 0x.0914 - eLBC Control Register */
|
||||
u8 res16[0xB20 - 0x918];
|
||||
u8 res918[0xb20 - 0x918];
|
||||
__be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
|
||||
__be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
|
||||
__be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
|
||||
u8 res17[0xE00 - 0xB2C];
|
||||
u8 resb2c[0xe00 - 0xb2c];
|
||||
__be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
|
||||
u8 res18[0xE10 - 0xE04];
|
||||
u8 rese04[0xe10 - 0xe04];
|
||||
__be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
|
||||
u8 res19[0xE20 - 0xE14];
|
||||
u8 rese14[0xe20 - 0xe14];
|
||||
__be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
|
||||
u8 res20[0xF04 - 0xE24];
|
||||
__be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */
|
||||
u8 rese28[0xf04 - 0xe28];
|
||||
__be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
|
||||
__be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
|
||||
u8 res21[0xF40 - 0xF0C];
|
||||
__be32 srds2cr0; /* 0x.0f40 - SerDes1 Control Register 0 */
|
||||
__be32 srds2cr1; /* 0x.0f44 - SerDes1 Control Register 0 */
|
||||
u8 resf0c[0xf2c - 0xf0c];
|
||||
__be32 itcr; /* 0x.0f2c - Internal transaction control register */
|
||||
u8 resf30[0xf40 - 0xf30];
|
||||
__be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
|
||||
__be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#ifdef CONFIG_PPC_86xx
|
||||
|
||||
#define CCSR_GUTS_DMACR_DEV_SSI 0 /* DMA controller/channel set to SSI */
|
||||
#define CCSR_GUTS_DMACR_DEV_IR 1 /* DMA controller/channel set to IR */
|
||||
|
||||
|
@ -93,7 +132,7 @@ struct ccsr_guts {
|
|||
* ch: The channel on the DMA controller (0, 1, 2, or 3)
|
||||
* device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
|
||||
*/
|
||||
static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
|
||||
static inline void guts_set_dmacr(struct ccsr_guts_86xx __iomem *guts,
|
||||
unsigned int co, unsigned int ch, unsigned int device)
|
||||
{
|
||||
unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
|
||||
|
@ -129,7 +168,7 @@ static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
|
|||
* ch: The channel on the DMA controller (0, 1, 2, or 3)
|
||||
* value: the new value for the bit (0 or 1)
|
||||
*/
|
||||
static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
|
||||
static inline void guts_set_pmuxcr_dma(struct ccsr_guts_86xx __iomem *guts,
|
||||
unsigned int co, unsigned int ch, unsigned int value)
|
||||
{
|
||||
if ((ch == 0) || (ch == 3)) {
|
||||
|
@ -152,5 +191,7 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
|
|||
#define CCSR_GUTS_CLKDVDR_SSICLK_MASK 0x000000FF
|
||||
#define CCSR_GUTS_CLKDVDR_SSICLK(x) ((x) & CCSR_GUTS_CLKDVDR_SSICLK_MASK)
|
||||
|
||||
#endif /* __ASM_POWERPC_IMMAP_86XX_H__ */
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -271,7 +271,7 @@ static struct platform_driver twl4030_vibra_driver = {
|
|||
.probe = twl4030_vibra_probe,
|
||||
.remove = __devexit_p(twl4030_vibra_remove),
|
||||
.driver = {
|
||||
.name = "twl4030_codec_vibra",
|
||||
.name = "twl4030-vibra",
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &twl4030_vibra_pm_ops,
|
||||
|
@ -291,7 +291,7 @@ static void __exit twl4030_vibra_exit(void)
|
|||
}
|
||||
module_exit(twl4030_vibra_exit);
|
||||
|
||||
MODULE_ALIAS("platform:twl4030_codec_vibra");
|
||||
MODULE_ALIAS("platform:twl4030-vibra");
|
||||
|
||||
MODULE_DESCRIPTION("TWL4030 Vibra driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -698,17 +698,17 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
|
|||
|
||||
if (twl_has_codec() && pdata->codec && twl_class_is_4030()) {
|
||||
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
|
||||
child = add_child(sub_chip_id, "twl4030_codec",
|
||||
child = add_child(sub_chip_id, "twl4030-audio",
|
||||
pdata->codec, sizeof(*pdata->codec),
|
||||
false, 0, 0);
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
}
|
||||
|
||||
/* Phoenix*/
|
||||
/* Phoenix codec driver is probed directly atm */
|
||||
if (twl_has_codec() && pdata->codec && twl_class_is_6030()) {
|
||||
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
|
||||
child = add_child(sub_chip_id, "twl6040_codec",
|
||||
child = add_child(sub_chip_id, "twl6040-codec",
|
||||
pdata->codec, sizeof(*pdata->codec),
|
||||
false, 0, 0);
|
||||
if (IS_ERR(child))
|
||||
|
|
|
@ -207,14 +207,14 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
|
|||
|
||||
if (pdata->audio) {
|
||||
cell = &codec->cells[childs];
|
||||
cell->name = "twl4030_codec_audio";
|
||||
cell->name = "twl4030-codec";
|
||||
cell->platform_data = pdata->audio;
|
||||
cell->data_size = sizeof(*pdata->audio);
|
||||
childs++;
|
||||
}
|
||||
if (pdata->vibra) {
|
||||
cell = &codec->cells[childs];
|
||||
cell->name = "twl4030_codec_vibra";
|
||||
cell->name = "twl4030-vibra";
|
||||
cell->platform_data = pdata->vibra;
|
||||
cell->data_size = sizeof(*pdata->vibra);
|
||||
childs++;
|
||||
|
@ -249,14 +249,14 @@ static int __devexit twl4030_codec_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
MODULE_ALIAS("platform:twl4030_codec");
|
||||
MODULE_ALIAS("platform:twl4030-audio");
|
||||
|
||||
static struct platform_driver twl4030_codec_driver = {
|
||||
.probe = twl4030_codec_probe,
|
||||
.remove = __devexit_p(twl4030_codec_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "twl4030_codec",
|
||||
.name = "twl4030-audio",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -553,8 +553,12 @@ extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
|
|||
extern int twl4030_remove_script(u8 flags);
|
||||
|
||||
struct twl4030_codec_audio_data {
|
||||
unsigned int audio_mclk;
|
||||
unsigned int audio_mclk; /* not used, will be removed */
|
||||
unsigned int digimic_delay; /* in ms */
|
||||
unsigned int ramp_delay_value;
|
||||
unsigned int offset_cncl_path;
|
||||
unsigned int check_defaults:1;
|
||||
unsigned int reset_registers:1;
|
||||
unsigned int hs_extmute:1;
|
||||
void (*set_hs_extmute)(int mute);
|
||||
};
|
||||
|
|
|
@ -114,7 +114,7 @@ struct sh_fsi_platform_info {
|
|||
int (*set_rate)(int is_porta, int rate); /* for master mode */
|
||||
};
|
||||
|
||||
extern struct snd_soc_dai fsi_soc_dai[2];
|
||||
extern struct snd_soc_platform fsi_soc_platform;
|
||||
extern struct snd_soc_dai_driver fsi_soc_dai[2];
|
||||
extern struct snd_soc_platform_driver fsi_soc_platform;
|
||||
|
||||
#endif /* __SOUND_FSI_H */
|
||||
|
|
|
@ -91,15 +91,17 @@ struct snd_pcm_substream;
|
|||
SNDRV_PCM_FMTBIT_S32_LE |\
|
||||
SNDRV_PCM_FMTBIT_S32_BE)
|
||||
|
||||
struct snd_soc_dai_ops;
|
||||
struct snd_soc_dai_driver;
|
||||
struct snd_soc_dai;
|
||||
struct snd_ac97_bus_ops;
|
||||
|
||||
/* Digital Audio Interface registration */
|
||||
int snd_soc_register_dai(struct snd_soc_dai *dai);
|
||||
void snd_soc_unregister_dai(struct snd_soc_dai *dai);
|
||||
int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count);
|
||||
void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count);
|
||||
int snd_soc_register_dai(struct device *dev,
|
||||
struct snd_soc_dai_driver *dai_drv);
|
||||
void snd_soc_unregister_dai(struct device *dev);
|
||||
int snd_soc_register_dais(struct device *dev,
|
||||
struct snd_soc_dai_driver *dai_drv, size_t count);
|
||||
void snd_soc_unregister_dais(struct device *dev, size_t count);
|
||||
|
||||
/* Digital Audio Interface clocking API.*/
|
||||
int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
|
||||
|
@ -126,16 +128,6 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
|
|||
/* Digital Audio Interface mute */
|
||||
int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
|
||||
|
||||
/*
|
||||
* Digital Audio Interface.
|
||||
*
|
||||
* Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
|
||||
* operations and capabilities. Codec and platform drivers will register this
|
||||
* structure for every DAI they have.
|
||||
*
|
||||
* This structure covers the clocking, formating and ALSA operations for each
|
||||
* interface.
|
||||
*/
|
||||
struct snd_soc_dai_ops {
|
||||
/*
|
||||
* DAI clocking configuration, all optional.
|
||||
|
@ -191,24 +183,24 @@ struct snd_soc_dai_ops {
|
|||
};
|
||||
|
||||
/*
|
||||
* Digital Audio Interface runtime data.
|
||||
* Digital Audio Interface Driver.
|
||||
*
|
||||
* Holds runtime data for a DAI.
|
||||
* Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
|
||||
* operations and capabilities. Codec and platform drivers will register this
|
||||
* structure for every DAI they have.
|
||||
*
|
||||
* This structure covers the clocking, formating and ALSA operations for each
|
||||
* interface.
|
||||
*/
|
||||
struct snd_soc_dai {
|
||||
struct snd_soc_dai_driver {
|
||||
/* DAI description */
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
int ac97_control;
|
||||
|
||||
struct device *dev;
|
||||
void *ac97_pdata; /* platform_data for the ac97 codec */
|
||||
|
||||
/* DAI callbacks */
|
||||
int (*probe)(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai);
|
||||
void (*remove)(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai);
|
||||
/* DAI driver callbacks */
|
||||
int (*probe)(struct snd_soc_dai *dai);
|
||||
int (*remove)(struct snd_soc_dai *dai);
|
||||
int (*suspend)(struct snd_soc_dai *dai);
|
||||
int (*resume)(struct snd_soc_dai *dai);
|
||||
|
||||
|
@ -219,26 +211,51 @@ struct snd_soc_dai {
|
|||
struct snd_soc_pcm_stream capture;
|
||||
struct snd_soc_pcm_stream playback;
|
||||
unsigned int symmetric_rates:1;
|
||||
};
|
||||
|
||||
/*
|
||||
* Digital Audio Interface runtime data.
|
||||
*
|
||||
* Holds runtime data for a DAI.
|
||||
*/
|
||||
struct snd_soc_dai {
|
||||
const char *name;
|
||||
int id;
|
||||
struct device *dev;
|
||||
void *ac97_pdata; /* platform_data for the ac97 codec */
|
||||
|
||||
/* driver ops */
|
||||
struct snd_soc_dai_driver *driver;
|
||||
|
||||
/* DAI runtime info */
|
||||
struct snd_soc_codec *codec;
|
||||
unsigned int capture_active:1; /* stream is in use */
|
||||
unsigned int playback_active:1; /* stream is in use */
|
||||
unsigned int symmetric_rates:1;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
unsigned int active;
|
||||
unsigned char pop_wait:1;
|
||||
unsigned char probed:1;
|
||||
|
||||
/* DAI private data */
|
||||
void *private_data;
|
||||
/* DAI DMA data */
|
||||
void *playback_dma_data;
|
||||
void *capture_dma_data;
|
||||
|
||||
/* parent platform */
|
||||
struct snd_soc_platform *platform;
|
||||
/* parent platform/codec */
|
||||
union {
|
||||
struct snd_soc_platform *platform;
|
||||
struct snd_soc_codec *codec;
|
||||
};
|
||||
struct snd_soc_card *card;
|
||||
|
||||
struct list_head list;
|
||||
struct list_head card_list;
|
||||
};
|
||||
|
||||
static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
|
||||
const struct snd_pcm_substream *ss)
|
||||
{
|
||||
return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
dai->playback.dma_data : dai->capture.dma_data;
|
||||
dai->playback_dma_data : dai->capture_dma_data;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
|
||||
|
@ -246,9 +263,20 @@ static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
|
|||
void *data)
|
||||
{
|
||||
if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dai->playback.dma_data = data;
|
||||
dai->playback_dma_data = data;
|
||||
else
|
||||
dai->capture.dma_data = data;
|
||||
dai->capture_dma_data = data;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
|
||||
void *data)
|
||||
{
|
||||
dev_set_drvdata(dai->dev, data);
|
||||
}
|
||||
|
||||
static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
|
||||
{
|
||||
return dev_get_drvdata(dai->dev);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -322,14 +322,14 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
|
|||
|
||||
/* dapm path setup */
|
||||
int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
|
||||
void snd_soc_dapm_free(struct snd_soc_device *socdev);
|
||||
void snd_soc_dapm_free(struct snd_soc_codec *codec);
|
||||
int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
|
||||
/* dapm events */
|
||||
int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
|
||||
int event);
|
||||
void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);
|
||||
int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
|
||||
const char *stream, int event);
|
||||
void snd_soc_dapm_shutdown(struct snd_soc_card *card);
|
||||
|
||||
/* dapm sys fs - used by the core */
|
||||
int snd_soc_dapm_sys_add(struct device *dev);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* OF helpers for ALSA SoC
|
||||
*
|
||||
* Copyright (C) 2008, Secret Lab Technologies Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOC_OF_H_
|
||||
#define _INCLUDE_SOC_OF_H_
|
||||
|
||||
#if defined(CONFIG_SND_SOC_OF_SIMPLE) || defined(CONFIG_SND_SOC_OF_SIMPLE_MODULE)
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
|
||||
void *codec_data, struct snd_soc_dai *dai,
|
||||
struct device_node *node);
|
||||
|
||||
int of_snd_soc_register_platform(struct snd_soc_platform *platform,
|
||||
struct device_node *node,
|
||||
struct snd_soc_dai *cpu_dai);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _INCLUDE_SOC_OF_H_ */
|
|
@ -228,13 +228,17 @@ struct snd_soc_ops;
|
|||
struct snd_soc_dai_mode;
|
||||
struct snd_soc_pcm_runtime;
|
||||
struct snd_soc_dai;
|
||||
struct snd_soc_dai_driver;
|
||||
struct snd_soc_platform;
|
||||
struct snd_soc_dai_link;
|
||||
struct snd_soc_platform_driver;
|
||||
struct snd_soc_codec;
|
||||
struct snd_soc_codec_driver;
|
||||
struct soc_enum;
|
||||
struct snd_soc_ac97_ops;
|
||||
struct snd_soc_jack;
|
||||
struct snd_soc_jack_pin;
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct snd_soc_jack_gpio;
|
||||
#endif
|
||||
|
@ -249,19 +253,18 @@ enum snd_soc_control_type {
|
|||
SND_SOC_SPI,
|
||||
};
|
||||
|
||||
int snd_soc_register_platform(struct snd_soc_platform *platform);
|
||||
void snd_soc_unregister_platform(struct snd_soc_platform *platform);
|
||||
int snd_soc_register_codec(struct snd_soc_codec *codec);
|
||||
void snd_soc_unregister_codec(struct snd_soc_codec *codec);
|
||||
int snd_soc_register_platform(struct device *dev,
|
||||
struct snd_soc_platform_driver *platform_drv);
|
||||
void snd_soc_unregister_platform(struct device *dev);
|
||||
int snd_soc_register_codec(struct device *dev,
|
||||
struct snd_soc_codec_driver *codec_drv,
|
||||
struct snd_soc_dai_driver *dai_drv, int num_dai);
|
||||
void snd_soc_unregister_codec(struct device *dev);
|
||||
int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
|
||||
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
|
||||
int addr_bits, int data_bits,
|
||||
enum snd_soc_control_type control);
|
||||
|
||||
/* pcm <-> DAI connect */
|
||||
void snd_soc_free_pcms(struct snd_soc_device *socdev);
|
||||
int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
|
||||
|
||||
/* Utility functions to get clock rates from various things */
|
||||
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
|
||||
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
|
||||
|
@ -273,7 +276,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
|
|||
const struct snd_pcm_hardware *hw);
|
||||
|
||||
/* Jack reporting */
|
||||
int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
|
||||
int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
|
||||
struct snd_soc_jack *jack);
|
||||
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
|
||||
int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
|
||||
|
@ -390,7 +393,7 @@ struct snd_soc_jack_gpio {
|
|||
|
||||
struct snd_soc_jack {
|
||||
struct snd_jack *jack;
|
||||
struct snd_soc_card *card;
|
||||
struct snd_soc_codec *codec;
|
||||
struct list_head pins;
|
||||
int status;
|
||||
struct blocking_notifier_head notifier;
|
||||
|
@ -398,15 +401,13 @@ struct snd_soc_jack {
|
|||
|
||||
/* SoC PCM stream information */
|
||||
struct snd_soc_pcm_stream {
|
||||
char *stream_name;
|
||||
const char *stream_name;
|
||||
u64 formats; /* SNDRV_PCM_FMTBIT_* */
|
||||
unsigned int rates; /* SNDRV_PCM_RATE_* */
|
||||
unsigned int rate_min; /* min rate */
|
||||
unsigned int rate_max; /* max rate */
|
||||
unsigned int channels_min; /* min channels */
|
||||
unsigned int channels_max; /* max channels */
|
||||
unsigned int active; /* stream is in use */
|
||||
void *dma_data; /* used by platform code */
|
||||
};
|
||||
|
||||
/* SoC audio ops */
|
||||
|
@ -419,44 +420,35 @@ struct snd_soc_ops {
|
|||
int (*trigger)(struct snd_pcm_substream *, int);
|
||||
};
|
||||
|
||||
/* SoC Audio Codec */
|
||||
/* SoC Audio Codec device */
|
||||
struct snd_soc_codec {
|
||||
char *name;
|
||||
struct module *owner;
|
||||
struct mutex mutex;
|
||||
const char *name;
|
||||
int id;
|
||||
struct device *dev;
|
||||
struct snd_soc_device *socdev;
|
||||
struct snd_soc_codec_driver *driver;
|
||||
|
||||
struct mutex mutex;
|
||||
struct snd_soc_card *card;
|
||||
struct list_head list;
|
||||
|
||||
/* callbacks */
|
||||
int (*set_bias_level)(struct snd_soc_codec *,
|
||||
enum snd_soc_bias_level level);
|
||||
struct list_head card_list;
|
||||
int num_dai;
|
||||
|
||||
/* runtime */
|
||||
struct snd_card *card;
|
||||
struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
|
||||
unsigned int active;
|
||||
unsigned int pcm_devs;
|
||||
void *drvdata;
|
||||
|
||||
/* codec IO */
|
||||
void *control_data; /* codec control (i2c/3wire) data */
|
||||
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
||||
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
|
||||
int (*display_register)(struct snd_soc_codec *, char *,
|
||||
size_t, unsigned int);
|
||||
int (*volatile_register)(unsigned int);
|
||||
int (*readable_register)(unsigned int);
|
||||
hw_write_t hw_write;
|
||||
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
|
||||
void *reg_cache;
|
||||
short reg_cache_size;
|
||||
short reg_cache_step;
|
||||
|
||||
unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
|
||||
unsigned int cache_only:1; /* Suppress writes to hardware */
|
||||
unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
|
||||
unsigned int suspended:1; /* Codec is in suspend PM state */
|
||||
unsigned int probed:1; /* Codec has been probed */
|
||||
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
|
||||
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
|
||||
|
||||
/* codec IO */
|
||||
void *control_data; /* codec control (i2c/3wire) data */
|
||||
hw_write_t hw_write;
|
||||
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
|
||||
void *reg_cache;
|
||||
|
||||
/* dapm */
|
||||
u32 pop_time;
|
||||
|
@ -466,10 +458,6 @@ struct snd_soc_codec {
|
|||
enum snd_soc_bias_level suspend_bias_level;
|
||||
struct delayed_work delayed_work;
|
||||
|
||||
/* codec DAI's */
|
||||
struct snd_soc_dai *dai;
|
||||
unsigned int num_dai;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_codec_root;
|
||||
struct dentry *debugfs_reg;
|
||||
|
@ -478,23 +466,40 @@ struct snd_soc_codec {
|
|||
#endif
|
||||
};
|
||||
|
||||
/* codec device */
|
||||
struct snd_soc_codec_device {
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
int (*remove)(struct platform_device *pdev);
|
||||
int (*suspend)(struct platform_device *pdev, pm_message_t state);
|
||||
int (*resume)(struct platform_device *pdev);
|
||||
/* codec driver */
|
||||
struct snd_soc_codec_driver {
|
||||
|
||||
/* driver ops */
|
||||
int (*probe)(struct snd_soc_codec *);
|
||||
int (*remove)(struct snd_soc_codec *);
|
||||
int (*suspend)(struct snd_soc_codec *,
|
||||
pm_message_t state);
|
||||
int (*resume)(struct snd_soc_codec *);
|
||||
|
||||
/* codec IO */
|
||||
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
||||
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
|
||||
int (*display_register)(struct snd_soc_codec *, char *,
|
||||
size_t, unsigned int);
|
||||
int (*volatile_register)(unsigned int);
|
||||
int (*readable_register)(unsigned int);
|
||||
short reg_cache_size;
|
||||
short reg_cache_step;
|
||||
short reg_word_size;
|
||||
const void *reg_cache_default;
|
||||
|
||||
/* codec bias level */
|
||||
int (*set_bias_level)(struct snd_soc_codec *,
|
||||
enum snd_soc_bias_level level);
|
||||
};
|
||||
|
||||
/* SoC platform interface */
|
||||
struct snd_soc_platform {
|
||||
char *name;
|
||||
struct list_head list;
|
||||
struct snd_soc_platform_driver {
|
||||
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
int (*remove)(struct platform_device *pdev);
|
||||
int (*suspend)(struct snd_soc_dai_link *dai_link);
|
||||
int (*resume)(struct snd_soc_dai_link *dai_link);
|
||||
int (*probe)(struct snd_soc_platform *);
|
||||
int (*remove)(struct snd_soc_platform *);
|
||||
int (*suspend)(struct snd_soc_dai *dai);
|
||||
int (*resume)(struct snd_soc_dai *dai);
|
||||
|
||||
/* pcm creation and destruction */
|
||||
int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
|
||||
|
@ -509,23 +514,31 @@ struct snd_soc_platform {
|
|||
struct snd_soc_dai *);
|
||||
|
||||
/* platform stream ops */
|
||||
struct snd_pcm_ops *pcm_ops;
|
||||
struct snd_pcm_ops *ops;
|
||||
};
|
||||
|
||||
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
|
||||
struct snd_soc_dai_link {
|
||||
char *name; /* Codec name */
|
||||
char *stream_name; /* Stream name */
|
||||
struct snd_soc_platform {
|
||||
const char *name;
|
||||
int id;
|
||||
struct device *dev;
|
||||
struct snd_soc_platform_driver *driver;
|
||||
|
||||
/* DAI */
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_dai *cpu_dai;
|
||||
unsigned int suspended:1; /* platform is suspended */
|
||||
unsigned int probed:1;
|
||||
|
||||
/* machine stream operations */
|
||||
struct snd_soc_ops *ops;
|
||||
struct snd_soc_card *card;
|
||||
struct list_head list;
|
||||
struct list_head card_list;
|
||||
};
|
||||
|
||||
/* codec/machine specific init - e.g. add machine controls */
|
||||
int (*init)(struct snd_soc_codec *codec);
|
||||
struct snd_soc_dai_link {
|
||||
/* config - must be set by machine driver */
|
||||
const char *name; /* Codec name */
|
||||
const char *stream_name; /* Stream name */
|
||||
const char *codec_name; /* for multi-codec */
|
||||
const char *platform_name; /* for multi-platform */
|
||||
const char *cpu_dai_name;
|
||||
const char *codec_dai_name;
|
||||
|
||||
/* Keep DAI active over suspend */
|
||||
unsigned int ignore_suspend:1;
|
||||
|
@ -533,21 +546,24 @@ struct snd_soc_dai_link {
|
|||
/* Symmetry requirements */
|
||||
unsigned int symmetric_rates:1;
|
||||
|
||||
/* Symmetry data - only valid if symmetry is being enforced */
|
||||
unsigned int rate;
|
||||
/* codec/machine specific init - e.g. add machine controls */
|
||||
int (*init)(struct snd_soc_pcm_runtime *rtd);
|
||||
|
||||
/* DAI pcm */
|
||||
struct snd_pcm *pcm;
|
||||
/* machine stream operations */
|
||||
struct snd_soc_ops *ops;
|
||||
};
|
||||
|
||||
/* SoC card */
|
||||
struct snd_soc_card {
|
||||
char *name;
|
||||
const char *name;
|
||||
struct device *dev;
|
||||
struct snd_card *snd_card;
|
||||
struct module *owner;
|
||||
|
||||
struct list_head list;
|
||||
struct mutex mutex;
|
||||
|
||||
int instantiated;
|
||||
bool instantiated;
|
||||
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
int (*remove)(struct platform_device *pdev);
|
||||
|
@ -568,28 +584,38 @@ struct snd_soc_card {
|
|||
/* CPU <--> Codec DAI links */
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
int num_links;
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
int num_rtd;
|
||||
|
||||
struct snd_soc_device *socdev;
|
||||
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
struct snd_soc_platform *platform;
|
||||
struct delayed_work delayed_work;
|
||||
struct work_struct deferred_resume_work;
|
||||
|
||||
/* lists of probed devices belonging to this card */
|
||||
struct list_head codec_dev_list;
|
||||
struct list_head platform_dev_list;
|
||||
struct list_head dai_dev_list;
|
||||
};
|
||||
|
||||
/* SoC Device - the audio subsystem */
|
||||
struct snd_soc_device {
|
||||
struct device *dev;
|
||||
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
|
||||
struct snd_soc_pcm_runtime {
|
||||
struct device dev;
|
||||
struct snd_soc_card *card;
|
||||
struct snd_soc_codec_device *codec_dev;
|
||||
void *codec_data;
|
||||
};
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
|
||||
/* runtime channel data */
|
||||
struct snd_soc_pcm_runtime {
|
||||
struct snd_soc_dai_link *dai;
|
||||
struct snd_soc_device *socdev;
|
||||
unsigned int complete:1;
|
||||
unsigned int dev_registered:1;
|
||||
|
||||
/* Symmetry data - only valid if symmetry is being enforced */
|
||||
unsigned int rate;
|
||||
long pmdown_time;
|
||||
|
||||
/* runtime devices */
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_soc_codec *codec;
|
||||
struct snd_soc_platform *platform;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_dai *cpu_dai;
|
||||
|
||||
struct delayed_work delayed_work;
|
||||
};
|
||||
|
||||
/* mixer control */
|
||||
|
@ -615,24 +641,48 @@ struct soc_enum {
|
|||
static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
|
||||
unsigned int reg)
|
||||
{
|
||||
return codec->read(codec, reg);
|
||||
return codec->driver->read(codec, reg);
|
||||
}
|
||||
|
||||
static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
|
||||
unsigned int reg, unsigned int val)
|
||||
{
|
||||
return codec->write(codec, reg, val);
|
||||
return codec->driver->write(codec, reg, val);
|
||||
}
|
||||
|
||||
/* device driver data */
|
||||
|
||||
static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
|
||||
void *data)
|
||||
void *data)
|
||||
{
|
||||
codec->drvdata = data;
|
||||
dev_set_drvdata(codec->dev, data);
|
||||
}
|
||||
|
||||
static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
|
||||
{
|
||||
return codec->drvdata;
|
||||
return dev_get_drvdata(codec->dev);
|
||||
}
|
||||
|
||||
static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
|
||||
void *data)
|
||||
{
|
||||
dev_set_drvdata(platform->dev, data);
|
||||
}
|
||||
|
||||
static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
|
||||
{
|
||||
return dev_get_drvdata(platform->dev);
|
||||
}
|
||||
|
||||
static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
|
||||
void *data)
|
||||
{
|
||||
dev_set_drvdata(&rtd->dev, data);
|
||||
}
|
||||
|
||||
static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
return dev_get_drvdata(&rtd->dev);
|
||||
}
|
||||
|
||||
#include <sound/soc-dai.h>
|
||||
|
|
|
@ -10,8 +10,49 @@
|
|||
#ifndef __TLV320AIC3x_H__
|
||||
#define __TLV320AIC3x_H__
|
||||
|
||||
struct aic3x_pdata {
|
||||
int gpio_reset; /* < 0 if not used */
|
||||
/* GPIO API */
|
||||
enum {
|
||||
AIC3X_GPIO1_FUNC_DISABLED = 0,
|
||||
AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
|
||||
AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
|
||||
AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
|
||||
AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
|
||||
AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
|
||||
AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
|
||||
AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
|
||||
AIC3X_GPIO1_FUNC_INPUT = 8,
|
||||
AIC3X_GPIO1_FUNC_OUTPUT = 9,
|
||||
AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
|
||||
AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
|
||||
AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
|
||||
AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
|
||||
AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
|
||||
AIC3X_GPIO1_FUNC_ALL_IRQ = 16
|
||||
};
|
||||
|
||||
#endif
|
||||
enum {
|
||||
AIC3X_GPIO2_FUNC_DISABLED = 0,
|
||||
AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
|
||||
AIC3X_GPIO2_FUNC_INPUT = 3,
|
||||
AIC3X_GPIO2_FUNC_OUTPUT = 4,
|
||||
AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
|
||||
AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
|
||||
AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
|
||||
AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
|
||||
AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
|
||||
AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
|
||||
AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
|
||||
AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
|
||||
AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
|
||||
};
|
||||
|
||||
struct aic3x_setup_data {
|
||||
unsigned int gpio_func[2];
|
||||
};
|
||||
|
||||
struct aic3x_pdata {
|
||||
int gpio_reset; /* < 0 if not used */
|
||||
struct aic3x_setup_data *setup;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -179,7 +179,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
runtime->dma_bytes = params_buffer_bytes(params);
|
||||
|
||||
prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
|
||||
prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
|
||||
|
||||
prtd->dma_buffer = runtime->dma_addr;
|
||||
|
@ -374,14 +374,14 @@ static int atmel_pcm_new(struct snd_card *card,
|
|||
if (!card->dev->coherent_dma_mask)
|
||||
card->dev->coherent_dma_mask = 0xffffffff;
|
||||
|
||||
if (dai->playback.channels_min) {
|
||||
if (dai->driver->playback.channels_min) {
|
||||
ret = atmel_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dai->capture.channels_min) {
|
||||
if (dai->driver->capture.channels_min) {
|
||||
pr_debug("at32-pcm:"
|
||||
"Allocating PCM capture DMA buffer\n");
|
||||
ret = atmel_pcm_preallocate_dma_buffer(pcm,
|
||||
|
@ -414,12 +414,9 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
|
||||
static int atmel_pcm_suspend(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_pcm *pcm = dai_link->pcm;
|
||||
struct snd_pcm_str *stream = &pcm->streams[0];
|
||||
struct snd_pcm_substream *substream = stream->substream;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = dai->runtime;
|
||||
struct atmel_runtime_data *prtd;
|
||||
struct atmel_pcm_dma_params *params;
|
||||
|
||||
|
@ -441,12 +438,9 @@ static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
|
||||
static int atmel_pcm_resume(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_pcm *pcm = dai_link->pcm;
|
||||
struct snd_pcm_str *stream = &pcm->streams[0];
|
||||
struct snd_pcm_substream *substream = stream->substream;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = dai->runtime;
|
||||
struct atmel_runtime_data *prtd;
|
||||
struct atmel_pcm_dma_params *params;
|
||||
|
||||
|
@ -470,27 +464,46 @@ static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
|
|||
#define atmel_pcm_resume NULL
|
||||
#endif
|
||||
|
||||
struct snd_soc_platform atmel_soc_platform = {
|
||||
.name = "atmel-audio",
|
||||
.pcm_ops = &atmel_pcm_ops,
|
||||
static struct snd_soc_platform_driver atmel_soc_platform = {
|
||||
.ops = &atmel_pcm_ops,
|
||||
.pcm_new = atmel_pcm_new,
|
||||
.pcm_free = atmel_pcm_free_dma_buffers,
|
||||
.suspend = atmel_pcm_suspend,
|
||||
.resume = atmel_pcm_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(atmel_soc_platform);
|
||||
|
||||
static int __init atmel_pcm_modinit(void)
|
||||
static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_platform(&atmel_soc_platform);
|
||||
return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
|
||||
}
|
||||
module_init(atmel_pcm_modinit);
|
||||
|
||||
static void __exit atmel_pcm_modexit(void)
|
||||
static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&atmel_soc_platform);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
module_exit(atmel_pcm_modexit);
|
||||
|
||||
static struct platform_driver atmel_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "atmel-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = atmel_soc_platform_probe,
|
||||
.remove = __devexit_p(atmel_soc_platform_remove),
|
||||
};
|
||||
|
||||
static int __init snd_atmel_pcm_init(void)
|
||||
{
|
||||
return platform_driver_register(&atmel_pcm_driver);
|
||||
}
|
||||
module_init(snd_atmel_pcm_init);
|
||||
|
||||
static void __exit snd_atmel_pcm_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&atmel_pcm_driver);
|
||||
}
|
||||
module_exit(snd_atmel_pcm_exit);
|
||||
|
||||
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
|
||||
MODULE_DESCRIPTION("Atmel PCM module");
|
||||
|
|
|
@ -74,9 +74,6 @@ struct atmel_pcm_dma_params {
|
|||
void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
|
||||
};
|
||||
|
||||
extern struct snd_soc_platform atmel_soc_platform;
|
||||
|
||||
|
||||
/*
|
||||
* SSC register access (since ssc_writel() / ssc_readl() require literal name)
|
||||
*/
|
||||
|
|
|
@ -205,8 +205,7 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
|
|||
static int atmel_ssc_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
|
||||
int dir_mask;
|
||||
|
||||
pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
|
||||
|
@ -235,8 +234,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
|
|||
static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
|
||||
struct atmel_pcm_dma_params *dma_params;
|
||||
int dir, dir_mask;
|
||||
|
||||
|
@ -338,7 +336,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
int id = rtd->dai->cpu_dai->id;
|
||||
int id = dai->id;
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[id];
|
||||
struct atmel_pcm_dma_params *dma_params;
|
||||
int dir, channels, bits;
|
||||
|
@ -368,7 +366,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
* function. It should not be used for other purposes
|
||||
* as it is common to all substreams.
|
||||
*/
|
||||
snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
|
||||
snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_params);
|
||||
|
||||
channels = params_channels(params);
|
||||
|
||||
|
@ -605,8 +603,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
|
||||
struct atmel_pcm_dma_params *dma_params;
|
||||
int dir;
|
||||
|
||||
|
@ -690,6 +687,32 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
|
|||
# define atmel_ssc_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int atmel_ssc_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
|
||||
int ret = 0;
|
||||
|
||||
snd_soc_dai_set_drvdata(dai, ssc_p);
|
||||
|
||||
/*
|
||||
* Request SSC device
|
||||
*/
|
||||
ssc_p->ssc = ssc_request(dai->id);
|
||||
if (IS_ERR(ssc_p->ssc)) {
|
||||
printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
|
||||
ret = PTR_ERR(ssc_p->ssc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int atmel_ssc_remove(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
ssc_free(ssc_p->ssc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
|
||||
|
||||
|
@ -705,9 +728,11 @@ static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
|
|||
.set_clkdiv = atmel_ssc_set_dai_clkdiv,
|
||||
};
|
||||
|
||||
struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
|
||||
{ .name = "atmel-ssc0",
|
||||
.id = 0,
|
||||
static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
|
||||
{
|
||||
.name = "atmel-ssc-dai.0",
|
||||
.probe = atmel_ssc_probe,
|
||||
.remove = atmel_ssc_remove,
|
||||
.suspend = atmel_ssc_suspend,
|
||||
.resume = atmel_ssc_resume,
|
||||
.playback = {
|
||||
|
@ -721,11 +746,12 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
|
|||
.rates = ATMEL_SSC_RATES,
|
||||
.formats = ATMEL_SSC_FORMATS,},
|
||||
.ops = &atmel_ssc_dai_ops,
|
||||
.private_data = &ssc_info[0],
|
||||
},
|
||||
#if NUM_SSC_DEVICES == 3
|
||||
{ .name = "atmel-ssc1",
|
||||
.id = 1,
|
||||
{
|
||||
.name = "atmel-ssc-dai.1",
|
||||
.probe = atmel_ssc_probe,
|
||||
.remove = atmel_ssc_remove,
|
||||
.suspend = atmel_ssc_suspend,
|
||||
.resume = atmel_ssc_resume,
|
||||
.playback = {
|
||||
|
@ -739,10 +765,11 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
|
|||
.rates = ATMEL_SSC_RATES,
|
||||
.formats = ATMEL_SSC_FORMATS,},
|
||||
.ops = &atmel_ssc_dai_ops,
|
||||
.private_data = &ssc_info[1],
|
||||
},
|
||||
{ .name = "atmel-ssc2",
|
||||
.id = 2,
|
||||
{
|
||||
.name = "atmel-ssc-dai.2",
|
||||
.probe = atmel_ssc_probe,
|
||||
.remove = atmel_ssc_remove,
|
||||
.suspend = atmel_ssc_suspend,
|
||||
.resume = atmel_ssc_resume,
|
||||
.playback = {
|
||||
|
@ -756,23 +783,43 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
|
|||
.rates = ATMEL_SSC_RATES,
|
||||
.formats = ATMEL_SSC_FORMATS,},
|
||||
.ops = &atmel_ssc_dai_ops,
|
||||
.private_data = &ssc_info[2],
|
||||
},
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(atmel_ssc_dai);
|
||||
|
||||
static int __init atmel_ssc_modinit(void)
|
||||
static __devinit int asoc_ssc_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
|
||||
return snd_soc_register_dais(&pdev->dev, atmel_ssc_dai,
|
||||
ARRAY_SIZE(atmel_ssc_dai));
|
||||
}
|
||||
module_init(atmel_ssc_modinit);
|
||||
|
||||
static void __exit atmel_ssc_modexit(void)
|
||||
static int __devexit asoc_ssc_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
|
||||
snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(atmel_ssc_dai));
|
||||
return 0;
|
||||
}
|
||||
module_exit(atmel_ssc_modexit);
|
||||
|
||||
static struct platform_driver asoc_ssc_driver = {
|
||||
.driver = {
|
||||
.name = "atmel-ssc-dai",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = asoc_ssc_probe,
|
||||
.remove = __devexit_p(asoc_ssc_remove),
|
||||
};
|
||||
|
||||
static int __init snd_atmel_ssc_init(void)
|
||||
{
|
||||
return platform_driver_register(&asoc_ssc_driver);
|
||||
}
|
||||
module_init(snd_atmel_ssc_init);
|
||||
|
||||
static void __exit snd_atmel_ssc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&asoc_ssc_driver);
|
||||
}
|
||||
module_exit(snd_atmel_ssc_exit);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
|
||||
|
|
|
@ -116,6 +116,5 @@ struct atmel_ssc_info {
|
|||
struct atmel_pcm_dma_params *dma_params[2];
|
||||
struct atmel_ssc_state ssc_state;
|
||||
};
|
||||
extern struct snd_soc_dai atmel_ssc_dai[];
|
||||
|
||||
#endif /* _AT91_SSC_DAI_H */
|
||||
|
|
|
@ -83,7 +83,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct at32_ssc_info *ssc_p = cpu_dai->private_data;
|
||||
struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct ssc_device *ssc = ssc_p->ssc;
|
||||
struct ssc_clock_data cd;
|
||||
unsigned int rate, width_bits, channels;
|
||||
|
@ -131,9 +131,9 @@ static int playpaq_wm8510_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 *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct at32_ssc_info *ssc_p = cpu_dai->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct ssc_device *ssc = ssc_p->ssc;
|
||||
unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
|
||||
int ret;
|
||||
|
@ -315,8 +315,9 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
|
||||
|
||||
|
||||
static int playpaq_wm8510_init(struct snd_soc_codec *codec)
|
||||
static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
@ -342,7 +343,7 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
|
|||
|
||||
|
||||
/* Make CSB show PLL rate */
|
||||
snd_soc_dai_set_clkdiv(codec->dai, WM8510_OPCLKDIV,
|
||||
snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV,
|
||||
WM8510_OPCLKDIV_1 | 4);
|
||||
|
||||
return 0;
|
||||
|
@ -353,8 +354,10 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
|
|||
static struct snd_soc_dai_link playpaq_wm8510_dai = {
|
||||
.name = "WM8510",
|
||||
.stream_name = "WM8510 PCM",
|
||||
.cpu_dai = &at32_ssc_dai[0],
|
||||
.codec_dai = &wm8510_dai,
|
||||
.cpu_dai_name= "atmel-ssc-dai.0",
|
||||
.platform_name = "atmel-pcm-audio",
|
||||
.codec_name = "wm8510-codec.0-0x1a",
|
||||
.codec_dai_name = "wm8510-hifi",
|
||||
.init = playpaq_wm8510_init,
|
||||
.ops = &playpaq_wm8510_ops,
|
||||
};
|
||||
|
@ -363,46 +366,16 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
|
|||
|
||||
static struct snd_soc_card snd_soc_playpaq = {
|
||||
.name = "LRS_PlayPaq_WM8510",
|
||||
.platform = &at32_soc_platform,
|
||||
.dai_link = &playpaq_wm8510_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct wm8510_setup_data playpaq_wm8510_setup = {
|
||||
.i2c_bus = 0,
|
||||
.i2c_address = 0x1a,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct snd_soc_device playpaq_wm8510_snd_devdata = {
|
||||
.card = &snd_soc_playpaq,
|
||||
.codec_dev = &soc_codec_dev_wm8510,
|
||||
.codec_data = &playpaq_wm8510_setup,
|
||||
};
|
||||
|
||||
static struct platform_device *playpaq_snd_device;
|
||||
|
||||
|
||||
static int __init playpaq_asoc_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
|
||||
struct ssc_device *ssc = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* Request SSC device
|
||||
*/
|
||||
ssc = ssc_request(0);
|
||||
if (IS_ERR(ssc)) {
|
||||
ret = PTR_ERR(ssc);
|
||||
goto err_ssc;
|
||||
}
|
||||
ssc_p->ssc = ssc;
|
||||
|
||||
|
||||
/*
|
||||
* Configure MCLK for WM8510
|
||||
|
@ -439,8 +412,7 @@ static int __init playpaq_asoc_init(void)
|
|||
goto err_device_alloc;
|
||||
}
|
||||
|
||||
platform_set_drvdata(playpaq_snd_device, &playpaq_wm8510_snd_devdata);
|
||||
playpaq_wm8510_snd_devdata.dev = &playpaq_snd_device->dev;
|
||||
platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq);
|
||||
|
||||
ret = platform_device_add(playpaq_snd_device);
|
||||
if (ret) {
|
||||
|
@ -468,25 +440,12 @@ err_pll0:
|
|||
clk_put(_gclk0);
|
||||
_gclk0 = NULL;
|
||||
}
|
||||
err_gclk0:
|
||||
ssc_free(ssc);
|
||||
err_ssc:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void __exit playpaq_asoc_exit(void)
|
||||
{
|
||||
struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
|
||||
struct ssc_device *ssc;
|
||||
|
||||
if (ssc_p != NULL) {
|
||||
ssc = ssc_p->ssc;
|
||||
if (ssc != NULL)
|
||||
ssc_free(ssc);
|
||||
ssc_p->ssc = NULL;
|
||||
}
|
||||
|
||||
if (_gclk0 != NULL) {
|
||||
clk_put(_gclk0);
|
||||
_gclk0 = NULL;
|
||||
|
|
|
@ -69,8 +69,8 @@ static int at91sam9g20ek_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 *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret;
|
||||
|
||||
/* set codec DAI configuration */
|
||||
|
@ -136,9 +136,10 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
/*
|
||||
* Logic for a wm8731 as connected on a at91sam9g20ek board.
|
||||
*/
|
||||
static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
|
||||
static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_dai *codec_dai = &codec->dai[0];
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
int ret;
|
||||
|
||||
printk(KERN_DEBUG
|
||||
|
@ -179,31 +180,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
|
|||
static struct snd_soc_dai_link at91sam9g20ek_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731 PCM",
|
||||
.cpu_dai = &atmel_ssc_dai[0],
|
||||
.codec_dai = &wm8731_dai,
|
||||
.cpu_dai_name = "atmel-ssc-dai.0",
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.init = at91sam9g20ek_wm8731_init,
|
||||
.platform_name = "atmel_pcm-audio",
|
||||
.codec_name = "wm8731-codec.0-001a",
|
||||
.ops = &at91sam9g20ek_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_at91sam9g20ek = {
|
||||
.name = "AT91SAMG20-EK",
|
||||
.platform = &atmel_soc_platform,
|
||||
.dai_link = &at91sam9g20ek_dai,
|
||||
.num_links = 1,
|
||||
.set_bias_level = at91sam9g20ek_set_bias_level,
|
||||
};
|
||||
|
||||
static struct snd_soc_device at91sam9g20ek_snd_devdata = {
|
||||
.card = &snd_soc_at91sam9g20ek,
|
||||
.codec_dev = &soc_codec_dev_wm8731,
|
||||
};
|
||||
|
||||
static struct platform_device *at91sam9g20ek_snd_device;
|
||||
|
||||
static int __init at91sam9g20ek_init(void)
|
||||
{
|
||||
struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
|
||||
struct ssc_device *ssc = NULL;
|
||||
struct clk *pllb;
|
||||
int ret;
|
||||
|
||||
|
@ -235,18 +230,6 @@ static int __init at91sam9g20ek_init(void)
|
|||
|
||||
clk_set_rate(mclk, MCLK_RATE);
|
||||
|
||||
/*
|
||||
* Request SSC device
|
||||
*/
|
||||
ssc = ssc_request(0);
|
||||
if (IS_ERR(ssc)) {
|
||||
printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
|
||||
ret = PTR_ERR(ssc);
|
||||
ssc = NULL;
|
||||
goto err_ssc;
|
||||
}
|
||||
ssc_p->ssc = ssc;
|
||||
|
||||
at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!at91sam9g20ek_snd_device) {
|
||||
printk(KERN_ERR "ASoC: Platform device allocation failed\n");
|
||||
|
@ -254,8 +237,7 @@ static int __init at91sam9g20ek_init(void)
|
|||
}
|
||||
|
||||
platform_set_drvdata(at91sam9g20ek_snd_device,
|
||||
&at91sam9g20ek_snd_devdata);
|
||||
at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
|
||||
&snd_soc_at91sam9g20ek);
|
||||
|
||||
ret = platform_device_add(at91sam9g20ek_snd_device);
|
||||
if (ret) {
|
||||
|
@ -265,9 +247,6 @@ static int __init at91sam9g20ek_init(void)
|
|||
|
||||
return ret;
|
||||
|
||||
err_ssc:
|
||||
ssc_free(ssc);
|
||||
ssc_p->ssc = NULL;
|
||||
err_mclk:
|
||||
clk_put(mclk);
|
||||
mclk = NULL;
|
||||
|
@ -277,16 +256,6 @@ err:
|
|||
|
||||
static void __exit at91sam9g20ek_exit(void)
|
||||
{
|
||||
struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
|
||||
struct ssc_device *ssc;
|
||||
|
||||
if (ssc_p != NULL) {
|
||||
ssc = ssc_p->ssc;
|
||||
if (ssc != NULL)
|
||||
ssc_free(ssc);
|
||||
ssc_p->ssc = NULL;
|
||||
}
|
||||
|
||||
platform_device_unregister(at91sam9g20ek_snd_device);
|
||||
at91sam9g20ek_snd_device = NULL;
|
||||
clk_put(mclk);
|
||||
|
|
|
@ -46,8 +46,8 @@ static int afeb9260_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 *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int err;
|
||||
|
||||
/* Set codec DAI configuration */
|
||||
|
@ -102,8 +102,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|||
{"MICIN", NULL, "Mic Jack"},
|
||||
};
|
||||
|
||||
static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec)
|
||||
static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
|
||||
/* Add afeb9260 specific widgets */
|
||||
snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
|
||||
|
@ -125,8 +126,10 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec)
|
|||
static struct snd_soc_dai_link afeb9260_dai = {
|
||||
.name = "TLV320AIC23",
|
||||
.stream_name = "AIC23",
|
||||
.cpu_dai = &atmel_ssc_dai[0],
|
||||
.codec_dai = &tlv320aic23_dai,
|
||||
.cpu_dai_name = "atmel-ssc-dai.0",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.platform_name = "atmel_pcm-audio",
|
||||
.codec_name = "tlv320aic23-codec.0-0x1a",
|
||||
.init = afeb9260_tlv320aic23_init,
|
||||
.ops = &afeb9260_ops,
|
||||
};
|
||||
|
@ -134,37 +137,20 @@ static struct snd_soc_dai_link afeb9260_dai = {
|
|||
/* Audio machine driver */
|
||||
static struct snd_soc_card snd_soc_machine_afeb9260 = {
|
||||
.name = "AFEB9260",
|
||||
.platform = &atmel_soc_platform,
|
||||
.dai_link = &afeb9260_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
/* Audio subsystem */
|
||||
static struct snd_soc_device afeb9260_snd_devdata = {
|
||||
.card = &snd_soc_machine_afeb9260,
|
||||
.codec_dev = &soc_codec_dev_tlv320aic23,
|
||||
};
|
||||
|
||||
static struct platform_device *afeb9260_snd_device;
|
||||
|
||||
static int __init afeb9260_soc_init(void)
|
||||
{
|
||||
int err;
|
||||
struct device *dev;
|
||||
struct atmel_ssc_info *ssc_p = afeb9260_dai.cpu_dai->private_data;
|
||||
struct ssc_device *ssc = NULL;
|
||||
|
||||
if (!(machine_is_afeb9260()))
|
||||
return -ENODEV;
|
||||
|
||||
ssc = ssc_request(0);
|
||||
if (IS_ERR(ssc)) {
|
||||
printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
|
||||
err = PTR_ERR(ssc);
|
||||
ssc = NULL;
|
||||
goto err_ssc;
|
||||
}
|
||||
ssc_p->ssc = ssc;
|
||||
|
||||
afeb9260_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!afeb9260_snd_device) {
|
||||
|
@ -172,8 +158,7 @@ static int __init afeb9260_soc_init(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
platform_set_drvdata(afeb9260_snd_device, &afeb9260_snd_devdata);
|
||||
afeb9260_snd_devdata.dev = &afeb9260_snd_device->dev;
|
||||
platform_set_drvdata(afeb9260_snd_device, &snd_soc_machine_afeb9260);
|
||||
err = platform_device_add(afeb9260_snd_device);
|
||||
if (err)
|
||||
goto err1;
|
||||
|
@ -184,9 +169,7 @@ static int __init afeb9260_soc_init(void)
|
|||
err1:
|
||||
platform_device_del(afeb9260_snd_device);
|
||||
platform_device_put(afeb9260_snd_device);
|
||||
err_ssc:
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void __exit afeb9260_soc_exit(void)
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <asm/mach-au1x00/au1xxx_dbdma.h>
|
||||
#include <asm/mach-db1x00/bcsr.h>
|
||||
|
||||
#include "../codecs/ac97.h"
|
||||
#include "../codecs/wm8731.h"
|
||||
#include "psc.h"
|
||||
|
||||
|
@ -28,20 +27,16 @@
|
|||
static struct snd_soc_dai_link db1200_ac97_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.cpu_dai = &au1xpsc_ac97_dai,
|
||||
.codec_dai = &ac97_dai,
|
||||
.cpu_dai_name = "au1xpsc-ac97",
|
||||
.codec_dai_name = "ac97-hifi",
|
||||
.platform_name = "au1xpsc-pcm-audio",
|
||||
.codec_name = "ac97-codec",
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1200_ac97_machine = {
|
||||
.name = "DB1200_AC97",
|
||||
.dai_link = &db1200_ac97_dai,
|
||||
.num_links = 1,
|
||||
.platform = &au1xpsc_soc_platform,
|
||||
};
|
||||
|
||||
static struct snd_soc_device db1200_ac97_devdata = {
|
||||
.card = &db1200_ac97_machine,
|
||||
.codec_dev = &soc_codec_dev_ac97,
|
||||
};
|
||||
|
||||
/*------------------------- I2S PART ---------------------------*/
|
||||
|
@ -49,8 +44,8 @@ static struct snd_soc_device db1200_ac97_devdata = {
|
|||
static int db1200_i2s_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret;
|
||||
|
||||
/* WM8731 has its own 12MHz crystal */
|
||||
|
@ -80,8 +75,10 @@ static struct snd_soc_ops db1200_i2s_wm8731_ops = {
|
|||
static struct snd_soc_dai_link db1200_i2s_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731 PCM",
|
||||
.cpu_dai = &au1xpsc_i2s_dai,
|
||||
.codec_dai = &wm8731_dai,
|
||||
.cpu_dai_name = "au1xpsc",
|
||||
.codec_dai_name = "wm8731-hifi"
|
||||
.platform_name = "au1xpsc-pcm-audio",
|
||||
.codec_name = "wm8731-codec.0-001a",
|
||||
.ops = &db1200_i2s_wm8731_ops,
|
||||
};
|
||||
|
||||
|
@ -89,12 +86,6 @@ static struct snd_soc_card db1200_i2s_machine = {
|
|||
.name = "DB1200_I2S",
|
||||
.dai_link = &db1200_i2s_dai,
|
||||
.num_links = 1,
|
||||
.platform = &au1xpsc_soc_platform,
|
||||
};
|
||||
|
||||
static struct snd_soc_device db1200_i2s_devdata = {
|
||||
.card = &db1200_i2s_machine,
|
||||
.codec_dev = &soc_codec_dev_wm8731,
|
||||
};
|
||||
|
||||
/*------------------------- COMMON PART ---------------------------*/
|
||||
|
@ -112,12 +103,10 @@ static int __init db1200_audio_load(void)
|
|||
|
||||
/* DB1200 board setup set PSC1MUX to preferred audio device */
|
||||
if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX)
|
||||
platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata);
|
||||
platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine);
|
||||
else
|
||||
platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata);
|
||||
platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine);
|
||||
|
||||
db1200_ac97_devdata.dev = &db1200_asoc_dev->dev;
|
||||
db1200_i2s_devdata.dev = &db1200_asoc_dev->dev;
|
||||
ret = platform_device_add(db1200_asoc_dev);
|
||||
|
||||
if (ret) {
|
||||
|
|
|
@ -329,7 +329,7 @@ static int au1xpsc_pcm_new(struct snd_card *card,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int au1xpsc_pcm_probe(struct platform_device *pdev)
|
||||
static int au1xpsc_pcm_probe(struct snd_soc_platform *platform)
|
||||
{
|
||||
if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
|
||||
return -ENODEV;
|
||||
|
@ -337,17 +337,10 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int au1xpsc_pcm_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* au1xpsc audio platform */
|
||||
struct snd_soc_platform au1xpsc_soc_platform = {
|
||||
.name = "au1xpsc-pcm-dbdma",
|
||||
struct snd_soc_platform_driver au1xpsc_soc_platform = {
|
||||
.probe = au1xpsc_pcm_probe,
|
||||
.remove = au1xpsc_pcm_remove,
|
||||
.pcm_ops = &au1xpsc_pcm_ops,
|
||||
.ops = &au1xpsc_pcm_ops,
|
||||
.pcm_new = au1xpsc_pcm_new,
|
||||
.pcm_free = au1xpsc_pcm_free_dma_buffers,
|
||||
};
|
||||
|
@ -387,7 +380,7 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
|
|||
}
|
||||
(au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
|
||||
|
||||
ret = snd_soc_register_platform(&au1xpsc_soc_platform);
|
||||
ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
|
@ -404,7 +397,7 @@ static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
|
|||
{
|
||||
int i;
|
||||
|
||||
snd_soc_unregister_platform(&au1xpsc_soc_platform);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (au1xpsc_audio_pcmdma[i]) {
|
||||
|
@ -419,7 +412,7 @@ static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
|
|||
|
||||
static struct platform_driver au1xpsc_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "au1xpsc-pcm",
|
||||
.name = "au1xpsc-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = au1xpsc_pcm_drvprobe,
|
||||
|
|
|
@ -315,27 +315,19 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int au1xpsc_ac97_probe(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
return au1xpsc_ac97_workdata ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static void au1xpsc_ac97_remove(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
|
||||
.trigger = au1xpsc_ac97_trigger,
|
||||
.hw_params = au1xpsc_ac97_hw_params,
|
||||
};
|
||||
|
||||
struct snd_soc_dai au1xpsc_ac97_dai = {
|
||||
.name = "au1xpsc_ac97",
|
||||
struct snd_soc_dai_driver au1xpsc_ac97_dai = {
|
||||
.ac97_control = 1,
|
||||
.probe = au1xpsc_ac97_probe,
|
||||
.remove = au1xpsc_ac97_remove,
|
||||
.playback = {
|
||||
.rates = AC97_RATES,
|
||||
.formats = AC97_FMTS,
|
||||
|
@ -395,7 +387,7 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
|
|||
au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
|
||||
au_sync();
|
||||
|
||||
ret = snd_soc_register_dai(&au1xpsc_ac97_dai);
|
||||
ret = snd_soc_register_dai(&pdev->dev, &au1xpsc_ac97_dai);
|
||||
if (ret)
|
||||
goto out1;
|
||||
|
||||
|
@ -406,7 +398,7 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
snd_soc_unregister_dai(&au1xpsc_ac97_dai);
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
out1:
|
||||
release_mem_region(r->start, resource_size(r));
|
||||
out0:
|
||||
|
@ -422,7 +414,7 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
|
|||
if (wd->dmapd)
|
||||
au1xpsc_pcm_destroy(wd->dmapd);
|
||||
|
||||
snd_soc_unregister_dai(&au1xpsc_ac97_dai);
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
|
||||
/* disable PSC completely */
|
||||
au_writel(0, AC97_CFG(wd));
|
||||
|
@ -485,7 +477,7 @@ static struct dev_pm_ops au1xpscac97_pmops = {
|
|||
|
||||
static struct platform_driver au1xpsc_ac97_driver = {
|
||||
.driver = {
|
||||
.name = "au1xpsc_ac97",
|
||||
.name = "au1xpsc-ac97",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = AU1XPSCAC97_PMOPS,
|
||||
},
|
||||
|
|
|
@ -263,27 +263,19 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int au1xpsc_i2s_probe(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
static int au1xpsc_i2s_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
return au1xpsc_i2s_workdata ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static void au1xpsc_i2s_remove(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
|
||||
.trigger = au1xpsc_i2s_trigger,
|
||||
.hw_params = au1xpsc_i2s_hw_params,
|
||||
.set_fmt = au1xpsc_i2s_set_fmt,
|
||||
};
|
||||
|
||||
struct snd_soc_dai au1xpsc_i2s_dai = {
|
||||
.name = "au1xpsc_i2s",
|
||||
static struct snd_soc_dai_driver au1xpsc_i2s_dai = {
|
||||
.probe = au1xpsc_i2s_probe,
|
||||
.remove = au1xpsc_i2s_remove,
|
||||
.playback = {
|
||||
.rates = AU1XPSC_I2S_RATES,
|
||||
.formats = AU1XPSC_I2S_FMTS,
|
||||
|
@ -298,7 +290,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
|
|||
},
|
||||
.ops = &au1xpsc_i2s_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL(au1xpsc_i2s_dai);
|
||||
|
||||
static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
|
||||
{
|
||||
|
@ -346,7 +337,7 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
|
|||
* time out.
|
||||
*/
|
||||
|
||||
ret = snd_soc_register_dai(&au1xpsc_i2s_dai);
|
||||
ret = snd_soc_register_dai(&pdev->dev, &au1xpsc_i2s_dai);
|
||||
if (ret)
|
||||
goto out1;
|
||||
|
||||
|
@ -358,7 +349,7 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
snd_soc_unregister_dai(&au1xpsc_i2s_dai);
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
out1:
|
||||
release_mem_region(r->start, resource_size(r));
|
||||
out0:
|
||||
|
@ -374,7 +365,7 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
|
|||
if (wd->dmapd)
|
||||
au1xpsc_pcm_destroy(wd->dmapd);
|
||||
|
||||
snd_soc_unregister_dai(&au1xpsc_i2s_dai);
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
|
||||
au_writel(0, I2S_CFG(wd));
|
||||
au_sync();
|
||||
|
@ -436,7 +427,7 @@ static struct dev_pm_ops au1xpsci2s_pmops = {
|
|||
|
||||
static struct platform_driver au1xpsc_i2s_driver = {
|
||||
.driver = {
|
||||
.name = "au1xpsc_i2s",
|
||||
.name = "au1xpsc",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = AU1XPSCI2S_PMOPS,
|
||||
},
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
#ifndef _AU1X_PCM_H
|
||||
#define _AU1X_PCM_H
|
||||
|
||||
extern struct snd_soc_dai au1xpsc_ac97_dai;
|
||||
extern struct snd_soc_dai au1xpsc_i2s_dai;
|
||||
extern struct snd_soc_platform au1xpsc_soc_platform;
|
||||
extern struct snd_ac97_bus_ops soc_ac97_ops;
|
||||
|
||||
/* DBDMA helpers */
|
||||
|
|
|
@ -422,14 +422,14 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
|
|||
if (!card->dev->coherent_dma_mask)
|
||||
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (dai->playback.channels_min) {
|
||||
if (dai->driver->playback.channels_min) {
|
||||
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dai->capture.channels_min) {
|
||||
if (dai->driver->capture.channels_min) {
|
||||
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
|
@ -439,25 +439,44 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct snd_soc_platform bf5xx_ac97_soc_platform = {
|
||||
.name = "bf5xx-audio",
|
||||
.pcm_ops = &bf5xx_pcm_ac97_ops,
|
||||
static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = {
|
||||
.ops = &bf5xx_pcm_ac97_ops,
|
||||
.pcm_new = bf5xx_pcm_ac97_new,
|
||||
.pcm_free = bf5xx_pcm_free_dma_buffers,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
|
||||
|
||||
static int __init bfin_ac97_init(void)
|
||||
static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_platform(&bf5xx_ac97_soc_platform);
|
||||
return snd_soc_register_platform(&pdev->dev, &bf5xx_ac97_soc_platform);
|
||||
}
|
||||
module_init(bfin_ac97_init);
|
||||
|
||||
static void __exit bfin_ac97_exit(void)
|
||||
static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&bf5xx_ac97_soc_platform);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
module_exit(bfin_ac97_exit);
|
||||
|
||||
static struct platform_driver bf5xx_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "bf5xx-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = bf5xx_soc_platform_probe,
|
||||
.remove = __devexit_p(bf5xx_soc_platform_remove),
|
||||
};
|
||||
|
||||
static int __init snd_bf5xx_pcm_init(void)
|
||||
{
|
||||
return platform_driver_register(&bf5xx_pcm_driver);
|
||||
}
|
||||
module_init(snd_bf5xx_pcm_init);
|
||||
|
||||
static void __exit snd_bf5xx_pcm_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bf5xx_pcm_driver);
|
||||
}
|
||||
module_exit(snd_bf5xx_pcm_exit);
|
||||
|
||||
MODULE_AUTHOR("Cliff Cai");
|
||||
MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
|
||||
|
|
|
@ -23,7 +23,4 @@ struct bf5xx_gpio {
|
|||
u32 frm;
|
||||
};
|
||||
|
||||
/* platform data */
|
||||
extern struct snd_soc_platform bf5xx_ac97_soc_platform;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -255,7 +255,7 @@ EXPORT_SYMBOL_GPL(soc_ac97_ops);
|
|||
#ifdef CONFIG_PM
|
||||
static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct sport_device *sport = dai->private_data;
|
||||
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
pr_debug("%s : sport %d\n", __func__, dai->id);
|
||||
if (!dai->active)
|
||||
|
@ -270,7 +270,7 @@ static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
|
|||
static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
|
||||
{
|
||||
int ret;
|
||||
struct sport_device *sport = dai->private_data;
|
||||
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
pr_debug("%s : sport %d\n", __func__, dai->id);
|
||||
if (!dai->active)
|
||||
|
@ -306,8 +306,7 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
|
|||
#define bf5xx_ac97_resume NULL
|
||||
#endif
|
||||
|
||||
static int bf5xx_ac97_probe(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
int ret = 0;
|
||||
cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
|
||||
|
@ -379,8 +378,7 @@ peripheral_err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void bf5xx_ac97_remove(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
static int bf5xx_ac97_remove(struct snd_soc_dai *dai)
|
||||
{
|
||||
free_page((unsigned long)cmd_count);
|
||||
cmd_count = NULL;
|
||||
|
@ -388,11 +386,10 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
|
|||
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
|
||||
gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_dai bfin_ac97_dai = {
|
||||
.name = "bf5xx-ac97",
|
||||
.id = 0,
|
||||
struct snd_soc_dai_driver bfin_ac97_dai = {
|
||||
.ac97_control = 1,
|
||||
.probe = bf5xx_ac97_probe,
|
||||
.remove = bf5xx_ac97_remove,
|
||||
|
@ -417,18 +414,40 @@ struct snd_soc_dai bfin_ac97_dai = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(bfin_ac97_dai);
|
||||
|
||||
static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
|
||||
}
|
||||
|
||||
static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver asoc_bfin_ac97_driver = {
|
||||
.driver = {
|
||||
.name = "bfin-ac97",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = asoc_bfin_ac97_probe,
|
||||
.remove = __devexit_p(asoc_bfin_ac97_remove),
|
||||
};
|
||||
|
||||
static int __init bfin_ac97_init(void)
|
||||
{
|
||||
return snd_soc_register_dai(&bfin_ac97_dai);
|
||||
return platform_driver_register(&asoc_bfin_ac97_driver);
|
||||
}
|
||||
module_init(bfin_ac97_init);
|
||||
|
||||
static void __exit bfin_ac97_exit(void)
|
||||
{
|
||||
snd_soc_unregister_dai(&bfin_ac97_dai);
|
||||
platform_driver_unregister(&asoc_bfin_ac97_driver);
|
||||
}
|
||||
module_exit(bfin_ac97_exit);
|
||||
|
||||
|
||||
MODULE_AUTHOR("Roy Huang");
|
||||
MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -50,8 +50,6 @@ struct ac97_frame {
|
|||
#define TAG_PCM_SR 0x0080
|
||||
#define TAG_PCM_LFE 0x0040
|
||||
|
||||
extern struct snd_soc_dai bfin_ac97_dai;
|
||||
|
||||
void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
|
||||
size_t count, unsigned int chan_mask);
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ static struct snd_soc_card bf5xx_ad1836;
|
|||
static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
|
||||
cpu_dai->private_data = sport_handle;
|
||||
snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@ static int bf5xx_ad1836_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->dai->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
|
||||
int ret = 0;
|
||||
/* set cpu DAI configuration */
|
||||
|
@ -83,23 +83,19 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
|
|||
static struct snd_soc_dai_link bf5xx_ad1836_dai = {
|
||||
.name = "ad1836",
|
||||
.stream_name = "AD1836",
|
||||
.cpu_dai = &bf5xx_tdm_dai,
|
||||
.codec_dai = &ad1836_dai,
|
||||
.cpu_dai_name = "bf5xx-tdm",
|
||||
.codec_dai_name = "ad1836-hifi",
|
||||
.platform_name = "bf5xx-tdm-pcm-audio",
|
||||
.codec_name = "ad1836-codec.0",
|
||||
.ops = &bf5xx_ad1836_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card bf5xx_ad1836 = {
|
||||
.name = "bf5xx_ad1836",
|
||||
.platform = &bf5xx_tdm_soc_platform,
|
||||
.dai_link = &bf5xx_ad1836_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_device bf5xx_ad1836_snd_devdata = {
|
||||
.card = &bf5xx_ad1836,
|
||||
.codec_dev = &soc_codec_dev_ad1836,
|
||||
};
|
||||
|
||||
static struct platform_device *bfxx_ad1836_snd_device;
|
||||
|
||||
static int __init bf5xx_ad1836_init(void)
|
||||
|
@ -110,8 +106,7 @@ static int __init bf5xx_ad1836_init(void)
|
|||
if (!bfxx_ad1836_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836_snd_devdata);
|
||||
bf5xx_ad1836_snd_devdata.dev = &bfxx_ad1836_snd_device->dev;
|
||||
platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836);
|
||||
ret = platform_device_add(bfxx_ad1836_snd_device);
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -49,9 +49,9 @@ static struct snd_soc_card bf5xx_ad193x;
|
|||
static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
|
||||
cpu_dai->private_data = sport_handle;
|
||||
snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ static int bf5xx_ad193x_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->dai->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
int ret = 0;
|
||||
/* set cpu DAI configuration */
|
||||
|
@ -97,23 +97,19 @@ static struct snd_soc_ops bf5xx_ad193x_ops = {
|
|||
static struct snd_soc_dai_link bf5xx_ad193x_dai = {
|
||||
.name = "ad193x",
|
||||
.stream_name = "AD193X",
|
||||
.cpu_dai = &bf5xx_tdm_dai,
|
||||
.codec_dai = &ad193x_dai,
|
||||
.cpu_dai_name = "bf5xx-tdm",
|
||||
.codec_dai_name ="ad193x-hifi",
|
||||
.platform_name = "bf5xx-tdm-pcm-audio",
|
||||
.codec_name = "ad193x-codec.5",
|
||||
.ops = &bf5xx_ad193x_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card bf5xx_ad193x = {
|
||||
.name = "bf5xx_ad193x",
|
||||
.platform = &bf5xx_tdm_soc_platform,
|
||||
.dai_link = &bf5xx_ad193x_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_device bf5xx_ad193x_snd_devdata = {
|
||||
.card = &bf5xx_ad193x,
|
||||
.codec_dev = &soc_codec_dev_ad193x,
|
||||
};
|
||||
|
||||
static struct platform_device *bfxx_ad193x_snd_device;
|
||||
|
||||
static int __init bf5xx_ad193x_init(void)
|
||||
|
@ -124,8 +120,7 @@ static int __init bf5xx_ad193x_init(void)
|
|||
if (!bfxx_ad193x_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x_snd_devdata);
|
||||
bf5xx_ad193x_snd_devdata.dev = &bfxx_ad193x_snd_device->dev;
|
||||
platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x);
|
||||
ret = platform_device_add(bfxx_ad193x_snd_device);
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -48,10 +48,10 @@ static struct snd_soc_card bf5xx_board;
|
|||
static int bf5xx_board_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
|
||||
pr_debug("%s enter\n", __func__);
|
||||
cpu_dai->private_data = sport_handle;
|
||||
snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -62,23 +62,19 @@ static struct snd_soc_ops bf5xx_board_ops = {
|
|||
static struct snd_soc_dai_link bf5xx_board_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.cpu_dai = &bfin_ac97_dai,
|
||||
.codec_dai = &ad1980_dai,
|
||||
.cpu_dai_name = "bfin-ac97",
|
||||
.codec_dai_name = "ad1980-hifi",
|
||||
.platform_name = "bfin-pcm-audio",
|
||||
.codec_name = "ad1980-codec",
|
||||
.ops = &bf5xx_board_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card bf5xx_board = {
|
||||
.name = "bf5xx-board",
|
||||
.platform = &bf5xx_ac97_soc_platform,
|
||||
.dai_link = &bf5xx_board_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_device bf5xx_board_snd_devdata = {
|
||||
.card = &bf5xx_board,
|
||||
.codec_dev = &soc_codec_dev_ad1980,
|
||||
};
|
||||
|
||||
static struct platform_device *bf5xx_board_snd_device;
|
||||
|
||||
static int __init bf5xx_board_init(void)
|
||||
|
@ -89,8 +85,7 @@ static int __init bf5xx_board_init(void)
|
|||
if (!bf5xx_board_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board_snd_devdata);
|
||||
bf5xx_board_snd_devdata.dev = &bf5xx_board_snd_device->dev;
|
||||
platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board);
|
||||
ret = platform_device_add(bf5xx_board_snd_device);
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "../codecs/ad73311.h"
|
||||
#include "bf5xx-sport.h"
|
||||
#include "bf5xx-i2s-pcm.h"
|
||||
#include "bf5xx-i2s.h"
|
||||
|
||||
#if CONFIG_SND_BF5XX_SPORT_NUM == 0
|
||||
#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
|
||||
|
@ -150,10 +149,10 @@ static int bf5xx_probe(struct platform_device *pdev)
|
|||
static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
|
||||
pr_debug("%s enter\n", __func__);
|
||||
cpu_dai->private_data = sport_handle;
|
||||
snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -161,7 +160,7 @@ 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->dai->cpu_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret = 0;
|
||||
|
||||
pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
|
||||
|
@ -185,24 +184,20 @@ static struct snd_soc_ops bf5xx_ad73311_ops = {
|
|||
static struct snd_soc_dai_link bf5xx_ad73311_dai = {
|
||||
.name = "ad73311",
|
||||
.stream_name = "AD73311",
|
||||
.cpu_dai = &bf5xx_i2s_dai,
|
||||
.codec_dai = &ad73311_dai,
|
||||
.cpu_dai_name = "bf5xx-i2s",
|
||||
.codec_dai_name = "ad73311-hifi",
|
||||
.platform_name = "bfin-pcm-audio",
|
||||
.codec_name = "ad73311-codec",
|
||||
.ops = &bf5xx_ad73311_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card bf5xx_ad73311 = {
|
||||
.name = "bf5xx_ad73311",
|
||||
.platform = &bf5xx_i2s_soc_platform,
|
||||
.probe = bf5xx_probe,
|
||||
.dai_link = &bf5xx_ad73311_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
|
||||
.card = &bf5xx_ad73311,
|
||||
.codec_dev = &soc_codec_dev_ad73311,
|
||||
};
|
||||
|
||||
static struct platform_device *bf5xx_ad73311_snd_device;
|
||||
|
||||
static int __init bf5xx_ad73311_init(void)
|
||||
|
@ -214,8 +209,7 @@ static int __init bf5xx_ad73311_init(void)
|
|||
if (!bf5xx_ad73311_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311_snd_devdata);
|
||||
bf5xx_ad73311_snd_devdata.dev = &bf5xx_ad73311_snd_device->dev;
|
||||
platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311);
|
||||
ret = platform_device_add(bf5xx_ad73311_snd_device);
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <asm/dma.h>
|
||||
|
||||
#include "bf5xx-i2s-pcm.h"
|
||||
#include "bf5xx-i2s.h"
|
||||
#include "bf5xx-sport.h"
|
||||
|
||||
static void bf5xx_dma_irq(void *data)
|
||||
|
@ -257,14 +256,14 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
|
|||
if (!card->dev->coherent_dma_mask)
|
||||
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (dai->playback.channels_min) {
|
||||
if (dai->driver->playback.channels_min) {
|
||||
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dai->capture.channels_min) {
|
||||
if (dai->driver->capture.channels_min) {
|
||||
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
|
@ -274,25 +273,44 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct snd_soc_platform bf5xx_i2s_soc_platform = {
|
||||
.name = "bf5xx-audio",
|
||||
.pcm_ops = &bf5xx_pcm_i2s_ops,
|
||||
static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
|
||||
.ops = &bf5xx_pcm_i2s_ops,
|
||||
.pcm_new = bf5xx_pcm_i2s_new,
|
||||
.pcm_free = bf5xx_pcm_free_dma_buffers,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
|
||||
|
||||
static int __init bfin_i2s_init(void)
|
||||
static int __devinit bfin_i2s_soc_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_platform(&bf5xx_i2s_soc_platform);
|
||||
return snd_soc_register_platform(&pdev->dev, &bf5xx_i2s_soc_platform);
|
||||
}
|
||||
module_init(bfin_i2s_init);
|
||||
|
||||
static void __exit bfin_i2s_exit(void)
|
||||
static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&bf5xx_i2s_soc_platform);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
module_exit(bfin_i2s_exit);
|
||||
|
||||
static struct platform_driver bfin_i2s_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "bfin-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = bfin_i2s_soc_platform_probe,
|
||||
.remove = __devexit_p(bfin_i2s_soc_platform_remove),
|
||||
};
|
||||
|
||||
static int __init snd_bfin_i2s_pcm_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_i2s_pcm_driver);
|
||||
}
|
||||
module_init(snd_bfin_i2s_pcm_init);
|
||||
|
||||
static void __exit snd_bfin_i2s_pcm_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_i2s_pcm_driver);
|
||||
}
|
||||
module_exit(snd_bfin_i2s_pcm_exit);
|
||||
|
||||
MODULE_AUTHOR("Cliff Cai");
|
||||
MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
|
||||
|
|
|
@ -23,7 +23,4 @@ struct bf5xx_gpio {
|
|||
u32 frm;
|
||||
};
|
||||
|
||||
/* platform data */
|
||||
extern struct snd_soc_platform bf5xx_i2s_soc_platform;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include <linux/gpio.h>
|
||||
|
||||
#include "bf5xx-sport.h"
|
||||
#include "bf5xx-i2s.h"
|
||||
|
||||
struct bf5xx_i2s_port {
|
||||
u16 tcr1;
|
||||
|
@ -195,8 +194,7 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
|
|||
bf5xx_i2s.configured = 0;
|
||||
}
|
||||
|
||||
static int bf5xx_i2s_probe(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
static int bf5xx_i2s_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
pr_debug("%s enter\n", __func__);
|
||||
if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
|
||||
|
@ -215,11 +213,11 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void bf5xx_i2s_remove(struct platform_device *pdev,
|
||||
struct snd_soc_dai *dai)
|
||||
static int bf5xx_i2s_remove(struct snd_soc_dai *dai)
|
||||
{
|
||||
pr_debug("%s enter\n", __func__);
|
||||
peripheral_free_list(&sport_req[sport_num][0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -228,9 +226,9 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
|
|||
|
||||
pr_debug("%s : sport %d\n", __func__, dai->id);
|
||||
|
||||
if (dai->capture.active)
|
||||
if (dai->capture_active)
|
||||
sport_rx_stop(sport_handle);
|
||||
if (dai->playback.active)
|
||||
if (dai->playback_active)
|
||||
sport_tx_stop(sport_handle);
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,9 +275,7 @@ static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
|
|||
.set_fmt = bf5xx_i2s_set_dai_fmt,
|
||||
};
|
||||
|
||||
struct snd_soc_dai bf5xx_i2s_dai = {
|
||||
.name = "bf5xx-i2s",
|
||||
.id = 0,
|
||||
static struct snd_soc_dai_driver bf5xx_i2s_dai = {
|
||||
.probe = bf5xx_i2s_probe,
|
||||
.remove = bf5xx_i2s_remove,
|
||||
.suspend = bf5xx_i2s_suspend,
|
||||
|
@ -296,18 +292,39 @@ struct snd_soc_dai bf5xx_i2s_dai = {
|
|||
.formats = BF5XX_I2S_FORMATS,},
|
||||
.ops = &bf5xx_i2s_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
|
||||
|
||||
static int bfin_i2s_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai);
|
||||
}
|
||||
|
||||
static int __devexit bfin_i2s_drv_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver bfin_i2s_driver = {
|
||||
.probe = bfin_i2s_drv_probe,
|
||||
.remove = __devexit_p(bfin_i2s_drv_remove),
|
||||
|
||||
.driver = {
|
||||
.name = "bf5xx-i2s",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bfin_i2s_init(void)
|
||||
{
|
||||
return snd_soc_register_dai(&bf5xx_i2s_dai);
|
||||
return platform_driver_register(&bfin_i2s_driver);
|
||||
}
|
||||
module_init(bfin_i2s_init);
|
||||
|
||||
static void __exit bfin_i2s_exit(void)
|
||||
{
|
||||
snd_soc_unregister_dai(&bf5xx_i2s_dai);
|
||||
platform_driver_unregister(&bfin_i2s_driver);
|
||||
}
|
||||
|
||||
module_init(bfin_i2s_init);
|
||||
module_exit(bfin_i2s_exit);
|
||||
|
||||
/* Module information */
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* sound/soc/blackfin/bf5xx-i2s.h
|
||||
*
|
||||
* 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 _BF5XX_I2S_H
|
||||
#define _BF5XX_I2S_H
|
||||
|
||||
extern struct snd_soc_dai bf5xx_i2s_dai;
|
||||
|
||||
#endif
|
|
@ -42,17 +42,16 @@
|
|||
#include "../codecs/ssm2602.h"
|
||||
#include "bf5xx-sport.h"
|
||||
#include "bf5xx-i2s-pcm.h"
|
||||
#include "bf5xx-i2s.h"
|
||||
|
||||
static struct snd_soc_card bf5xx_ssm2602;
|
||||
|
||||
static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
|
||||
pr_debug("%s enter\n", __func__);
|
||||
cpu_dai->private_data = sport_handle;
|
||||
snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -60,8 +59,8 @@ static int bf5xx_ssm2602_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 *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
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;
|
||||
|
||||
|
@ -118,36 +117,19 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
|
|||
static struct snd_soc_dai_link bf5xx_ssm2602_dai = {
|
||||
.name = "ssm2602",
|
||||
.stream_name = "SSM2602",
|
||||
.cpu_dai = &bf5xx_i2s_dai,
|
||||
.codec_dai = &ssm2602_dai,
|
||||
.cpu_dai_name = "bf5xx-i2s",
|
||||
.codec_dai_name = "ssm2602-hifi",
|
||||
.platform_name = "bf5xx-pcm-audio",
|
||||
.codec_name = "ssm2602-codec.0-0x1b",
|
||||
.ops = &bf5xx_ssm2602_ops,
|
||||
};
|
||||
|
||||
/*
|
||||
* SSM2602 2 wire address is determined by CSB
|
||||
* state during powerup.
|
||||
* low = 0x1a
|
||||
* high = 0x1b
|
||||
*/
|
||||
|
||||
static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
|
||||
.i2c_bus = 0,
|
||||
.i2c_address = 0x1b,
|
||||
};
|
||||
|
||||
static struct snd_soc_card bf5xx_ssm2602 = {
|
||||
.name = "bf5xx_ssm2602",
|
||||
.platform = &bf5xx_i2s_soc_platform,
|
||||
.dai_link = &bf5xx_ssm2602_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
|
||||
.card = &bf5xx_ssm2602,
|
||||
.codec_dev = &soc_codec_dev_ssm2602,
|
||||
.codec_data = &bf5xx_ssm2602_setup,
|
||||
};
|
||||
|
||||
static struct platform_device *bf5xx_ssm2602_snd_device;
|
||||
|
||||
static int __init bf5xx_ssm2602_init(void)
|
||||
|
@ -159,9 +141,7 @@ static int __init bf5xx_ssm2602_init(void)
|
|||
if (!bf5xx_ssm2602_snd_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(bf5xx_ssm2602_snd_device,
|
||||
&bf5xx_ssm2602_snd_devdata);
|
||||
bf5xx_ssm2602_snd_devdata.dev = &bf5xx_ssm2602_snd_device->dev;
|
||||
platform_set_drvdata(bf5xx_ssm2602_snd_device, &bf5xx_ssm2602);
|
||||
ret = platform_device_add(bf5xx_ssm2602_snd_device);
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -290,14 +290,14 @@ static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
|
|||
if (!card->dev->coherent_dma_mask)
|
||||
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (dai->playback.channels_min) {
|
||||
if (dai->driver->playback.channels_min) {
|
||||
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dai->capture.channels_min) {
|
||||
if (dai->driver->capture.channels_min) {
|
||||
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
|
@ -307,25 +307,44 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct snd_soc_platform bf5xx_tdm_soc_platform = {
|
||||
.name = "bf5xx-audio",
|
||||
.pcm_ops = &bf5xx_pcm_tdm_ops,
|
||||
static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = {
|
||||
.ops = &bf5xx_pcm_tdm_ops,
|
||||
.pcm_new = bf5xx_pcm_tdm_new,
|
||||
.pcm_free = bf5xx_pcm_free_dma_buffers,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(bf5xx_tdm_soc_platform);
|
||||
|
||||
static int __init bfin_pcm_tdm_init(void)
|
||||
static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_platform(&bf5xx_tdm_soc_platform);
|
||||
return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
|
||||
}
|
||||
module_init(bfin_pcm_tdm_init);
|
||||
|
||||
static void __exit bfin_pcm_tdm_exit(void)
|
||||
static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&bf5xx_tdm_soc_platform);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
module_exit(bfin_pcm_tdm_exit);
|
||||
|
||||
static struct platform_driver bfin_tdm_driver = {
|
||||
.driver = {
|
||||
.name = "bf5xx-tdm-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = bf5xx_soc_platform_probe,
|
||||
.remove = __devexit_p(bf5xx_soc_platform_remove),
|
||||
};
|
||||
|
||||
static int __init snd_bfin_tdm_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_tdm_driver);
|
||||
}
|
||||
module_init(snd_bfin_tdm_init);
|
||||
|
||||
static void __exit snd_bfin_tdm_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_tdm_driver);
|
||||
}
|
||||
module_exit(snd_bfin_tdm_exit);
|
||||
|
||||
MODULE_AUTHOR("Barry Song");
|
||||
MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
|
||||
|
|
|
@ -15,7 +15,4 @@ struct bf5xx_pcm_dma_params {
|
|||
char *name; /* stream identifier */
|
||||
};
|
||||
|
||||
/* platform data */
|
||||
extern struct snd_soc_platform bf5xx_tdm_soc_platform;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -214,9 +214,9 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
|
|||
|
||||
if (!dai->active)
|
||||
return 0;
|
||||
if (dai->capture.active)
|
||||
if (dai->capture_active)
|
||||
sport_rx_stop(sport);
|
||||
if (dai->playback.active)
|
||||
if (dai->playback_active)
|
||||
sport_tx_stop(sport);
|
||||
return 0;
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
|
|||
static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
|
||||
{
|
||||
int ret;
|
||||
struct sport_device *sport = dai->private_data;
|
||||
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!dai->active)
|
||||
return 0;
|
||||
|
@ -262,9 +262,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
|
|||
.set_channel_map = bf5xx_tdm_set_channel_map,
|
||||
};
|
||||
|
||||
struct snd_soc_dai bf5xx_tdm_dai = {
|
||||
.name = "bf5xx-tdm",
|
||||
.id = 0,
|
||||
static struct snd_soc_dai_driver bf5xx_tdm_dai = {
|
||||
.suspend = bf5xx_tdm_suspend,
|
||||
.resume = bf5xx_tdm_resume,
|
||||
.playback = {
|
||||
|
@ -279,7 +277,6 @@ struct snd_soc_dai bf5xx_tdm_dai = {
|
|||
.formats = SNDRV_PCM_FMTBIT_S32_LE,},
|
||||
.ops = &bf5xx_tdm_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(bf5xx_tdm_dai);
|
||||
|
||||
static int __devinit bfin_tdm_probe(struct platform_device *pdev)
|
||||
{
|
||||
|
@ -320,7 +317,7 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
|
|||
goto sport_config_err;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&bf5xx_tdm_dai);
|
||||
ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai);
|
||||
if (ret) {
|
||||
pr_err("Failed to register DAI: %d\n", ret);
|
||||
goto sport_config_err;
|
||||
|
@ -337,7 +334,7 @@ sport_config_err:
|
|||
static int __devexit bfin_tdm_remove(struct platform_device *pdev)
|
||||
{
|
||||
peripheral_free_list(&sport_req[sport_num][0]);
|
||||
snd_soc_unregister_dai(&bf5xx_tdm_dai);
|
||||
snd_soc_unregister_dai(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,4 @@ struct bf5xx_tdm_port {
|
|||
int configured;
|
||||
};
|
||||
|
||||
extern struct snd_soc_dai bf5xx_tdm_dai;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <sound/ac97_codec.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
#include "ac97.h"
|
||||
|
||||
#define AC97_VERSION "0.6"
|
||||
|
||||
|
@ -30,8 +29,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
|
||||
int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
|
||||
|
@ -46,8 +44,8 @@ static struct snd_soc_dai_ops ac97_dai_ops = {
|
|||
.prepare = ac97_prepare,
|
||||
};
|
||||
|
||||
struct snd_soc_dai ac97_dai = {
|
||||
.name = "AC97 HiFi",
|
||||
static struct snd_soc_dai_driver ac97_dai = {
|
||||
.name = "ac97-hifi",
|
||||
.ac97_control = 1,
|
||||
.playback = {
|
||||
.stream_name = "AC97 Playback",
|
||||
|
@ -63,7 +61,6 @@ struct snd_soc_dai ac97_dai = {
|
|||
.formats = SND_SOC_STD_AC97_FMTS,},
|
||||
.ops = &ac97_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ac97_dai);
|
||||
|
||||
static unsigned int ac97_read(struct snd_soc_codec *codec,
|
||||
unsigned int reg)
|
||||
|
@ -78,95 +75,49 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ac97_soc_probe(struct platform_device *pdev)
|
||||
static int ac97_soc_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_card *card = socdev->card;
|
||||
struct snd_soc_codec *codec;
|
||||
struct snd_ac97_bus *ac97_bus;
|
||||
struct snd_ac97_template ac97_template;
|
||||
int i;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
|
||||
|
||||
socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (!socdev->card->codec)
|
||||
return -ENOMEM;
|
||||
codec = socdev->card->codec;
|
||||
mutex_init(&codec->mutex);
|
||||
|
||||
codec->name = "AC97";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ac97_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->write = ac97_write;
|
||||
codec->read = ac97_read;
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* add codec as bus device for standard ac97 */
|
||||
ret = snd_ac97_bus(codec->card, 0, &soc_ac97_ops, NULL, &ac97_bus);
|
||||
ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus);
|
||||
if (ret < 0)
|
||||
goto bus_err;
|
||||
return ret;
|
||||
|
||||
memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
|
||||
ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97);
|
||||
if (ret < 0)
|
||||
goto bus_err;
|
||||
|
||||
for (i = 0; i < card->num_links; i++) {
|
||||
if (card->dai_link[i].codec_dai->ac97_control) {
|
||||
snd_ac97_dev_add_pdata(codec->ac97,
|
||||
card->dai_link[i].cpu_dai->ac97_pdata);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
bus_err:
|
||||
snd_soc_free_pcms(socdev);
|
||||
|
||||
err:
|
||||
kfree(socdev->card->codec);
|
||||
socdev->card->codec = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ac97_soc_remove(struct platform_device *pdev)
|
||||
static int ac97_soc_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
if (!codec)
|
||||
return 0;
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
kfree(socdev->card->codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg)
|
||||
static int ac97_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_ac97_suspend(socdev->card->codec->ac97);
|
||||
snd_ac97_suspend(codec->ac97);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ac97_soc_resume(struct platform_device *pdev)
|
||||
static int ac97_soc_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_ac97_resume(socdev->card->codec->ac97);
|
||||
snd_ac97_resume(codec->ac97);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -175,13 +126,48 @@ static int ac97_soc_resume(struct platform_device *pdev)
|
|||
#define ac97_soc_resume NULL
|
||||
#endif
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ac97 = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
|
||||
.write = ac97_write,
|
||||
.read = ac97_read,
|
||||
.probe = ac97_soc_probe,
|
||||
.remove = ac97_soc_remove,
|
||||
.suspend = ac97_soc_suspend,
|
||||
.resume = ac97_soc_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ac97);
|
||||
|
||||
static __devinit int ac97_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_ac97, &ac97_dai, 1);
|
||||
}
|
||||
|
||||
static int __devexit ac97_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ac97_codec_driver = {
|
||||
.driver = {
|
||||
.name = "ac97-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = ac97_probe,
|
||||
.remove = __devexit_p(ac97_remove),
|
||||
};
|
||||
|
||||
static int __init ac97_init(void)
|
||||
{
|
||||
return platform_driver_register(&ac97_codec_driver);
|
||||
}
|
||||
module_init(ac97_init);
|
||||
|
||||
static void __exit ac97_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ac97_codec_driver);
|
||||
}
|
||||
module_exit(ac97_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Soc Generic AC97 driver");
|
||||
MODULE_AUTHOR("Liam Girdwood");
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* linux/sound/codecs/ac97.h -- ALSA SoC Layer
|
||||
*
|
||||
* Author: Liam Girdwood
|
||||
* Created: Dec 1st 2005
|
||||
* Copyright: 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_SOC_AC97_H
|
||||
#define __LINUX_SND_SOC_AC97_H
|
||||
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ac97;
|
||||
extern struct snd_soc_dai ac97_dai;
|
||||
|
||||
#endif
|
|
@ -33,15 +33,10 @@
|
|||
|
||||
/* codec private data */
|
||||
struct ad1836_priv {
|
||||
struct snd_soc_codec codec;
|
||||
u16 reg_cache[AD1836_NUM_REGS];
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
};
|
||||
|
||||
static struct snd_soc_codec *ad1836_codec;
|
||||
struct snd_soc_codec_device soc_codec_dev_ad1836;
|
||||
static int ad1836_register(struct ad1836_priv *ad1836);
|
||||
static void ad1836_unregister(struct ad1836_priv *ad1836);
|
||||
|
||||
/*
|
||||
* AD1836 volume/mute/de-emphasis etc. controls
|
||||
*/
|
||||
|
@ -146,8 +141,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
|
|||
int word_len = 0;
|
||||
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
|
||||
/* bit size */
|
||||
switch (params_format(params)) {
|
||||
|
@ -173,12 +167,9 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ad1836_soc_suspend(struct platform_device *pdev,
|
||||
static int ad1836_soc_suspend(struct snd_soc_codec *codec,
|
||||
pm_message_t state)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
/* reset clock control mode */
|
||||
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
|
||||
adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
|
||||
|
@ -186,11 +177,8 @@ static int ad1836_soc_suspend(struct platform_device *pdev,
|
|||
return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
|
||||
}
|
||||
|
||||
static int ad1836_soc_resume(struct platform_device *pdev)
|
||||
static int ad1836_soc_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
/* restore clock control mode */
|
||||
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
|
||||
adc_ctrl2 |= AD1836_ADC_AUX;
|
||||
|
@ -202,49 +190,14 @@ static int ad1836_soc_resume(struct platform_device *pdev)
|
|||
#define ad1836_soc_resume NULL
|
||||
#endif
|
||||
|
||||
static int __devinit ad1836_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
struct ad1836_priv *ad1836;
|
||||
|
||||
ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
|
||||
if (ad1836 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
codec = &ad1836->codec;
|
||||
codec->control_data = spi;
|
||||
codec->dev = &spi->dev;
|
||||
|
||||
dev_set_drvdata(&spi->dev, ad1836);
|
||||
|
||||
return ad1836_register(ad1836);
|
||||
}
|
||||
|
||||
static int __devexit ad1836_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
|
||||
|
||||
ad1836_unregister(ad1836);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver ad1836_spi_driver = {
|
||||
.driver = {
|
||||
.name = "ad1836",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ad1836_spi_probe,
|
||||
.remove = __devexit_p(ad1836_spi_remove),
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_ops ad1836_dai_ops = {
|
||||
.hw_params = ad1836_hw_params,
|
||||
.set_fmt = ad1836_set_dai_fmt,
|
||||
};
|
||||
|
||||
/* codec DAI instance */
|
||||
struct snd_soc_dai ad1836_dai = {
|
||||
.name = "AD1836",
|
||||
static struct snd_soc_dai_driver ad1836_dai = {
|
||||
.name = "ad1836-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
|
@ -263,35 +216,13 @@ struct snd_soc_dai ad1836_dai = {
|
|||
},
|
||||
.ops = &ad1836_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ad1836_dai);
|
||||
|
||||
static int ad1836_register(struct ad1836_priv *ad1836)
|
||||
static int ad1836_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
int ret;
|
||||
struct snd_soc_codec *codec = &ad1836->codec;
|
||||
|
||||
if (ad1836_codec) {
|
||||
dev_err(codec->dev, "Another ad1836 is registered\n");
|
||||
kfree(ad1836);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
snd_soc_codec_set_drvdata(codec, ad1836);
|
||||
codec->reg_cache = ad1836->reg_cache;
|
||||
codec->reg_cache_size = AD1836_NUM_REGS;
|
||||
codec->name = "AD1836";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ad1836_dai;
|
||||
codec->num_dai = 1;
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
ad1836_dai.dev = codec->dev;
|
||||
ad1836_codec = codec;
|
||||
struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret = 0;
|
||||
|
||||
codec->control_data = ad1836->control_data;
|
||||
ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to set cache I/O: %d\n",
|
||||
|
@ -319,81 +250,69 @@ static int ad1836_register(struct ad1836_priv *ad1836)
|
|||
snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
|
||||
snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
|
||||
kfree(ad1836);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&ad1836_dai);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
|
||||
snd_soc_unregister_codec(codec);
|
||||
kfree(ad1836);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ad1836_unregister(struct ad1836_priv *ad1836)
|
||||
{
|
||||
snd_soc_unregister_dai(&ad1836_dai);
|
||||
snd_soc_unregister_codec(&ad1836->codec);
|
||||
kfree(ad1836);
|
||||
ad1836_codec = NULL;
|
||||
}
|
||||
|
||||
static int ad1836_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret = 0;
|
||||
|
||||
if (ad1836_codec == NULL) {
|
||||
dev_err(&pdev->dev, "Codec device not registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
socdev->card->codec = ad1836_codec;
|
||||
codec = ad1836_codec;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
|
||||
goto pcm_err;
|
||||
}
|
||||
|
||||
snd_soc_add_controls(codec, ad1836_snd_controls,
|
||||
ARRAY_SIZE(ad1836_snd_controls));
|
||||
snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
|
||||
ARRAY_SIZE(ad1836_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
|
||||
|
||||
pcm_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int ad1836_remove(struct platform_device *pdev)
|
||||
static int ad1836_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
/* reset clock control mode */
|
||||
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
|
||||
adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
|
||||
return 0;
|
||||
return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ad1836 = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
|
||||
.probe = ad1836_probe,
|
||||
.remove = ad1836_remove,
|
||||
.suspend = ad1836_soc_suspend,
|
||||
.resume = ad1836_soc_resume,
|
||||
.reg_cache_size = AD1836_NUM_REGS,
|
||||
.reg_word_size = sizeof(u16),
|
||||
};
|
||||
|
||||
static int __devinit ad1836_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct ad1836_priv *ad1836;
|
||||
int ret;
|
||||
|
||||
ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
|
||||
if (ad1836 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
spi_set_drvdata(spi, ad1836);
|
||||
ad1836->control_data = spi;
|
||||
ad1836->control_type = SND_SOC_SPI;
|
||||
|
||||
ret = snd_soc_register_codec(&spi->dev,
|
||||
&soc_codec_dev_ad1836, &ad1836_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(ad1836);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ad1836_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
snd_soc_unregister_codec(&spi->dev);
|
||||
kfree(spi_get_drvdata(spi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver ad1836_spi_driver = {
|
||||
.driver = {
|
||||
.name = "ad1836-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ad1836_spi_probe,
|
||||
.remove = __devexit_p(ad1836_spi_remove),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
|
||||
|
||||
static int __init ad1836_init(void)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,4 @@
|
|||
|
||||
#define AD1836_NUM_REGS 16
|
||||
|
||||
extern struct snd_soc_dai ad1836_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ad1836;
|
||||
#endif
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
|
||||
/* codec private data */
|
||||
struct ad193x_priv {
|
||||
unsigned int sysclk;
|
||||
struct snd_soc_codec codec;
|
||||
u8 reg_cache[AD193X_NUM_REGS];
|
||||
enum snd_soc_control_type bus_type;
|
||||
void *control_data;
|
||||
int sysclk;
|
||||
};
|
||||
|
||||
/* ad193x register cache & default register settings */
|
||||
|
@ -34,9 +35,6 @@ static const u8 ad193x_reg[AD193X_NUM_REGS] = {
|
|||
0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
|
||||
};
|
||||
|
||||
static struct snd_soc_codec *ad193x_codec;
|
||||
struct snd_soc_codec_device soc_codec_dev_ad193x;
|
||||
|
||||
/*
|
||||
* AD193X volume/mute/de-emphasis etc. controls
|
||||
*/
|
||||
|
@ -275,8 +273,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
|
|||
int word_len = 0, reg = 0, master_rate = 0;
|
||||
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
/* bit size */
|
||||
|
@ -323,46 +320,46 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
|
||||
static struct snd_soc_dai_ops ad193x_dai_ops = {
|
||||
.hw_params = ad193x_hw_params,
|
||||
.digital_mute = ad193x_mute,
|
||||
.set_tdm_slot = ad193x_set_tdm_slot,
|
||||
.set_sysclk = ad193x_set_dai_sysclk,
|
||||
.set_fmt = ad193x_set_dai_fmt,
|
||||
};
|
||||
|
||||
/* codec DAI instance */
|
||||
static struct snd_soc_dai_driver ad193x_dai = {
|
||||
.name = "ad193x-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 2,
|
||||
.channels_max = 4,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
.ops = &ad193x_dai_ops,
|
||||
};
|
||||
|
||||
static int ad193x_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
struct ad193x_priv *ad193x;
|
||||
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
if (ad193x_codec) {
|
||||
dev_err(dev, "Another ad193x is registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
|
||||
if (ad193x == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, ad193x);
|
||||
|
||||
codec = &ad193x->codec;
|
||||
mutex_init(&codec->mutex);
|
||||
codec->control_data = ctrl_data;
|
||||
codec->dev = dev;
|
||||
snd_soc_codec_set_drvdata(codec, ad193x);
|
||||
codec->reg_cache = ad193x->reg_cache;
|
||||
codec->reg_cache_size = AD193X_NUM_REGS;
|
||||
codec->name = "AD193X";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ad193x_dai;
|
||||
codec->num_dai = 1;
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
ad193x_dai.dev = codec->dev;
|
||||
ad193x_codec = codec;
|
||||
|
||||
memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
|
||||
|
||||
if (bus_type == SND_SOC_I2C)
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
|
||||
codec->control_data = ad193x->control_data;
|
||||
if (ad193x->bus_type == SND_SOC_I2C)
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
|
||||
else
|
||||
ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
|
||||
ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to set cache I/O: %d\n",
|
||||
ret);
|
||||
|
@ -385,89 +382,6 @@ static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
|
|||
/* pll input: mclki/xi */
|
||||
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
|
||||
snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
|
||||
ad193x->sysclk = 12288000;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
|
||||
kfree(ad193x);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&ad193x_dai);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
|
||||
snd_soc_unregister_codec(codec);
|
||||
kfree(ad193x);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad193x_bus_remove(struct device *dev)
|
||||
{
|
||||
struct ad193x_priv *ad193x = dev_get_drvdata(dev);
|
||||
|
||||
snd_soc_unregister_dai(&ad193x_dai);
|
||||
snd_soc_unregister_codec(&ad193x->codec);
|
||||
kfree(ad193x);
|
||||
ad193x_codec = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_ops ad193x_dai_ops = {
|
||||
.hw_params = ad193x_hw_params,
|
||||
.digital_mute = ad193x_mute,
|
||||
.set_tdm_slot = ad193x_set_tdm_slot,
|
||||
.set_sysclk = ad193x_set_dai_sysclk,
|
||||
.set_fmt = ad193x_set_dai_fmt,
|
||||
};
|
||||
|
||||
/* codec DAI instance */
|
||||
struct snd_soc_dai ad193x_dai = {
|
||||
.name = "AD193X",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 2,
|
||||
.channels_max = 4,
|
||||
.rates = SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
.ops = &ad193x_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ad193x_dai);
|
||||
|
||||
static int ad193x_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret = 0;
|
||||
|
||||
if (ad193x_codec == NULL) {
|
||||
dev_err(&pdev->dev, "Codec device not registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
socdev->card->codec = ad193x_codec;
|
||||
codec = ad193x_codec;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
|
||||
goto pcm_err;
|
||||
}
|
||||
|
||||
snd_soc_add_controls(codec, ad193x_snd_controls,
|
||||
ARRAY_SIZE(ad193x_snd_controls));
|
||||
|
@ -475,41 +389,47 @@ static int ad193x_probe(struct platform_device *pdev)
|
|||
ARRAY_SIZE(ad193x_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
|
||||
|
||||
pcm_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int ad193x_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ad193x = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
|
||||
.probe = ad193x_probe,
|
||||
.remove = ad193x_remove,
|
||||
.reg_cache_default = ad193x_reg,
|
||||
.reg_cache_size = AD193X_NUM_REGS,
|
||||
.reg_word_size = sizeof(u16),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
|
||||
|
||||
#if defined(CONFIG_SPI_MASTER)
|
||||
static int __devinit ad193x_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI);
|
||||
struct ad193x_priv *ad193x;
|
||||
int ret;
|
||||
|
||||
ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
|
||||
if (ad193x == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
spi_set_drvdata(spi, ad193x);
|
||||
ad193x->control_data = spi;
|
||||
ad193x->bus_type = SND_SOC_SPI;
|
||||
|
||||
ret = snd_soc_register_codec(&spi->dev,
|
||||
&soc_codec_dev_ad193x, &ad193x_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(ad193x);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ad193x_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
return ad193x_bus_remove(&spi->dev);
|
||||
snd_soc_unregister_codec(&spi->dev);
|
||||
kfree(spi_get_drvdata(spi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver ad193x_spi_driver = {
|
||||
.driver = {
|
||||
.name = "ad193x",
|
||||
.name = "ad193x-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ad193x_spi_probe,
|
||||
|
@ -528,17 +448,34 @@ MODULE_DEVICE_TABLE(i2c, ad193x_id);
|
|||
static int __devinit ad193x_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C);
|
||||
struct ad193x_priv *ad193x;
|
||||
int ret;
|
||||
|
||||
ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
|
||||
if (ad193x == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, ad193x);
|
||||
ad193x->control_data = client;
|
||||
ad193x->bus_type = SND_SOC_I2C;
|
||||
|
||||
ret = snd_soc_register_codec(&client->dev,
|
||||
&soc_codec_dev_ad193x, &ad193x_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(ad193x);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ad193x_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return ad193x_bus_remove(&client->dev);
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver ad193x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ad193x",
|
||||
.name = "ad193x-codec",
|
||||
},
|
||||
.probe = ad193x_i2c_probe,
|
||||
.remove = __devexit_p(ad193x_i2c_remove),
|
||||
|
|
|
@ -80,7 +80,4 @@
|
|||
|
||||
#define AD193X_NUM_REGS 17
|
||||
|
||||
extern struct snd_soc_dai ad193x_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ad193x;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -130,8 +130,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_dai ad1980_dai = {
|
||||
.name = "AC97",
|
||||
struct snd_soc_dai_driver ad1980_dai = {
|
||||
.name = "ad1980-hifi",
|
||||
.ac97_control = 1,
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
|
@ -177,53 +177,20 @@ err:
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int ad1980_soc_probe(struct platform_device *pdev)
|
||||
static int ad1980_soc_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
u16 vendor_id2;
|
||||
u16 ext_status;
|
||||
|
||||
printk(KERN_INFO "AD1980 SoC Audio Codec\n");
|
||||
|
||||
socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (socdev->card->codec == NULL)
|
||||
return -ENOMEM;
|
||||
codec = socdev->card->codec;
|
||||
mutex_init(&codec->mutex);
|
||||
|
||||
codec->reg_cache =
|
||||
kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
|
||||
if (codec->reg_cache == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto cache_err;
|
||||
}
|
||||
memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
|
||||
ARRAY_SIZE(ad1980_reg));
|
||||
codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
|
||||
codec->reg_cache_step = 2;
|
||||
codec->name = "AD1980";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ad1980_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->write = ac97_write;
|
||||
codec->read = ac97_read;
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
|
||||
goto codec_err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0)
|
||||
goto pcm_err;
|
||||
|
||||
|
||||
ret = ad1980_reset(codec, 0);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
|
||||
|
@ -262,41 +229,59 @@ static int ad1980_soc_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
reset_err:
|
||||
snd_soc_free_pcms(socdev);
|
||||
|
||||
pcm_err:
|
||||
snd_soc_free_ac97_codec(codec);
|
||||
|
||||
codec_err:
|
||||
kfree(codec->reg_cache);
|
||||
|
||||
cache_err:
|
||||
kfree(socdev->card->codec);
|
||||
socdev->card->codec = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ad1980_soc_remove(struct platform_device *pdev)
|
||||
static int ad1980_soc_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
if (codec == NULL)
|
||||
return 0;
|
||||
|
||||
snd_soc_dapm_free(socdev);
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_free_ac97_codec(codec);
|
||||
kfree(codec->reg_cache);
|
||||
kfree(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ad1980 = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
|
||||
.probe = ad1980_soc_probe,
|
||||
.remove = ad1980_soc_remove,
|
||||
.reg_cache_size = ARRAY_SIZE(ad1980_reg),
|
||||
.reg_word_size = sizeof(u16),
|
||||
.reg_cache_step = 2,
|
||||
.write = ac97_write,
|
||||
.read = ac97_read,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
|
||||
|
||||
static __devinit int ad1980_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_ad1980, &ad1980_dai, 1);
|
||||
}
|
||||
|
||||
static int __devexit ad1980_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ad1980_codec_driver = {
|
||||
.driver = {
|
||||
.name = "ad1980-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = ad1980_probe,
|
||||
.remove = __devexit_p(ad1980_remove),
|
||||
};
|
||||
|
||||
static int __init ad1980_init(void)
|
||||
{
|
||||
return platform_driver_register(&ad1980_codec_driver);
|
||||
}
|
||||
module_init(ad1980_init);
|
||||
|
||||
static void __exit ad1980_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ad1980_codec_driver);
|
||||
}
|
||||
module_exit(ad1980_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC ad1980 driver");
|
||||
MODULE_AUTHOR("Roy Huang, Cliff Cai");
|
||||
|
|
|
@ -17,7 +17,4 @@
|
|||
#define PR5 0x2000
|
||||
#define PR6 0x4000
|
||||
|
||||
extern struct snd_soc_dai ad1980_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ad1980;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
#include "ad73311.h"
|
||||
|
||||
struct snd_soc_dai ad73311_dai = {
|
||||
.name = "AD73311",
|
||||
static struct snd_soc_dai_driver ad73311_dai = {
|
||||
.name = "ad73311-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -38,68 +38,40 @@ struct snd_soc_dai ad73311_dai = {
|
|||
.rates = SNDRV_PCM_RATE_8000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ad73311_dai);
|
||||
|
||||
static int ad73311_soc_probe(struct platform_device *pdev)
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ad73311;
|
||||
|
||||
static int ad73311_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret = 0;
|
||||
|
||||
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (codec == NULL)
|
||||
return -ENOMEM;
|
||||
mutex_init(&codec->mutex);
|
||||
codec->name = "AD73311";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ad73311_dai;
|
||||
codec->num_dai = 1;
|
||||
socdev->card->codec = codec;
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "ad73311: failed to create pcms\n");
|
||||
goto pcm_err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
pcm_err:
|
||||
kfree(socdev->card->codec);
|
||||
socdev->card->codec = NULL;
|
||||
return ret;
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_ad73311, &ad73311_dai, 1);
|
||||
}
|
||||
|
||||
static int ad73311_soc_remove(struct platform_device *pdev)
|
||||
static int ad73311_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
if (codec == NULL)
|
||||
return 0;
|
||||
snd_soc_free_pcms(socdev);
|
||||
kfree(codec);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ad73311 = {
|
||||
.probe = ad73311_soc_probe,
|
||||
.remove = ad73311_soc_remove,
|
||||
static struct platform_driver ad73311_codec_driver = {
|
||||
.driver = {
|
||||
.name = "ad73311-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = ad73311_probe,
|
||||
.remove = __devexit_p(ad73311_remove),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
|
||||
|
||||
static int __init ad73311_init(void)
|
||||
{
|
||||
return snd_soc_register_dai(&ad73311_dai);
|
||||
return platform_driver_register(&ad73311_codec_driver);
|
||||
}
|
||||
module_init(ad73311_init);
|
||||
|
||||
static void __exit ad73311_exit(void)
|
||||
{
|
||||
snd_soc_unregister_dai(&ad73311_dai);
|
||||
platform_driver_unregister(&ad73311_codec_driver);
|
||||
}
|
||||
module_exit(ad73311_exit);
|
||||
|
||||
|
|
|
@ -85,6 +85,4 @@
|
|||
#define REGF_INV (1 << 6)
|
||||
#define REGF_ALB (1 << 7)
|
||||
|
||||
extern struct snd_soc_dai ad73311_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ad73311;
|
||||
#endif
|
||||
|
|
|
@ -19,16 +19,12 @@
|
|||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "ads117x.h"
|
||||
|
||||
#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
|
||||
|
||||
#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
|
||||
|
||||
struct snd_soc_dai ads117x_dai = {
|
||||
static struct snd_soc_dai_driver ads117x_dai = {
|
||||
/* ADC */
|
||||
.name = "ADS117X ADC",
|
||||
.id = 1,
|
||||
.name = "ads117x-hifi",
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
|
@ -36,75 +32,29 @@ struct snd_soc_dai ads117x_dai = {
|
|||
.rates = ADS117X_RATES,
|
||||
.formats = ADS117X_FORMATS,},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ads117x_dai);
|
||||
|
||||
static int ads117x_probe(struct platform_device *pdev)
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ads117x;
|
||||
|
||||
static __devinit int ads117x_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (codec == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
socdev->card->codec = codec;
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
codec->name = "ADS117X";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ads117x_dai;
|
||||
codec->num_dai = 1;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "ads117x: failed to create pcms\n");
|
||||
kfree(codec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_ads117x, &ads117x_dai, 1);
|
||||
}
|
||||
|
||||
static int ads117x_remove(struct platform_device *pdev)
|
||||
static int __devexit ads117x_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
kfree(codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ads117x = {
|
||||
.probe = ads117x_probe,
|
||||
.remove = ads117x_remove,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
|
||||
|
||||
static __devinit int ads117x_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
ads117x_dai.dev = &pdev->dev;
|
||||
return snd_soc_register_dai(&ads117x_dai);
|
||||
}
|
||||
|
||||
static int __devexit ads117x_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_dai(&ads117x_dai);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ads117x_codec_driver = {
|
||||
.driver = {
|
||||
.name = "ads117x",
|
||||
.name = "ads117x-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = ads117x_platform_probe,
|
||||
.remove = __devexit_p(ads117x_platform_remove),
|
||||
.probe = ads117x_probe,
|
||||
.remove = __devexit_p(ads117x_remove),
|
||||
};
|
||||
|
||||
static int __init ads117x_init(void)
|
||||
|
|
|
@ -9,5 +9,5 @@
|
|||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
extern struct snd_soc_dai ads117x_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ads117x;
|
||||
extern struct snd_soc_dai_driver ads117x_dai;
|
||||
extern struct snd_soc_codec_driver soc_codec_dev_ads117x;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#include <linux/spi/spi.h>
|
||||
#include <sound/asoundef.h>
|
||||
|
||||
#include "ak4104.h"
|
||||
|
||||
/* AK4104 registers addresses */
|
||||
#define AK4104_REG_CONTROL1 0x00
|
||||
#define AK4104_REG_RESERVED 0x01
|
||||
|
@ -45,11 +43,11 @@
|
|||
#define AK4104_TX_TXE (1 << 0)
|
||||
#define AK4104_TX_V (1 << 1)
|
||||
|
||||
#define DRV_NAME "ak4104"
|
||||
#define DRV_NAME "ak4104-codec"
|
||||
|
||||
struct ak4104_private {
|
||||
struct snd_soc_codec codec;
|
||||
u8 reg_cache[AK4104_NUM_REGS];
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
};
|
||||
|
||||
static int ak4104_fill_cache(struct snd_soc_codec *codec)
|
||||
|
@ -58,7 +56,7 @@ static int ak4104_fill_cache(struct snd_soc_codec *codec)
|
|||
u8 *reg_cache = codec->reg_cache;
|
||||
struct spi_device *spi = codec->control_data;
|
||||
|
||||
for (i = 0; i < codec->reg_cache_size; i++) {
|
||||
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");
|
||||
|
@ -76,7 +74,7 @@ static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
|
|||
{
|
||||
u8 *reg_cache = codec->reg_cache;
|
||||
|
||||
if (reg >= codec->reg_cache_size)
|
||||
if (reg >= codec->driver->reg_cache_size)
|
||||
return -EINVAL;
|
||||
|
||||
return reg_cache[reg];
|
||||
|
@ -88,7 +86,7 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
|
|||
u8 *cache = codec->reg_cache;
|
||||
struct spi_device *spi = codec->control_data;
|
||||
|
||||
if (reg >= codec->reg_cache_size)
|
||||
if (reg >= codec->driver->reg_cache_size)
|
||||
return -EINVAL;
|
||||
|
||||
/* only write to the hardware if value has changed */
|
||||
|
@ -145,8 +143,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
int val = 0;
|
||||
|
||||
/* set the IEC958 bits: consumer mode, no copyright bit */
|
||||
|
@ -178,8 +175,8 @@ static struct snd_soc_dai_ops ak4101_dai_ops = {
|
|||
.set_fmt = ak4104_set_dai_fmt,
|
||||
};
|
||||
|
||||
struct snd_soc_dai ak4104_dai = {
|
||||
.name = DRV_NAME,
|
||||
static struct snd_soc_dai_driver ak4104_dai = {
|
||||
.name = "ak4104-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
|
@ -192,13 +189,71 @@ struct snd_soc_dai ak4104_dai = {
|
|||
.ops = &ak4101_dai_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_codec *ak4104_codec;
|
||||
static int ak4104_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret, val;
|
||||
|
||||
codec->control_data = ak4104->control_data;
|
||||
|
||||
/* 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");
|
||||
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);
|
||||
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);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_info(codec->dev, "SPI device initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ak4104_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
int val, ret;
|
||||
|
||||
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
/* clear power-up and non-reset bits */
|
||||
val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
|
||||
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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(u16),
|
||||
};
|
||||
|
||||
static int ak4104_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
struct ak4104_private *ak4104;
|
||||
int ret, val;
|
||||
int ret;
|
||||
|
||||
spi->bits_per_word = 8;
|
||||
spi->mode = SPI_MODE_0;
|
||||
|
@ -207,125 +262,27 @@ static int ak4104_spi_probe(struct spi_device *spi)
|
|||
return ret;
|
||||
|
||||
ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
|
||||
if (!ak4104) {
|
||||
dev_err(&spi->dev, "could not allocate codec\n");
|
||||
if (ak4104 == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
codec = &ak4104->codec;
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
codec->dev = &spi->dev;
|
||||
codec->name = DRV_NAME;
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &ak4104_dai;
|
||||
codec->num_dai = 1;
|
||||
snd_soc_codec_set_drvdata(codec, ak4104);
|
||||
codec->control_data = spi;
|
||||
codec->reg_cache = ak4104->reg_cache;
|
||||
codec->reg_cache_size = AK4104_NUM_REGS;
|
||||
|
||||
/* read all regs and fill the cache */
|
||||
ret = ak4104_fill_cache(codec);
|
||||
if (ret < 0) {
|
||||
dev_err(&spi->dev, "failed to fill register cache\n");
|
||||
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) {
|
||||
ret = -ENODEV;
|
||||
goto error_free_codec;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (ret < 0)
|
||||
goto error_free_codec;
|
||||
|
||||
/* enable transmitter */
|
||||
val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
|
||||
val |= AK4104_TX_TXE;
|
||||
ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
|
||||
if (ret < 0)
|
||||
goto error_free_codec;
|
||||
|
||||
ak4104_codec = codec;
|
||||
ret = snd_soc_register_dai(&ak4104_dai);
|
||||
if (ret < 0) {
|
||||
dev_err(&spi->dev, "failed to register DAI\n");
|
||||
goto error_free_codec;
|
||||
}
|
||||
|
||||
ak4104->control_data = spi;
|
||||
ak4104->control_type = SND_SOC_SPI;
|
||||
spi_set_drvdata(spi, ak4104);
|
||||
dev_info(&spi->dev, "SPI device initialized\n");
|
||||
return 0;
|
||||
|
||||
error_free_codec:
|
||||
kfree(ak4104);
|
||||
ak4104_dai.dev = NULL;
|
||||
ret = snd_soc_register_codec(&spi->dev,
|
||||
&soc_codec_device_ak4104, &ak4104_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(ak4104);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ak4104_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
int ret, val;
|
||||
struct ak4104_private *ak4104 = spi_get_drvdata(spi);
|
||||
|
||||
val = ak4104_read_reg_cache(&ak4104->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(&ak4104->codec, AK4104_REG_CONTROL1, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ak4104_codec = NULL;
|
||||
kfree(ak4104);
|
||||
snd_soc_unregister_codec(&spi->dev);
|
||||
kfree(spi_get_drvdata(spi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ak4104_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = ak4104_codec;
|
||||
int ret;
|
||||
|
||||
/* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
|
||||
socdev->card->codec = codec;
|
||||
|
||||
/* Register PCMs */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to create pcms\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ak4104_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
snd_soc_free_pcms(socdev);
|
||||
return 0;
|
||||
};
|
||||
|
||||
struct snd_soc_codec_device soc_codec_device_ak4104 = {
|
||||
.probe = ak4104_probe,
|
||||
.remove = ak4104_remove
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_device_ak4104);
|
||||
|
||||
static struct spi_driver ak4104_spi_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef _AK4104_H
|
||||
#define _AK4104_H
|
||||
|
||||
extern struct snd_soc_dai ak4104_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_device_ak4104;
|
||||
|
||||
#endif
|
|
@ -31,11 +31,11 @@
|
|||
|
||||
#define AK4535_VERSION "0.3"
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ak4535;
|
||||
|
||||
/* codec private data */
|
||||
struct ak4535_priv {
|
||||
unsigned int sysclk;
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -313,8 +313,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
|
||||
u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
|
||||
int rate = params_rate(params), fs = 256;
|
||||
|
@ -378,14 +377,16 @@ static int ak4535_mute(struct snd_soc_dai *dai, int mute)
|
|||
static int ak4535_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
u16 i;
|
||||
u16 i, mute_reg;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
ak4535_mute(codec->dai, 0);
|
||||
mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
|
||||
ak4535_write(codec, AK4535_DAC, mute_reg);
|
||||
break;
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
ak4535_mute(codec->dai, 1);
|
||||
mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
|
||||
ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
|
||||
break;
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
i = ak4535_read_reg_cache(codec, AK4535_PM1);
|
||||
|
@ -413,8 +414,8 @@ static struct snd_soc_dai_ops ak4535_dai_ops = {
|
|||
.set_sysclk = ak4535_set_dai_sysclk,
|
||||
};
|
||||
|
||||
struct snd_soc_dai ak4535_dai = {
|
||||
.name = "AK4535",
|
||||
static struct snd_soc_dai_driver ak4535_dai = {
|
||||
.name = "ak4535-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -429,54 +430,27 @@ struct snd_soc_dai ak4535_dai = {
|
|||
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
|
||||
.ops = &ak4535_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ak4535_dai);
|
||||
|
||||
static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ak4535_resume(struct platform_device *pdev)
|
||||
static int ak4535_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
ak4535_sync(codec);
|
||||
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialise the AK4535 driver
|
||||
* register the mixer and dsp interfaces with the kernel
|
||||
*/
|
||||
static int ak4535_init(struct snd_soc_device *socdev)
|
||||
static int ak4535_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
int ret = 0;
|
||||
struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
codec->name = "AK4535";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->read = ak4535_read_reg_cache;
|
||||
codec->write = ak4535_write;
|
||||
codec->set_bias_level = ak4535_set_bias_level;
|
||||
codec->dai = &ak4535_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
|
||||
codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL);
|
||||
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
|
||||
|
||||
if (codec->reg_cache == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "ak4535: failed to create pcms\n");
|
||||
goto pcm_err;
|
||||
}
|
||||
codec->control_data = ak4535->control_data;
|
||||
|
||||
/* power on device */
|
||||
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
@ -485,39 +459,55 @@ static int ak4535_init(struct snd_soc_device *socdev)
|
|||
ARRAY_SIZE(ak4535_snd_controls));
|
||||
ak4535_add_widgets(codec);
|
||||
|
||||
return ret;
|
||||
|
||||
pcm_err:
|
||||
kfree(codec->reg_cache);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_device *ak4535_socdev;
|
||||
/* power down chip */
|
||||
static int ak4535_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
|
||||
.probe = ak4535_probe,
|
||||
.remove = ak4535_remove,
|
||||
.suspend = ak4535_suspend,
|
||||
.resume = ak4535_resume,
|
||||
.read = ak4535_read_reg_cache,
|
||||
.write = ak4535_write,
|
||||
.set_bias_level = ak4535_set_bias_level,
|
||||
.reg_cache_size = ARRAY_SIZE(ak4535_reg),
|
||||
.reg_word_size = sizeof(u8),
|
||||
.reg_cache_default = ak4535_reg,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
|
||||
static int ak4535_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct snd_soc_device *socdev = ak4535_socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct ak4535_priv *ak4535;
|
||||
int ret;
|
||||
|
||||
i2c_set_clientdata(i2c, codec);
|
||||
codec->control_data = i2c;
|
||||
ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
|
||||
if (ak4535 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = ak4535_init(socdev);
|
||||
i2c_set_clientdata(i2c, ak4535);
|
||||
ak4535->control_data = i2c;
|
||||
ak4535->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&soc_codec_dev_ak4535, &ak4535_dai, 1);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "failed to initialise AK4535\n");
|
||||
|
||||
kfree(ak4535);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ak4535_i2c_remove(struct i2c_client *client)
|
||||
static __devexit int ak4535_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct snd_soc_codec *codec = i2c_get_clientdata(client);
|
||||
kfree(codec->reg_cache);
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -529,138 +519,34 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
|
|||
|
||||
static struct i2c_driver ak4535_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "AK4535 I2C Codec",
|
||||
.name = "ak4535-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ak4535_i2c_probe,
|
||||
.remove = ak4535_i2c_remove,
|
||||
.remove = __devexit_p(ak4535_i2c_remove),
|
||||
.id_table = ak4535_i2c_id,
|
||||
};
|
||||
|
||||
static int ak4535_add_i2c_device(struct platform_device *pdev,
|
||||
const struct ak4535_setup_data *setup)
|
||||
{
|
||||
struct i2c_board_info info;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *client;
|
||||
int ret;
|
||||
|
||||
ret = i2c_add_driver(&ak4535_i2c_driver);
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "can't add i2c driver\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&info, 0, sizeof(struct i2c_board_info));
|
||||
info.addr = setup->i2c_address;
|
||||
strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
|
||||
|
||||
adapter = i2c_get_adapter(setup->i2c_bus);
|
||||
if (!adapter) {
|
||||
dev_err(&pdev->dev, "can't get i2c adapter %d\n",
|
||||
setup->i2c_bus);
|
||||
goto err_driver;
|
||||
}
|
||||
|
||||
client = i2c_new_device(adapter, &info);
|
||||
i2c_put_adapter(adapter);
|
||||
if (!client) {
|
||||
dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
|
||||
(unsigned int)info.addr);
|
||||
goto err_driver;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_driver:
|
||||
i2c_del_driver(&ak4535_i2c_driver);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ak4535_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct ak4535_setup_data *setup;
|
||||
struct snd_soc_codec *codec;
|
||||
struct ak4535_priv *ak4535;
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
|
||||
|
||||
setup = socdev->codec_data;
|
||||
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (codec == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
|
||||
if (ak4535 == NULL) {
|
||||
kfree(codec);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, ak4535);
|
||||
socdev->card->codec = codec;
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
ak4535_socdev = socdev;
|
||||
ret = -ENODEV;
|
||||
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
if (setup->i2c_address) {
|
||||
codec->hw_write = (hw_write_t)i2c_master_send;
|
||||
ret = ak4535_add_i2c_device(pdev, setup);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
kfree(snd_soc_codec_get_drvdata(codec));
|
||||
kfree(codec);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int ak4535_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
if (codec->control_data)
|
||||
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
if (codec->control_data)
|
||||
i2c_unregister_device(codec->control_data);
|
||||
i2c_del_driver(&ak4535_i2c_driver);
|
||||
#endif
|
||||
kfree(snd_soc_codec_get_drvdata(codec));
|
||||
kfree(codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ak4535 = {
|
||||
.probe = ak4535_probe,
|
||||
.remove = ak4535_remove,
|
||||
.suspend = ak4535_suspend,
|
||||
.resume = ak4535_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
|
||||
|
||||
static int __init ak4535_modinit(void)
|
||||
{
|
||||
return snd_soc_register_dai(&ak4535_dai);
|
||||
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)
|
||||
{
|
||||
snd_soc_unregister_dai(&ak4535_dai);
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
i2c_del_driver(&ak4535_i2c_driver);
|
||||
#endif
|
||||
}
|
||||
module_exit(ak4535_exit);
|
||||
|
||||
|
|
|
@ -36,12 +36,4 @@
|
|||
|
||||
#define AK4535_CACHEREGNUM 0x10
|
||||
|
||||
struct ak4535_setup_data {
|
||||
int i2c_bus;
|
||||
unsigned short i2c_address;
|
||||
};
|
||||
|
||||
extern struct snd_soc_dai ak4535_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ak4535;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#include "ak4642.h"
|
||||
|
||||
#define AK4642_VERSION "0.0.1"
|
||||
|
||||
#define PW_MGMT1 0x00
|
||||
|
@ -102,7 +100,6 @@
|
|||
#define FS3 (1 << 5)
|
||||
#define FS_MASK (FS0 | FS1 | FS2 | FS3)
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ak4642;
|
||||
|
||||
/*
|
||||
* Playback Volume (table 39)
|
||||
|
@ -123,11 +120,11 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
|
|||
|
||||
/* codec private data */
|
||||
struct ak4642_priv {
|
||||
struct snd_soc_codec codec;
|
||||
unsigned int sysclk;
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
};
|
||||
|
||||
static struct snd_soc_codec *ak4642_codec;
|
||||
|
||||
/*
|
||||
* ak4642 register cache
|
||||
*/
|
||||
|
@ -393,8 +390,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
|
|||
.hw_params = ak4642_dai_hw_params,
|
||||
};
|
||||
|
||||
struct snd_soc_dai ak4642_dai = {
|
||||
.name = "AK4642",
|
||||
static struct snd_soc_dai_driver ak4642_dai = {
|
||||
.name = "ak4642-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -410,112 +407,63 @@ struct snd_soc_dai ak4642_dai = {
|
|||
.ops = &ak4642_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ak4642_dai);
|
||||
|
||||
static int ak4642_resume(struct platform_device *pdev)
|
||||
static int ak4642_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
ak4642_sync(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialise the AK4642 driver
|
||||
* register the mixer and dsp interfaces with the kernel
|
||||
*/
|
||||
static int ak4642_init(struct ak4642_priv *ak4642)
|
||||
|
||||
static int ak4642_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_codec *codec = &ak4642->codec;
|
||||
int ret = 0;
|
||||
struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (ak4642_codec) {
|
||||
dev_err(codec->dev, "Another ak4642 is registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, ak4642);
|
||||
codec->name = "AK4642";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->read = ak4642_read_reg_cache;
|
||||
codec->write = ak4642_write;
|
||||
codec->dai = &ak4642_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->hw_write = (hw_write_t)i2c_master_send;
|
||||
codec->reg_cache_size = ARRAY_SIZE(ak4642_reg);
|
||||
codec->reg_cache = kmemdup(ak4642_reg,
|
||||
sizeof(ak4642_reg), GFP_KERNEL);
|
||||
codec->control_data = ak4642->control_data;
|
||||
|
||||
if (!codec->reg_cache)
|
||||
return -ENOMEM;
|
||||
|
||||
ak4642_dai.dev = codec->dev;
|
||||
ak4642_codec = codec;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret) {
|
||||
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
|
||||
goto reg_cache_err;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&ak4642_dai);
|
||||
if (ret) {
|
||||
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
|
||||
snd_soc_unregister_codec(codec);
|
||||
goto reg_cache_err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
reg_cache_err:
|
||||
kfree(codec->reg_cache);
|
||||
codec->reg_cache = NULL;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
|
||||
.probe = ak4642_probe,
|
||||
.resume = ak4642_resume,
|
||||
.read = ak4642_read_reg_cache,
|
||||
.write = ak4642_write,
|
||||
.reg_cache_size = ARRAY_SIZE(ak4642_reg),
|
||||
.reg_word_size = sizeof(u8),
|
||||
.reg_cache_default = ak4642_reg,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
static int ak4642_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct ak4642_priv *ak4642;
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
|
||||
if (!ak4642)
|
||||
if (ak4642 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
codec = &ak4642->codec;
|
||||
codec->dev = &i2c->dev;
|
||||
|
||||
i2c_set_clientdata(i2c, ak4642);
|
||||
codec->control_data = i2c;
|
||||
ak4642->control_data = i2c;
|
||||
ak4642->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = ak4642_init(ak4642);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "failed to initialise AK4642\n");
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&soc_codec_dev_ak4642, &ak4642_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(ak4642);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ak4642_i2c_remove(struct i2c_client *client)
|
||||
static __devexit int ak4642_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ak4642_priv *ak4642 = i2c_get_clientdata(client);
|
||||
|
||||
snd_soc_unregister_dai(&ak4642_dai);
|
||||
snd_soc_unregister_codec(&ak4642->codec);
|
||||
kfree(ak4642->codec.reg_cache);
|
||||
kfree(ak4642);
|
||||
ak4642_codec = NULL;
|
||||
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -528,64 +476,15 @@ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
|
|||
|
||||
static struct i2c_driver ak4642_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "AK4642 I2C Codec",
|
||||
.name = "ak4642-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ak4642_i2c_probe,
|
||||
.remove = ak4642_i2c_remove,
|
||||
.id_table = ak4642_i2c_id,
|
||||
.probe = ak4642_i2c_probe,
|
||||
.remove = __devexit_p(ak4642_i2c_remove),
|
||||
.id_table = ak4642_i2c_id,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static int ak4642_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
if (!ak4642_codec) {
|
||||
dev_err(&pdev->dev, "Codec device not registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
socdev->card->codec = ak4642_codec;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "ak4642: failed to create pcms\n");
|
||||
goto pcm_err;
|
||||
}
|
||||
|
||||
snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
|
||||
ARRAY_SIZE(ak4642_snd_controls));
|
||||
|
||||
dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
|
||||
return ret;
|
||||
|
||||
pcm_err:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int ak4642_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ak4642 = {
|
||||
.probe = ak4642_probe,
|
||||
.remove = ak4642_remove,
|
||||
.resume = ak4642_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
|
||||
|
||||
static int __init ak4642_modinit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* ak4642.h -- AK4642 Soc Audio driver
|
||||
*
|
||||
* Copyright (C) 2009 Renesas Solutions Corp.
|
||||
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
|
||||
*
|
||||
* Based on ak4535.c
|
||||
*
|
||||
* 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 _AK4642_H
|
||||
#define _AK4642_H
|
||||
|
||||
extern struct snd_soc_dai ak4642_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ak4642;
|
||||
|
||||
#endif
|
|
@ -23,11 +23,11 @@
|
|||
|
||||
#include "ak4671.h"
|
||||
|
||||
static struct snd_soc_codec *ak4671_codec;
|
||||
|
||||
/* codec private data */
|
||||
struct ak4671_priv {
|
||||
struct snd_soc_codec codec;
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
u8 reg_cache[AK4671_CACHEREGNUM];
|
||||
};
|
||||
|
||||
|
@ -619,8 +619,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = {
|
|||
.set_fmt = ak4671_set_dai_fmt,
|
||||
};
|
||||
|
||||
struct snd_soc_dai ak4671_dai = {
|
||||
.name = "AK4671",
|
||||
static struct snd_soc_dai_driver ak4671_dai = {
|
||||
.name = "ak4671-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -635,27 +635,19 @@ struct snd_soc_dai ak4671_dai = {
|
|||
.formats = AK4671_FORMATS,},
|
||||
.ops = &ak4671_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ak4671_dai);
|
||||
|
||||
static int ak4671_probe(struct platform_device *pdev)
|
||||
static int ak4671_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret = 0;
|
||||
struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
if (ak4671_codec == NULL) {
|
||||
dev_err(&pdev->dev, "Codec device not registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
codec->hw_write = (hw_write_t)i2c_master_send;
|
||||
codec->bias_level = SND_SOC_BIAS_OFF;
|
||||
|
||||
socdev->card->codec = ak4671_codec;
|
||||
codec = ak4671_codec;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
|
||||
goto pcm_err;
|
||||
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_soc_add_controls(codec, ak4671_snd_controls,
|
||||
|
@ -665,121 +657,48 @@ static int ak4671_probe(struct platform_device *pdev)
|
|||
ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return ret;
|
||||
|
||||
pcm_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ak4671_remove(struct platform_device *pdev)
|
||||
static int ak4671_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
|
||||
ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_ak4671 = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
|
||||
.probe = ak4671_probe,
|
||||
.remove = ak4671_remove,
|
||||
.set_bias_level = ak4671_set_bias_level,
|
||||
.reg_cache_size = AK4671_CACHEREGNUM,
|
||||
.reg_word_size = sizeof(u8),
|
||||
.reg_cache_default = ak4671_reg,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
|
||||
|
||||
static int ak4671_register(struct ak4671_priv *ak4671,
|
||||
enum snd_soc_control_type control)
|
||||
{
|
||||
int ret;
|
||||
struct snd_soc_codec *codec = &ak4671->codec;
|
||||
|
||||
if (ak4671_codec) {
|
||||
dev_err(codec->dev, "Another AK4671 is registered\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, ak4671);
|
||||
codec->name = "AK4671";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->bias_level = SND_SOC_BIAS_OFF;
|
||||
codec->set_bias_level = ak4671_set_bias_level;
|
||||
codec->dai = &ak4671_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->reg_cache_size = AK4671_CACHEREGNUM;
|
||||
codec->reg_cache = &ak4671->reg_cache;
|
||||
|
||||
memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ak4671_dai.dev = codec->dev;
|
||||
ak4671_codec = codec;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&ak4671_dai);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
|
||||
goto err_codec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_codec:
|
||||
snd_soc_unregister_codec(codec);
|
||||
err:
|
||||
kfree(ak4671);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ak4671_unregister(struct ak4671_priv *ak4671)
|
||||
{
|
||||
ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
|
||||
snd_soc_unregister_dai(&ak4671_dai);
|
||||
snd_soc_unregister_codec(&ak4671->codec);
|
||||
kfree(ak4671);
|
||||
ak4671_codec = NULL;
|
||||
}
|
||||
|
||||
static int __devinit ak4671_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct ak4671_priv *ak4671;
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
|
||||
if (ak4671 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
codec = &ak4671->codec;
|
||||
codec->hw_write = (hw_write_t)i2c_master_send;
|
||||
|
||||
i2c_set_clientdata(client, ak4671);
|
||||
codec->control_data = client;
|
||||
ak4671->control_data = client;
|
||||
ak4671->control_type = SND_SOC_I2C;
|
||||
|
||||
codec->dev = &client->dev;
|
||||
|
||||
return ak4671_register(ak4671, SND_SOC_I2C);
|
||||
ret = snd_soc_register_codec(&client->dev,
|
||||
&soc_codec_dev_ak4671, &ak4671_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(ak4671);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __devexit int ak4671_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
|
||||
|
||||
ak4671_unregister(ak4671);
|
||||
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -791,7 +710,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
|
|||
|
||||
static struct i2c_driver ak4671_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ak4671",
|
||||
.name = "ak4671-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ak4671_i2c_probe,
|
||||
|
|
|
@ -150,7 +150,4 @@
|
|||
/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
|
||||
#define AK4671_MUTEN 0x04
|
||||
|
||||
extern struct snd_soc_dai ak4671_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_ak4671;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mfd/davinci_voicecodec.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
|
@ -41,8 +42,6 @@
|
|||
|
||||
#include <mach/dm365.h>
|
||||
|
||||
#include "cq93vc.h"
|
||||
|
||||
static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
|
||||
unsigned int reg)
|
||||
{
|
||||
|
@ -130,8 +129,8 @@ static struct snd_soc_dai_ops cq93vc_dai_ops = {
|
|||
.set_sysclk = cq93vc_set_dai_sysclk,
|
||||
};
|
||||
|
||||
struct snd_soc_dai cq93vc_dai = {
|
||||
.name = "CQ93VC",
|
||||
static struct snd_soc_dai_driver cq93vc_dai = {
|
||||
.name = "cq93vc-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -146,36 +145,20 @@ struct snd_soc_dai cq93vc_dai = {
|
|||
.formats = CQ93VC_FORMATS,},
|
||||
.ops = &cq93vc_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cq93vc_dai);
|
||||
|
||||
static int cq93vc_resume(struct platform_device *pdev)
|
||||
static int cq93vc_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec *cq93vc_codec;
|
||||
|
||||
static int cq93vc_probe(struct platform_device *pdev)
|
||||
static int cq93vc_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
struct davinci_vc *davinci_vc = codec->dev->platform_data;
|
||||
|
||||
socdev->card->codec = cq93vc_codec;
|
||||
codec = socdev->card->codec;
|
||||
|
||||
/* Register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: failed to create pcms\n", pdev->name);
|
||||
return ret;
|
||||
}
|
||||
davinci_vc->cq93vc.codec = codec;
|
||||
codec->control_data = davinci_vc;
|
||||
|
||||
/* Set controls */
|
||||
snd_soc_add_controls(codec, cq93vc_snd_controls,
|
||||
|
@ -187,108 +170,51 @@ static int cq93vc_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cq93vc_remove(struct platform_device *pdev)
|
||||
static int cq93vc_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
cq93vc_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_cq93vc = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
|
||||
.read = cq93vc_read,
|
||||
.write = cq93vc_write,
|
||||
.set_bias_level = cq93vc_set_bias_level,
|
||||
.probe = cq93vc_probe,
|
||||
.remove = cq93vc_remove,
|
||||
.resume = cq93vc_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
|
||||
|
||||
static __init int cq93vc_codec_probe(struct platform_device *pdev)
|
||||
static int cq93vc_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (codec == NULL) {
|
||||
dev_dbg(davinci_vc->dev,
|
||||
"could not allocate memory for codec data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
davinci_vc->cq93vc.codec = codec;
|
||||
|
||||
cq93vc_dai.dev = &pdev->dev;
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
codec->dev = &pdev->dev;
|
||||
codec->name = "CQ93VC";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->read = cq93vc_read;
|
||||
codec->write = cq93vc_write;
|
||||
codec->set_bias_level = cq93vc_set_bias_level;
|
||||
codec->dai = &cq93vc_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->control_data = davinci_vc;
|
||||
|
||||
cq93vc_codec = codec;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret) {
|
||||
dev_err(davinci_vc->dev, "failed to register codec\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&cq93vc_dai);
|
||||
if (ret) {
|
||||
dev_err(davinci_vc->dev, "could register dai\n");
|
||||
goto fail2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
snd_soc_unregister_codec(codec);
|
||||
|
||||
fail1:
|
||||
kfree(codec);
|
||||
cq93vc_codec = NULL;
|
||||
|
||||
return ret;
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_cq93vc, &cq93vc_dai, 1);
|
||||
}
|
||||
|
||||
static int __devexit cq93vc_codec_remove(struct platform_device *pdev)
|
||||
static int cq93vc_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
snd_soc_unregister_dai(&cq93vc_dai);
|
||||
snd_soc_unregister_codec(&codec);
|
||||
|
||||
kfree(codec);
|
||||
cq93vc_codec = NULL;
|
||||
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cq93vc_codec_driver = {
|
||||
.driver = {
|
||||
.name = "cq93vc",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = cq93vc_codec_probe,
|
||||
.remove = __devexit_p(cq93vc_codec_remove),
|
||||
.name = "cq93vc-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = cq93vc_platform_probe,
|
||||
.remove = __devexit_p(cq93vc_platform_remove),
|
||||
};
|
||||
|
||||
static __init int cq93vc_init(void)
|
||||
static int __init cq93vc_init(void)
|
||||
{
|
||||
return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe);
|
||||
return platform_driver_register(&cq93vc_codec_driver);
|
||||
}
|
||||
module_init(cq93vc_init);
|
||||
|
||||
static __exit void cq93vc_exit(void)
|
||||
static void __exit cq93vc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&cq93vc_codec_driver);
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments, Inc
|
||||
*
|
||||
* Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _CQ93VC_H
|
||||
#define _CQ93VC_H
|
||||
|
||||
extern struct snd_soc_dai cq93vc_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_cq93vc;
|
||||
|
||||
#endif
|
|
@ -31,8 +31,6 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include "cs4270.h"
|
||||
|
||||
/*
|
||||
* The codec isn't really big-endian or little-endian, since the I2S
|
||||
* interface requires data to be sent serially with the MSbit first.
|
||||
|
@ -114,7 +112,8 @@ static const char *supply_names[] = {
|
|||
|
||||
/* Private data for the CS4270 */
|
||||
struct cs4270_private {
|
||||
struct snd_soc_codec codec;
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
u8 reg_cache[CS4270_NUMREGS];
|
||||
unsigned int mclk; /* Input frequency of the MCLK pin */
|
||||
unsigned int mode; /* The mode (I2S or left-justified) */
|
||||
|
@ -212,44 +211,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
|||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int rates = 0;
|
||||
unsigned int rate_min = -1;
|
||||
unsigned int rate_max = 0;
|
||||
unsigned int i;
|
||||
|
||||
cs4270->mclk = freq;
|
||||
|
||||
if (cs4270->mclk) {
|
||||
for (i = 0; i < NUM_MCLK_RATIOS; i++) {
|
||||
unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
|
||||
rates |= snd_pcm_rate_to_rate_bit(rate);
|
||||
if (rate < rate_min)
|
||||
rate_min = rate;
|
||||
if (rate > rate_max)
|
||||
rate_max = rate;
|
||||
}
|
||||
/* FIXME: soc should support a rate list */
|
||||
rates &= ~SNDRV_PCM_RATE_KNOT;
|
||||
|
||||
if (!rates) {
|
||||
dev_err(codec->dev, "could not find a valid sample rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/* enable all possible rates */
|
||||
rates = SNDRV_PCM_RATE_8000_192000;
|
||||
rate_min = 8000;
|
||||
rate_max = 192000;
|
||||
}
|
||||
|
||||
codec_dai->playback.rates = rates;
|
||||
codec_dai->playback.rate_min = rate_min;
|
||||
codec_dai->playback.rate_max = rate_max;
|
||||
|
||||
codec_dai->capture.rates = rates;
|
||||
codec_dai->capture.rate_min = rate_min;
|
||||
codec_dai->capture.rate_max = rate_max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -410,8 +373,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
@ -549,19 +511,6 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
|
|||
snd_soc_get_volsw, cs4270_soc_put_mute),
|
||||
};
|
||||
|
||||
/*
|
||||
* cs4270_codec - global variable to store codec for the ASoC probe function
|
||||
*
|
||||
* If struct i2c_driver had a private_data field, we wouldn't need to use
|
||||
* cs4270_codec. This is the only way to pass the codec structure from
|
||||
* cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
|
||||
* way to synchronize these two functions. cs4270_i2c_probe() can be called
|
||||
* multiple times before cs4270_probe() is called even once. So for now, we
|
||||
* also only allow cs4270_i2c_probe() to be run once. That means that we do
|
||||
* not support more than one cs4270 device in the system, at least for now.
|
||||
*/
|
||||
static struct snd_soc_codec *cs4270_codec;
|
||||
|
||||
static struct snd_soc_dai_ops cs4270_dai_ops = {
|
||||
.hw_params = cs4270_hw_params,
|
||||
.set_sysclk = cs4270_set_dai_sysclk,
|
||||
|
@ -569,20 +518,24 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
|
|||
.digital_mute = cs4270_dai_mute,
|
||||
};
|
||||
|
||||
struct snd_soc_dai cs4270_dai = {
|
||||
.name = "cs4270",
|
||||
struct snd_soc_dai_driver cs4270_dai = {
|
||||
.name = "cs4270-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = 0,
|
||||
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
||||
.rate_min = 4000,
|
||||
.rate_max = 216000,
|
||||
.formats = CS4270_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = 0,
|
||||
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
||||
.rate_min = 4000,
|
||||
.rate_max = 216000,
|
||||
.formats = CS4270_FORMATS,
|
||||
},
|
||||
.ops = &cs4270_dai_ops,
|
||||
|
@ -596,153 +549,19 @@ EXPORT_SYMBOL_GPL(cs4270_dai);
|
|||
* This function is called when ASoC has all the pieces it needs to
|
||||
* instantiate a sound driver.
|
||||
*/
|
||||
static int cs4270_probe(struct platform_device *pdev)
|
||||
static int cs4270_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = cs4270_codec;
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
int i, ret;
|
||||
int i, ret, reg;
|
||||
|
||||
/* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
|
||||
socdev->card->codec = codec;
|
||||
|
||||
/* Register PCMs */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to create pcms\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add the non-DAPM controls */
|
||||
ret = snd_soc_add_controls(codec, cs4270_snd_controls,
|
||||
ARRAY_SIZE(cs4270_snd_controls));
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "failed to add controls\n");
|
||||
goto error_free_pcms;
|
||||
}
|
||||
|
||||
/* get the power supply regulators */
|
||||
for (i = 0; i < ARRAY_SIZE(supply_names); i++)
|
||||
cs4270->supplies[i].supply = supply_names[i];
|
||||
|
||||
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
|
||||
cs4270->supplies);
|
||||
if (ret < 0)
|
||||
goto error_free_pcms;
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
|
||||
cs4270->supplies);
|
||||
if (ret < 0)
|
||||
goto error_free_regulators;
|
||||
|
||||
return 0;
|
||||
|
||||
error_free_regulators:
|
||||
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
|
||||
cs4270->supplies);
|
||||
|
||||
error_free_pcms:
|
||||
snd_soc_free_pcms(socdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cs4270_remove - ASoC remove function
|
||||
* @pdev: platform device
|
||||
*
|
||||
* This function is the counterpart to cs4270_probe().
|
||||
*/
|
||||
static int cs4270_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = cs4270_codec;
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
|
||||
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* cs4270_i2c_probe - initialize the I2C interface of the CS4270
|
||||
* @i2c_client: the I2C client object
|
||||
* @id: the I2C device ID (ignored)
|
||||
*
|
||||
* This function is called whenever the I2C subsystem finds a device that
|
||||
* matches the device ID given via a prior call to i2c_add_driver().
|
||||
*/
|
||||
static int cs4270_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
struct cs4270_private *cs4270;
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
||||
/* For now, we only support one cs4270 device in the system. See the
|
||||
* comment for cs4270_codec.
|
||||
*/
|
||||
if (cs4270_codec) {
|
||||
dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
|
||||
i2c_client->addr);
|
||||
dev_err(&i2c_client->dev, "only one per board allowed\n");
|
||||
/* Should we return something other than ENODEV here? */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Verify that we have a CS4270 */
|
||||
|
||||
ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
|
||||
i2c_client->addr);
|
||||
return ret;
|
||||
}
|
||||
/* The top four bits of the chip ID should be 1100. */
|
||||
if ((ret & 0xF0) != 0xC0) {
|
||||
dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
|
||||
i2c_client->addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev, "found device at i2c address %X\n",
|
||||
i2c_client->addr);
|
||||
dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
|
||||
|
||||
/* Allocate enough space for the snd_soc_codec structure
|
||||
and our private data together. */
|
||||
cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
|
||||
if (!cs4270) {
|
||||
dev_err(&i2c_client->dev, "could not allocate codec\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
codec = &cs4270->codec;
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
codec->dev = &i2c_client->dev;
|
||||
codec->name = "CS4270";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &cs4270_dai;
|
||||
codec->num_dai = 1;
|
||||
snd_soc_codec_set_drvdata(codec, cs4270);
|
||||
codec->control_data = i2c_client;
|
||||
codec->read = cs4270_read_reg_cache;
|
||||
codec->write = cs4270_i2c_write;
|
||||
codec->reg_cache = cs4270->reg_cache;
|
||||
codec->reg_cache_size = CS4270_NUMREGS;
|
||||
codec->control_data = cs4270->control_data;
|
||||
|
||||
/* The I2C interface is set up, so pre-fill our register cache */
|
||||
|
||||
ret = cs4270_fill_cache(codec);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to fill register cache\n");
|
||||
goto error_free_codec;
|
||||
dev_err(codec->dev, "failed to fill register cache\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable auto-mute. This feature appears to be buggy. In some
|
||||
|
@ -755,7 +574,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
|
|||
reg &= ~CS4270_MUTE_AUTO;
|
||||
ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "i2c write failed\n");
|
||||
dev_err(codec->dev, "i2c write failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -769,65 +588,56 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
|
|||
reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
|
||||
ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "i2c write failed\n");
|
||||
dev_err(codec->dev, "i2c write failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
|
||||
* structure for each CS4270 device, but the machine driver needs to
|
||||
* have a pointer to the DAI structure, so for now it must be a global
|
||||
* variable.
|
||||
*/
|
||||
cs4270_dai.dev = &i2c_client->dev;
|
||||
|
||||
/* Register the DAI. If all the other ASoC driver have already
|
||||
* registered, then this will call our probe function, so
|
||||
* cs4270_codec needs to be ready.
|
||||
*/
|
||||
cs4270_codec = codec;
|
||||
ret = snd_soc_register_dai(&cs4270_dai);
|
||||
/* Add the non-DAPM controls */
|
||||
ret = snd_soc_add_controls(codec, cs4270_snd_controls,
|
||||
ARRAY_SIZE(cs4270_snd_controls));
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to register DAIe\n");
|
||||
goto error_free_codec;
|
||||
dev_err(codec->dev, "failed to add controls\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c_client, cs4270);
|
||||
/* get the power supply regulators */
|
||||
for (i = 0; i < ARRAY_SIZE(supply_names); i++)
|
||||
cs4270->supplies[i].supply = supply_names[i];
|
||||
|
||||
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
|
||||
cs4270->supplies);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
|
||||
cs4270->supplies);
|
||||
if (ret < 0)
|
||||
goto error_free_regulators;
|
||||
|
||||
return 0;
|
||||
|
||||
error_free_codec:
|
||||
kfree(cs4270);
|
||||
cs4270_codec = NULL;
|
||||
cs4270_dai.dev = NULL;
|
||||
error_free_regulators:
|
||||
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
|
||||
cs4270->supplies);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cs4270_i2c_remove - remove an I2C device
|
||||
* @i2c_client: the I2C client object
|
||||
* cs4270_remove - ASoC remove function
|
||||
* @pdev: platform device
|
||||
*
|
||||
* This function is the counterpart to cs4270_i2c_probe().
|
||||
* This function is the counterpart to cs4270_probe().
|
||||
*/
|
||||
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
|
||||
static int cs4270_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
kfree(cs4270);
|
||||
cs4270_codec = NULL;
|
||||
cs4270_dai.dev = NULL;
|
||||
regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
|
||||
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* cs4270_id - I2C device IDs supported by this driver
|
||||
*/
|
||||
static struct i2c_device_id cs4270_id[] = {
|
||||
{"cs4270", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs4270_id);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
|
@ -840,9 +650,8 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
|
|||
* and all registers are written back to the hardware when resuming.
|
||||
*/
|
||||
|
||||
static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
|
||||
static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
|
||||
{
|
||||
struct snd_soc_codec *codec = cs4270_codec;
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
int reg, ret;
|
||||
|
||||
|
@ -860,9 +669,8 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cs4270_soc_resume(struct platform_device *pdev)
|
||||
static int cs4270_soc_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_codec *codec = cs4270_codec;
|
||||
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
|
||||
struct i2c_client *i2c_client = codec->control_data;
|
||||
int reg;
|
||||
|
@ -895,6 +703,95 @@ static int cs4270_soc_resume(struct platform_device *pdev)
|
|||
#define cs4270_soc_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/*
|
||||
* ASoC codec device structure
|
||||
*
|
||||
* Assign this variable to the codec_dev field of the machine driver's
|
||||
* snd_soc_device structure.
|
||||
*/
|
||||
static struct snd_soc_codec_driver soc_codec_device_cs4270 = {
|
||||
.probe = cs4270_probe,
|
||||
.remove = cs4270_remove,
|
||||
.suspend = cs4270_soc_suspend,
|
||||
.resume = cs4270_soc_resume,
|
||||
.read = cs4270_read_reg_cache,
|
||||
.write = cs4270_i2c_write,
|
||||
.reg_cache_size = CS4270_NUMREGS,
|
||||
.reg_word_size = sizeof(u8),
|
||||
};
|
||||
|
||||
/**
|
||||
* cs4270_i2c_probe - initialize the I2C interface of the CS4270
|
||||
* @i2c_client: the I2C client object
|
||||
* @id: the I2C device ID (ignored)
|
||||
*
|
||||
* This function is called whenever the I2C subsystem finds a device that
|
||||
* matches the device ID given via a prior call to i2c_add_driver().
|
||||
*/
|
||||
static int cs4270_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct cs4270_private *cs4270;
|
||||
int ret;
|
||||
|
||||
/* Verify that we have a CS4270 */
|
||||
|
||||
ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
|
||||
i2c_client->addr);
|
||||
return ret;
|
||||
}
|
||||
/* The top four bits of the chip ID should be 1100. */
|
||||
if ((ret & 0xF0) != 0xC0) {
|
||||
dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
|
||||
i2c_client->addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev, "found device at i2c address %X\n",
|
||||
i2c_client->addr);
|
||||
dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
|
||||
|
||||
cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
|
||||
if (!cs4270) {
|
||||
dev_err(&i2c_client->dev, "could not allocate codec\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c_client, cs4270);
|
||||
cs4270->control_data = i2c_client;
|
||||
cs4270->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c_client->dev,
|
||||
&soc_codec_device_cs4270, &cs4270_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(cs4270);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cs4270_i2c_remove - remove an I2C device
|
||||
* @i2c_client: the I2C client object
|
||||
*
|
||||
* This function is the counterpart to cs4270_i2c_probe().
|
||||
*/
|
||||
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
|
||||
{
|
||||
snd_soc_unregister_codec(&i2c_client->dev);
|
||||
kfree(i2c_get_clientdata(i2c_client));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* cs4270_id - I2C device IDs supported by this driver
|
||||
*/
|
||||
static struct i2c_device_id cs4270_id[] = {
|
||||
{"cs4270", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs4270_id);
|
||||
|
||||
/*
|
||||
* cs4270_i2c_driver - I2C device identification
|
||||
*
|
||||
|
@ -903,7 +800,7 @@ static int cs4270_soc_resume(struct platform_device *pdev)
|
|||
*/
|
||||
static struct i2c_driver cs4270_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs4270",
|
||||
.name = "cs4270-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.id_table = cs4270_id,
|
||||
|
@ -911,20 +808,6 @@ static struct i2c_driver cs4270_i2c_driver = {
|
|||
.remove = cs4270_i2c_remove,
|
||||
};
|
||||
|
||||
/*
|
||||
* ASoC codec device structure
|
||||
*
|
||||
* Assign this variable to the codec_dev field of the machine driver's
|
||||
* snd_soc_device structure.
|
||||
*/
|
||||
struct snd_soc_codec_device soc_codec_device_cs4270 = {
|
||||
.probe = cs4270_probe,
|
||||
.remove = cs4270_remove,
|
||||
.suspend = cs4270_soc_suspend,
|
||||
.resume = cs4270_soc_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
|
||||
|
||||
static int __init cs4270_init(void)
|
||||
{
|
||||
pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Cirrus Logic CS4270 ALSA SoC Codec Driver
|
||||
*
|
||||
* Author: Timur Tabi <timur@freescale.com>
|
||||
*
|
||||
* Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
#ifndef _CS4270_H
|
||||
#define _CS4270_H
|
||||
|
||||
/*
|
||||
* The ASoC codec DAI structure for the CS4270. Assign this structure to
|
||||
* the .codec_dai field of your machine driver's snd_soc_dai_link structure.
|
||||
*/
|
||||
extern struct snd_soc_dai cs4270_dai;
|
||||
|
||||
/*
|
||||
* The ASoC codec device structure for the CS4270. Assign this structure
|
||||
* to the .codec_dev field of your machine driver's snd_soc_device
|
||||
* structure.
|
||||
*/
|
||||
extern struct snd_soc_codec_device soc_codec_device_cs4270;
|
||||
|
||||
#endif
|
|
@ -42,15 +42,14 @@ enum master_slave_mode {
|
|||
};
|
||||
|
||||
struct cs42l51_private {
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
unsigned int mclk;
|
||||
unsigned int audio_mode; /* The mode (I2S or left-justified) */
|
||||
enum master_slave_mode func;
|
||||
struct snd_soc_codec codec;
|
||||
u8 reg_cache[CS42L51_NUMREGS];
|
||||
};
|
||||
|
||||
static struct snd_soc_codec *cs42l51_codec;
|
||||
|
||||
#define CS42L51_FORMATS ( \
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
|
||||
SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
|
||||
|
@ -75,134 +74,6 @@ static int cs42l51_fill_cache(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
struct cs42l51_private *cs42l51;
|
||||
int ret = 0;
|
||||
int reg;
|
||||
|
||||
if (cs42l51_codec)
|
||||
return -EBUSY;
|
||||
|
||||
/* Verify that we have a CS42L51 */
|
||||
ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to read I2C\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
|
||||
(ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
|
||||
dev_err(&i2c_client->dev, "Invalid chip id\n");
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
|
||||
ret & 7);
|
||||
|
||||
cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
|
||||
if (!cs42l51) {
|
||||
dev_err(&i2c_client->dev, "could not allocate codec\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
codec = &cs42l51->codec;
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
codec->dev = &i2c_client->dev;
|
||||
codec->name = "CS42L51";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &cs42l51_dai;
|
||||
codec->num_dai = 1;
|
||||
snd_soc_codec_set_drvdata(codec, cs42l51);
|
||||
|
||||
codec->control_data = i2c_client;
|
||||
codec->reg_cache = cs42l51->reg_cache;
|
||||
codec->reg_cache_size = CS42L51_NUMREGS;
|
||||
i2c_set_clientdata(i2c_client, codec);
|
||||
|
||||
ret = cs42l51_fill_cache(codec);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to fill register cache\n");
|
||||
goto error_alloc;
|
||||
}
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
|
||||
goto error_alloc;
|
||||
}
|
||||
|
||||
/*
|
||||
* DAC configuration
|
||||
* - Use signal processor
|
||||
* - auto mute
|
||||
* - vol changes immediate
|
||||
* - no de-emphasize
|
||||
*/
|
||||
reg = CS42L51_DAC_CTL_DATA_SEL(1)
|
||||
| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
|
||||
ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
|
||||
if (ret < 0)
|
||||
goto error_alloc;
|
||||
|
||||
cs42l51_dai.dev = codec->dev;
|
||||
cs42l51_codec = codec;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
|
||||
goto error_alloc;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&cs42l51_dai);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to register DAIe\n");
|
||||
goto error_reg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_reg:
|
||||
snd_soc_unregister_codec(codec);
|
||||
error_alloc:
|
||||
kfree(cs42l51);
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs42l51_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
|
||||
snd_soc_unregister_dai(&cs42l51_dai);
|
||||
snd_soc_unregister_codec(cs42l51_codec);
|
||||
cs42l51_codec = NULL;
|
||||
kfree(cs42l51);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct i2c_device_id cs42l51_id[] = {
|
||||
{"cs42l51", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
|
||||
|
||||
static struct i2c_driver cs42l51_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "CS42L51 I2C",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.id_table = cs42l51_id,
|
||||
.probe = cs42l51_i2c_probe,
|
||||
.remove = cs42l51_i2c_remove,
|
||||
};
|
||||
|
||||
static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
@ -484,51 +355,8 @@ static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
|||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
|
||||
struct cs42l51_ratios *ratios = NULL;
|
||||
int nr_ratios = 0;
|
||||
unsigned int rates = 0;
|
||||
unsigned int rate_min = -1;
|
||||
unsigned int rate_max = 0;
|
||||
int i;
|
||||
|
||||
cs42l51->mclk = freq;
|
||||
|
||||
switch (cs42l51->func) {
|
||||
case MODE_MASTER:
|
||||
return -EINVAL;
|
||||
case MODE_SLAVE:
|
||||
ratios = slave_ratios;
|
||||
nr_ratios = ARRAY_SIZE(slave_ratios);
|
||||
break;
|
||||
case MODE_SLAVE_AUTO:
|
||||
ratios = slave_auto_ratios;
|
||||
nr_ratios = ARRAY_SIZE(slave_auto_ratios);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr_ratios; i++) {
|
||||
unsigned int rate = freq / ratios[i].ratio;
|
||||
rates |= snd_pcm_rate_to_rate_bit(rate);
|
||||
if (rate < rate_min)
|
||||
rate_min = rate;
|
||||
if (rate > rate_max)
|
||||
rate_max = rate;
|
||||
}
|
||||
rates &= ~SNDRV_PCM_RATE_KNOT;
|
||||
|
||||
if (!rates) {
|
||||
dev_err(codec->dev, "could not find a valid sample rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
codec_dai->playback.rates = rates;
|
||||
codec_dai->playback.rate_min = rate_min;
|
||||
codec_dai->playback.rate_max = rate_max;
|
||||
|
||||
codec_dai->capture.rates = rates;
|
||||
codec_dai->capture.rate_min = rate_min;
|
||||
codec_dai->capture.rate_max = rate_max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -537,8 +365,7 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
@ -670,8 +497,8 @@ static struct snd_soc_dai_ops cs42l51_dai_ops = {
|
|||
.digital_mute = cs42l51_dai_mute,
|
||||
};
|
||||
|
||||
struct snd_soc_dai cs42l51_dai = {
|
||||
.name = "CS42L51 HiFi",
|
||||
static struct snd_soc_dai_driver cs42l51_dai = {
|
||||
.name = "cs42l51-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -688,30 +515,39 @@ struct snd_soc_dai cs42l51_dai = {
|
|||
},
|
||||
.ops = &cs42l51_dai_ops,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cs42l51_dai);
|
||||
|
||||
|
||||
static int cs42l51_probe(struct platform_device *pdev)
|
||||
static int cs42l51_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret = 0;
|
||||
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret, reg;
|
||||
|
||||
if (!cs42l51_codec) {
|
||||
dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
codec->control_data = cs42l51->control_data;
|
||||
|
||||
socdev->card->codec = cs42l51_codec;
|
||||
codec = socdev->card->codec;
|
||||
|
||||
/* Register PCMs */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
ret = cs42l51_fill_cache(codec);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to create PCMs\n");
|
||||
dev_err(codec->dev, "failed to fill register cache\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* DAC configuration
|
||||
* - Use signal processor
|
||||
* - auto mute
|
||||
* - vol changes immediate
|
||||
* - no de-emphasize
|
||||
*/
|
||||
reg = CS42L51_DAC_CTL_DATA_SEL(1)
|
||||
| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
|
||||
ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
snd_soc_add_controls(codec, cs42l51_snd_controls,
|
||||
ARRAY_SIZE(cs42l51_snd_controls));
|
||||
snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
|
||||
|
@ -722,22 +558,77 @@ static int cs42l51_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
|
||||
.probe = cs42l51_probe,
|
||||
.reg_cache_size = CS42L51_NUMREGS,
|
||||
.reg_word_size = sizeof(u8),
|
||||
};
|
||||
|
||||
static int cs42l51_remove(struct platform_device *pdev)
|
||||
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct cs42l51_private *cs42l51;
|
||||
int ret;
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
/* Verify that we have a CS42L51 */
|
||||
ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "failed to read I2C\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
|
||||
(ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
|
||||
dev_err(&i2c_client->dev, "Invalid chip id\n");
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
|
||||
ret & 7);
|
||||
|
||||
cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
|
||||
if (!cs42l51) {
|
||||
dev_err(&i2c_client->dev, "could not allocate codec\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c_client, cs42l51);
|
||||
cs42l51->control_data = i2c_client;
|
||||
cs42l51->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c_client->dev,
|
||||
&soc_codec_device_cs42l51, &cs42l51_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(cs42l51);
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs42l51_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
|
||||
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(cs42l51);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_device_cs42l51 = {
|
||||
.probe = cs42l51_probe,
|
||||
.remove = cs42l51_remove
|
||||
static const struct i2c_device_id cs42l51_id[] = {
|
||||
{"cs42l51", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
|
||||
|
||||
static struct i2c_driver cs42l51_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs42L51-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.id_table = cs42l51_id,
|
||||
.probe = cs42l51_i2c_probe,
|
||||
.remove = cs42l51_i2c_remove,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
|
||||
|
||||
static int __init cs42l51_init(void)
|
||||
{
|
||||
|
|
|
@ -158,6 +158,4 @@
|
|||
#define CS42L51_LASTREG 0x20
|
||||
#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
|
||||
|
||||
extern struct snd_soc_dai cs42l51_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_device_cs42l51;
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
|
||||
struct cx20442_priv {
|
||||
struct snd_soc_codec codec;
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
u8 reg_cache[1];
|
||||
};
|
||||
|
||||
|
@ -102,7 +103,7 @@ static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
|
|||
{
|
||||
u8 *reg_cache = codec->reg_cache;
|
||||
|
||||
if (reg >= codec->reg_cache_size)
|
||||
if (reg >= codec->driver->reg_cache_size)
|
||||
return -EINVAL;
|
||||
|
||||
return reg_cache[reg];
|
||||
|
@ -164,16 +165,17 @@ static int cx20442_pm_to_v253_vsp(u8 value)
|
|||
static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
|
||||
unsigned int value)
|
||||
{
|
||||
struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
|
||||
u8 *reg_cache = codec->reg_cache;
|
||||
int vls, vsp, old, len;
|
||||
char buf[18];
|
||||
|
||||
if (reg >= codec->reg_cache_size)
|
||||
if (reg >= codec->driver->reg_cache_size)
|
||||
return -EINVAL;
|
||||
|
||||
/* hw_write and control_data pointers required for talking to the modem
|
||||
* are expected to be set by the line discipline initialization code */
|
||||
if (!codec->hw_write || !codec->control_data)
|
||||
if (!codec->hw_write || !cx20442->control_data)
|
||||
return -EIO;
|
||||
|
||||
old = reg_cache[reg];
|
||||
|
@ -202,17 +204,13 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
|
|||
return -ENOMEM;
|
||||
|
||||
dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
|
||||
if (codec->hw_write(codec->control_data, buf, len) != len)
|
||||
if (codec->hw_write(cx20442->control_data, buf, len) != len)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Moved up here as line discipline referres it during initialization */
|
||||
static struct snd_soc_codec *cx20442_codec;
|
||||
|
||||
|
||||
/*
|
||||
* Line discpline related code
|
||||
*
|
||||
|
@ -228,15 +226,15 @@ static const char *v253_init = "ate0m0q0+fclass=8\r";
|
|||
/* Line discipline .open() */
|
||||
static int v253_open(struct tty_struct *tty)
|
||||
{
|
||||
struct snd_soc_codec *codec = cx20442_codec;
|
||||
int ret, len = strlen(v253_init);
|
||||
|
||||
/* Doesn't make sense without write callback */
|
||||
if (!tty->ops->write)
|
||||
return -EINVAL;
|
||||
|
||||
/* Pass the codec structure address for use by other ldisc callbacks */
|
||||
tty->disc_data = codec;
|
||||
/* Won't work if no codec pointer has been passed by a card driver */
|
||||
if (!tty->disc_data)
|
||||
return -ENODEV;
|
||||
|
||||
if (tty->ops->write(tty, v253_init, len) != len) {
|
||||
ret = -EIO;
|
||||
|
@ -253,15 +251,18 @@ err:
|
|||
static void v253_close(struct tty_struct *tty)
|
||||
{
|
||||
struct snd_soc_codec *codec = tty->disc_data;
|
||||
struct cx20442_priv *cx20442;
|
||||
|
||||
tty->disc_data = NULL;
|
||||
|
||||
if (!codec)
|
||||
return;
|
||||
|
||||
cx20442 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
/* Prevent the codec driver from further accessing the modem */
|
||||
codec->hw_write = NULL;
|
||||
codec->control_data = NULL;
|
||||
cx20442->control_data = NULL;
|
||||
codec->pop_time = 0;
|
||||
}
|
||||
|
||||
|
@ -277,15 +278,18 @@ static void v253_receive(struct tty_struct *tty,
|
|||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct snd_soc_codec *codec = tty->disc_data;
|
||||
struct cx20442_priv *cx20442;
|
||||
|
||||
if (!codec)
|
||||
return;
|
||||
|
||||
if (!codec->control_data) {
|
||||
cx20442 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (!cx20442->control_data) {
|
||||
/* First modem response, complete setup procedure */
|
||||
|
||||
/* Set up codec driver access to modem controls */
|
||||
codec->control_data = tty;
|
||||
cx20442->control_data = tty;
|
||||
codec->hw_write = (hw_write_t)tty->ops->write;
|
||||
codec->pop_time = 1;
|
||||
}
|
||||
|
@ -313,8 +317,8 @@ EXPORT_SYMBOL_GPL(v253_ops);
|
|||
* Codec DAI
|
||||
*/
|
||||
|
||||
struct snd_soc_dai cx20442_dai = {
|
||||
.name = "CX20442",
|
||||
static struct snd_soc_dai_driver cx20442_dai = {
|
||||
.name = "cx20442-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -330,142 +334,63 @@ struct snd_soc_dai cx20442_dai = {
|
|||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cx20442_dai);
|
||||
|
||||
static int cx20442_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
if (!cx20442_codec) {
|
||||
dev_err(&pdev->dev, "cx20442 not yet discovered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
codec = cx20442_codec;
|
||||
|
||||
socdev->card->codec = codec;
|
||||
|
||||
/* register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to create pcms\n");
|
||||
goto pcm_err;
|
||||
}
|
||||
|
||||
cx20442_add_widgets(codec);
|
||||
|
||||
pcm_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* power down chip */
|
||||
static int cx20442_codec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device cx20442_codec_dev = {
|
||||
.probe = cx20442_codec_probe,
|
||||
.remove = cx20442_codec_remove,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cx20442_codec_dev);
|
||||
|
||||
static int cx20442_register(struct cx20442_priv *cx20442)
|
||||
{
|
||||
struct snd_soc_codec *codec = &cx20442->codec;
|
||||
int ret;
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
codec->name = "CX20442";
|
||||
codec->owner = THIS_MODULE;
|
||||
snd_soc_codec_set_drvdata(codec, cx20442);
|
||||
|
||||
codec->dai = &cx20442_dai;
|
||||
codec->num_dai = 1;
|
||||
|
||||
codec->reg_cache = &cx20442->reg_cache;
|
||||
codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
|
||||
codec->read = cx20442_read_reg_cache;
|
||||
codec->write = cx20442_write;
|
||||
|
||||
codec->bias_level = SND_SOC_BIAS_OFF;
|
||||
|
||||
cx20442_dai.dev = codec->dev;
|
||||
|
||||
cx20442_codec = codec;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&cx20442_dai);
|
||||
if (ret != 0) {
|
||||
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
|
||||
goto err_codec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_codec:
|
||||
snd_soc_unregister_codec(codec);
|
||||
err:
|
||||
cx20442_codec = NULL;
|
||||
kfree(cx20442);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cx20442_unregister(struct cx20442_priv *cx20442)
|
||||
{
|
||||
snd_soc_unregister_dai(&cx20442_dai);
|
||||
snd_soc_unregister_codec(&cx20442->codec);
|
||||
|
||||
cx20442_codec = NULL;
|
||||
kfree(cx20442);
|
||||
}
|
||||
|
||||
static int cx20442_platform_probe(struct platform_device *pdev)
|
||||
static int cx20442_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct cx20442_priv *cx20442;
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
|
||||
if (cx20442 == NULL)
|
||||
return -ENOMEM;
|
||||
snd_soc_codec_set_drvdata(codec, cx20442);
|
||||
|
||||
codec = &cx20442->codec;
|
||||
cx20442_add_widgets(codec);
|
||||
|
||||
codec->control_data = NULL;
|
||||
cx20442->control_data = NULL;
|
||||
codec->hw_write = NULL;
|
||||
codec->pop_time = 0;
|
||||
|
||||
codec->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, cx20442);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cx20442_register(cx20442);
|
||||
/* power down chip */
|
||||
static int cx20442_codec_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (cx20442->control_data) {
|
||||
struct tty_struct *tty = cx20442->control_data;
|
||||
tty_hangup(tty);
|
||||
}
|
||||
|
||||
kfree(cx20442);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver cx20442_codec_dev = {
|
||||
.probe = cx20442_codec_probe,
|
||||
.remove = cx20442_codec_remove,
|
||||
.reg_cache_size = 1,
|
||||
.reg_word_size = sizeof(u8),
|
||||
.read = cx20442_read_reg_cache,
|
||||
.write = cx20442_write,
|
||||
};
|
||||
|
||||
static int cx20442_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&cx20442_codec_dev, &cx20442_dai, 1);
|
||||
}
|
||||
|
||||
static int __exit cx20442_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cx20442_priv *cx20442 = platform_get_drvdata(pdev);
|
||||
|
||||
cx20442_unregister(cx20442);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cx20442_platform_driver = {
|
||||
.driver = {
|
||||
.name = "cx20442",
|
||||
.name = "cx20442-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = cx20442_platform_probe,
|
||||
|
@ -487,4 +412,4 @@ module_exit(cx20442_exit);
|
|||
MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
|
||||
MODULE_AUTHOR("Janusz Krzysztofik");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:cx20442");
|
||||
MODULE_ALIAS("platform:cx20442-codec");
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#ifndef _CX20442_CODEC_H
|
||||
#define _CX20442_CODEC_H
|
||||
|
||||
extern struct snd_soc_dai cx20442_dai;
|
||||
extern struct snd_soc_codec_device cx20442_codec_dev;
|
||||
extern struct tty_ldisc_ops v253_ops;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#include "da7210.h"
|
||||
|
||||
/* DA7210 register space */
|
||||
#define DA7210_STATUS 0x02
|
||||
#define DA7210_STARTUP1 0x03
|
||||
|
@ -162,11 +160,10 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
|
|||
|
||||
/* Codec private data */
|
||||
struct da7210_priv {
|
||||
struct snd_soc_codec codec;
|
||||
enum snd_soc_control_type control_type;
|
||||
void *control_data;
|
||||
};
|
||||
|
||||
static struct snd_soc_codec *da7210_codec;
|
||||
|
||||
/*
|
||||
* Register cache
|
||||
*/
|
||||
|
@ -209,12 +206,12 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
|
|||
u8 *cache = codec->reg_cache;
|
||||
u8 data[2];
|
||||
|
||||
BUG_ON(codec->volatile_register);
|
||||
BUG_ON(codec->driver->volatile_register);
|
||||
|
||||
data[0] = reg & 0xff;
|
||||
data[1] = value & 0xff;
|
||||
|
||||
if (reg >= codec->reg_cache_size)
|
||||
if (reg >= codec->driver->reg_cache_size)
|
||||
return -EIO;
|
||||
|
||||
if (2 != codec->hw_write(codec->control_data, data, 2))
|
||||
|
@ -267,8 +264,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
u32 dai_cfg1;
|
||||
u32 hpf_reg, hpf_mask, hpf_value;
|
||||
u32 fs, bypass;
|
||||
|
@ -430,9 +426,8 @@ static struct snd_soc_dai_ops da7210_dai_ops = {
|
|||
.set_fmt = da7210_set_dai_fmt,
|
||||
};
|
||||
|
||||
struct snd_soc_dai da7210_dai = {
|
||||
.name = "DA7210 IIS",
|
||||
.id = 0,
|
||||
static struct snd_soc_dai_driver da7210_dai = {
|
||||
.name = "da7210-hifi",
|
||||
/* playback capabilities */
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
|
@ -452,55 +447,15 @@ struct snd_soc_dai da7210_dai = {
|
|||
.ops = &da7210_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(da7210_dai);
|
||||
|
||||
/*
|
||||
* Initialize the DA7210 driver
|
||||
* register the mixer and dsp interfaces with the kernel
|
||||
*/
|
||||
static int da7210_init(struct da7210_priv *da7210)
|
||||
static int da7210_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_codec *codec = &da7210->codec;
|
||||
int ret = 0;
|
||||
struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (da7210_codec) {
|
||||
dev_err(codec->dev, "Another da7210 is registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, da7210);
|
||||
codec->name = "DA7210";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->read = da7210_read;
|
||||
codec->write = da7210_write;
|
||||
codec->dai = &da7210_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->control_data = da7210->control_data;
|
||||
codec->hw_write = (hw_write_t)i2c_master_send;
|
||||
codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
|
||||
codec->reg_cache = kmemdup(da7210_reg,
|
||||
sizeof(da7210_reg), GFP_KERNEL);
|
||||
|
||||
if (!codec->reg_cache)
|
||||
return -ENOMEM;
|
||||
|
||||
da7210_dai.dev = codec->dev;
|
||||
da7210_codec = codec;
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
if (ret) {
|
||||
dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
|
||||
goto init_err;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&da7210_dai);
|
||||
if (ret) {
|
||||
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
|
||||
goto codec_err;
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
*
|
||||
|
@ -583,54 +538,50 @@ static int da7210_init(struct da7210_priv *da7210)
|
|||
/* Activate all enabled subsystem */
|
||||
da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
|
||||
|
||||
return ret;
|
||||
snd_soc_add_controls(codec, da7210_snd_controls,
|
||||
ARRAY_SIZE(da7210_snd_controls));
|
||||
|
||||
codec_err:
|
||||
snd_soc_unregister_codec(codec);
|
||||
init_err:
|
||||
kfree(codec->reg_cache);
|
||||
codec->reg_cache = NULL;
|
||||
|
||||
return ret;
|
||||
dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
|
||||
.probe = da7210_probe,
|
||||
.read = da7210_read,
|
||||
.write = da7210_write,
|
||||
.reg_cache_size = ARRAY_SIZE(da7210_reg),
|
||||
.reg_word_size = sizeof(u8),
|
||||
.reg_cache_default = da7210_reg,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
|
||||
static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct da7210_priv *da7210;
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
|
||||
if (!da7210)
|
||||
return -ENOMEM;
|
||||
|
||||
codec = &da7210->codec;
|
||||
codec->dev = &i2c->dev;
|
||||
|
||||
i2c_set_clientdata(i2c, da7210);
|
||||
codec->control_data = i2c;
|
||||
da7210->control_data = i2c;
|
||||
da7210->control_type = SND_SOC_I2C;
|
||||
|
||||
ret = da7210_init(da7210);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to initialise da7210 audio codec\n");
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&soc_codec_dev_da7210, &da7210_dai, 1);
|
||||
if (ret < 0)
|
||||
kfree(da7210);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit da7210_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct da7210_priv *da7210 = i2c_get_clientdata(client);
|
||||
|
||||
snd_soc_unregister_dai(&da7210_dai);
|
||||
kfree(da7210->codec.reg_cache);
|
||||
kfree(da7210);
|
||||
da7210_codec = NULL;
|
||||
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
kfree(i2c_get_clientdata(client));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -643,7 +594,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
|
|||
/* I2C codec control layer */
|
||||
static struct i2c_driver da7210_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "DA7210 I2C Codec",
|
||||
.name = "da7210-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = da7210_i2c_probe,
|
||||
|
@ -652,50 +603,6 @@ static struct i2c_driver da7210_i2c_driver = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static int da7210_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
int ret;
|
||||
|
||||
if (!da7210_codec) {
|
||||
dev_err(&pdev->dev, "Codec device not registered\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
socdev->card->codec = da7210_codec;
|
||||
codec = da7210_codec;
|
||||
|
||||
/* Register pcms */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0)
|
||||
goto pcm_err;
|
||||
|
||||
snd_soc_add_controls(da7210_codec, da7210_snd_controls,
|
||||
ARRAY_SIZE(da7210_snd_controls));
|
||||
|
||||
dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
|
||||
|
||||
pcm_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da7210_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_da7210 = {
|
||||
.probe = da7210_probe,
|
||||
.remove = da7210_remove,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
|
||||
|
||||
static int __init da7210_modinit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* da7210.h -- audio driver for da7210
|
||||
*
|
||||
* Copyright (c) 2009 Dialog Semiconductor
|
||||
* Written by David Chen <Dajun.chen@diasemi.com>
|
||||
*
|
||||
* Copyright (C) 2009 Renesas Solutions Corp.
|
||||
* Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DA7210_H
|
||||
#define _DA7210_H
|
||||
|
||||
extern struct snd_soc_dai da7210_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_da7210;
|
||||
|
||||
#endif
|
||||
|
|
@ -74,29 +74,22 @@ static const uint32_t jz4740_codec_regs[] = {
|
|||
struct jz4740_codec {
|
||||
void __iomem *base;
|
||||
struct resource *mem;
|
||||
|
||||
uint32_t reg_cache[2];
|
||||
struct snd_soc_codec codec;
|
||||
};
|
||||
|
||||
static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
|
||||
{
|
||||
return container_of(codec, struct jz4740_codec, codec);
|
||||
}
|
||||
|
||||
static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
|
||||
unsigned int reg)
|
||||
{
|
||||
struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
|
||||
struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
|
||||
return readl(jz4740_codec->base + (reg << 2));
|
||||
}
|
||||
|
||||
static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
|
||||
struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
|
||||
u32 *cache = codec->reg_cache;
|
||||
|
||||
jz4740_codec->reg_cache[reg] = val;
|
||||
cache[reg] = val;
|
||||
writel(val, jz4740_codec->base + (reg << 2));
|
||||
|
||||
return 0;
|
||||
|
@ -172,8 +165,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
uint32_t val;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_device *socdev = rtd->socdev;
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct snd_soc_codec *codec =rtd->codec;
|
||||
|
||||
switch (params_rate(params)) {
|
||||
case 8000:
|
||||
|
@ -219,8 +211,8 @@ static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
|
|||
.hw_params = jz4740_codec_hw_params,
|
||||
};
|
||||
|
||||
struct snd_soc_dai jz4740_codec_dai = {
|
||||
.name = "jz4740",
|
||||
static struct snd_soc_dai_driver jz4740_codec_dai = {
|
||||
.name = "jz4740-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
|
@ -238,7 +230,6 @@ struct snd_soc_dai jz4740_codec_dai = {
|
|||
.ops = &jz4740_codec_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(jz4740_codec_dai);
|
||||
|
||||
static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
|
||||
{
|
||||
|
@ -302,23 +293,10 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec *jz4740_codec_codec;
|
||||
|
||||
static int jz4740_codec_dev_probe(struct platform_device *pdev)
|
||||
static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
int ret;
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = jz4740_codec_codec;
|
||||
|
||||
BUG_ON(!codec);
|
||||
|
||||
socdev->card->codec = codec;
|
||||
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
|
||||
JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
|
||||
|
||||
snd_soc_add_controls(codec, jz4740_codec_controls,
|
||||
ARRAY_SIZE(jz4740_codec_controls));
|
||||
|
@ -331,34 +309,27 @@ static int jz4740_codec_dev_probe(struct platform_device *pdev)
|
|||
|
||||
snd_soc_dapm_new_widgets(codec);
|
||||
|
||||
jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz4740_codec_dev_remove(struct platform_device *pdev)
|
||||
static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_free_pcms(socdev);
|
||||
snd_soc_dapm_free(socdev);
|
||||
jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
}
|
||||
|
||||
static int jz4740_codec_resume(struct platform_device *pdev)
|
||||
static int jz4740_codec_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
|
||||
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
}
|
||||
|
||||
|
@ -367,19 +338,23 @@ static int jz4740_codec_resume(struct platform_device *pdev)
|
|||
#define jz4740_codec_resume NULL
|
||||
#endif
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_jz4740_codec = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
|
||||
.probe = jz4740_codec_dev_probe,
|
||||
.remove = jz4740_codec_dev_remove,
|
||||
.suspend = jz4740_codec_suspend,
|
||||
.resume = jz4740_codec_resume,
|
||||
.read = jz4740_codec_read,
|
||||
.write = jz4740_codec_write,
|
||||
.set_bias_level = jz4740_codec_set_bias_level,
|
||||
.reg_cache_default = jz4740_codec_regs,
|
||||
.reg_word_size = sizeof(u32),
|
||||
.reg_cache_size = 2,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
|
||||
|
||||
static int __devinit jz4740_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct jz4740_codec *jz4740_codec;
|
||||
struct snd_soc_codec *codec;
|
||||
struct resource *mem;
|
||||
|
||||
jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
|
||||
|
@ -408,55 +383,17 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev)
|
|||
}
|
||||
jz4740_codec->mem = mem;
|
||||
|
||||
jz4740_codec_dai.dev = &pdev->dev;
|
||||
|
||||
codec = &jz4740_codec->codec;
|
||||
|
||||
codec->dev = &pdev->dev;
|
||||
codec->name = "jz4740";
|
||||
codec->owner = THIS_MODULE;
|
||||
|
||||
codec->read = jz4740_codec_read;
|
||||
codec->write = jz4740_codec_write;
|
||||
codec->set_bias_level = jz4740_codec_set_bias_level;
|
||||
codec->bias_level = SND_SOC_BIAS_OFF;
|
||||
|
||||
codec->dai = &jz4740_codec_dai;
|
||||
codec->num_dai = 1;
|
||||
|
||||
codec->reg_cache = jz4740_codec->reg_cache;
|
||||
codec->reg_cache_size = 2;
|
||||
memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
|
||||
|
||||
mutex_init(&codec->mutex);
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
jz4740_codec_codec = codec;
|
||||
|
||||
snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
|
||||
JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
|
||||
|
||||
platform_set_drvdata(pdev, jz4740_codec);
|
||||
|
||||
ret = snd_soc_register_codec(codec);
|
||||
ret = snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register codec\n");
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_dai(&jz4740_codec_dai);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register codec dai\n");
|
||||
goto err_unregister_codec;
|
||||
}
|
||||
|
||||
jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_codec:
|
||||
snd_soc_unregister_codec(codec);
|
||||
err_iounmap:
|
||||
iounmap(jz4740_codec->base);
|
||||
err_release_mem_region:
|
||||
|
@ -472,8 +409,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev)
|
|||
struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
|
||||
struct resource *mem = jz4740_codec->mem;
|
||||
|
||||
snd_soc_unregister_dai(&jz4740_codec_dai);
|
||||
snd_soc_unregister_codec(&jz4740_codec->codec);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
|
||||
iounmap(jz4740_codec->base);
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009, 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 version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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 __SND_SOC_CODECS_JZ4740_CODEC_H__
|
||||
#define __SND_SOC_CODECS_JZ4740_CODEC_H__
|
||||
|
||||
extern struct snd_soc_dai jz4740_codec_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
|
||||
|
||||
#endif
|
|
@ -32,8 +32,8 @@
|
|||
#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
|
||||
SNDRV_PCM_RATE_48000)
|
||||
|
||||
struct snd_soc_dai pcm3008_dai = {
|
||||
.name = "PCM3008 HiFi",
|
||||
static struct snd_soc_dai_driver pcm3008_dai = {
|
||||
.name = "pcm3008-hifi",
|
||||
.playback = {
|
||||
.stream_name = "PCM3008 Playback",
|
||||
.channels_min = 1,
|
||||
|
@ -49,7 +49,6 @@ struct snd_soc_dai pcm3008_dai = {
|
|||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(pcm3008_dai);
|
||||
|
||||
static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
|
||||
{
|
||||
|
@ -59,38 +58,13 @@ static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
|
|||
gpio_free(setup->pdda_pin);
|
||||
}
|
||||
|
||||
static int pcm3008_soc_probe(struct platform_device *pdev)
|
||||
static int pcm3008_soc_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec;
|
||||
struct pcm3008_setup_data *setup = socdev->codec_data;
|
||||
struct pcm3008_setup_data *setup = codec->dev->platform_data;
|
||||
int ret = 0;
|
||||
|
||||
printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
|
||||
|
||||
socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
|
||||
if (!socdev->card->codec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec = socdev->card->codec;
|
||||
mutex_init(&codec->mutex);
|
||||
|
||||
codec->name = "PCM3008";
|
||||
codec->owner = THIS_MODULE;
|
||||
codec->dai = &pcm3008_dai;
|
||||
codec->num_dai = 1;
|
||||
codec->write = NULL;
|
||||
codec->read = NULL;
|
||||
INIT_LIST_HEAD(&codec->dapm_widgets);
|
||||
INIT_LIST_HEAD(&codec->dapm_paths);
|
||||
|
||||
/* Register PCMs. */
|
||||
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "pcm3008: failed to create pcms\n");
|
||||
goto pcm_err;
|
||||
}
|
||||
|
||||
/* DEM1 DEM0 DE-EMPHASIS_MODE
|
||||
* Low Low De-emphasis 44.1 kHz ON
|
||||
* Low High De-emphasis OFF
|
||||
|
@ -130,33 +104,22 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
|
|||
|
||||
gpio_err:
|
||||
pcm3008_gpio_free(setup);
|
||||
pcm_err:
|
||||
kfree(socdev->card->codec);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pcm3008_soc_remove(struct platform_device *pdev)
|
||||
static int pcm3008_soc_remove(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct snd_soc_codec *codec = socdev->card->codec;
|
||||
struct pcm3008_setup_data *setup = socdev->codec_data;
|
||||
|
||||
if (!codec)
|
||||
return 0;
|
||||
struct pcm3008_setup_data *setup = codec->dev->platform_data;
|
||||
|
||||
pcm3008_gpio_free(setup);
|
||||
snd_soc_free_pcms(socdev);
|
||||
kfree(socdev->card->codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
|
||||
static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct pcm3008_setup_data *setup = socdev->codec_data;
|
||||
struct pcm3008_setup_data *setup = codec->dev->platform_data;
|
||||
|
||||
gpio_set_value(setup->pdad_pin, 0);
|
||||
gpio_set_value(setup->pdda_pin, 0);
|
||||
|
@ -164,10 +127,9 @@ static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pcm3008_soc_resume(struct platform_device *pdev)
|
||||
static int pcm3008_soc_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
|
||||
struct pcm3008_setup_data *setup = socdev->codec_data;
|
||||
struct pcm3008_setup_data *setup = codec->dev->platform_data;
|
||||
|
||||
gpio_set_value(setup->pdad_pin, 1);
|
||||
gpio_set_value(setup->pdda_pin, 1);
|
||||
|
@ -179,23 +141,45 @@ static int pcm3008_soc_resume(struct platform_device *pdev)
|
|||
#define pcm3008_soc_resume NULL
|
||||
#endif
|
||||
|
||||
struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
|
||||
static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
|
||||
.probe = pcm3008_soc_probe,
|
||||
.remove = pcm3008_soc_remove,
|
||||
.suspend = pcm3008_soc_suspend,
|
||||
.resume = pcm3008_soc_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
|
||||
|
||||
static int __init pcm3008_init(void)
|
||||
static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_dai(&pcm3008_dai);
|
||||
return snd_soc_register_codec(&pdev->dev,
|
||||
&soc_codec_dev_pcm3008, &pcm3008_dai, 1);
|
||||
}
|
||||
module_init(pcm3008_init);
|
||||
|
||||
static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_ALIAS("platform:pcm3008-codec");
|
||||
|
||||
static struct platform_driver pcm3008_codec_driver = {
|
||||
.probe = pcm3008_codec_probe,
|
||||
.remove = __devexit_p(pcm3008_codec_remove),
|
||||
.driver = {
|
||||
.name = "pcm3008-codec",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init pcm3008_modinit(void)
|
||||
{
|
||||
return platform_driver_register(&pcm3008_codec_driver);
|
||||
}
|
||||
module_init(pcm3008_modinit);
|
||||
|
||||
static void __exit pcm3008_exit(void)
|
||||
{
|
||||
snd_soc_unregister_dai(&pcm3008_dai);
|
||||
platform_driver_unregister(&pcm3008_codec_driver);
|
||||
}
|
||||
module_exit(pcm3008_exit);
|
||||
|
||||
|
|
|
@ -19,7 +19,4 @@ struct pcm3008_setup_data {
|
|||
unsigned pdda_pin;
|
||||
};
|
||||
|
||||
extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
|
||||
extern struct snd_soc_dai pcm3008_dai;
|
||||
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue