Merge branch 'topic/multi-component' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into for-2.6.37

This commit is contained in:
Mark Brown 2010-08-12 14:40:28 +01:00
commit cf7af01aa7
340 changed files with 9495 additions and 13645 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -34,8 +35,11 @@ static void __init omap_zoom2_init_irq(void)
omap_gpio_init();
}
/* REVISIT: These audio entries can be removed once MFD code is merged */
#if 0
/* EXTMUTE callback function */
void zoom2_set_hs_extmute(int mute)
{
gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
}
static struct twl4030_madc_platform_data zoom2_madc_data = {
.irq_line = 1,
@ -43,6 +47,9 @@ static struct twl4030_madc_platform_data zoom2_madc_data = {
static struct twl4030_codec_audio_data zoom2_audio_data = {
.audio_mclk = 26000000,
.ramp_delay_value = 3, /* 161 ms */
.hs_extmute = 1,
.set_hs_extmute = zoom2_set_hs_extmute,
};
static struct twl4030_codec_data zoom2_codec_data = {
@ -64,10 +71,24 @@ static struct twl4030_platform_data zoom2_twldata = {
.vmmc1 = &zoom2_vmmc1,
.vmmc2 = &zoom2_vmmc2,
.vsim = &zoom2_vsim,
};
#endif
static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
.irq = INT_34XX_SYS_NIRQ,
.platform_data = &zoom2_twldata,
},
};
static int __init omap3_zoom2_i2c_init(void)
{
omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo,
ARRAY_SIZE(zoom2_i2c_boardinfo));
return 0;
}
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
@ -81,6 +102,7 @@ static void __init omap_zoom2_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
zoom_peripherals_init();
omap3_zoom2_i2c_init();
zoom_debugboard_init();
}

View File

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

View File

@ -3,3 +3,5 @@
*/
extern int __init zoom_debugboard_init(void);
extern void __init zoom_peripherals_init(void);
#define ZOOM2_HEADSET_EXTMUTE_GPIO 153

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -286,6 +286,7 @@
ssi@16100 {
compatible = "fsl,mpc8610-ssi";
status = "disabled";
cell-index = <1>;
reg = <0x16100 0x100>;
interrupt-parent = <&mpic>;

View File

@ -1,5 +1,5 @@
/**
* MPC86xx Internal Memory Map
* Freecale 85xx and 86xx Global Utilties register set
*
* Authors: Jeff Brown
* Timur Tabi <timur@freescale.com>
@ -10,73 +10,112 @@
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This header file defines structures for various 86xx SOC devices that are
* used by multiple source files.
*/
#ifndef __ASM_POWERPC_IMMAP_86XX_H__
#define __ASM_POWERPC_IMMAP_86XX_H__
#ifndef __ASM_POWERPC_FSL_GUTS_H__
#define __ASM_POWERPC_FSL_GUTS_H__
#ifdef __KERNEL__
/* Global Utility Registers */
struct ccsr_guts {
/*
* These #ifdefs are safe because it's not possible to build a kernel that
* runs on e500 and e600 cores.
*/
#if !defined(CONFIG_PPC_85xx) && !defined(CONFIG_PPC_86xx)
#error Only 85xx and 86xx SOCs are supported
#endif
/**
* Global Utility Registers.
*
* Not all registers defined in this structure are available on all chips, so
* you are expected to know whether a given register actually exists on your
* chip before you access it.
*
* Also, some registers are similar on different chips but have slightly
* different names. In these cases, one name is chosen to avoid extraneous
* #ifdefs.
*/
#ifdef CONFIG_PPC_85xx
struct ccsr_guts_85xx {
#else
struct ccsr_guts_86xx {
#endif
__be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
__be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
__be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
__be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
__be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
u8 res1[0x20 - 0x14];
__be32 pordevsr2; /* 0x.0014 - POR device status register 2 */
u8 res018[0x20 - 0x18];
__be32 porcir; /* 0x.0020 - POR Configuration Information Register */
u8 res2[0x30 - 0x24];
u8 res024[0x30 - 0x24];
__be32 gpiocr; /* 0x.0030 - GPIO Control Register */
u8 res3[0x40 - 0x34];
u8 res034[0x40 - 0x34];
__be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
u8 res4[0x50 - 0x44];
u8 res044[0x50 - 0x44];
__be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
u8 res5[0x60 - 0x54];
u8 res054[0x60 - 0x54];
__be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
u8 res6[0x70 - 0x64];
__be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */
__be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
u8 res06c[0x70 - 0x6c];
__be32 devdisr; /* 0x.0070 - Device Disable Control */
__be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
u8 res7[0x80 - 0x78];
u8 res078[0x7c - 0x78];
__be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
__be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
u8 res8[0x90 - 0x84];
__be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */
__be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */
__be32 pmcdr; /* 0x.008c - 4Power management clock disable register */
__be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
__be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
u8 res9[0xA0 - 0x98];
__be32 ectrstcr; /* 0x.0098 - Exception reset control register */
__be32 autorstsr; /* 0x.009c - Automatic reset status register */
__be32 pvr; /* 0x.00a0 - Processor Version Register */
__be32 svr; /* 0x.00a4 - System Version Register */
u8 res10[0xB0 - 0xA8];
u8 res0a8[0xb0 - 0xa8];
__be32 rstcr; /* 0x.00b0 - Reset Control Register */
u8 res11[0xC0 - 0xB4];
u8 res0b4[0xc0 - 0xb4];
#ifdef CONFIG_PPC_85xx
__be32 iovselsr; /* 0x.00c0 - I/O voltage select status register */
#else
__be32 elbcvselcr; /* 0x.00c0 - eLBC Voltage Select Ctrl Reg */
u8 res12[0x800 - 0xC4];
#endif
u8 res0c4[0x224 - 0xc4];
__be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
__be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
u8 res22c[0x800 - 0x22c];
__be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
u8 res13[0x900 - 0x804];
u8 res804[0x900 - 0x804];
__be32 ircr; /* 0x.0900 - Infrared Control Register */
u8 res14[0x908 - 0x904];
u8 res904[0x908 - 0x904];
__be32 dmacr; /* 0x.0908 - DMA Control Register */
u8 res15[0x914 - 0x90C];
u8 res90c[0x914 - 0x90c];
__be32 elbccr; /* 0x.0914 - eLBC Control Register */
u8 res16[0xB20 - 0x918];
u8 res918[0xb20 - 0x918];
__be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
__be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
__be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
u8 res17[0xE00 - 0xB2C];
u8 resb2c[0xe00 - 0xb2c];
__be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
u8 res18[0xE10 - 0xE04];
u8 rese04[0xe10 - 0xe04];
__be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
u8 res19[0xE20 - 0xE14];
u8 rese14[0xe20 - 0xe14];
__be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
u8 res20[0xF04 - 0xE24];
__be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */
u8 rese28[0xf04 - 0xe28];
__be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
__be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
u8 res21[0xF40 - 0xF0C];
__be32 srds2cr0; /* 0x.0f40 - SerDes1 Control Register 0 */
__be32 srds2cr1; /* 0x.0f44 - SerDes1 Control Register 0 */
u8 resf0c[0xf2c - 0xf0c];
__be32 itcr; /* 0x.0f2c - Internal transaction control register */
u8 resf30[0xf40 - 0xf30];
__be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
__be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
} __attribute__ ((packed));
#ifdef CONFIG_PPC_86xx
#define CCSR_GUTS_DMACR_DEV_SSI 0 /* DMA controller/channel set to SSI */
#define CCSR_GUTS_DMACR_DEV_IR 1 /* DMA controller/channel set to IR */
@ -93,7 +132,7 @@ struct ccsr_guts {
* ch: The channel on the DMA controller (0, 1, 2, or 3)
* device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
*/
static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
static inline void guts_set_dmacr(struct ccsr_guts_86xx __iomem *guts,
unsigned int co, unsigned int ch, unsigned int device)
{
unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
@ -129,7 +168,7 @@ static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
* ch: The channel on the DMA controller (0, 1, 2, or 3)
* value: the new value for the bit (0 or 1)
*/
static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
static inline void guts_set_pmuxcr_dma(struct ccsr_guts_86xx __iomem *guts,
unsigned int co, unsigned int ch, unsigned int value)
{
if ((ch == 0) || (ch == 3)) {
@ -152,5 +191,7 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
#define CCSR_GUTS_CLKDVDR_SSICLK_MASK 0x000000FF
#define CCSR_GUTS_CLKDVDR_SSICLK(x) ((x) & CCSR_GUTS_CLKDVDR_SSICLK_MASK)
#endif /* __ASM_POWERPC_IMMAP_86XX_H__ */
#endif /* __KERNEL__ */
#endif
#endif
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,25 +0,0 @@
/*
* OF helpers for ALSA SoC
*
* Copyright (C) 2008, Secret Lab Technologies Ltd.
*/
#ifndef _INCLUDE_SOC_OF_H_
#define _INCLUDE_SOC_OF_H_
#if defined(CONFIG_SND_SOC_OF_SIMPLE) || defined(CONFIG_SND_SOC_OF_SIMPLE_MODULE)
#include <linux/of.h>
#include <sound/soc.h>
int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
void *codec_data, struct snd_soc_dai *dai,
struct device_node *node);
int of_snd_soc_register_platform(struct snd_soc_platform *platform,
struct device_node *node,
struct snd_soc_dai *cpu_dai);
#endif
#endif /* _INCLUDE_SOC_OF_H_ */

View File

@ -228,13 +228,17 @@ struct snd_soc_ops;
struct snd_soc_dai_mode;
struct snd_soc_pcm_runtime;
struct snd_soc_dai;
struct snd_soc_dai_driver;
struct snd_soc_platform;
struct snd_soc_dai_link;
struct snd_soc_platform_driver;
struct snd_soc_codec;
struct snd_soc_codec_driver;
struct soc_enum;
struct snd_soc_ac97_ops;
struct snd_soc_jack;
struct snd_soc_jack_pin;
#ifdef CONFIG_GPIOLIB
struct snd_soc_jack_gpio;
#endif
@ -249,19 +253,18 @@ enum snd_soc_control_type {
SND_SOC_SPI,
};
int snd_soc_register_platform(struct snd_soc_platform *platform);
void snd_soc_unregister_platform(struct snd_soc_platform *platform);
int snd_soc_register_codec(struct snd_soc_codec *codec);
void snd_soc_unregister_codec(struct snd_soc_codec *codec);
int snd_soc_register_platform(struct device *dev,
struct snd_soc_platform_driver *platform_drv);
void snd_soc_unregister_platform(struct device *dev);
int snd_soc_register_codec(struct device *dev,
struct snd_soc_codec_driver *codec_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_codec(struct device *dev);
int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
int addr_bits, int data_bits,
enum snd_soc_control_type control);
/* pcm <-> DAI connect */
void snd_soc_free_pcms(struct snd_soc_device *socdev);
int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
/* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
@ -273,7 +276,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw);
/* Jack reporting */
int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
struct snd_soc_jack *jack);
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
@ -390,7 +393,7 @@ struct snd_soc_jack_gpio {
struct snd_soc_jack {
struct snd_jack *jack;
struct snd_soc_card *card;
struct snd_soc_codec *codec;
struct list_head pins;
int status;
struct blocking_notifier_head notifier;
@ -398,15 +401,13 @@ struct snd_soc_jack {
/* SoC PCM stream information */
struct snd_soc_pcm_stream {
char *stream_name;
const char *stream_name;
u64 formats; /* SNDRV_PCM_FMTBIT_* */
unsigned int rates; /* SNDRV_PCM_RATE_* */
unsigned int rate_min; /* min rate */
unsigned int rate_max; /* max rate */
unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */
unsigned int active; /* stream is in use */
void *dma_data; /* used by platform code */
};
/* SoC audio ops */
@ -419,44 +420,35 @@ struct snd_soc_ops {
int (*trigger)(struct snd_pcm_substream *, int);
};
/* SoC Audio Codec */
/* SoC Audio Codec device */
struct snd_soc_codec {
char *name;
struct module *owner;
struct mutex mutex;
const char *name;
int id;
struct device *dev;
struct snd_soc_device *socdev;
struct snd_soc_codec_driver *driver;
struct mutex mutex;
struct snd_soc_card *card;
struct list_head list;
/* callbacks */
int (*set_bias_level)(struct snd_soc_codec *,
enum snd_soc_bias_level level);
struct list_head card_list;
int num_dai;
/* runtime */
struct snd_card *card;
struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
unsigned int active;
unsigned int pcm_devs;
void *drvdata;
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
int (*display_register)(struct snd_soc_codec *, char *,
size_t, unsigned int);
int (*volatile_register)(unsigned int);
int (*readable_register)(unsigned int);
hw_write_t hw_write;
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
void *reg_cache;
short reg_cache_size;
short reg_cache_step;
unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
unsigned int cache_only:1; /* Suppress writes to hardware */
unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
unsigned int suspended:1; /* Codec is in suspend PM state */
unsigned int probed:1; /* Codec has been probed */
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
hw_write_t hw_write;
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
void *reg_cache;
/* dapm */
u32 pop_time;
@ -466,10 +458,6 @@ struct snd_soc_codec {
enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work;
/* codec DAI's */
struct snd_soc_dai *dai;
unsigned int num_dai;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_codec_root;
struct dentry *debugfs_reg;
@ -478,23 +466,40 @@ struct snd_soc_codec {
#endif
};
/* codec device */
struct snd_soc_codec_device {
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
int (*suspend)(struct platform_device *pdev, pm_message_t state);
int (*resume)(struct platform_device *pdev);
/* codec driver */
struct snd_soc_codec_driver {
/* driver ops */
int (*probe)(struct snd_soc_codec *);
int (*remove)(struct snd_soc_codec *);
int (*suspend)(struct snd_soc_codec *,
pm_message_t state);
int (*resume)(struct snd_soc_codec *);
/* codec IO */
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
int (*display_register)(struct snd_soc_codec *, char *,
size_t, unsigned int);
int (*volatile_register)(unsigned int);
int (*readable_register)(unsigned int);
short reg_cache_size;
short reg_cache_step;
short reg_word_size;
const void *reg_cache_default;
/* codec bias level */
int (*set_bias_level)(struct snd_soc_codec *,
enum snd_soc_bias_level level);
};
/* SoC platform interface */
struct snd_soc_platform {
char *name;
struct list_head list;
struct snd_soc_platform_driver {
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
int (*suspend)(struct snd_soc_dai_link *dai_link);
int (*resume)(struct snd_soc_dai_link *dai_link);
int (*probe)(struct snd_soc_platform *);
int (*remove)(struct snd_soc_platform *);
int (*suspend)(struct snd_soc_dai *dai);
int (*resume)(struct snd_soc_dai *dai);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
@ -509,23 +514,31 @@ struct snd_soc_platform {
struct snd_soc_dai *);
/* platform stream ops */
struct snd_pcm_ops *pcm_ops;
struct snd_pcm_ops *ops;
};
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
struct snd_soc_dai_link {
char *name; /* Codec name */
char *stream_name; /* Stream name */
struct snd_soc_platform {
const char *name;
int id;
struct device *dev;
struct snd_soc_platform_driver *driver;
/* DAI */
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai;
unsigned int suspended:1; /* platform is suspended */
unsigned int probed:1;
/* machine stream operations */
struct snd_soc_ops *ops;
struct snd_soc_card *card;
struct list_head list;
struct list_head card_list;
};
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_codec *codec);
struct snd_soc_dai_link {
/* config - must be set by machine driver */
const char *name; /* Codec name */
const char *stream_name; /* Stream name */
const char *codec_name; /* for multi-codec */
const char *platform_name; /* for multi-platform */
const char *cpu_dai_name;
const char *codec_dai_name;
/* Keep DAI active over suspend */
unsigned int ignore_suspend:1;
@ -533,21 +546,24 @@ struct snd_soc_dai_link {
/* Symmetry requirements */
unsigned int symmetric_rates:1;
/* Symmetry data - only valid if symmetry is being enforced */
unsigned int rate;
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_pcm_runtime *rtd);
/* DAI pcm */
struct snd_pcm *pcm;
/* machine stream operations */
struct snd_soc_ops *ops;
};
/* SoC card */
struct snd_soc_card {
char *name;
const char *name;
struct device *dev;
struct snd_card *snd_card;
struct module *owner;
struct list_head list;
struct mutex mutex;
int instantiated;
bool instantiated;
int (*probe)(struct platform_device *pdev);
int (*remove)(struct platform_device *pdev);
@ -568,28 +584,38 @@ struct snd_soc_card {
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link;
int num_links;
struct snd_soc_pcm_runtime *rtd;
int num_rtd;
struct snd_soc_device *socdev;
struct snd_soc_codec *codec;
struct snd_soc_platform *platform;
struct delayed_work delayed_work;
struct work_struct deferred_resume_work;
/* lists of probed devices belonging to this card */
struct list_head codec_dev_list;
struct list_head platform_dev_list;
struct list_head dai_dev_list;
};
/* SoC Device - the audio subsystem */
struct snd_soc_device {
struct device *dev;
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
struct snd_soc_pcm_runtime {
struct device dev;
struct snd_soc_card *card;
struct snd_soc_codec_device *codec_dev;
void *codec_data;
};
struct snd_soc_dai_link *dai_link;
/* runtime channel data */
struct snd_soc_pcm_runtime {
struct snd_soc_dai_link *dai;
struct snd_soc_device *socdev;
unsigned int complete:1;
unsigned int dev_registered:1;
/* Symmetry data - only valid if symmetry is being enforced */
unsigned int rate;
long pmdown_time;
/* runtime devices */
struct snd_pcm *pcm;
struct snd_soc_codec *codec;
struct snd_soc_platform *platform;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai;
struct delayed_work delayed_work;
};
/* mixer control */
@ -615,24 +641,48 @@ struct soc_enum {
static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
unsigned int reg)
{
return codec->read(codec, reg);
return codec->driver->read(codec, reg);
}
static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int val)
{
return codec->write(codec, reg, val);
return codec->driver->write(codec, reg, val);
}
/* device driver data */
static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
void *data)
void *data)
{
codec->drvdata = data;
dev_set_drvdata(codec->dev, data);
}
static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
{
return codec->drvdata;
return dev_get_drvdata(codec->dev);
}
static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
void *data)
{
dev_set_drvdata(platform->dev, data);
}
static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
{
return dev_get_drvdata(platform->dev);
}
static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
void *data)
{
dev_set_drvdata(&rtd->dev, data);
}
static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
{
return dev_get_drvdata(&rtd->dev);
}
#include <sound/soc-dai.h>

View File

@ -10,8 +10,49 @@
#ifndef __TLV320AIC3x_H__
#define __TLV320AIC3x_H__
struct aic3x_pdata {
int gpio_reset; /* < 0 if not used */
/* GPIO API */
enum {
AIC3X_GPIO1_FUNC_DISABLED = 0,
AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
AIC3X_GPIO1_FUNC_INPUT = 8,
AIC3X_GPIO1_FUNC_OUTPUT = 9,
AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
AIC3X_GPIO1_FUNC_ALL_IRQ = 16
};
#endif
enum {
AIC3X_GPIO2_FUNC_DISABLED = 0,
AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
AIC3X_GPIO2_FUNC_INPUT = 3,
AIC3X_GPIO2_FUNC_OUTPUT = 4,
AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
};
struct aic3x_setup_data {
unsigned int gpio_func[2];
};
struct aic3x_pdata {
int gpio_reset; /* < 0 if not used */
struct aic3x_setup_data *setup;
};
#endif

View File

@ -179,7 +179,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params);
prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
prtd->dma_buffer = runtime->dma_addr;
@ -374,14 +374,14 @@ static int atmel_pcm_new(struct snd_card *card,
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = 0xffffffff;
if (dai->playback.channels_min) {
if (dai->driver->playback.channels_min) {
ret = atmel_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (dai->capture.channels_min) {
if (dai->driver->capture.channels_min) {
pr_debug("at32-pcm:"
"Allocating PCM capture DMA buffer\n");
ret = atmel_pcm_preallocate_dma_buffer(pcm,
@ -414,12 +414,9 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
}
#ifdef CONFIG_PM
static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
static int atmel_pcm_suspend(struct snd_soc_dai *dai)
{
struct snd_pcm *pcm = dai_link->pcm;
struct snd_pcm_str *stream = &pcm->streams[0];
struct snd_pcm_substream *substream = stream->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = dai->runtime;
struct atmel_runtime_data *prtd;
struct atmel_pcm_dma_params *params;
@ -441,12 +438,9 @@ static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
return 0;
}
static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
static int atmel_pcm_resume(struct snd_soc_dai *dai)
{
struct snd_pcm *pcm = dai_link->pcm;
struct snd_pcm_str *stream = &pcm->streams[0];
struct snd_pcm_substream *substream = stream->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_pcm_runtime *runtime = dai->runtime;
struct atmel_runtime_data *prtd;
struct atmel_pcm_dma_params *params;
@ -470,27 +464,46 @@ static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
#define atmel_pcm_resume NULL
#endif
struct snd_soc_platform atmel_soc_platform = {
.name = "atmel-audio",
.pcm_ops = &atmel_pcm_ops,
static struct snd_soc_platform_driver atmel_soc_platform = {
.ops = &atmel_pcm_ops,
.pcm_new = atmel_pcm_new,
.pcm_free = atmel_pcm_free_dma_buffers,
.suspend = atmel_pcm_suspend,
.resume = atmel_pcm_resume,
};
EXPORT_SYMBOL_GPL(atmel_soc_platform);
static int __init atmel_pcm_modinit(void)
static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
{
return snd_soc_register_platform(&atmel_soc_platform);
return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
}
module_init(atmel_pcm_modinit);
static void __exit atmel_pcm_modexit(void)
static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&atmel_soc_platform);
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
module_exit(atmel_pcm_modexit);
static struct platform_driver atmel_pcm_driver = {
.driver = {
.name = "atmel-pcm-audio",
.owner = THIS_MODULE,
},
.probe = atmel_soc_platform_probe,
.remove = __devexit_p(atmel_soc_platform_remove),
};
static int __init snd_atmel_pcm_init(void)
{
return platform_driver_register(&atmel_pcm_driver);
}
module_init(snd_atmel_pcm_init);
static void __exit snd_atmel_pcm_exit(void)
{
platform_driver_unregister(&atmel_pcm_driver);
}
module_exit(snd_atmel_pcm_exit);
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
MODULE_DESCRIPTION("Atmel PCM module");

View File

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

View File

@ -205,8 +205,7 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
static int atmel_ssc_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
int dir_mask;
pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
@ -235,8 +234,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
struct atmel_pcm_dma_params *dma_params;
int dir, dir_mask;
@ -338,7 +336,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
int id = rtd->dai->cpu_dai->id;
int id = dai->id;
struct atmel_ssc_info *ssc_p = &ssc_info[id];
struct atmel_pcm_dma_params *dma_params;
int dir, channels, bits;
@ -368,7 +366,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
* function. It should not be used for other purposes
* as it is common to all substreams.
*/
snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_params);
channels = params_channels(params);
@ -605,8 +603,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
struct atmel_pcm_dma_params *dma_params;
int dir;
@ -690,6 +687,32 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
# define atmel_ssc_resume NULL
#endif /* CONFIG_PM */
static int atmel_ssc_probe(struct snd_soc_dai *dai)
{
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
int ret = 0;
snd_soc_dai_set_drvdata(dai, ssc_p);
/*
* Request SSC device
*/
ssc_p->ssc = ssc_request(dai->id);
if (IS_ERR(ssc_p->ssc)) {
printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
ret = PTR_ERR(ssc_p->ssc);
}
return ret;
}
static int atmel_ssc_remove(struct snd_soc_dai *dai)
{
struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
ssc_free(ssc_p->ssc);
return 0;
}
#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
@ -705,9 +728,11 @@ static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.set_clkdiv = atmel_ssc_set_dai_clkdiv,
};
struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
{ .name = "atmel-ssc0",
.id = 0,
static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
{
.name = "atmel-ssc-dai.0",
.probe = atmel_ssc_probe,
.remove = atmel_ssc_remove,
.suspend = atmel_ssc_suspend,
.resume = atmel_ssc_resume,
.playback = {
@ -721,11 +746,12 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
.rates = ATMEL_SSC_RATES,
.formats = ATMEL_SSC_FORMATS,},
.ops = &atmel_ssc_dai_ops,
.private_data = &ssc_info[0],
},
#if NUM_SSC_DEVICES == 3
{ .name = "atmel-ssc1",
.id = 1,
{
.name = "atmel-ssc-dai.1",
.probe = atmel_ssc_probe,
.remove = atmel_ssc_remove,
.suspend = atmel_ssc_suspend,
.resume = atmel_ssc_resume,
.playback = {
@ -739,10 +765,11 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
.rates = ATMEL_SSC_RATES,
.formats = ATMEL_SSC_FORMATS,},
.ops = &atmel_ssc_dai_ops,
.private_data = &ssc_info[1],
},
{ .name = "atmel-ssc2",
.id = 2,
{
.name = "atmel-ssc-dai.2",
.probe = atmel_ssc_probe,
.remove = atmel_ssc_remove,
.suspend = atmel_ssc_suspend,
.resume = atmel_ssc_resume,
.playback = {
@ -756,23 +783,43 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
.rates = ATMEL_SSC_RATES,
.formats = ATMEL_SSC_FORMATS,},
.ops = &atmel_ssc_dai_ops,
.private_data = &ssc_info[2],
},
#endif
};
EXPORT_SYMBOL_GPL(atmel_ssc_dai);
static int __init atmel_ssc_modinit(void)
static __devinit int asoc_ssc_probe(struct platform_device *pdev)
{
return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
return snd_soc_register_dais(&pdev->dev, atmel_ssc_dai,
ARRAY_SIZE(atmel_ssc_dai));
}
module_init(atmel_ssc_modinit);
static void __exit atmel_ssc_modexit(void)
static int __devexit asoc_ssc_remove(struct platform_device *pdev)
{
snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(atmel_ssc_dai));
return 0;
}
module_exit(atmel_ssc_modexit);
static struct platform_driver asoc_ssc_driver = {
.driver = {
.name = "atmel-ssc-dai",
.owner = THIS_MODULE,
},
.probe = asoc_ssc_probe,
.remove = __devexit_p(asoc_ssc_remove),
};
static int __init snd_atmel_ssc_init(void)
{
return platform_driver_register(&asoc_ssc_driver);
}
module_init(snd_atmel_ssc_init);
static void __exit snd_atmel_ssc_exit(void)
{
platform_driver_unregister(&asoc_ssc_driver);
}
module_exit(snd_atmel_ssc_exit);
/* Module information */
MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");

View File

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

View File

@ -83,7 +83,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
struct snd_pcm_hw_params *params,
struct snd_soc_dai *cpu_dai)
{
struct at32_ssc_info *ssc_p = cpu_dai->private_data;
struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
struct ssc_device *ssc = ssc_p->ssc;
struct ssc_clock_data cd;
unsigned int rate, width_bits, channels;
@ -131,9 +131,9 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct at32_ssc_info *ssc_p = cpu_dai->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
struct ssc_device *ssc = ssc_p->ssc;
unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
int ret;
@ -315,8 +315,9 @@ static const struct snd_soc_dapm_route intercon[] = {
static int playpaq_wm8510_init(struct snd_soc_codec *codec)
static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
int i;
/*
@ -342,7 +343,7 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
/* Make CSB show PLL rate */
snd_soc_dai_set_clkdiv(codec->dai, WM8510_OPCLKDIV,
snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV,
WM8510_OPCLKDIV_1 | 4);
return 0;
@ -353,8 +354,10 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link playpaq_wm8510_dai = {
.name = "WM8510",
.stream_name = "WM8510 PCM",
.cpu_dai = &at32_ssc_dai[0],
.codec_dai = &wm8510_dai,
.cpu_dai_name= "atmel-ssc-dai.0",
.platform_name = "atmel-pcm-audio",
.codec_name = "wm8510-codec.0-0x1a",
.codec_dai_name = "wm8510-hifi",
.init = playpaq_wm8510_init,
.ops = &playpaq_wm8510_ops,
};
@ -363,46 +366,16 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
static struct snd_soc_card snd_soc_playpaq = {
.name = "LRS_PlayPaq_WM8510",
.platform = &at32_soc_platform,
.dai_link = &playpaq_wm8510_dai,
.num_links = 1,
};
static struct wm8510_setup_data playpaq_wm8510_setup = {
.i2c_bus = 0,
.i2c_address = 0x1a,
};
static struct snd_soc_device playpaq_wm8510_snd_devdata = {
.card = &snd_soc_playpaq,
.codec_dev = &soc_codec_dev_wm8510,
.codec_data = &playpaq_wm8510_setup,
};
static struct platform_device *playpaq_snd_device;
static int __init playpaq_asoc_init(void)
{
int ret = 0;
struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
struct ssc_device *ssc = NULL;
/*
* Request SSC device
*/
ssc = ssc_request(0);
if (IS_ERR(ssc)) {
ret = PTR_ERR(ssc);
goto err_ssc;
}
ssc_p->ssc = ssc;
/*
* Configure MCLK for WM8510
@ -439,8 +412,7 @@ static int __init playpaq_asoc_init(void)
goto err_device_alloc;
}
platform_set_drvdata(playpaq_snd_device, &playpaq_wm8510_snd_devdata);
playpaq_wm8510_snd_devdata.dev = &playpaq_snd_device->dev;
platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq);
ret = platform_device_add(playpaq_snd_device);
if (ret) {
@ -468,25 +440,12 @@ err_pll0:
clk_put(_gclk0);
_gclk0 = NULL;
}
err_gclk0:
ssc_free(ssc);
err_ssc:
return ret;
}
static void __exit playpaq_asoc_exit(void)
{
struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
struct ssc_device *ssc;
if (ssc_p != NULL) {
ssc = ssc_p->ssc;
if (ssc != NULL)
ssc_free(ssc);
ssc_p->ssc = NULL;
}
if (_gclk0 != NULL) {
clk_put(_gclk0);
_gclk0 = NULL;

View File

@ -69,8 +69,8 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;
/* set codec DAI configuration */
@ -136,9 +136,10 @@ static const struct snd_soc_dapm_route intercon[] = {
/*
* Logic for a wm8731 as connected on a at91sam9g20ek board.
*/
static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *codec_dai = &codec->dai[0];
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
printk(KERN_DEBUG
@ -179,31 +180,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link at91sam9g20ek_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
.cpu_dai = &atmel_ssc_dai[0],
.codec_dai = &wm8731_dai,
.cpu_dai_name = "atmel-ssc-dai.0",
.codec_dai_name = "wm8731-hifi",
.init = at91sam9g20ek_wm8731_init,
.platform_name = "atmel_pcm-audio",
.codec_name = "wm8731-codec.0-001a",
.ops = &at91sam9g20ek_ops,
};
static struct snd_soc_card snd_soc_at91sam9g20ek = {
.name = "AT91SAMG20-EK",
.platform = &atmel_soc_platform,
.dai_link = &at91sam9g20ek_dai,
.num_links = 1,
.set_bias_level = at91sam9g20ek_set_bias_level,
};
static struct snd_soc_device at91sam9g20ek_snd_devdata = {
.card = &snd_soc_at91sam9g20ek,
.codec_dev = &soc_codec_dev_wm8731,
};
static struct platform_device *at91sam9g20ek_snd_device;
static int __init at91sam9g20ek_init(void)
{
struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
struct ssc_device *ssc = NULL;
struct clk *pllb;
int ret;
@ -235,18 +230,6 @@ static int __init at91sam9g20ek_init(void)
clk_set_rate(mclk, MCLK_RATE);
/*
* Request SSC device
*/
ssc = ssc_request(0);
if (IS_ERR(ssc)) {
printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
ret = PTR_ERR(ssc);
ssc = NULL;
goto err_ssc;
}
ssc_p->ssc = ssc;
at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
if (!at91sam9g20ek_snd_device) {
printk(KERN_ERR "ASoC: Platform device allocation failed\n");
@ -254,8 +237,7 @@ static int __init at91sam9g20ek_init(void)
}
platform_set_drvdata(at91sam9g20ek_snd_device,
&at91sam9g20ek_snd_devdata);
at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
&snd_soc_at91sam9g20ek);
ret = platform_device_add(at91sam9g20ek_snd_device);
if (ret) {
@ -265,9 +247,6 @@ static int __init at91sam9g20ek_init(void)
return ret;
err_ssc:
ssc_free(ssc);
ssc_p->ssc = NULL;
err_mclk:
clk_put(mclk);
mclk = NULL;
@ -277,16 +256,6 @@ err:
static void __exit at91sam9g20ek_exit(void)
{
struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
struct ssc_device *ssc;
if (ssc_p != NULL) {
ssc = ssc_p->ssc;
if (ssc != NULL)
ssc_free(ssc);
ssc_p->ssc = NULL;
}
platform_device_unregister(at91sam9g20ek_snd_device);
at91sam9g20ek_snd_device = NULL;
clk_put(mclk);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -422,14 +422,14 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
if (dai->driver->playback.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (dai->capture.channels_min) {
if (dai->driver->capture.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@ -439,25 +439,44 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
return ret;
}
struct snd_soc_platform bf5xx_ac97_soc_platform = {
.name = "bf5xx-audio",
.pcm_ops = &bf5xx_pcm_ac97_ops,
static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = {
.ops = &bf5xx_pcm_ac97_ops,
.pcm_new = bf5xx_pcm_ac97_new,
.pcm_free = bf5xx_pcm_free_dma_buffers,
};
EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
static int __init bfin_ac97_init(void)
static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
{
return snd_soc_register_platform(&bf5xx_ac97_soc_platform);
return snd_soc_register_platform(&pdev->dev, &bf5xx_ac97_soc_platform);
}
module_init(bfin_ac97_init);
static void __exit bfin_ac97_exit(void)
static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&bf5xx_ac97_soc_platform);
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
module_exit(bfin_ac97_exit);
static struct platform_driver bf5xx_pcm_driver = {
.driver = {
.name = "bf5xx-pcm-audio",
.owner = THIS_MODULE,
},
.probe = bf5xx_soc_platform_probe,
.remove = __devexit_p(bf5xx_soc_platform_remove),
};
static int __init snd_bf5xx_pcm_init(void)
{
return platform_driver_register(&bf5xx_pcm_driver);
}
module_init(snd_bf5xx_pcm_init);
static void __exit snd_bf5xx_pcm_exit(void)
{
platform_driver_unregister(&bf5xx_pcm_driver);
}
module_exit(snd_bf5xx_pcm_exit);
MODULE_AUTHOR("Cliff Cai");
MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");

View File

@ -23,7 +23,4 @@ struct bf5xx_gpio {
u32 frm;
};
/* platform data */
extern struct snd_soc_platform bf5xx_ac97_soc_platform;
#endif

View File

@ -255,7 +255,7 @@ EXPORT_SYMBOL_GPL(soc_ac97_ops);
#ifdef CONFIG_PM
static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
{
struct sport_device *sport = dai->private_data;
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
pr_debug("%s : sport %d\n", __func__, dai->id);
if (!dai->active)
@ -270,7 +270,7 @@ static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
{
int ret;
struct sport_device *sport = dai->private_data;
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
pr_debug("%s : sport %d\n", __func__, dai->id);
if (!dai->active)
@ -306,8 +306,7 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
#define bf5xx_ac97_resume NULL
#endif
static int bf5xx_ac97_probe(struct platform_device *pdev,
struct snd_soc_dai *dai)
static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
{
int ret = 0;
cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
@ -379,8 +378,7 @@ peripheral_err:
return ret;
}
static void bf5xx_ac97_remove(struct platform_device *pdev,
struct snd_soc_dai *dai)
static int bf5xx_ac97_remove(struct snd_soc_dai *dai)
{
free_page((unsigned long)cmd_count);
cmd_count = NULL;
@ -388,11 +386,10 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
#endif
return 0;
}
struct snd_soc_dai bfin_ac97_dai = {
.name = "bf5xx-ac97",
.id = 0,
struct snd_soc_dai_driver bfin_ac97_dai = {
.ac97_control = 1,
.probe = bf5xx_ac97_probe,
.remove = bf5xx_ac97_remove,
@ -417,18 +414,40 @@ struct snd_soc_dai bfin_ac97_dai = {
};
EXPORT_SYMBOL_GPL(bfin_ac97_dai);
static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
{
return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
}
static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
{
snd_soc_unregister_dai(&pdev->dev);
return 0;
}
static struct platform_driver asoc_bfin_ac97_driver = {
.driver = {
.name = "bfin-ac97",
.owner = THIS_MODULE,
},
.probe = asoc_bfin_ac97_probe,
.remove = __devexit_p(asoc_bfin_ac97_remove),
};
static int __init bfin_ac97_init(void)
{
return snd_soc_register_dai(&bfin_ac97_dai);
return platform_driver_register(&asoc_bfin_ac97_driver);
}
module_init(bfin_ac97_init);
static void __exit bfin_ac97_exit(void)
{
snd_soc_unregister_dai(&bfin_ac97_dai);
platform_driver_unregister(&asoc_bfin_ac97_driver);
}
module_exit(bfin_ac97_exit);
MODULE_AUTHOR("Roy Huang");
MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
MODULE_LICENSE("GPL");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -40,7 +40,6 @@
#include <asm/dma.h>
#include "bf5xx-i2s-pcm.h"
#include "bf5xx-i2s.h"
#include "bf5xx-sport.h"
static void bf5xx_dma_irq(void *data)
@ -257,14 +256,14 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
if (dai->driver->playback.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (dai->capture.channels_min) {
if (dai->driver->capture.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@ -274,25 +273,44 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
return ret;
}
struct snd_soc_platform bf5xx_i2s_soc_platform = {
.name = "bf5xx-audio",
.pcm_ops = &bf5xx_pcm_i2s_ops,
static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
.ops = &bf5xx_pcm_i2s_ops,
.pcm_new = bf5xx_pcm_i2s_new,
.pcm_free = bf5xx_pcm_free_dma_buffers,
};
EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
static int __init bfin_i2s_init(void)
static int __devinit bfin_i2s_soc_platform_probe(struct platform_device *pdev)
{
return snd_soc_register_platform(&bf5xx_i2s_soc_platform);
return snd_soc_register_platform(&pdev->dev, &bf5xx_i2s_soc_platform);
}
module_init(bfin_i2s_init);
static void __exit bfin_i2s_exit(void)
static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&bf5xx_i2s_soc_platform);
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
module_exit(bfin_i2s_exit);
static struct platform_driver bfin_i2s_pcm_driver = {
.driver = {
.name = "bfin-pcm-audio",
.owner = THIS_MODULE,
},
.probe = bfin_i2s_soc_platform_probe,
.remove = __devexit_p(bfin_i2s_soc_platform_remove),
};
static int __init snd_bfin_i2s_pcm_init(void)
{
return platform_driver_register(&bfin_i2s_pcm_driver);
}
module_init(snd_bfin_i2s_pcm_init);
static void __exit snd_bfin_i2s_pcm_exit(void)
{
platform_driver_unregister(&bfin_i2s_pcm_driver);
}
module_exit(snd_bfin_i2s_pcm_exit);
MODULE_AUTHOR("Cliff Cai");
MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");

View File

@ -23,7 +23,4 @@ struct bf5xx_gpio {
u32 frm;
};
/* platform data */
extern struct snd_soc_platform bf5xx_i2s_soc_platform;
#endif

View File

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

View File

@ -1,14 +0,0 @@
/*
* sound/soc/blackfin/bf5xx-i2s.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _BF5XX_I2S_H
#define _BF5XX_I2S_H
extern struct snd_soc_dai bf5xx_i2s_dai;
#endif

View File

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

View File

@ -290,14 +290,14 @@ static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
if (dai->driver->playback.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (dai->capture.channels_min) {
if (dai->driver->capture.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
@ -307,25 +307,44 @@ out:
return ret;
}
struct snd_soc_platform bf5xx_tdm_soc_platform = {
.name = "bf5xx-audio",
.pcm_ops = &bf5xx_pcm_tdm_ops,
static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = {
.ops = &bf5xx_pcm_tdm_ops,
.pcm_new = bf5xx_pcm_tdm_new,
.pcm_free = bf5xx_pcm_free_dma_buffers,
};
EXPORT_SYMBOL_GPL(bf5xx_tdm_soc_platform);
static int __init bfin_pcm_tdm_init(void)
static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
{
return snd_soc_register_platform(&bf5xx_tdm_soc_platform);
return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
}
module_init(bfin_pcm_tdm_init);
static void __exit bfin_pcm_tdm_exit(void)
static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&bf5xx_tdm_soc_platform);
snd_soc_unregister_platform(&pdev->dev);
return 0;
}
module_exit(bfin_pcm_tdm_exit);
static struct platform_driver bfin_tdm_driver = {
.driver = {
.name = "bf5xx-tdm-pcm-audio",
.owner = THIS_MODULE,
},
.probe = bf5xx_soc_platform_probe,
.remove = __devexit_p(bf5xx_soc_platform_remove),
};
static int __init snd_bfin_tdm_init(void)
{
return platform_driver_register(&bfin_tdm_driver);
}
module_init(snd_bfin_tdm_init);
static void __exit snd_bfin_tdm_exit(void)
{
platform_driver_unregister(&bfin_tdm_driver);
}
module_exit(snd_bfin_tdm_exit);
MODULE_AUTHOR("Barry Song");
MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");

View File

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

View File

@ -214,9 +214,9 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
if (!dai->active)
return 0;
if (dai->capture.active)
if (dai->capture_active)
sport_rx_stop(sport);
if (dai->playback.active)
if (dai->playback_active)
sport_tx_stop(sport);
return 0;
}
@ -224,7 +224,7 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
{
int ret;
struct sport_device *sport = dai->private_data;
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
if (!dai->active)
return 0;
@ -262,9 +262,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
.set_channel_map = bf5xx_tdm_set_channel_map,
};
struct snd_soc_dai bf5xx_tdm_dai = {
.name = "bf5xx-tdm",
.id = 0,
static struct snd_soc_dai_driver bf5xx_tdm_dai = {
.suspend = bf5xx_tdm_suspend,
.resume = bf5xx_tdm_resume,
.playback = {
@ -279,7 +277,6 @@ struct snd_soc_dai bf5xx_tdm_dai = {
.formats = SNDRV_PCM_FMTBIT_S32_LE,},
.ops = &bf5xx_tdm_dai_ops,
};
EXPORT_SYMBOL_GPL(bf5xx_tdm_dai);
static int __devinit bfin_tdm_probe(struct platform_device *pdev)
{
@ -320,7 +317,7 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
goto sport_config_err;
}
ret = snd_soc_register_dai(&bf5xx_tdm_dai);
ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai);
if (ret) {
pr_err("Failed to register DAI: %d\n", ret);
goto sport_config_err;
@ -337,7 +334,7 @@ sport_config_err:
static int __devexit bfin_tdm_remove(struct platform_device *pdev)
{
peripheral_free_list(&sport_req[sport_num][0]);
snd_soc_unregister_dai(&bf5xx_tdm_dai);
snd_soc_unregister_dai(&pdev->dev);
return 0;
}

View File

@ -20,6 +20,4 @@ struct bf5xx_tdm_port {
int configured;
};
extern struct snd_soc_dai bf5xx_tdm_dai;
#endif

View File

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

View File

@ -1,19 +0,0 @@
/*
* linux/sound/codecs/ac97.h -- ALSA SoC Layer
*
* Author: Liam Girdwood
* Created: Dec 1st 2005
* Copyright: Wolfson Microelectronics. PLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_SND_SOC_AC97_H
#define __LINUX_SND_SOC_AC97_H
extern struct snd_soc_codec_device soc_codec_dev_ac97;
extern struct snd_soc_dai ac97_dai;
#endif

View File

@ -33,15 +33,10 @@
/* codec private data */
struct ad1836_priv {
struct snd_soc_codec codec;
u16 reg_cache[AD1836_NUM_REGS];
enum snd_soc_control_type control_type;
void *control_data;
};
static struct snd_soc_codec *ad1836_codec;
struct snd_soc_codec_device soc_codec_dev_ad1836;
static int ad1836_register(struct ad1836_priv *ad1836);
static void ad1836_unregister(struct ad1836_priv *ad1836);
/*
* AD1836 volume/mute/de-emphasis etc. controls
*/
@ -146,8 +141,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
int word_len = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
/* bit size */
switch (params_format(params)) {
@ -173,12 +167,9 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
}
#ifdef CONFIG_PM
static int ad1836_soc_suspend(struct platform_device *pdev,
static int ad1836_soc_suspend(struct snd_soc_codec *codec,
pm_message_t state)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
/* reset clock control mode */
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
@ -186,11 +177,8 @@ static int ad1836_soc_suspend(struct platform_device *pdev,
return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
}
static int ad1836_soc_resume(struct platform_device *pdev)
static int ad1836_soc_resume(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
/* restore clock control mode */
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
adc_ctrl2 |= AD1836_ADC_AUX;
@ -202,49 +190,14 @@ static int ad1836_soc_resume(struct platform_device *pdev)
#define ad1836_soc_resume NULL
#endif
static int __devinit ad1836_spi_probe(struct spi_device *spi)
{
struct snd_soc_codec *codec;
struct ad1836_priv *ad1836;
ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
if (ad1836 == NULL)
return -ENOMEM;
codec = &ad1836->codec;
codec->control_data = spi;
codec->dev = &spi->dev;
dev_set_drvdata(&spi->dev, ad1836);
return ad1836_register(ad1836);
}
static int __devexit ad1836_spi_remove(struct spi_device *spi)
{
struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
ad1836_unregister(ad1836);
return 0;
}
static struct spi_driver ad1836_spi_driver = {
.driver = {
.name = "ad1836",
.owner = THIS_MODULE,
},
.probe = ad1836_spi_probe,
.remove = __devexit_p(ad1836_spi_remove),
};
static struct snd_soc_dai_ops ad1836_dai_ops = {
.hw_params = ad1836_hw_params,
.set_fmt = ad1836_set_dai_fmt,
};
/* codec DAI instance */
struct snd_soc_dai ad1836_dai = {
.name = "AD1836",
static struct snd_soc_dai_driver ad1836_dai = {
.name = "ad1836-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@ -263,35 +216,13 @@ struct snd_soc_dai ad1836_dai = {
},
.ops = &ad1836_dai_ops,
};
EXPORT_SYMBOL_GPL(ad1836_dai);
static int ad1836_register(struct ad1836_priv *ad1836)
static int ad1836_probe(struct snd_soc_codec *codec)
{
int ret;
struct snd_soc_codec *codec = &ad1836->codec;
if (ad1836_codec) {
dev_err(codec->dev, "Another ad1836 is registered\n");
kfree(ad1836);
return -EINVAL;
}
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
snd_soc_codec_set_drvdata(codec, ad1836);
codec->reg_cache = ad1836->reg_cache;
codec->reg_cache_size = AD1836_NUM_REGS;
codec->name = "AD1836";
codec->owner = THIS_MODULE;
codec->dai = &ad1836_dai;
codec->num_dai = 1;
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
ad1836_dai.dev = codec->dev;
ad1836_codec = codec;
struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
codec->control_data = ad1836->control_data;
ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
@ -319,81 +250,69 @@ static int ad1836_register(struct ad1836_priv *ad1836)
snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
kfree(ad1836);
return ret;
}
ret = snd_soc_register_dai(&ad1836_dai);
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
snd_soc_unregister_codec(codec);
kfree(ad1836);
return ret;
}
return 0;
}
static void ad1836_unregister(struct ad1836_priv *ad1836)
{
snd_soc_unregister_dai(&ad1836_dai);
snd_soc_unregister_codec(&ad1836->codec);
kfree(ad1836);
ad1836_codec = NULL;
}
static int ad1836_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
if (ad1836_codec == NULL) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
}
socdev->card->codec = ad1836_codec;
codec = ad1836_codec;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
goto pcm_err;
}
snd_soc_add_controls(codec, ad1836_snd_controls,
ARRAY_SIZE(ad1836_snd_controls));
snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
ARRAY_SIZE(ad1836_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
pcm_err:
return ret;
}
/* power down chip */
static int ad1836_remove(struct platform_device *pdev)
static int ad1836_remove(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
/* reset clock control mode */
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
}
struct snd_soc_codec_device soc_codec_dev_ad1836 = {
static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
.probe = ad1836_probe,
.remove = ad1836_remove,
.suspend = ad1836_soc_suspend,
.resume = ad1836_soc_resume,
.reg_cache_size = AD1836_NUM_REGS,
.reg_word_size = sizeof(u16),
};
static int __devinit ad1836_spi_probe(struct spi_device *spi)
{
struct ad1836_priv *ad1836;
int ret;
ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
if (ad1836 == NULL)
return -ENOMEM;
spi_set_drvdata(spi, ad1836);
ad1836->control_data = spi;
ad1836->control_type = SND_SOC_SPI;
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_ad1836, &ad1836_dai, 1);
if (ret < 0)
kfree(ad1836);
return ret;
}
static int __devexit ad1836_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver ad1836_spi_driver = {
.driver = {
.name = "ad1836-codec",
.owner = THIS_MODULE,
},
.probe = ad1836_spi_probe,
.remove = __devexit_p(ad1836_spi_remove),
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
static int __init ad1836_init(void)
{

View File

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

View File

@ -24,9 +24,10 @@
/* codec private data */
struct ad193x_priv {
unsigned int sysclk;
struct snd_soc_codec codec;
u8 reg_cache[AD193X_NUM_REGS];
enum snd_soc_control_type bus_type;
void *control_data;
int sysclk;
};
/* ad193x register cache & default register settings */
@ -34,9 +35,6 @@ static const u8 ad193x_reg[AD193X_NUM_REGS] = {
0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
};
static struct snd_soc_codec *ad193x_codec;
struct snd_soc_codec_device soc_codec_dev_ad193x;
/*
* AD193X volume/mute/de-emphasis etc. controls
*/
@ -275,8 +273,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
int word_len = 0, reg = 0, master_rate = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
/* bit size */
@ -323,46 +320,46 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
return 0;
}
static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
static struct snd_soc_dai_ops ad193x_dai_ops = {
.hw_params = ad193x_hw_params,
.digital_mute = ad193x_mute,
.set_tdm_slot = ad193x_set_tdm_slot,
.set_sysclk = ad193x_set_dai_sysclk,
.set_fmt = ad193x_set_dai_fmt,
};
/* codec DAI instance */
static struct snd_soc_dai_driver ad193x_dai = {
.name = "ad193x-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 4,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
.ops = &ad193x_dai_ops,
};
static int ad193x_probe(struct snd_soc_codec *codec)
{
struct snd_soc_codec *codec;
struct ad193x_priv *ad193x;
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
int ret;
if (ad193x_codec) {
dev_err(dev, "Another ad193x is registered\n");
return -EINVAL;
}
ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
dev_set_drvdata(dev, ad193x);
codec = &ad193x->codec;
mutex_init(&codec->mutex);
codec->control_data = ctrl_data;
codec->dev = dev;
snd_soc_codec_set_drvdata(codec, ad193x);
codec->reg_cache = ad193x->reg_cache;
codec->reg_cache_size = AD193X_NUM_REGS;
codec->name = "AD193X";
codec->owner = THIS_MODULE;
codec->dai = &ad193x_dai;
codec->num_dai = 1;
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
ad193x_dai.dev = codec->dev;
ad193x_codec = codec;
memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
if (bus_type == SND_SOC_I2C)
ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
codec->control_data = ad193x->control_data;
if (ad193x->bus_type == SND_SOC_I2C)
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
else
ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
ret);
@ -385,89 +382,6 @@ static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
/* pll input: mclki/xi */
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
ad193x->sysclk = 12288000;
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
kfree(ad193x);
return ret;
}
ret = snd_soc_register_dai(&ad193x_dai);
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
snd_soc_unregister_codec(codec);
kfree(ad193x);
return ret;
}
return 0;
}
static int ad193x_bus_remove(struct device *dev)
{
struct ad193x_priv *ad193x = dev_get_drvdata(dev);
snd_soc_unregister_dai(&ad193x_dai);
snd_soc_unregister_codec(&ad193x->codec);
kfree(ad193x);
ad193x_codec = NULL;
return 0;
}
static struct snd_soc_dai_ops ad193x_dai_ops = {
.hw_params = ad193x_hw_params,
.digital_mute = ad193x_mute,
.set_tdm_slot = ad193x_set_tdm_slot,
.set_sysclk = ad193x_set_dai_sysclk,
.set_fmt = ad193x_set_dai_fmt,
};
/* codec DAI instance */
struct snd_soc_dai ad193x_dai = {
.name = "AD193X",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 4,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
.ops = &ad193x_dai_ops,
};
EXPORT_SYMBOL_GPL(ad193x_dai);
static int ad193x_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
if (ad193x_codec == NULL) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
}
socdev->card->codec = ad193x_codec;
codec = ad193x_codec;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
goto pcm_err;
}
snd_soc_add_controls(codec, ad193x_snd_controls,
ARRAY_SIZE(ad193x_snd_controls));
@ -475,41 +389,47 @@ static int ad193x_probe(struct platform_device *pdev)
ARRAY_SIZE(ad193x_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
pcm_err:
return ret;
}
/* power down chip */
static int ad193x_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ad193x = {
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
.probe = ad193x_probe,
.remove = ad193x_remove,
.reg_cache_default = ad193x_reg,
.reg_cache_size = AD193X_NUM_REGS,
.reg_word_size = sizeof(u16),
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
#if defined(CONFIG_SPI_MASTER)
static int __devinit ad193x_spi_probe(struct spi_device *spi)
{
return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI);
struct ad193x_priv *ad193x;
int ret;
ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
spi_set_drvdata(spi, ad193x);
ad193x->control_data = spi;
ad193x->bus_type = SND_SOC_SPI;
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_ad193x, &ad193x_dai, 1);
if (ret < 0)
kfree(ad193x);
return ret;
}
static int __devexit ad193x_spi_remove(struct spi_device *spi)
{
return ad193x_bus_remove(&spi->dev);
snd_soc_unregister_codec(&spi->dev);
kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver ad193x_spi_driver = {
.driver = {
.name = "ad193x",
.name = "ad193x-codec",
.owner = THIS_MODULE,
},
.probe = ad193x_spi_probe,
@ -528,17 +448,34 @@ MODULE_DEVICE_TABLE(i2c, ad193x_id);
static int __devinit ad193x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C);
struct ad193x_priv *ad193x;
int ret;
ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
i2c_set_clientdata(client, ad193x);
ad193x->control_data = client;
ad193x->bus_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&client->dev,
&soc_codec_dev_ad193x, &ad193x_dai, 1);
if (ret < 0)
kfree(ad193x);
return ret;
}
static int __devexit ad193x_i2c_remove(struct i2c_client *client)
{
return ad193x_bus_remove(&client->dev);
snd_soc_unregister_codec(&client->dev);
kfree(i2c_get_clientdata(client));
return 0;
}
static struct i2c_driver ad193x_i2c_driver = {
.driver = {
.name = "ad193x",
.name = "ad193x-codec",
},
.probe = ad193x_i2c_probe,
.remove = __devexit_p(ad193x_i2c_remove),

View File

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

View File

@ -130,8 +130,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
return 0;
}
struct snd_soc_dai ad1980_dai = {
.name = "AC97",
struct snd_soc_dai_driver ad1980_dai = {
.name = "ad1980-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "Playback",
@ -177,53 +177,20 @@ err:
return -EIO;
}
static int ad1980_soc_probe(struct platform_device *pdev)
static int ad1980_soc_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
int ret;
u16 vendor_id2;
u16 ext_status;
printk(KERN_INFO "AD1980 SoC Audio Codec\n");
socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (socdev->card->codec == NULL)
return -ENOMEM;
codec = socdev->card->codec;
mutex_init(&codec->mutex);
codec->reg_cache =
kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
if (codec->reg_cache == NULL) {
ret = -ENOMEM;
goto cache_err;
}
memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
ARRAY_SIZE(ad1980_reg));
codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
codec->reg_cache_step = 2;
codec->name = "AD1980";
codec->owner = THIS_MODULE;
codec->dai = &ad1980_dai;
codec->num_dai = 1;
codec->write = ac97_write;
codec->read = ac97_read;
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
goto codec_err;
return ret;
}
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0)
goto pcm_err;
ret = ad1980_reset(codec, 0);
if (ret < 0) {
printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
@ -262,41 +229,59 @@ static int ad1980_soc_probe(struct platform_device *pdev)
return 0;
reset_err:
snd_soc_free_pcms(socdev);
pcm_err:
snd_soc_free_ac97_codec(codec);
codec_err:
kfree(codec->reg_cache);
cache_err:
kfree(socdev->card->codec);
socdev->card->codec = NULL;
return ret;
}
static int ad1980_soc_remove(struct platform_device *pdev)
static int ad1980_soc_remove(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
if (codec == NULL)
return 0;
snd_soc_dapm_free(socdev);
snd_soc_free_pcms(socdev);
snd_soc_free_ac97_codec(codec);
kfree(codec->reg_cache);
kfree(codec);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ad1980 = {
static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
.probe = ad1980_soc_probe,
.remove = ad1980_soc_remove,
.reg_cache_size = ARRAY_SIZE(ad1980_reg),
.reg_word_size = sizeof(u16),
.reg_cache_step = 2,
.write = ac97_write,
.read = ac97_read,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
static __devinit int ad1980_probe(struct platform_device *pdev)
{
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_ad1980, &ad1980_dai, 1);
}
static int __devexit ad1980_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver ad1980_codec_driver = {
.driver = {
.name = "ad1980-codec",
.owner = THIS_MODULE,
},
.probe = ad1980_probe,
.remove = __devexit_p(ad1980_remove),
};
static int __init ad1980_init(void)
{
return platform_driver_register(&ad1980_codec_driver);
}
module_init(ad1980_init);
static void __exit ad1980_exit(void)
{
platform_driver_unregister(&ad1980_codec_driver);
}
module_exit(ad1980_exit);
MODULE_DESCRIPTION("ASoC ad1980 driver");
MODULE_AUTHOR("Roy Huang, Cliff Cai");

View File

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

View File

@ -23,8 +23,8 @@
#include "ad73311.h"
struct snd_soc_dai ad73311_dai = {
.name = "AD73311",
static struct snd_soc_dai_driver ad73311_dai = {
.name = "ad73311-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -38,68 +38,40 @@ struct snd_soc_dai ad73311_dai = {
.rates = SNDRV_PCM_RATE_8000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
};
EXPORT_SYMBOL_GPL(ad73311_dai);
static int ad73311_soc_probe(struct platform_device *pdev)
static struct snd_soc_codec_driver soc_codec_dev_ad73311;
static int ad73311_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (codec == NULL)
return -ENOMEM;
mutex_init(&codec->mutex);
codec->name = "AD73311";
codec->owner = THIS_MODULE;
codec->dai = &ad73311_dai;
codec->num_dai = 1;
socdev->card->codec = codec;
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "ad73311: failed to create pcms\n");
goto pcm_err;
}
return ret;
pcm_err:
kfree(socdev->card->codec);
socdev->card->codec = NULL;
return ret;
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_ad73311, &ad73311_dai, 1);
}
static int ad73311_soc_remove(struct platform_device *pdev)
static int ad73311_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
if (codec == NULL)
return 0;
snd_soc_free_pcms(socdev);
kfree(codec);
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ad73311 = {
.probe = ad73311_soc_probe,
.remove = ad73311_soc_remove,
static struct platform_driver ad73311_codec_driver = {
.driver = {
.name = "ad73311-codec",
.owner = THIS_MODULE,
},
.probe = ad73311_probe,
.remove = __devexit_p(ad73311_remove),
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
static int __init ad73311_init(void)
{
return snd_soc_register_dai(&ad73311_dai);
return platform_driver_register(&ad73311_codec_driver);
}
module_init(ad73311_init);
static void __exit ad73311_exit(void)
{
snd_soc_unregister_dai(&ad73311_dai);
platform_driver_unregister(&ad73311_codec_driver);
}
module_exit(ad73311_exit);

View File

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

View File

@ -19,16 +19,12 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include "ads117x.h"
#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
struct snd_soc_dai ads117x_dai = {
static struct snd_soc_dai_driver ads117x_dai = {
/* ADC */
.name = "ADS117X ADC",
.id = 1,
.name = "ads117x-hifi",
.capture = {
.stream_name = "Capture",
.channels_min = 1,
@ -36,75 +32,29 @@ struct snd_soc_dai ads117x_dai = {
.rates = ADS117X_RATES,
.formats = ADS117X_FORMATS,},
};
EXPORT_SYMBOL_GPL(ads117x_dai);
static int ads117x_probe(struct platform_device *pdev)
static struct snd_soc_codec_driver soc_codec_dev_ads117x;
static __devinit int ads117x_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret;
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (codec == NULL)
return -ENOMEM;
socdev->card->codec = codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
codec->name = "ADS117X";
codec->owner = THIS_MODULE;
codec->dai = &ads117x_dai;
codec->num_dai = 1;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "ads117x: failed to create pcms\n");
kfree(codec);
return ret;
}
return 0;
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_ads117x, &ads117x_dai, 1);
}
static int ads117x_remove(struct platform_device *pdev)
static int __devexit ads117x_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
snd_soc_free_pcms(socdev);
kfree(codec);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ads117x = {
.probe = ads117x_probe,
.remove = ads117x_remove,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
static __devinit int ads117x_platform_probe(struct platform_device *pdev)
{
ads117x_dai.dev = &pdev->dev;
return snd_soc_register_dai(&ads117x_dai);
}
static int __devexit ads117x_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_dai(&ads117x_dai);
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver ads117x_codec_driver = {
.driver = {
.name = "ads117x",
.name = "ads117x-codec",
.owner = THIS_MODULE,
},
.probe = ads117x_platform_probe,
.remove = __devexit_p(ads117x_platform_remove),
.probe = ads117x_probe,
.remove = __devexit_p(ads117x_remove),
};
static int __init ads117x_init(void)

View File

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

View File

@ -17,8 +17,6 @@
#include <linux/spi/spi.h>
#include <sound/asoundef.h>
#include "ak4104.h"
/* AK4104 registers addresses */
#define AK4104_REG_CONTROL1 0x00
#define AK4104_REG_RESERVED 0x01
@ -45,11 +43,11 @@
#define AK4104_TX_TXE (1 << 0)
#define AK4104_TX_V (1 << 1)
#define DRV_NAME "ak4104"
#define DRV_NAME "ak4104-codec"
struct ak4104_private {
struct snd_soc_codec codec;
u8 reg_cache[AK4104_NUM_REGS];
enum snd_soc_control_type control_type;
void *control_data;
};
static int ak4104_fill_cache(struct snd_soc_codec *codec)
@ -58,7 +56,7 @@ static int ak4104_fill_cache(struct snd_soc_codec *codec)
u8 *reg_cache = codec->reg_cache;
struct spi_device *spi = codec->control_data;
for (i = 0; i < codec->reg_cache_size; i++) {
for (i = 0; i < codec->driver->reg_cache_size; i++) {
int ret = spi_w8r8(spi, i | AK4104_READ);
if (ret < 0) {
dev_err(&spi->dev, "SPI write failure\n");
@ -76,7 +74,7 @@ static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
{
u8 *reg_cache = codec->reg_cache;
if (reg >= codec->reg_cache_size)
if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
return reg_cache[reg];
@ -88,7 +86,7 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
u8 *cache = codec->reg_cache;
struct spi_device *spi = codec->control_data;
if (reg >= codec->reg_cache_size)
if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
/* only write to the hardware if value has changed */
@ -145,8 +143,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
int val = 0;
/* set the IEC958 bits: consumer mode, no copyright bit */
@ -178,8 +175,8 @@ static struct snd_soc_dai_ops ak4101_dai_ops = {
.set_fmt = ak4104_set_dai_fmt,
};
struct snd_soc_dai ak4104_dai = {
.name = DRV_NAME,
static struct snd_soc_dai_driver ak4104_dai = {
.name = "ak4104-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@ -192,13 +189,71 @@ struct snd_soc_dai ak4104_dai = {
.ops = &ak4101_dai_ops,
};
static struct snd_soc_codec *ak4104_codec;
static int ak4104_probe(struct snd_soc_codec *codec)
{
struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
int ret, val;
codec->control_data = ak4104->control_data;
/* read all regs and fill the cache */
ret = ak4104_fill_cache(codec);
if (ret < 0) {
dev_err(codec->dev, "failed to fill register cache\n");
return ret;
}
/* read the 'reserved' register - according to the datasheet, it
* should contain 0x5b. Not a good way to verify the presence of
* the device, but there is no hardware ID register. */
if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
AK4104_RESERVED_VAL)
return -ENODEV;
/* set power-up and non-reset bits */
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
if (ret < 0)
return ret;
/* enable transmitter */
val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
val |= AK4104_TX_TXE;
ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
if (ret < 0)
return ret;
dev_info(codec->dev, "SPI device initialized\n");
return 0;
}
static int ak4104_remove(struct snd_soc_codec *codec)
{
int val, ret;
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
if (val < 0)
return val;
/* clear power-up and non-reset bits */
val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
return ret;
}
static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
.probe = ak4104_probe,
.remove = ak4104_remove,
.reg_cache_size = AK4104_NUM_REGS,
.reg_word_size = sizeof(u16),
};
static int ak4104_spi_probe(struct spi_device *spi)
{
struct snd_soc_codec *codec;
struct ak4104_private *ak4104;
int ret, val;
int ret;
spi->bits_per_word = 8;
spi->mode = SPI_MODE_0;
@ -207,125 +262,27 @@ static int ak4104_spi_probe(struct spi_device *spi)
return ret;
ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
if (!ak4104) {
dev_err(&spi->dev, "could not allocate codec\n");
if (ak4104 == NULL)
return -ENOMEM;
}
codec = &ak4104->codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
codec->dev = &spi->dev;
codec->name = DRV_NAME;
codec->owner = THIS_MODULE;
codec->dai = &ak4104_dai;
codec->num_dai = 1;
snd_soc_codec_set_drvdata(codec, ak4104);
codec->control_data = spi;
codec->reg_cache = ak4104->reg_cache;
codec->reg_cache_size = AK4104_NUM_REGS;
/* read all regs and fill the cache */
ret = ak4104_fill_cache(codec);
if (ret < 0) {
dev_err(&spi->dev, "failed to fill register cache\n");
return ret;
}
/* read the 'reserved' register - according to the datasheet, it
* should contain 0x5b. Not a good way to verify the presence of
* the device, but there is no hardware ID register. */
if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
AK4104_RESERVED_VAL) {
ret = -ENODEV;
goto error_free_codec;
}
/* set power-up and non-reset bits */
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
if (ret < 0)
goto error_free_codec;
/* enable transmitter */
val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
val |= AK4104_TX_TXE;
ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
if (ret < 0)
goto error_free_codec;
ak4104_codec = codec;
ret = snd_soc_register_dai(&ak4104_dai);
if (ret < 0) {
dev_err(&spi->dev, "failed to register DAI\n");
goto error_free_codec;
}
ak4104->control_data = spi;
ak4104->control_type = SND_SOC_SPI;
spi_set_drvdata(spi, ak4104);
dev_info(&spi->dev, "SPI device initialized\n");
return 0;
error_free_codec:
kfree(ak4104);
ak4104_dai.dev = NULL;
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_device_ak4104, &ak4104_dai, 1);
if (ret < 0)
kfree(ak4104);
return ret;
}
static int __devexit ak4104_spi_remove(struct spi_device *spi)
{
int ret, val;
struct ak4104_private *ak4104 = spi_get_drvdata(spi);
val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1);
if (val < 0)
return val;
/* clear power-up and non-reset bits */
val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
ret = ak4104_spi_write(&ak4104->codec, AK4104_REG_CONTROL1, val);
if (ret < 0)
return ret;
ak4104_codec = NULL;
kfree(ak4104);
snd_soc_unregister_codec(&spi->dev);
kfree(spi_get_drvdata(spi));
return 0;
}
static int ak4104_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = ak4104_codec;
int ret;
/* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
socdev->card->codec = codec;
/* Register PCMs */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(codec->dev, "failed to create pcms\n");
return ret;
}
return 0;
}
static int ak4104_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
return 0;
};
struct snd_soc_codec_device soc_codec_device_ak4104 = {
.probe = ak4104_probe,
.remove = ak4104_remove
};
EXPORT_SYMBOL_GPL(soc_codec_device_ak4104);
static struct spi_driver ak4104_spi_driver = {
.driver = {
.name = DRV_NAME,

View File

@ -1,7 +0,0 @@
#ifndef _AK4104_H
#define _AK4104_H
extern struct snd_soc_dai ak4104_dai;
extern struct snd_soc_codec_device soc_codec_device_ak4104;
#endif

View File

@ -31,11 +31,11 @@
#define AK4535_VERSION "0.3"
struct snd_soc_codec_device soc_codec_dev_ak4535;
/* codec private data */
struct ak4535_priv {
unsigned int sysclk;
enum snd_soc_control_type control_type;
void *control_data;
};
/*
@ -313,8 +313,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
int rate = params_rate(params), fs = 256;
@ -378,14 +377,16 @@ static int ak4535_mute(struct snd_soc_dai *dai, int mute)
static int ak4535_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
u16 i;
u16 i, mute_reg;
switch (level) {
case SND_SOC_BIAS_ON:
ak4535_mute(codec->dai, 0);
mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
ak4535_write(codec, AK4535_DAC, mute_reg);
break;
case SND_SOC_BIAS_PREPARE:
ak4535_mute(codec->dai, 1);
mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
break;
case SND_SOC_BIAS_STANDBY:
i = ak4535_read_reg_cache(codec, AK4535_PM1);
@ -413,8 +414,8 @@ static struct snd_soc_dai_ops ak4535_dai_ops = {
.set_sysclk = ak4535_set_dai_sysclk,
};
struct snd_soc_dai ak4535_dai = {
.name = "AK4535",
static struct snd_soc_dai_driver ak4535_dai = {
.name = "ak4535-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -429,54 +430,27 @@ struct snd_soc_dai ak4535_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.ops = &ak4535_dai_ops,
};
EXPORT_SYMBOL_GPL(ak4535_dai);
static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
static int ak4535_resume(struct platform_device *pdev)
static int ak4535_resume(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
ak4535_sync(codec);
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
/*
* initialise the AK4535 driver
* register the mixer and dsp interfaces with the kernel
*/
static int ak4535_init(struct snd_soc_device *socdev)
static int ak4535_probe(struct snd_soc_codec *codec)
{
struct snd_soc_codec *codec = socdev->card->codec;
int ret = 0;
struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
codec->name = "AK4535";
codec->owner = THIS_MODULE;
codec->read = ak4535_read_reg_cache;
codec->write = ak4535_write;
codec->set_bias_level = ak4535_set_bias_level;
codec->dai = &ak4535_dai;
codec->num_dai = 1;
codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL);
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
if (codec->reg_cache == NULL)
return -ENOMEM;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "ak4535: failed to create pcms\n");
goto pcm_err;
}
codec->control_data = ak4535->control_data;
/* power on device */
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@ -485,39 +459,55 @@ static int ak4535_init(struct snd_soc_device *socdev)
ARRAY_SIZE(ak4535_snd_controls));
ak4535_add_widgets(codec);
return ret;
pcm_err:
kfree(codec->reg_cache);
return ret;
return 0;
}
static struct snd_soc_device *ak4535_socdev;
/* power down chip */
static int ak4535_remove(struct snd_soc_codec *codec)
{
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
.probe = ak4535_probe,
.remove = ak4535_remove,
.suspend = ak4535_suspend,
.resume = ak4535_resume,
.read = ak4535_read_reg_cache,
.write = ak4535_write,
.set_bias_level = ak4535_set_bias_level,
.reg_cache_size = ARRAY_SIZE(ak4535_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = ak4535_reg,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int ak4535_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct snd_soc_device *socdev = ak4535_socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct ak4535_priv *ak4535;
int ret;
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
if (ak4535 == NULL)
return -ENOMEM;
ret = ak4535_init(socdev);
i2c_set_clientdata(i2c, ak4535);
ak4535->control_data = i2c;
ak4535->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_ak4535, &ak4535_dai, 1);
if (ret < 0)
printk(KERN_ERR "failed to initialise AK4535\n");
kfree(ak4535);
return ret;
}
static int ak4535_i2c_remove(struct i2c_client *client)
static __devexit int ak4535_i2c_remove(struct i2c_client *client)
{
struct snd_soc_codec *codec = i2c_get_clientdata(client);
kfree(codec->reg_cache);
snd_soc_unregister_codec(&client->dev);
kfree(i2c_get_clientdata(client));
return 0;
}
@ -529,138 +519,34 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
static struct i2c_driver ak4535_i2c_driver = {
.driver = {
.name = "AK4535 I2C Codec",
.name = "ak4535-codec",
.owner = THIS_MODULE,
},
.probe = ak4535_i2c_probe,
.remove = ak4535_i2c_remove,
.remove = __devexit_p(ak4535_i2c_remove),
.id_table = ak4535_i2c_id,
};
static int ak4535_add_i2c_device(struct platform_device *pdev,
const struct ak4535_setup_data *setup)
{
struct i2c_board_info info;
struct i2c_adapter *adapter;
struct i2c_client *client;
int ret;
ret = i2c_add_driver(&ak4535_i2c_driver);
if (ret != 0) {
dev_err(&pdev->dev, "can't add i2c driver\n");
return ret;
}
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = setup->i2c_address;
strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
adapter = i2c_get_adapter(setup->i2c_bus);
if (!adapter) {
dev_err(&pdev->dev, "can't get i2c adapter %d\n",
setup->i2c_bus);
goto err_driver;
}
client = i2c_new_device(adapter, &info);
i2c_put_adapter(adapter);
if (!client) {
dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
(unsigned int)info.addr);
goto err_driver;
}
return 0;
err_driver:
i2c_del_driver(&ak4535_i2c_driver);
return -ENODEV;
}
#endif
static int ak4535_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct ak4535_setup_data *setup;
struct snd_soc_codec *codec;
struct ak4535_priv *ak4535;
int ret;
printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
setup = socdev->codec_data;
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (codec == NULL)
return -ENOMEM;
ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
if (ak4535 == NULL) {
kfree(codec);
return -ENOMEM;
}
snd_soc_codec_set_drvdata(codec, ak4535);
socdev->card->codec = codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
ak4535_socdev = socdev;
ret = -ENODEV;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
if (setup->i2c_address) {
codec->hw_write = (hw_write_t)i2c_master_send;
ret = ak4535_add_i2c_device(pdev, setup);
}
#endif
if (ret != 0) {
kfree(snd_soc_codec_get_drvdata(codec));
kfree(codec);
}
return ret;
}
/* power down chip */
static int ak4535_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
if (codec->control_data)
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
if (codec->control_data)
i2c_unregister_device(codec->control_data);
i2c_del_driver(&ak4535_i2c_driver);
#endif
kfree(snd_soc_codec_get_drvdata(codec));
kfree(codec);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ak4535 = {
.probe = ak4535_probe,
.remove = ak4535_remove,
.suspend = ak4535_suspend,
.resume = ak4535_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
static int __init ak4535_modinit(void)
{
return snd_soc_register_dai(&ak4535_dai);
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&ak4535_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
ret);
}
#endif
return ret;
}
module_init(ak4535_modinit);
static void __exit ak4535_exit(void)
{
snd_soc_unregister_dai(&ak4535_dai);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&ak4535_i2c_driver);
#endif
}
module_exit(ak4535_exit);

View File

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

View File

@ -30,8 +30,6 @@
#include <sound/initval.h>
#include <sound/tlv.h>
#include "ak4642.h"
#define AK4642_VERSION "0.0.1"
#define PW_MGMT1 0x00
@ -102,7 +100,6 @@
#define FS3 (1 << 5)
#define FS_MASK (FS0 | FS1 | FS2 | FS3)
struct snd_soc_codec_device soc_codec_dev_ak4642;
/*
* Playback Volume (table 39)
@ -123,11 +120,11 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
/* codec private data */
struct ak4642_priv {
struct snd_soc_codec codec;
unsigned int sysclk;
enum snd_soc_control_type control_type;
void *control_data;
};
static struct snd_soc_codec *ak4642_codec;
/*
* ak4642 register cache
*/
@ -393,8 +390,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
.hw_params = ak4642_dai_hw_params,
};
struct snd_soc_dai ak4642_dai = {
.name = "AK4642",
static struct snd_soc_dai_driver ak4642_dai = {
.name = "ak4642-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -410,112 +407,63 @@ struct snd_soc_dai ak4642_dai = {
.ops = &ak4642_dai_ops,
.symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(ak4642_dai);
static int ak4642_resume(struct platform_device *pdev)
static int ak4642_resume(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
ak4642_sync(codec);
return 0;
}
/*
* initialise the AK4642 driver
* register the mixer and dsp interfaces with the kernel
*/
static int ak4642_init(struct ak4642_priv *ak4642)
static int ak4642_probe(struct snd_soc_codec *codec)
{
struct snd_soc_codec *codec = &ak4642->codec;
int ret = 0;
struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
if (ak4642_codec) {
dev_err(codec->dev, "Another ak4642 is registered\n");
return -EINVAL;
}
dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
snd_soc_codec_set_drvdata(codec, ak4642);
codec->name = "AK4642";
codec->owner = THIS_MODULE;
codec->read = ak4642_read_reg_cache;
codec->write = ak4642_write;
codec->dai = &ak4642_dai;
codec->num_dai = 1;
codec->hw_write = (hw_write_t)i2c_master_send;
codec->reg_cache_size = ARRAY_SIZE(ak4642_reg);
codec->reg_cache = kmemdup(ak4642_reg,
sizeof(ak4642_reg), GFP_KERNEL);
codec->control_data = ak4642->control_data;
if (!codec->reg_cache)
return -ENOMEM;
ak4642_dai.dev = codec->dev;
ak4642_codec = codec;
ret = snd_soc_register_codec(codec);
if (ret) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
goto reg_cache_err;
}
ret = snd_soc_register_dai(&ak4642_dai);
if (ret) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
snd_soc_unregister_codec(codec);
goto reg_cache_err;
}
return ret;
reg_cache_err:
kfree(codec->reg_cache);
codec->reg_cache = NULL;
return ret;
return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
.probe = ak4642_probe,
.resume = ak4642_resume,
.read = ak4642_read_reg_cache,
.write = ak4642_write,
.reg_cache_size = ARRAY_SIZE(ak4642_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = ak4642_reg,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int ak4642_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct ak4642_priv *ak4642;
struct snd_soc_codec *codec;
int ret;
ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
if (!ak4642)
if (ak4642 == NULL)
return -ENOMEM;
codec = &ak4642->codec;
codec->dev = &i2c->dev;
i2c_set_clientdata(i2c, ak4642);
codec->control_data = i2c;
ak4642->control_data = i2c;
ak4642->control_type = SND_SOC_I2C;
ret = ak4642_init(ak4642);
if (ret < 0) {
printk(KERN_ERR "failed to initialise AK4642\n");
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_ak4642, &ak4642_dai, 1);
if (ret < 0)
kfree(ak4642);
}
return ret;
}
static int ak4642_i2c_remove(struct i2c_client *client)
static __devexit int ak4642_i2c_remove(struct i2c_client *client)
{
struct ak4642_priv *ak4642 = i2c_get_clientdata(client);
snd_soc_unregister_dai(&ak4642_dai);
snd_soc_unregister_codec(&ak4642->codec);
kfree(ak4642->codec.reg_cache);
kfree(ak4642);
ak4642_codec = NULL;
snd_soc_unregister_codec(&client->dev);
kfree(i2c_get_clientdata(client));
return 0;
}
@ -528,64 +476,15 @@ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
static struct i2c_driver ak4642_i2c_driver = {
.driver = {
.name = "AK4642 I2C Codec",
.name = "ak4642-codec",
.owner = THIS_MODULE,
},
.probe = ak4642_i2c_probe,
.remove = ak4642_i2c_remove,
.id_table = ak4642_i2c_id,
.probe = ak4642_i2c_probe,
.remove = __devexit_p(ak4642_i2c_remove),
.id_table = ak4642_i2c_id,
};
#endif
static int ak4642_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
int ret;
if (!ak4642_codec) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
}
socdev->card->codec = ak4642_codec;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "ak4642: failed to create pcms\n");
goto pcm_err;
}
snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
ARRAY_SIZE(ak4642_snd_controls));
dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
return ret;
pcm_err:
return ret;
}
/* power down chip */
static int ak4642_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ak4642 = {
.probe = ak4642_probe,
.remove = ak4642_remove,
.resume = ak4642_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
static int __init ak4642_modinit(void)
{
int ret = 0;

View File

@ -1,20 +0,0 @@
/*
* ak4642.h -- AK4642 Soc Audio driver
*
* Copyright (C) 2009 Renesas Solutions Corp.
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
*
* Based on ak4535.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _AK4642_H
#define _AK4642_H
extern struct snd_soc_dai ak4642_dai;
extern struct snd_soc_codec_device soc_codec_dev_ak4642;
#endif

View File

@ -23,11 +23,11 @@
#include "ak4671.h"
static struct snd_soc_codec *ak4671_codec;
/* codec private data */
struct ak4671_priv {
struct snd_soc_codec codec;
enum snd_soc_control_type control_type;
void *control_data;
u8 reg_cache[AK4671_CACHEREGNUM];
};
@ -619,8 +619,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = {
.set_fmt = ak4671_set_dai_fmt,
};
struct snd_soc_dai ak4671_dai = {
.name = "AK4671",
static struct snd_soc_dai_driver ak4671_dai = {
.name = "ak4671-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -635,27 +635,19 @@ struct snd_soc_dai ak4671_dai = {
.formats = AK4671_FORMATS,},
.ops = &ak4671_dai_ops,
};
EXPORT_SYMBOL_GPL(ak4671_dai);
static int ak4671_probe(struct platform_device *pdev)
static int ak4671_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
int ret;
if (ak4671_codec == NULL) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
}
codec->hw_write = (hw_write_t)i2c_master_send;
codec->bias_level = SND_SOC_BIAS_OFF;
socdev->card->codec = ak4671_codec;
codec = ak4671_codec;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
if (ret < 0) {
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
goto pcm_err;
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
snd_soc_add_controls(codec, ak4671_snd_controls,
@ -665,121 +657,48 @@ static int ak4671_probe(struct platform_device *pdev)
ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return ret;
pcm_err:
return ret;
}
static int ak4671_remove(struct platform_device *pdev)
static int ak4671_remove(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_ak4671 = {
static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
.probe = ak4671_probe,
.remove = ak4671_remove,
.set_bias_level = ak4671_set_bias_level,
.reg_cache_size = AK4671_CACHEREGNUM,
.reg_word_size = sizeof(u8),
.reg_cache_default = ak4671_reg,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
static int ak4671_register(struct ak4671_priv *ak4671,
enum snd_soc_control_type control)
{
int ret;
struct snd_soc_codec *codec = &ak4671->codec;
if (ak4671_codec) {
dev_err(codec->dev, "Another AK4671 is registered\n");
ret = -EINVAL;
goto err;
}
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
snd_soc_codec_set_drvdata(codec, ak4671);
codec->name = "AK4671";
codec->owner = THIS_MODULE;
codec->bias_level = SND_SOC_BIAS_OFF;
codec->set_bias_level = ak4671_set_bias_level;
codec->dai = &ak4671_dai;
codec->num_dai = 1;
codec->reg_cache_size = AK4671_CACHEREGNUM;
codec->reg_cache = &ak4671->reg_cache;
memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
goto err;
}
ak4671_dai.dev = codec->dev;
ak4671_codec = codec;
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
goto err;
}
ret = snd_soc_register_dai(&ak4671_dai);
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
goto err_codec;
}
return 0;
err_codec:
snd_soc_unregister_codec(codec);
err:
kfree(ak4671);
return ret;
}
static void ak4671_unregister(struct ak4671_priv *ak4671)
{
ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
snd_soc_unregister_dai(&ak4671_dai);
snd_soc_unregister_codec(&ak4671->codec);
kfree(ak4671);
ak4671_codec = NULL;
}
static int __devinit ak4671_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ak4671_priv *ak4671;
struct snd_soc_codec *codec;
int ret;
ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
if (ak4671 == NULL)
return -ENOMEM;
codec = &ak4671->codec;
codec->hw_write = (hw_write_t)i2c_master_send;
i2c_set_clientdata(client, ak4671);
codec->control_data = client;
ak4671->control_data = client;
ak4671->control_type = SND_SOC_I2C;
codec->dev = &client->dev;
return ak4671_register(ak4671, SND_SOC_I2C);
ret = snd_soc_register_codec(&client->dev,
&soc_codec_dev_ak4671, &ak4671_dai, 1);
if (ret < 0)
kfree(ak4671);
return ret;
}
static __devexit int ak4671_i2c_remove(struct i2c_client *client)
{
struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
ak4671_unregister(ak4671);
snd_soc_unregister_codec(&client->dev);
kfree(i2c_get_clientdata(client));
return 0;
}
@ -791,7 +710,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
static struct i2c_driver ak4671_i2c_driver = {
.driver = {
.name = "ak4671",
.name = "ak4671-codec",
.owner = THIS_MODULE,
},
.probe = ak4671_i2c_probe,

View File

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

View File

@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/mfd/davinci_voicecodec.h>
#include <linux/spi/spi.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -41,8 +42,6 @@
#include <mach/dm365.h>
#include "cq93vc.h"
static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
unsigned int reg)
{
@ -130,8 +129,8 @@ static struct snd_soc_dai_ops cq93vc_dai_ops = {
.set_sysclk = cq93vc_set_dai_sysclk,
};
struct snd_soc_dai cq93vc_dai = {
.name = "CQ93VC",
static struct snd_soc_dai_driver cq93vc_dai = {
.name = "cq93vc-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -146,36 +145,20 @@ struct snd_soc_dai cq93vc_dai = {
.formats = CQ93VC_FORMATS,},
.ops = &cq93vc_dai_ops,
};
EXPORT_SYMBOL_GPL(cq93vc_dai);
static int cq93vc_resume(struct platform_device *pdev)
static int cq93vc_resume(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
static struct snd_soc_codec *cq93vc_codec;
static int cq93vc_probe(struct platform_device *pdev)
static int cq93vc_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
struct snd_soc_codec *codec;
int ret;
struct davinci_vc *davinci_vc = codec->dev->platform_data;
socdev->card->codec = cq93vc_codec;
codec = socdev->card->codec;
/* Register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(dev, "%s: failed to create pcms\n", pdev->name);
return ret;
}
davinci_vc->cq93vc.codec = codec;
codec->control_data = davinci_vc;
/* Set controls */
snd_soc_add_controls(codec, cq93vc_snd_controls,
@ -187,108 +170,51 @@ static int cq93vc_probe(struct platform_device *pdev)
return 0;
}
static int cq93vc_remove(struct platform_device *pdev)
static int cq93vc_remove(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
cq93vc_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_cq93vc = {
static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
.read = cq93vc_read,
.write = cq93vc_write,
.set_bias_level = cq93vc_set_bias_level,
.probe = cq93vc_probe,
.remove = cq93vc_remove,
.resume = cq93vc_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
static __init int cq93vc_codec_probe(struct platform_device *pdev)
static int cq93vc_platform_probe(struct platform_device *pdev)
{
struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret;
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (codec == NULL) {
dev_dbg(davinci_vc->dev,
"could not allocate memory for codec data\n");
return -ENOMEM;
}
davinci_vc->cq93vc.codec = codec;
cq93vc_dai.dev = &pdev->dev;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
codec->dev = &pdev->dev;
codec->name = "CQ93VC";
codec->owner = THIS_MODULE;
codec->read = cq93vc_read;
codec->write = cq93vc_write;
codec->set_bias_level = cq93vc_set_bias_level;
codec->dai = &cq93vc_dai;
codec->num_dai = 1;
codec->control_data = davinci_vc;
cq93vc_codec = codec;
ret = snd_soc_register_codec(codec);
if (ret) {
dev_err(davinci_vc->dev, "failed to register codec\n");
goto fail1;
}
ret = snd_soc_register_dai(&cq93vc_dai);
if (ret) {
dev_err(davinci_vc->dev, "could register dai\n");
goto fail2;
}
return 0;
fail2:
snd_soc_unregister_codec(codec);
fail1:
kfree(codec);
cq93vc_codec = NULL;
return ret;
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_cq93vc, &cq93vc_dai, 1);
}
static int __devexit cq93vc_codec_remove(struct platform_device *pdev)
static int cq93vc_platform_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
snd_soc_unregister_dai(&cq93vc_dai);
snd_soc_unregister_codec(&codec);
kfree(codec);
cq93vc_codec = NULL;
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver cq93vc_codec_driver = {
.driver = {
.name = "cq93vc",
.owner = THIS_MODULE,
},
.probe = cq93vc_codec_probe,
.remove = __devexit_p(cq93vc_codec_remove),
.name = "cq93vc-codec",
.owner = THIS_MODULE,
},
.probe = cq93vc_platform_probe,
.remove = __devexit_p(cq93vc_platform_remove),
};
static __init int cq93vc_init(void)
static int __init cq93vc_init(void)
{
return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe);
return platform_driver_register(&cq93vc_codec_driver);
}
module_init(cq93vc_init);
static __exit void cq93vc_exit(void)
static void __exit cq93vc_exit(void)
{
platform_driver_unregister(&cq93vc_codec_driver);
}

View File

@ -1,29 +0,0 @@
/*
* ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
*
* Copyright (C) 2010 Texas Instruments, Inc
*
* Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CQ93VC_H
#define _CQ93VC_H
extern struct snd_soc_dai cq93vc_dai;
extern struct snd_soc_codec_device soc_codec_dev_cq93vc;
#endif

View File

@ -31,8 +31,6 @@
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include "cs4270.h"
/*
* The codec isn't really big-endian or little-endian, since the I2S
* interface requires data to be sent serially with the MSbit first.
@ -114,7 +112,8 @@ static const char *supply_names[] = {
/* Private data for the CS4270 */
struct cs4270_private {
struct snd_soc_codec codec;
enum snd_soc_control_type control_type;
void *control_data;
u8 reg_cache[CS4270_NUMREGS];
unsigned int mclk; /* Input frequency of the MCLK pin */
unsigned int mode; /* The mode (I2S or left-justified) */
@ -212,44 +211,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_codec *codec = codec_dai->codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
unsigned int rates = 0;
unsigned int rate_min = -1;
unsigned int rate_max = 0;
unsigned int i;
cs4270->mclk = freq;
if (cs4270->mclk) {
for (i = 0; i < NUM_MCLK_RATIOS; i++) {
unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
rates |= snd_pcm_rate_to_rate_bit(rate);
if (rate < rate_min)
rate_min = rate;
if (rate > rate_max)
rate_max = rate;
}
/* FIXME: soc should support a rate list */
rates &= ~SNDRV_PCM_RATE_KNOT;
if (!rates) {
dev_err(codec->dev, "could not find a valid sample rate\n");
return -EINVAL;
}
} else {
/* enable all possible rates */
rates = SNDRV_PCM_RATE_8000_192000;
rate_min = 8000;
rate_max = 192000;
}
codec_dai->playback.rates = rates;
codec_dai->playback.rate_min = rate_min;
codec_dai->playback.rate_max = rate_max;
codec_dai->capture.rates = rates;
codec_dai->capture.rate_min = rate_min;
codec_dai->capture.rate_max = rate_max;
return 0;
}
@ -410,8 +373,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int ret;
unsigned int i;
@ -549,19 +511,6 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
snd_soc_get_volsw, cs4270_soc_put_mute),
};
/*
* cs4270_codec - global variable to store codec for the ASoC probe function
*
* If struct i2c_driver had a private_data field, we wouldn't need to use
* cs4270_codec. This is the only way to pass the codec structure from
* cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
* way to synchronize these two functions. cs4270_i2c_probe() can be called
* multiple times before cs4270_probe() is called even once. So for now, we
* also only allow cs4270_i2c_probe() to be run once. That means that we do
* not support more than one cs4270 device in the system, at least for now.
*/
static struct snd_soc_codec *cs4270_codec;
static struct snd_soc_dai_ops cs4270_dai_ops = {
.hw_params = cs4270_hw_params,
.set_sysclk = cs4270_set_dai_sysclk,
@ -569,20 +518,24 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
.digital_mute = cs4270_dai_mute,
};
struct snd_soc_dai cs4270_dai = {
.name = "cs4270",
struct snd_soc_dai_driver cs4270_dai = {
.name = "cs4270-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
.rates = 0,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 4000,
.rate_max = 216000,
.formats = CS4270_FORMATS,
},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 2,
.rates = 0,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 4000,
.rate_max = 216000,
.formats = CS4270_FORMATS,
},
.ops = &cs4270_dai_ops,
@ -596,153 +549,19 @@ EXPORT_SYMBOL_GPL(cs4270_dai);
* This function is called when ASoC has all the pieces it needs to
* instantiate a sound driver.
*/
static int cs4270_probe(struct platform_device *pdev)
static int cs4270_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int i, ret;
int i, ret, reg;
/* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
socdev->card->codec = codec;
/* Register PCMs */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(codec->dev, "failed to create pcms\n");
return ret;
}
/* Add the non-DAPM controls */
ret = snd_soc_add_controls(codec, cs4270_snd_controls,
ARRAY_SIZE(cs4270_snd_controls));
if (ret < 0) {
dev_err(codec->dev, "failed to add controls\n");
goto error_free_pcms;
}
/* get the power supply regulators */
for (i = 0; i < ARRAY_SIZE(supply_names); i++)
cs4270->supplies[i].supply = supply_names[i];
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
if (ret < 0)
goto error_free_pcms;
ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
if (ret < 0)
goto error_free_regulators;
return 0;
error_free_regulators:
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
error_free_pcms:
snd_soc_free_pcms(socdev);
return ret;
}
/**
* cs4270_remove - ASoC remove function
* @pdev: platform device
*
* This function is the counterpart to cs4270_probe().
*/
static int cs4270_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
snd_soc_free_pcms(socdev);
regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
return 0;
};
/**
* cs4270_i2c_probe - initialize the I2C interface of the CS4270
* @i2c_client: the I2C client object
* @id: the I2C device ID (ignored)
*
* This function is called whenever the I2C subsystem finds a device that
* matches the device ID given via a prior call to i2c_add_driver().
*/
static int cs4270_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct snd_soc_codec *codec;
struct cs4270_private *cs4270;
unsigned int reg;
int ret;
/* For now, we only support one cs4270 device in the system. See the
* comment for cs4270_codec.
*/
if (cs4270_codec) {
dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
i2c_client->addr);
dev_err(&i2c_client->dev, "only one per board allowed\n");
/* Should we return something other than ENODEV here? */
return -ENODEV;
}
/* Verify that we have a CS4270 */
ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
i2c_client->addr);
return ret;
}
/* The top four bits of the chip ID should be 1100. */
if ((ret & 0xF0) != 0xC0) {
dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
i2c_client->addr);
return -ENODEV;
}
dev_info(&i2c_client->dev, "found device at i2c address %X\n",
i2c_client->addr);
dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
/* Allocate enough space for the snd_soc_codec structure
and our private data together. */
cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
if (!cs4270) {
dev_err(&i2c_client->dev, "could not allocate codec\n");
return -ENOMEM;
}
codec = &cs4270->codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
codec->dev = &i2c_client->dev;
codec->name = "CS4270";
codec->owner = THIS_MODULE;
codec->dai = &cs4270_dai;
codec->num_dai = 1;
snd_soc_codec_set_drvdata(codec, cs4270);
codec->control_data = i2c_client;
codec->read = cs4270_read_reg_cache;
codec->write = cs4270_i2c_write;
codec->reg_cache = cs4270->reg_cache;
codec->reg_cache_size = CS4270_NUMREGS;
codec->control_data = cs4270->control_data;
/* The I2C interface is set up, so pre-fill our register cache */
ret = cs4270_fill_cache(codec);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to fill register cache\n");
goto error_free_codec;
dev_err(codec->dev, "failed to fill register cache\n");
return ret;
}
/* Disable auto-mute. This feature appears to be buggy. In some
@ -755,7 +574,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
reg &= ~CS4270_MUTE_AUTO;
ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
if (ret < 0) {
dev_err(&i2c_client->dev, "i2c write failed\n");
dev_err(codec->dev, "i2c write failed\n");
return ret;
}
@ -769,65 +588,56 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
if (ret < 0) {
dev_err(&i2c_client->dev, "i2c write failed\n");
dev_err(codec->dev, "i2c write failed\n");
return ret;
}
/* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
* structure for each CS4270 device, but the machine driver needs to
* have a pointer to the DAI structure, so for now it must be a global
* variable.
*/
cs4270_dai.dev = &i2c_client->dev;
/* Register the DAI. If all the other ASoC driver have already
* registered, then this will call our probe function, so
* cs4270_codec needs to be ready.
*/
cs4270_codec = codec;
ret = snd_soc_register_dai(&cs4270_dai);
/* Add the non-DAPM controls */
ret = snd_soc_add_controls(codec, cs4270_snd_controls,
ARRAY_SIZE(cs4270_snd_controls));
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to register DAIe\n");
goto error_free_codec;
dev_err(codec->dev, "failed to add controls\n");
return ret;
}
i2c_set_clientdata(i2c_client, cs4270);
/* get the power supply regulators */
for (i = 0; i < ARRAY_SIZE(supply_names); i++)
cs4270->supplies[i].supply = supply_names[i];
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
if (ret < 0)
return ret;
ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
if (ret < 0)
goto error_free_regulators;
return 0;
error_free_codec:
kfree(cs4270);
cs4270_codec = NULL;
cs4270_dai.dev = NULL;
error_free_regulators:
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
return ret;
}
/**
* cs4270_i2c_remove - remove an I2C device
* @i2c_client: the I2C client object
* cs4270_remove - ASoC remove function
* @pdev: platform device
*
* This function is the counterpart to cs4270_i2c_probe().
* This function is the counterpart to cs4270_probe().
*/
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
static int cs4270_remove(struct snd_soc_codec *codec)
{
struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
kfree(cs4270);
cs4270_codec = NULL;
cs4270_dai.dev = NULL;
regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
return 0;
}
/*
* cs4270_id - I2C device IDs supported by this driver
*/
static struct i2c_device_id cs4270_id[] = {
{"cs4270", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, cs4270_id);
#ifdef CONFIG_PM
@ -840,9 +650,8 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
* and all registers are written back to the hardware when resuming.
*/
static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
{
struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int reg, ret;
@ -860,9 +669,8 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
return 0;
}
static int cs4270_soc_resume(struct platform_device *pdev)
static int cs4270_soc_resume(struct snd_soc_codec *codec)
{
struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c_client = codec->control_data;
int reg;
@ -895,6 +703,95 @@ static int cs4270_soc_resume(struct platform_device *pdev)
#define cs4270_soc_resume NULL
#endif /* CONFIG_PM */
/*
* ASoC codec device structure
*
* Assign this variable to the codec_dev field of the machine driver's
* snd_soc_device structure.
*/
static struct snd_soc_codec_driver soc_codec_device_cs4270 = {
.probe = cs4270_probe,
.remove = cs4270_remove,
.suspend = cs4270_soc_suspend,
.resume = cs4270_soc_resume,
.read = cs4270_read_reg_cache,
.write = cs4270_i2c_write,
.reg_cache_size = CS4270_NUMREGS,
.reg_word_size = sizeof(u8),
};
/**
* cs4270_i2c_probe - initialize the I2C interface of the CS4270
* @i2c_client: the I2C client object
* @id: the I2C device ID (ignored)
*
* This function is called whenever the I2C subsystem finds a device that
* matches the device ID given via a prior call to i2c_add_driver().
*/
static int cs4270_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct cs4270_private *cs4270;
int ret;
/* Verify that we have a CS4270 */
ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
i2c_client->addr);
return ret;
}
/* The top four bits of the chip ID should be 1100. */
if ((ret & 0xF0) != 0xC0) {
dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
i2c_client->addr);
return -ENODEV;
}
dev_info(&i2c_client->dev, "found device at i2c address %X\n",
i2c_client->addr);
dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
if (!cs4270) {
dev_err(&i2c_client->dev, "could not allocate codec\n");
return -ENOMEM;
}
i2c_set_clientdata(i2c_client, cs4270);
cs4270->control_data = i2c_client;
cs4270->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs4270, &cs4270_dai, 1);
if (ret < 0)
kfree(cs4270);
return ret;
}
/**
* cs4270_i2c_remove - remove an I2C device
* @i2c_client: the I2C client object
*
* This function is the counterpart to cs4270_i2c_probe().
*/
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
{
snd_soc_unregister_codec(&i2c_client->dev);
kfree(i2c_get_clientdata(i2c_client));
return 0;
}
/*
* cs4270_id - I2C device IDs supported by this driver
*/
static struct i2c_device_id cs4270_id[] = {
{"cs4270", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, cs4270_id);
/*
* cs4270_i2c_driver - I2C device identification
*
@ -903,7 +800,7 @@ static int cs4270_soc_resume(struct platform_device *pdev)
*/
static struct i2c_driver cs4270_i2c_driver = {
.driver = {
.name = "cs4270",
.name = "cs4270-codec",
.owner = THIS_MODULE,
},
.id_table = cs4270_id,
@ -911,20 +808,6 @@ static struct i2c_driver cs4270_i2c_driver = {
.remove = cs4270_i2c_remove,
};
/*
* ASoC codec device structure
*
* Assign this variable to the codec_dev field of the machine driver's
* snd_soc_device structure.
*/
struct snd_soc_codec_device soc_codec_device_cs4270 = {
.probe = cs4270_probe,
.remove = cs4270_remove,
.suspend = cs4270_soc_suspend,
.resume = cs4270_soc_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
static int __init cs4270_init(void)
{
pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");

View File

@ -1,28 +0,0 @@
/*
* Cirrus Logic CS4270 ALSA SoC Codec Driver
*
* Author: Timur Tabi <timur@freescale.com>
*
* Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _CS4270_H
#define _CS4270_H
/*
* The ASoC codec DAI structure for the CS4270. Assign this structure to
* the .codec_dai field of your machine driver's snd_soc_dai_link structure.
*/
extern struct snd_soc_dai cs4270_dai;
/*
* The ASoC codec device structure for the CS4270. Assign this structure
* to the .codec_dev field of your machine driver's snd_soc_device
* structure.
*/
extern struct snd_soc_codec_device soc_codec_device_cs4270;
#endif

View File

@ -42,15 +42,14 @@ enum master_slave_mode {
};
struct cs42l51_private {
enum snd_soc_control_type control_type;
void *control_data;
unsigned int mclk;
unsigned int audio_mode; /* The mode (I2S or left-justified) */
enum master_slave_mode func;
struct snd_soc_codec codec;
u8 reg_cache[CS42L51_NUMREGS];
};
static struct snd_soc_codec *cs42l51_codec;
#define CS42L51_FORMATS ( \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
@ -75,134 +74,6 @@ static int cs42l51_fill_cache(struct snd_soc_codec *codec)
return 0;
}
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct snd_soc_codec *codec;
struct cs42l51_private *cs42l51;
int ret = 0;
int reg;
if (cs42l51_codec)
return -EBUSY;
/* Verify that we have a CS42L51 */
ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read I2C\n");
goto error;
}
if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
(ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
dev_err(&i2c_client->dev, "Invalid chip id\n");
ret = -ENODEV;
goto error;
}
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
ret & 7);
cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
if (!cs42l51) {
dev_err(&i2c_client->dev, "could not allocate codec\n");
return -ENOMEM;
}
codec = &cs42l51->codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
codec->dev = &i2c_client->dev;
codec->name = "CS42L51";
codec->owner = THIS_MODULE;
codec->dai = &cs42l51_dai;
codec->num_dai = 1;
snd_soc_codec_set_drvdata(codec, cs42l51);
codec->control_data = i2c_client;
codec->reg_cache = cs42l51->reg_cache;
codec->reg_cache_size = CS42L51_NUMREGS;
i2c_set_clientdata(i2c_client, codec);
ret = cs42l51_fill_cache(codec);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to fill register cache\n");
goto error_alloc;
}
ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
if (ret < 0) {
dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
goto error_alloc;
}
/*
* DAC configuration
* - Use signal processor
* - auto mute
* - vol changes immediate
* - no de-emphasize
*/
reg = CS42L51_DAC_CTL_DATA_SEL(1)
| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
if (ret < 0)
goto error_alloc;
cs42l51_dai.dev = codec->dev;
cs42l51_codec = codec;
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
goto error_alloc;
}
ret = snd_soc_register_dai(&cs42l51_dai);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to register DAIe\n");
goto error_reg;
}
return 0;
error_reg:
snd_soc_unregister_codec(codec);
error_alloc:
kfree(cs42l51);
error:
return ret;
}
static int cs42l51_i2c_remove(struct i2c_client *client)
{
struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
snd_soc_unregister_dai(&cs42l51_dai);
snd_soc_unregister_codec(cs42l51_codec);
cs42l51_codec = NULL;
kfree(cs42l51);
return 0;
}
static const struct i2c_device_id cs42l51_id[] = {
{"cs42l51", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
static struct i2c_driver cs42l51_i2c_driver = {
.driver = {
.name = "CS42L51 I2C",
.owner = THIS_MODULE,
},
.id_table = cs42l51_id,
.probe = cs42l51_i2c_probe,
.remove = cs42l51_i2c_remove,
};
static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@ -484,51 +355,8 @@ static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_codec *codec = codec_dai->codec;
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
struct cs42l51_ratios *ratios = NULL;
int nr_ratios = 0;
unsigned int rates = 0;
unsigned int rate_min = -1;
unsigned int rate_max = 0;
int i;
cs42l51->mclk = freq;
switch (cs42l51->func) {
case MODE_MASTER:
return -EINVAL;
case MODE_SLAVE:
ratios = slave_ratios;
nr_ratios = ARRAY_SIZE(slave_ratios);
break;
case MODE_SLAVE_AUTO:
ratios = slave_auto_ratios;
nr_ratios = ARRAY_SIZE(slave_auto_ratios);
break;
}
for (i = 0; i < nr_ratios; i++) {
unsigned int rate = freq / ratios[i].ratio;
rates |= snd_pcm_rate_to_rate_bit(rate);
if (rate < rate_min)
rate_min = rate;
if (rate > rate_max)
rate_max = rate;
}
rates &= ~SNDRV_PCM_RATE_KNOT;
if (!rates) {
dev_err(codec->dev, "could not find a valid sample rate\n");
return -EINVAL;
}
codec_dai->playback.rates = rates;
codec_dai->playback.rate_min = rate_min;
codec_dai->playback.rate_max = rate_max;
codec_dai->capture.rates = rates;
codec_dai->capture.rate_min = rate_min;
codec_dai->capture.rate_max = rate_max;
return 0;
}
@ -537,8 +365,7 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
int ret;
unsigned int i;
@ -670,8 +497,8 @@ static struct snd_soc_dai_ops cs42l51_dai_ops = {
.digital_mute = cs42l51_dai_mute,
};
struct snd_soc_dai cs42l51_dai = {
.name = "CS42L51 HiFi",
static struct snd_soc_dai_driver cs42l51_dai = {
.name = "cs42l51-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -688,30 +515,39 @@ struct snd_soc_dai cs42l51_dai = {
},
.ops = &cs42l51_dai_ops,
};
EXPORT_SYMBOL_GPL(cs42l51_dai);
static int cs42l51_probe(struct platform_device *pdev)
static int cs42l51_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
int ret, reg;
if (!cs42l51_codec) {
dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
return -EINVAL;
}
codec->control_data = cs42l51->control_data;
socdev->card->codec = cs42l51_codec;
codec = socdev->card->codec;
/* Register PCMs */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
ret = cs42l51_fill_cache(codec);
if (ret < 0) {
dev_err(&pdev->dev, "failed to create PCMs\n");
dev_err(codec->dev, "failed to fill register cache\n");
return ret;
}
ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
/*
* DAC configuration
* - Use signal processor
* - auto mute
* - vol changes immediate
* - no de-emphasize
*/
reg = CS42L51_DAC_CTL_DATA_SEL(1)
| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
if (ret < 0)
return ret;
snd_soc_add_controls(codec, cs42l51_snd_controls,
ARRAY_SIZE(cs42l51_snd_controls));
snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
@ -722,22 +558,77 @@ static int cs42l51_probe(struct platform_device *pdev)
return 0;
}
static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
.probe = cs42l51_probe,
.reg_cache_size = CS42L51_NUMREGS,
.reg_word_size = sizeof(u8),
};
static int cs42l51_remove(struct platform_device *pdev)
static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct cs42l51_private *cs42l51;
int ret;
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
/* Verify that we have a CS42L51 */
ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read I2C\n");
goto error;
}
if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
(ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
dev_err(&i2c_client->dev, "Invalid chip id\n");
ret = -ENODEV;
goto error;
}
dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
ret & 7);
cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
if (!cs42l51) {
dev_err(&i2c_client->dev, "could not allocate codec\n");
return -ENOMEM;
}
i2c_set_clientdata(i2c_client, cs42l51);
cs42l51->control_data = i2c_client;
cs42l51->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs42l51, &cs42l51_dai, 1);
if (ret < 0)
kfree(cs42l51);
error:
return ret;
}
static int cs42l51_i2c_remove(struct i2c_client *client)
{
struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
snd_soc_unregister_codec(&client->dev);
kfree(cs42l51);
return 0;
}
struct snd_soc_codec_device soc_codec_device_cs42l51 = {
.probe = cs42l51_probe,
.remove = cs42l51_remove
static const struct i2c_device_id cs42l51_id[] = {
{"cs42l51", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, cs42l51_id);
static struct i2c_driver cs42l51_i2c_driver = {
.driver = {
.name = "cs42L51-codec",
.owner = THIS_MODULE,
},
.id_table = cs42l51_id,
.probe = cs42l51_i2c_probe,
.remove = cs42l51_i2c_remove,
};
EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
static int __init cs42l51_init(void)
{

View File

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

View File

@ -24,7 +24,8 @@
struct cx20442_priv {
struct snd_soc_codec codec;
enum snd_soc_control_type control_type;
void *control_data;
u8 reg_cache[1];
};
@ -102,7 +103,7 @@ static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
{
u8 *reg_cache = codec->reg_cache;
if (reg >= codec->reg_cache_size)
if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
return reg_cache[reg];
@ -164,16 +165,17 @@ static int cx20442_pm_to_v253_vsp(u8 value)
static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
u8 *reg_cache = codec->reg_cache;
int vls, vsp, old, len;
char buf[18];
if (reg >= codec->reg_cache_size)
if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
/* hw_write and control_data pointers required for talking to the modem
* are expected to be set by the line discipline initialization code */
if (!codec->hw_write || !codec->control_data)
if (!codec->hw_write || !cx20442->control_data)
return -EIO;
old = reg_cache[reg];
@ -202,17 +204,13 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
return -ENOMEM;
dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
if (codec->hw_write(codec->control_data, buf, len) != len)
if (codec->hw_write(cx20442->control_data, buf, len) != len)
return -EIO;
return 0;
}
/* Moved up here as line discipline referres it during initialization */
static struct snd_soc_codec *cx20442_codec;
/*
* Line discpline related code
*
@ -228,15 +226,15 @@ static const char *v253_init = "ate0m0q0+fclass=8\r";
/* Line discipline .open() */
static int v253_open(struct tty_struct *tty)
{
struct snd_soc_codec *codec = cx20442_codec;
int ret, len = strlen(v253_init);
/* Doesn't make sense without write callback */
if (!tty->ops->write)
return -EINVAL;
/* Pass the codec structure address for use by other ldisc callbacks */
tty->disc_data = codec;
/* Won't work if no codec pointer has been passed by a card driver */
if (!tty->disc_data)
return -ENODEV;
if (tty->ops->write(tty, v253_init, len) != len) {
ret = -EIO;
@ -253,15 +251,18 @@ err:
static void v253_close(struct tty_struct *tty)
{
struct snd_soc_codec *codec = tty->disc_data;
struct cx20442_priv *cx20442;
tty->disc_data = NULL;
if (!codec)
return;
cx20442 = snd_soc_codec_get_drvdata(codec);
/* Prevent the codec driver from further accessing the modem */
codec->hw_write = NULL;
codec->control_data = NULL;
cx20442->control_data = NULL;
codec->pop_time = 0;
}
@ -277,15 +278,18 @@ static void v253_receive(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct snd_soc_codec *codec = tty->disc_data;
struct cx20442_priv *cx20442;
if (!codec)
return;
if (!codec->control_data) {
cx20442 = snd_soc_codec_get_drvdata(codec);
if (!cx20442->control_data) {
/* First modem response, complete setup procedure */
/* Set up codec driver access to modem controls */
codec->control_data = tty;
cx20442->control_data = tty;
codec->hw_write = (hw_write_t)tty->ops->write;
codec->pop_time = 1;
}
@ -313,8 +317,8 @@ EXPORT_SYMBOL_GPL(v253_ops);
* Codec DAI
*/
struct snd_soc_dai cx20442_dai = {
.name = "CX20442",
static struct snd_soc_dai_driver cx20442_dai = {
.name = "cx20442-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@ -330,142 +334,63 @@ struct snd_soc_dai cx20442_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
};
EXPORT_SYMBOL_GPL(cx20442_dai);
static int cx20442_codec_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret;
if (!cx20442_codec) {
dev_err(&pdev->dev, "cx20442 not yet discovered\n");
return -ENODEV;
}
codec = cx20442_codec;
socdev->card->codec = codec;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(&pdev->dev, "failed to create pcms\n");
goto pcm_err;
}
cx20442_add_widgets(codec);
pcm_err:
return ret;
}
/* power down chip */
static int cx20442_codec_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
}
struct snd_soc_codec_device cx20442_codec_dev = {
.probe = cx20442_codec_probe,
.remove = cx20442_codec_remove,
};
EXPORT_SYMBOL_GPL(cx20442_codec_dev);
static int cx20442_register(struct cx20442_priv *cx20442)
{
struct snd_soc_codec *codec = &cx20442->codec;
int ret;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
codec->name = "CX20442";
codec->owner = THIS_MODULE;
snd_soc_codec_set_drvdata(codec, cx20442);
codec->dai = &cx20442_dai;
codec->num_dai = 1;
codec->reg_cache = &cx20442->reg_cache;
codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
codec->read = cx20442_read_reg_cache;
codec->write = cx20442_write;
codec->bias_level = SND_SOC_BIAS_OFF;
cx20442_dai.dev = codec->dev;
cx20442_codec = codec;
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
goto err;
}
ret = snd_soc_register_dai(&cx20442_dai);
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
goto err_codec;
}
return 0;
err_codec:
snd_soc_unregister_codec(codec);
err:
cx20442_codec = NULL;
kfree(cx20442);
return ret;
}
static void cx20442_unregister(struct cx20442_priv *cx20442)
{
snd_soc_unregister_dai(&cx20442_dai);
snd_soc_unregister_codec(&cx20442->codec);
cx20442_codec = NULL;
kfree(cx20442);
}
static int cx20442_platform_probe(struct platform_device *pdev)
static int cx20442_codec_probe(struct snd_soc_codec *codec)
{
struct cx20442_priv *cx20442;
struct snd_soc_codec *codec;
cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
if (cx20442 == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, cx20442);
codec = &cx20442->codec;
cx20442_add_widgets(codec);
codec->control_data = NULL;
cx20442->control_data = NULL;
codec->hw_write = NULL;
codec->pop_time = 0;
codec->dev = &pdev->dev;
platform_set_drvdata(pdev, cx20442);
return 0;
}
return cx20442_register(cx20442);
/* power down chip */
static int cx20442_codec_remove(struct snd_soc_codec *codec)
{
struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
if (cx20442->control_data) {
struct tty_struct *tty = cx20442->control_data;
tty_hangup(tty);
}
kfree(cx20442);
return 0;
}
static struct snd_soc_codec_driver cx20442_codec_dev = {
.probe = cx20442_codec_probe,
.remove = cx20442_codec_remove,
.reg_cache_size = 1,
.reg_word_size = sizeof(u8),
.read = cx20442_read_reg_cache,
.write = cx20442_write,
};
static int cx20442_platform_probe(struct platform_device *pdev)
{
return snd_soc_register_codec(&pdev->dev,
&cx20442_codec_dev, &cx20442_dai, 1);
}
static int __exit cx20442_platform_remove(struct platform_device *pdev)
{
struct cx20442_priv *cx20442 = platform_get_drvdata(pdev);
cx20442_unregister(cx20442);
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver cx20442_platform_driver = {
.driver = {
.name = "cx20442",
.name = "cx20442-codec",
.owner = THIS_MODULE,
},
.probe = cx20442_platform_probe,
@ -487,4 +412,4 @@ module_exit(cx20442_exit);
MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
MODULE_AUTHOR("Janusz Krzysztofik");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:cx20442");
MODULE_ALIAS("platform:cx20442-codec");

View File

@ -13,8 +13,6 @@
#ifndef _CX20442_CODEC_H
#define _CX20442_CODEC_H
extern struct snd_soc_dai cx20442_dai;
extern struct snd_soc_codec_device cx20442_codec_dev;
extern struct tty_ldisc_ops v253_ops;
#endif

View File

@ -25,8 +25,6 @@
#include <sound/initval.h>
#include <sound/tlv.h>
#include "da7210.h"
/* DA7210 register space */
#define DA7210_STATUS 0x02
#define DA7210_STARTUP1 0x03
@ -162,11 +160,10 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
/* Codec private data */
struct da7210_priv {
struct snd_soc_codec codec;
enum snd_soc_control_type control_type;
void *control_data;
};
static struct snd_soc_codec *da7210_codec;
/*
* Register cache
*/
@ -209,12 +206,12 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
u8 *cache = codec->reg_cache;
u8 data[2];
BUG_ON(codec->volatile_register);
BUG_ON(codec->driver->volatile_register);
data[0] = reg & 0xff;
data[1] = value & 0xff;
if (reg >= codec->reg_cache_size)
if (reg >= codec->driver->reg_cache_size)
return -EIO;
if (2 != codec->hw_write(codec->control_data, data, 2))
@ -267,8 +264,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec = rtd->codec;
u32 dai_cfg1;
u32 hpf_reg, hpf_mask, hpf_value;
u32 fs, bypass;
@ -430,9 +426,8 @@ static struct snd_soc_dai_ops da7210_dai_ops = {
.set_fmt = da7210_set_dai_fmt,
};
struct snd_soc_dai da7210_dai = {
.name = "DA7210 IIS",
.id = 0,
static struct snd_soc_dai_driver da7210_dai = {
.name = "da7210-hifi",
/* playback capabilities */
.playback = {
.stream_name = "Playback",
@ -452,55 +447,15 @@ struct snd_soc_dai da7210_dai = {
.ops = &da7210_dai_ops,
.symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(da7210_dai);
/*
* Initialize the DA7210 driver
* register the mixer and dsp interfaces with the kernel
*/
static int da7210_init(struct da7210_priv *da7210)
static int da7210_probe(struct snd_soc_codec *codec)
{
struct snd_soc_codec *codec = &da7210->codec;
int ret = 0;
struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
if (da7210_codec) {
dev_err(codec->dev, "Another da7210 is registered\n");
return -EINVAL;
}
dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
snd_soc_codec_set_drvdata(codec, da7210);
codec->name = "DA7210";
codec->owner = THIS_MODULE;
codec->read = da7210_read;
codec->write = da7210_write;
codec->dai = &da7210_dai;
codec->num_dai = 1;
codec->control_data = da7210->control_data;
codec->hw_write = (hw_write_t)i2c_master_send;
codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
codec->reg_cache = kmemdup(da7210_reg,
sizeof(da7210_reg), GFP_KERNEL);
if (!codec->reg_cache)
return -ENOMEM;
da7210_dai.dev = codec->dev;
da7210_codec = codec;
ret = snd_soc_register_codec(codec);
if (ret) {
dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
goto init_err;
}
ret = snd_soc_register_dai(&da7210_dai);
if (ret) {
dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
goto codec_err;
}
/* FIXME
*
@ -583,54 +538,50 @@ static int da7210_init(struct da7210_priv *da7210)
/* Activate all enabled subsystem */
da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
return ret;
snd_soc_add_controls(codec, da7210_snd_controls,
ARRAY_SIZE(da7210_snd_controls));
codec_err:
snd_soc_unregister_codec(codec);
init_err:
kfree(codec->reg_cache);
codec->reg_cache = NULL;
return ret;
dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
.probe = da7210_probe,
.read = da7210_read,
.write = da7210_write,
.reg_cache_size = ARRAY_SIZE(da7210_reg),
.reg_word_size = sizeof(u8),
.reg_cache_default = da7210_reg,
};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct da7210_priv *da7210;
struct snd_soc_codec *codec;
int ret;
da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
if (!da7210)
return -ENOMEM;
codec = &da7210->codec;
codec->dev = &i2c->dev;
i2c_set_clientdata(i2c, da7210);
codec->control_data = i2c;
da7210->control_data = i2c;
da7210->control_type = SND_SOC_I2C;
ret = da7210_init(da7210);
if (ret < 0) {
pr_err("Failed to initialise da7210 audio codec\n");
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_da7210, &da7210_dai, 1);
if (ret < 0)
kfree(da7210);
}
return ret;
}
static int __devexit da7210_i2c_remove(struct i2c_client *client)
{
struct da7210_priv *da7210 = i2c_get_clientdata(client);
snd_soc_unregister_dai(&da7210_dai);
kfree(da7210->codec.reg_cache);
kfree(da7210);
da7210_codec = NULL;
snd_soc_unregister_codec(&client->dev);
kfree(i2c_get_clientdata(client));
return 0;
}
@ -643,7 +594,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
/* I2C codec control layer */
static struct i2c_driver da7210_i2c_driver = {
.driver = {
.name = "DA7210 I2C Codec",
.name = "da7210-codec",
.owner = THIS_MODULE,
},
.probe = da7210_i2c_probe,
@ -652,50 +603,6 @@ static struct i2c_driver da7210_i2c_driver = {
};
#endif
static int da7210_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret;
if (!da7210_codec) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
}
socdev->card->codec = da7210_codec;
codec = da7210_codec;
/* Register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0)
goto pcm_err;
snd_soc_add_controls(da7210_codec, da7210_snd_controls,
ARRAY_SIZE(da7210_snd_controls));
dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
pcm_err:
return ret;
}
static int da7210_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_da7210 = {
.probe = da7210_probe,
.remove = da7210_remove,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
static int __init da7210_modinit(void)
{
int ret = 0;

View File

@ -1,24 +0,0 @@
/*
* da7210.h -- audio driver for da7210
*
* Copyright (c) 2009 Dialog Semiconductor
* Written by David Chen <Dajun.chen@diasemi.com>
*
* Copyright (C) 2009 Renesas Solutions Corp.
* Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef _DA7210_H
#define _DA7210_H
extern struct snd_soc_dai da7210_dai;
extern struct snd_soc_codec_device soc_codec_dev_da7210;
#endif

View File

@ -74,29 +74,22 @@ static const uint32_t jz4740_codec_regs[] = {
struct jz4740_codec {
void __iomem *base;
struct resource *mem;
uint32_t reg_cache[2];
struct snd_soc_codec codec;
};
static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
{
return container_of(codec, struct jz4740_codec, codec);
}
static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
unsigned int reg)
{
struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
return readl(jz4740_codec->base + (reg << 2));
}
static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int val)
{
struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
u32 *cache = codec->reg_cache;
jz4740_codec->reg_cache[reg] = val;
cache[reg] = val;
writel(val, jz4740_codec->base + (reg << 2));
return 0;
@ -172,8 +165,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
{
uint32_t val;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_codec *codec =rtd->codec;
switch (params_rate(params)) {
case 8000:
@ -219,8 +211,8 @@ static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
.hw_params = jz4740_codec_hw_params,
};
struct snd_soc_dai jz4740_codec_dai = {
.name = "jz4740",
static struct snd_soc_dai_driver jz4740_codec_dai = {
.name = "jz4740-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@ -238,7 +230,6 @@ struct snd_soc_dai jz4740_codec_dai = {
.ops = &jz4740_codec_dai_ops,
.symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(jz4740_codec_dai);
static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
{
@ -302,23 +293,10 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
static struct snd_soc_codec *jz4740_codec_codec;
static int jz4740_codec_dev_probe(struct platform_device *pdev)
static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
{
int ret;
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = jz4740_codec_codec;
BUG_ON(!codec);
socdev->card->codec = codec;
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret) {
dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
return ret;
}
snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
snd_soc_add_controls(codec, jz4740_codec_controls,
ARRAY_SIZE(jz4740_codec_controls));
@ -331,34 +309,27 @@ static int jz4740_codec_dev_probe(struct platform_device *pdev)
snd_soc_dapm_new_widgets(codec);
jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
static int jz4740_codec_dev_remove(struct platform_device *pdev)
static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state)
static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
static int jz4740_codec_resume(struct platform_device *pdev)
static int jz4740_codec_resume(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
}
@ -367,19 +338,23 @@ static int jz4740_codec_resume(struct platform_device *pdev)
#define jz4740_codec_resume NULL
#endif
struct snd_soc_codec_device soc_codec_dev_jz4740_codec = {
static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
.probe = jz4740_codec_dev_probe,
.remove = jz4740_codec_dev_remove,
.suspend = jz4740_codec_suspend,
.resume = jz4740_codec_resume,
.read = jz4740_codec_read,
.write = jz4740_codec_write,
.set_bias_level = jz4740_codec_set_bias_level,
.reg_cache_default = jz4740_codec_regs,
.reg_word_size = sizeof(u32),
.reg_cache_size = 2,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
static int __devinit jz4740_codec_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_codec *jz4740_codec;
struct snd_soc_codec *codec;
struct resource *mem;
jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
@ -408,55 +383,17 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev)
}
jz4740_codec->mem = mem;
jz4740_codec_dai.dev = &pdev->dev;
codec = &jz4740_codec->codec;
codec->dev = &pdev->dev;
codec->name = "jz4740";
codec->owner = THIS_MODULE;
codec->read = jz4740_codec_read;
codec->write = jz4740_codec_write;
codec->set_bias_level = jz4740_codec_set_bias_level;
codec->bias_level = SND_SOC_BIAS_OFF;
codec->dai = &jz4740_codec_dai;
codec->num_dai = 1;
codec->reg_cache = jz4740_codec->reg_cache;
codec->reg_cache_size = 2;
memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
jz4740_codec_codec = codec;
snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
platform_set_drvdata(pdev, jz4740_codec);
ret = snd_soc_register_codec(codec);
ret = snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
if (ret) {
dev_err(&pdev->dev, "Failed to register codec\n");
goto err_iounmap;
}
ret = snd_soc_register_dai(&jz4740_codec_dai);
if (ret) {
dev_err(&pdev->dev, "Failed to register codec dai\n");
goto err_unregister_codec;
}
jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
err_unregister_codec:
snd_soc_unregister_codec(codec);
err_iounmap:
iounmap(jz4740_codec->base);
err_release_mem_region:
@ -472,8 +409,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev)
struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
struct resource *mem = jz4740_codec->mem;
snd_soc_unregister_dai(&jz4740_codec_dai);
snd_soc_unregister_codec(&jz4740_codec->codec);
snd_soc_unregister_codec(&pdev->dev);
iounmap(jz4740_codec->base);
release_mem_region(mem->start, resource_size(mem));

View File

@ -1,20 +0,0 @@
/*
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __SND_SOC_CODECS_JZ4740_CODEC_H__
#define __SND_SOC_CODECS_JZ4740_CODEC_H__
extern struct snd_soc_dai jz4740_codec_dai;
extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
#endif

View File

@ -32,8 +32,8 @@
#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000)
struct snd_soc_dai pcm3008_dai = {
.name = "PCM3008 HiFi",
static struct snd_soc_dai_driver pcm3008_dai = {
.name = "pcm3008-hifi",
.playback = {
.stream_name = "PCM3008 Playback",
.channels_min = 1,
@ -49,7 +49,6 @@ struct snd_soc_dai pcm3008_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
};
EXPORT_SYMBOL_GPL(pcm3008_dai);
static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
{
@ -59,38 +58,13 @@ static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
gpio_free(setup->pdda_pin);
}
static int pcm3008_soc_probe(struct platform_device *pdev)
static int pcm3008_soc_probe(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
struct pcm3008_setup_data *setup = socdev->codec_data;
struct pcm3008_setup_data *setup = codec->dev->platform_data;
int ret = 0;
printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
if (!socdev->card->codec)
return -ENOMEM;
codec = socdev->card->codec;
mutex_init(&codec->mutex);
codec->name = "PCM3008";
codec->owner = THIS_MODULE;
codec->dai = &pcm3008_dai;
codec->num_dai = 1;
codec->write = NULL;
codec->read = NULL;
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
/* Register PCMs. */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "pcm3008: failed to create pcms\n");
goto pcm_err;
}
/* DEM1 DEM0 DE-EMPHASIS_MODE
* Low Low De-emphasis 44.1 kHz ON
* Low High De-emphasis OFF
@ -130,33 +104,22 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
gpio_err:
pcm3008_gpio_free(setup);
pcm_err:
kfree(socdev->card->codec);
return ret;
}
static int pcm3008_soc_remove(struct platform_device *pdev)
static int pcm3008_soc_remove(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
struct pcm3008_setup_data *setup = socdev->codec_data;
if (!codec)
return 0;
struct pcm3008_setup_data *setup = codec->dev->platform_data;
pcm3008_gpio_free(setup);
snd_soc_free_pcms(socdev);
kfree(socdev->card->codec);
return 0;
}
#ifdef CONFIG_PM
static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct pcm3008_setup_data *setup = socdev->codec_data;
struct pcm3008_setup_data *setup = codec->dev->platform_data;
gpio_set_value(setup->pdad_pin, 0);
gpio_set_value(setup->pdda_pin, 0);
@ -164,10 +127,9 @@ static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
return 0;
}
static int pcm3008_soc_resume(struct platform_device *pdev)
static int pcm3008_soc_resume(struct snd_soc_codec *codec)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct pcm3008_setup_data *setup = socdev->codec_data;
struct pcm3008_setup_data *setup = codec->dev->platform_data;
gpio_set_value(setup->pdad_pin, 1);
gpio_set_value(setup->pdda_pin, 1);
@ -179,23 +141,45 @@ static int pcm3008_soc_resume(struct platform_device *pdev)
#define pcm3008_soc_resume NULL
#endif
struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
.probe = pcm3008_soc_probe,
.remove = pcm3008_soc_remove,
.suspend = pcm3008_soc_suspend,
.resume = pcm3008_soc_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
static int __init pcm3008_init(void)
static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
{
return snd_soc_register_dai(&pcm3008_dai);
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_pcm3008, &pcm3008_dai, 1);
}
module_init(pcm3008_init);
static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
MODULE_ALIAS("platform:pcm3008-codec");
static struct platform_driver pcm3008_codec_driver = {
.probe = pcm3008_codec_probe,
.remove = __devexit_p(pcm3008_codec_remove),
.driver = {
.name = "pcm3008-codec",
.owner = THIS_MODULE,
},
};
static int __init pcm3008_modinit(void)
{
return platform_driver_register(&pcm3008_codec_driver);
}
module_init(pcm3008_modinit);
static void __exit pcm3008_exit(void)
{
snd_soc_unregister_dai(&pcm3008_dai);
platform_driver_unregister(&pcm3008_codec_driver);
}
module_exit(pcm3008_exit);

View File

@ -19,7 +19,4 @@ struct pcm3008_setup_data {
unsigned pdda_pin;
};
extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
extern struct snd_soc_dai pcm3008_dai;
#endif

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