Commit f0fba2ad authored by Liam Girdwood's avatar Liam Girdwood

ASoC: multi-component - ASoC Multi-Component Support

This patch extends the ASoC API to allow sound cards to have more than one
CODEC and more than one platform DMA controller. This is achieved by dividing
some current ASoC structures that contain both driver data and device data into
structures that only either contain device data or driver data. i.e.

 struct snd_soc_codec    --->  struct snd_soc_codec (device data)
                          +->  struct snd_soc_codec_driver (driver data)

 struct snd_soc_platform --->  struct snd_soc_platform (device data)
                          +->  struct snd_soc_platform_driver (driver data)

 struct snd_soc_dai      --->  struct snd_soc_dai (device data)
                          +->  struct snd_soc_dai_driver (driver data)

 struct snd_soc_device   --->  deleted

This now allows ASoC to be more tightly aligned with the Linux driver model and
also means that every ASoC codec, platform and (platform) DAI is a kernel
device. ASoC component private data is now stored as device private data.

The ASoC sound card struct snd_soc_card has also been updated to store lists
of it's components rather than a pointer to a codec and platform. The PCM
runtime struct soc_pcm_runtime now has pointers to all its components.

This patch adds DAPM support for ASoC multi-component and removes struct
snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec
or runtime PCM level basis rather than using snd_soc_socdev.

Other notable multi-component changes:-

 * Stream operations now de-reference less structures.
 * close_delayed work() now runs on a DAI basis rather than looping all DAIs
   in a card.
 * PM suspend()/resume() operations can now handle N CODECs and Platforms
   per sound card.
 * Added soc_bind_dai_link() to bind the component devices to the sound card.
 * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove
   DAI link components.
 * sysfs entries can now be registered per component per card.
 * snd_soc_new_pcms() functionailty rolled into dai_link_probe().
 * snd_soc_register_codec() now does all the codec list and mutex init.

This patch changes the probe() and remove() of the CODEC drivers as follows:-

 o Make CODEC driver a platform driver
 o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core.
 o Removed all static codec pointers (drivers now support > 1 codec dev)
 o snd_soc_register_pcms() now done by core.
 o snd_soc_register_dai() folded into snd_soc_register_codec().

CS4270 portions:
Acked-by: default avatarTimur Tabi <timur@freescale.com>

Some TLV320aic23 and Cirrus platform fixes.
Signed-off-by: default avatarRyan Mallon <ryan@bluewatersys.com>

TI CODEC and OMAP fixes
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: default avatarJanusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Signed-off-by: default avatarJarkko Nikula <jhnikula@gmail.com>

Samsung platform and misc fixes :-
Signed-off-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: default avatarJoonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: default avatarJassi Brar <jassi.brar@samsung.com>
Signed-off-by: default avatarSeungwhan Youn <sw.youn@samsung.com>

MPC8610 and PPC fixes.
Signed-off-by: default avatarTimur Tabi <timur@freescale.com>

i.MX fixes and some core fixes.
Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>

J4740 platform fixes:-
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>

CC: Tony Lindgren <tony@atomide.com>
CC: Nicolas Ferre <nicolas.ferre@atmel.com>
CC: Kevin Hilman <khilman@deeprootsystems.com>
CC: Sascha Hauer <s.hauer@pengutronix.de>
CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
CC: Kuninori Morimoto <morimoto.kuninori@renesas.com>
CC: Daniel Gloeckner <dg@emlix.com>
CC: Manuel Lauss <mano@roarinelk.homelinux.net>
CC: Mike Frysinger <vapier.adi@gmail.com>
CC: Arnaud Patard <apatard@mandriva.com>
CC: Wan ZongShun <mcuos.com@gmail.com>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent bda7d2a8
......@@ -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,
};
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,
},
};
#endif
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;
......
......@@ -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);
......
/*
* 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_ */
This diff is collapsed.
......@@ -10,8 +10,49 @@
#ifndef __TLV320AIC3x_H__
#define __TLV320AIC3x_H__
/* 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
};
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
\ No newline at end of file
#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(&pdev->dev, &atmel_soc_platform);
}
static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
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 snd_soc_register_platform(&atmel_soc_platform);
return platform_driver_register(&atmel_pcm_driver);
}
module_init(atmel_pcm_modinit);
module_init(snd_atmel_pcm_init);
static void __exit atmel_pcm_modexit(void)
static void __exit snd_atmel_pcm_exit(void)
{
snd_soc_unregister_platform(&atmel_soc_platform);
platform_driver_unregister(&atmel_pcm_driver);
}
module_exit(atmel_pcm_modexit);
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(&pdev->dev, atmel_ssc_dai,
ARRAY_SIZE(atmel_ssc_dai));
}
static int __devexit asoc_ssc_remove(struct platform_device *pdev)
{
snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(atmel_ssc_dai));
return 0;
}
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 snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
return platform_driver_register(&asoc_ssc_driver);
}
module_init(atmel_ssc_modinit);
module_init(snd_atmel_ssc_init);
static void __exit atmel_ssc_modexit(void)
static void __exit snd_atmel_ssc_exit(void)
{
snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
platform_driver_unregister(&asoc_ssc_driver);
}
module_exit(atmel_ssc_modexit);
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 @@ static int __init playpaq_asoc_init(void)
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 @@ static int __init at91sam9g20ek_init(void)
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;
}
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(bfin_ac97_exit);
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 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
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;
}
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(bfin_i2s_exit);
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 */
......
/*
* 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 @@ static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
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;
}
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(bfin_pcm_tdm_exit);
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 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
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");
......
/*
* 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);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
/* reset clock control mode */
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
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,100 +320,6 @@ 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)
{
struct snd_soc_codec *codec;
struct ad193x_priv *ad193x;
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);
else
ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
kfree(ad193x);
return ret;
}
/* default setting for ad193x */
/* unmute dac channels */
snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
/* de-emphasis: 48kHz, powedown dac */
snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
/* powerdown dac, dac in tdm mode */
snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
/* high-pass filter enable */
snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
/* sata delay=1, adc aux mode */
snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
/* 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,
......@@ -426,8 +329,8 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
};
/* codec DAI instance */
struct snd_soc_dai ad193x_dai = {
.name = "AD193X",
static struct snd_soc_dai_driver ad193x_dai = {
.name = "ad193x-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
......@@ -446,28 +349,39 @@ struct snd_soc_dai ad193x_dai = {
},
.ops = &ad193x_dai_ops,
};
EXPORT_SYMBOL_GPL(ad193x_dai);
static int ad193x_probe(struct platform_device *pdev)
static int ad193x_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
int ret;
if (ad193x_codec == NULL) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
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, ad193x->bus_type);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
kfree(ad193x);
return ret;
}
socdev->card->codec = ad193x_codec;
codec = ad193x_codec;
/* default setting for ad193x */
/* 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;
}
/* unmute dac channels */
snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
/* de-emphasis: 48kHz, powedown dac */
snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
/* powerdown dac, dac in tdm mode */
snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
/* high-pass filter enable */
snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
/* sata delay=1, adc aux mode */
snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
/* 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);
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 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
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)
{
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;
static struct snd_soc_codec_driver soc_codec_dev_ad73311;
pcm_err:
kfree(socdev->card->codec);
socdev->card->codec = NULL;
return ret;
static int ad73311_probe(struct platform_device *pdev)
{
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)
{
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;
}
static int 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 struct snd_soc_codec_driver soc_codec_dev_ads117x;
static __devinit int ads117x_platform_probe(struct platform_device *pdev)
static __devinit int ads117x_probe(struct platform_device *pdev)
{
ads117x_dai.dev = &pdev->dev;
return snd_soc_register_dai(&ads117x_dai);
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_ads117x, &ads117x_dai, 1);
}
static int __devexit ads117x_platform_remove(struct platform_device *pdev)
static int __devexit ads117x_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,45 +189,17 @@ struct snd_soc_dai ak4104_dai = {
.ops = &ak4101_dai_ops,
};
static struct snd_soc_codec *ak4104_codec;
static int ak4104_spi_probe(struct spi_device *spi)
static int ak4104_probe(struct snd_soc_codec *codec)
{
struct snd_soc_codec *codec;
struct ak4104_private *ak4104;
struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
int ret, val;
spi->bits_per_word = 8;
spi->mode = SPI_MODE_0;
ret = spi_setup(spi);
if (ret < 0)
return ret;
ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
if (!ak4104) {
dev_err(&spi->dev, "could not allocate codec\n");
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;
codec->control_data = ak4104->control_data;
/* 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");
dev_err(codec->dev, "failed to fill register cache\n");
return ret;
}
......@@ -238,93 +207,81 @@ static int ak4104_spi_probe(struct spi_device *spi)
* 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;
}
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)
goto error_free_codec;
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)
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;
}
return ret;
spi_set_drvdata(spi, ak4104);
dev_info(&spi->dev, "SPI device initialized\n");
dev_info(codec->dev, "SPI device initialized\n");
return 0;
error_free_codec:
kfree(ak4104);
ak4104_dai.dev = NULL;
return ret;
}
static int __devexit ak4104_spi_remove(struct spi_device *spi)
static int ak4104_remove(struct snd_soc_codec *codec)
{
int ret, val;
struct ak4104_private *ak4104 = spi_get_drvdata(spi);
int val, ret;
val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1);
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(&ak4104->codec, AK4104_REG_CONTROL1, val);
if (ret < 0)
return ret;
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
ak4104_codec = NULL;
kfree(ak4104);
return 0;
return ret;
}
static int ak4104_probe(struct platform_device *pdev)
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_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = ak4104_codec;
struct ak4104_private *ak4104;
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");
spi->bits_per_word = 8;
spi->mode = SPI_MODE_0;
ret = spi_setup(spi);
if (ret < 0)
return ret;
}
return 0;
ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
if (ak4104 == NULL)
return -ENOMEM;
ak4104->control_data = spi;
ak4104->control_type = SND_SOC_SPI;
spi_set_drvdata(spi, ak4104);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_device_ak4104, &ak4104_dai, 1);
if (ret < 0)
kfree(ak4104);
return ret;
}
static int ak4104_remove(struct platform_device *pdev)
static int __devexit ak4104_spi_remove(struct spi_device *spi)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_unregister_codec(&spi->dev);
kfree(spi_get_drvdata(spi));
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 = {
......
#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);
if (codec->reg_cache == NULL)
return -ENOMEM;
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
/* 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 0;
}
return ret;
/* 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_device *ak4535_socdev;
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);
if (ret < 0)
printk(KERN_ERR "failed to initialise AK4535\n");
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)
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)
static int __init ak4535_modinit(void)
{
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;
int ret = 0;
#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
ret = i2c_add_driver(&ak4535_i2c_driver);
if (ret != 0) {
kfree(snd_soc_codec_get_drvdata(codec));
kfree(codec);
printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
ret);
}
#endif
return ret;
}
module_init(ak4535_modinit);
/* power down chip */
static int ak4535_remove(struct platform_device *pdev)
static void __exit ak4535_exit(void)
{
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);
}
module_init(ak4535_modinit);
static void __exit ak4535_exit(void)
{
snd_soc_unregister_dai(&ak4535_dai);
}
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);
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;
}
codec->control_data = ak4642->control_data;
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;
......
/*
* 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
This diff is collapsed.
......@@ -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
This diff is collapsed.
/*
* 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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment