Merge branch 'topic/asoc' into for-linus

Conflicts:
	arch/powerpc/platforms/85xx/p1022_ds.c
This commit is contained in:
Takashi Iwai 2010-10-25 10:00:30 +02:00
commit aa5c14d5c0
380 changed files with 31740 additions and 16402 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

@ -776,9 +776,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 | \
@ -826,6 +832,40 @@ void ep93xx_i2s_release(void)
}
EXPORT_SYMBOL(ep93xx_i2s_release);
/*************************************************************************
* EP93xx AC97 audio peripheral handling
*************************************************************************/
static struct resource ep93xx_ac97_resources[] = {
{
.start = EP93XX_AAC_PHYS_BASE,
.end = EP93XX_AAC_PHYS_BASE + 0xb0 - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_EP93XX_AACINTR,
.end = IRQ_EP93XX_AACINTR,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device ep93xx_ac97_device = {
.name = "ep93xx-ac97",
.id = -1,
.num_resources = ARRAY_SIZE(ep93xx_ac97_resources),
.resource = ep93xx_ac97_resources,
};
void __init ep93xx_register_ac97(void)
{
/*
* Make sure that the AC97 pins are not used by I2S.
*/
ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONAC97);
platform_device_register(&ep93xx_ac97_device);
platform_device_register(&ep93xx_pcm_device);
}
extern void ep93xx_gpio_init(void);
void __init ep93xx_init_devices(void)

View File

@ -105,6 +105,7 @@
#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8)
#define EP93XX_AAC_PHYS_BASE EP93XX_APB_PHYS(0x00080000)
#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000)

View File

@ -61,6 +61,7 @@ void ep93xx_keypad_release_gpio(struct platform_device *pdev);
void ep93xx_register_i2s(void);
int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config);
void ep93xx_i2s_release(void);
void ep93xx_register_ac97(void);
void ep93xx_init_devices(void);
extern struct sys_timer ep93xx_timer;

View File

@ -61,6 +61,7 @@ static void __init simone_init_machine(void)
ep93xx_register_fb(&simone_fb_info);
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
ARRAY_SIZE(simone_i2c_board_info));
ep93xx_register_ac97();
}
MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")

View File

@ -903,10 +903,16 @@ static struct platform_device kirkwood_i2s_device = {
},
};
static struct platform_device kirkwood_pcm_device = {
.name = "kirkwood-pcm-audio",
.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

@ -25,6 +25,7 @@
#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/omap7xx.h>
#include <plat/mcbsp.h>
/*-------------------------------------------------------------------------*/
@ -195,6 +196,30 @@ static inline void omap_init_spi100k(void)
static inline void omap_init_sti(void) {}
#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
/*-------------------------------------------------------------------------*/
/*
@ -227,6 +252,7 @@ static int __init omap1_init_devices(void)
omap_init_rtc();
omap_init_spi100k();
omap_init_sti();
omap_init_audio();
return 0;
}

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/board.h>
@ -689,7 +690,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,
@ -710,10 +710,6 @@ static struct twl4030_platform_data rx51_twldata __initdata = {
.vio = &rx51_vio,
};
static struct aic3x_pdata rx51_aic3x_data __initdata = {
.gpio_reset = 60,
};
static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata = {
.id = TPA6130A2,
.power_gpio = 98,
@ -728,6 +724,17 @@ 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_aic3x_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),

View File

@ -24,6 +24,8 @@
#include <plat/common.h>
#include <plat/usb.h>
#include <mach/board-zoom.h>
#include "mux.h"
#include "hsmmc.h"
@ -188,6 +190,11 @@ static int zoom_twl_gpio_setup(struct device *dev,
return 0;
}
/* EXTMUTE callback function */
void zoom2_set_hs_extmute(int mute)
{
gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
}
static int zoom_batt_table[] = {
/* 0 C*/
@ -257,6 +264,11 @@ static struct i2c_board_info __initdata zoom_i2c_boardinfo[] = {
static int __init omap_i2c_init(void)
{
if (machine_is_omap_zoom2()) {
zoom_audio_data.ramp_delay_value = 3; /* 161 ms */
zoom_audio_data.hs_extmute = 1;
zoom_audio_data.set_hs_extmute = zoom2_set_hs_extmute;
}
omap_register_i2c_bus(1, 2400, zoom_i2c_boardinfo,
ARRAY_SIZE(zoom_i2c_boardinfo));
omap_register_i2c_bus(2, 400, NULL, 0);

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,41 +35,6 @@ 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
static struct twl4030_madc_platform_data zoom2_madc_data = {
.irq_line = 1,
};
static struct twl4030_codec_audio_data zoom2_audio_data = {
.audio_mclk = 26000000,
};
static struct twl4030_codec_data zoom2_codec_data = {
.audio_mclk = 26000000,
.audio = &zoom2_audio_data,
};
static struct twl4030_platform_data zoom2_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
/* platform_data for children goes here */
.bci = &zoom2_bci_data,
.madc = &zoom2_madc_data,
.usb = &zoom2_usb_data,
.gpio = &zoom2_gpio_data,
.keypad = &zoom2_kp_twl4030_data,
.codec = &zoom2_codec_data,
.vmmc1 = &zoom2_vmmc1,
.vmmc2 = &zoom2_vmmc2,
.vsim = &zoom2_vsim,
};
#endif
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* WLAN IRQ - GPIO 162 */

View File

@ -25,6 +25,7 @@
#include <plat/control.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mcbsp.h>
#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/dma.h>
@ -235,6 +236,43 @@ static inline void omap_init_mbox(void) { }
static inline void omap_init_sti(void) {}
#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>
@ -847,6 +885,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

@ -9,3 +9,5 @@
extern void __init board_nand_init(struct mtd_partition *, u8 nr_parts, u8 cs);
extern int __init zoom_debugboard_init(void);
extern void __init zoom_peripherals_init(void);
#define ZOOM2_HEADSET_EXTMUTE_GPIO 153

View File

@ -354,6 +354,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

@ -38,4 +38,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

@ -385,6 +385,10 @@ static struct platform_device *devices[] __initdata = {
&pxa27x_device_udc,
&pxa_device_pmu,
&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

@ -610,6 +610,11 @@ static struct platform_device *devices[] __initdata = {
&pxa27x_device_udc,
&pxa_device_pmu,
&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

@ -43,8 +43,10 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
break;
default:
printk(KERN_DEBUG "Invalid I2S Controller number!");
printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
pdev->id);
return -EINVAL;
}
@ -184,7 +186,8 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
break;
default:
printk(KERN_DEBUG "Invalid PCM Controller number!");
printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
pdev->id);
return -EINVAL;
}
@ -333,3 +336,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

@ -283,6 +283,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_ohci,
&s3c_device_usb_hsotg,
&s3c_device_pcm,
&s3c64xx_device_iisv4,
&samsung_device_keypad,

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

@ -247,7 +247,7 @@ static struct resource s3c_iis_resource[] = {
static u64 s3c_device_iis_dmamask = 0xffffffffUL;
struct platform_device s3c_device_iis = {
.name = "s3c2410-iis",
.name = "s3c24xx-iis",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_iis_resource),
.resource = s3c_iis_resource,
@ -259,6 +259,21 @@ struct platform_device s3c_device_iis = {
EXPORT_SYMBOL(s3c_device_iis);
/* ASoC PCM DMA */
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);
/* RTC */
static struct resource s3c_rtc_resource[] = {
@ -481,19 +496,30 @@ static struct resource s3c_ac97_resource[] = {
},
};
static u64 s3c_device_ac97_dmamask = 0xffffffffUL;
struct platform_device s3c_device_ac97 = {
.name = "s3c-ac97",
.id = -1,
.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 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

@ -429,6 +429,11 @@ static struct platform_device db1200_audio_dev = {
.resource = au1200_psc1_res,
};
static struct platform_device db1200_stac_dev = {
.name = "ac97-codec",
.id = 1, /* on PSC1 */
};
static struct platform_device *db1200_devs[] __initdata = {
NULL, /* PSC0, selected by S6.8 */
&db1200_ide_dev,
@ -436,6 +441,7 @@ static struct platform_device *db1200_devs[] __initdata = {
&db1200_rtc_dev,
&db1200_nand_dev,
&db1200_audio_dev,
&db1200_stac_dev,
};
static int __init db1200_dev_init(void)

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

@ -124,6 +124,9 @@ CONFIG_I2C_CPM=m
CONFIG_I2C_MPC=y
# CONFIG_HWMON is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
CONFIG_FB_FSL_DIU=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_SOUND=y
CONFIG_SND=y
# CONFIG_SND_SUPPORT_OLD_API is not set

View File

@ -126,6 +126,9 @@ CONFIG_I2C_CPM=m
CONFIG_I2C_MPC=y
# CONFIG_HWMON is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
CONFIG_FB_FSL_DIU=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_SOUND=y
CONFIG_SND=y
# CONFIG_SND_SUPPORT_OLD_API is not set

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

@ -8,7 +8,6 @@
* Copyright 2010 Freescale Semiconductor, Inc.
*
* This file is taken from the Freescale P1022DS BSP, with modifications:
* 1) No DIU support (pending rewrite of DIU code)
* 2) No AMP support
* 3) No PCI endpoint support
*
@ -20,12 +19,211 @@
#include <linux/pci.h>
#include <linux/of_platform.h>
#include <linux/memblock.h>
#include <asm/div64.h>
#include <asm/mpic.h>
#include <asm/swiotlb.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include <asm/fsl_guts.h>
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
/*
* Board-specific initialization of the DIU. This code should probably be
* executed when the DIU is opened, rather than in arch code, but the DIU
* driver does not have a mechanism for this (yet).
*
* This is especially problematic on the P1022DS because the local bus (eLBC)
* and the DIU video signals share the same pins, which means that enabling the
* DIU will disable access to NOR flash.
*/
/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */
#define CLKDVDR_PXCKEN 0x80000000
#define CLKDVDR_PXCKINV 0x10000000
#define CLKDVDR_PXCKDLY 0x06000000
#define CLKDVDR_PXCLK_MASK 0x00FF0000
/* Some ngPIXIS register definitions */
#define PX_BRDCFG1_DVIEN 0x80
#define PX_BRDCFG1_DFPEN 0x40
#define PX_BRDCFG1_BACKLIGHT 0x20
#define PX_BRDCFG1_DDCEN 0x10
/*
* DIU Area Descriptor
*
* Note that we need to byte-swap the value before it's written to the AD
* register. So even though the registers don't look like they're in the same
* bit positions as they are on the MPC8610, the same value is written to the
* AD register on the MPC8610 and on the P1022.
*/
#define AD_BYTE_F 0x10000000
#define AD_ALPHA_C_MASK 0x0E000000
#define AD_ALPHA_C_SHIFT 25
#define AD_BLUE_C_MASK 0x01800000
#define AD_BLUE_C_SHIFT 23
#define AD_GREEN_C_MASK 0x00600000
#define AD_GREEN_C_SHIFT 21
#define AD_RED_C_MASK 0x00180000
#define AD_RED_C_SHIFT 19
#define AD_PALETTE 0x00040000
#define AD_PIXEL_S_MASK 0x00030000
#define AD_PIXEL_S_SHIFT 16
#define AD_COMP_3_MASK 0x0000F000
#define AD_COMP_3_SHIFT 12
#define AD_COMP_2_MASK 0x00000F00
#define AD_COMP_2_SHIFT 8
#define AD_COMP_1_MASK 0x000000F0
#define AD_COMP_1_SHIFT 4
#define AD_COMP_0_MASK 0x0000000F
#define AD_COMP_0_SHIFT 0
#define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \
cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \
(blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \
(red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \
(c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
(c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
/**
* p1022ds_get_pixel_format: return the Area Descriptor for a given pixel depth
*
* The Area Descriptor is a 32-bit value that determine which bits in each
* pixel are to be used for each color.
*/
static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
int monitor_port)
{
switch (bits_per_pixel) {
case 32:
/* 0x88883316 */
return MAKE_AD(3, 2, 0, 1, 3, 8, 8, 8, 8);
case 24:
/* 0x88082219 */
return MAKE_AD(4, 0, 1, 2, 2, 0, 8, 8, 8);
case 16:
/* 0x65053118 */
return MAKE_AD(4, 2, 1, 0, 1, 5, 6, 5, 0);
default:
pr_err("fsl-diu: unsupported pixel depth %u\n", bits_per_pixel);
return 0;
}
}
/**
* p1022ds_set_gamma_table: update the gamma table, if necessary
*
* On some boards, the gamma table for some ports may need to be modified.
* This is not the case on the P1022DS, so we do nothing.
*/
static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
{
}
/**
* p1022ds_set_monitor_port: switch the output to a different monitor port
*
*/
static void p1022ds_set_monitor_port(int monitor_port)
{
struct device_node *pixis_node;
u8 __iomem *brdcfg1;
pixis_node = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis");
if (!pixis_node) {
pr_err("p1022ds: missing ngPIXIS node\n");
return;
}
brdcfg1 = of_iomap(pixis_node, 0);
if (!brdcfg1) {
pr_err("p1022ds: could not map ngPIXIS registers\n");
return;
}
brdcfg1 += 9; /* BRDCFG1 is at offset 9 in the ngPIXIS */
switch (monitor_port) {
case 0: /* DVI */
/* Enable the DVI port, disable the DFP and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DVIEN);
break;
case 1: /* Single link LVDS */
/* Enable the DFP port, disable the DVI and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DFPEN);
break;
default:
pr_err("p1022ds: unsupported monitor port %i\n", monitor_port);
}
}
/**
* p1022ds_set_pixel_clock: program the DIU's clock
*
* @pixclock: the wavelength, in picoseconds, of the clock
*/
void p1022ds_set_pixel_clock(unsigned int pixclock)
{
struct device_node *guts_np = NULL;
struct ccsr_guts_85xx __iomem *guts;
unsigned long freq;
u64 temp;
u32 pxclk;
/* Map the global utilities registers. */
guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
if (!guts_np) {
pr_err("p1022ds: missing global utilties device node\n");
return;
}
guts = of_iomap(guts_np, 0);
of_node_put(guts_np);
if (!guts) {
pr_err("p1022ds: could not map global utilties device\n");
return;
}
/* Convert pixclock from a wavelength to a frequency */
temp = 1000000000000ULL;
do_div(temp, pixclock);
freq = temp;
/* pixclk is the ratio of the platform clock to the pixel clock */
pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
/* Disable the pixel clock, and set it to non-inverted and no delay */
clrbits32(&guts->clkdvdr,
CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
/* Enable the clock and set the pxclk */
setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
}
/**
* p1022ds_show_monitor_port: show the current monitor
*
* This function returns a string indicating whether the current monitor is
* set to DVI or LVDS.
*/
ssize_t p1022ds_show_monitor_port(int monitor_port, char *buf)
{
return sprintf(buf, "%c0 - DVI\n%c1 - Single link LVDS\n",
monitor_port == 0 ? '*' : ' ', monitor_port == 1 ? '*' : ' ');
}
/**
* p1022ds_set_sysfs_monitor_port: set the monitor port for sysfs
*/
int p1022ds_set_sysfs_monitor_port(int val)
{
return val < 2 ? val : 0;
}
#endif
void __init p1022_ds_pic_init(void)
{
@ -92,6 +290,15 @@ static void __init p1022_ds_setup_arch(void)
}
#endif
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diu_ops.get_pixel_format = p1022ds_get_pixel_format;
diu_ops.set_gamma_table = p1022ds_set_gamma_table;
diu_ops.set_monitor_port = p1022ds_set_monitor_port;
diu_ops.set_pixel_clock = p1022ds_set_pixel_clock;
diu_ops.show_monitor_port = p1022ds_show_monitor_port;
diu_ops.set_sysfs_monitor_port = p1022ds_set_sysfs_monitor_port;
#endif
#ifdef CONFIG_SMP
mpc85xx_smp_init();
#endif

View File

@ -551,7 +551,7 @@ static struct resource siu_resources[] = {
};
static struct platform_device siu_device = {
.name = "sh_siu",
.name = "siu-pcm-audio",
.id = -1,
.dev = {
.platform_data = &siu_platform_data,

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

@ -12,4 +12,4 @@ TODO:
- get rid of non-linux related stuff
Please send patches to:
Arnaud Patard <apatard@mandriva.com>
Arnaud Patard <arnaud.patard@rtp-net.org>

View File

@ -1919,6 +1919,9 @@ config FB_SH_MOBILE_HDMI
tristate "SuperH Mobile HDMI controller support"
depends on FB_SH_MOBILE_LCDC
select FB_MODE_HELPERS
select SOUND
select SND
select SND_SOC
---help---
Driver for the on-chip SH-Mobile HDMI controller.

View File

@ -22,6 +22,8 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <video/sh_mobile_hdmi.h>
#include <video/sh_mobile_lcdc.h>
@ -222,6 +224,58 @@ static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
return ioread8(hdmi->base + reg);
}
/*
* HDMI sound
*/
static unsigned int sh_hdmi_snd_read(struct snd_soc_codec *codec,
unsigned int reg)
{
struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
return hdmi_read(hdmi, reg);
}
static int sh_hdmi_snd_write(struct snd_soc_codec *codec,
unsigned int reg,
unsigned int value)
{
struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
hdmi_write(hdmi, value, reg);
return 0;
}
static struct snd_soc_dai_driver sh_hdmi_dai = {
.name = "sh_mobile_hdmi-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
},
};
static int sh_hdmi_snd_probe(struct snd_soc_codec *codec)
{
dev_info(codec->dev, "SH Mobile HDMI Audio Codec");
return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
.probe = sh_hdmi_snd_probe,
.read = sh_hdmi_snd_read,
.write = sh_hdmi_snd_write,
};
/*
* HDMI video
*/
/* External video parameter settings */
static void hdmi_external_video_param(struct sh_hdmi *hdmi)
{
@ -318,6 +372,9 @@ static void sh_hdmi_video_config(struct sh_hdmi *hdmi)
*/
static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
{
u8 data;
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
/*
* [7:4] L/R data swap control
* [3:0] appropriate N[19:16]
@ -335,7 +392,23 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
* [6:5] set required down sampling rate if required
* [4:3] set required audio source
*/
hdmi_write(hdmi, 0x00, HDMI_AUDIO_SETTING_1);
switch (pdata->flags & HDMI_SND_SRC_MASK) {
default:
/* fall through */
case HDMI_SND_SRC_I2S:
data = 0x0 << 3;
break;
case HDMI_SND_SRC_SPDIF:
data = 0x1 << 3;
break;
case HDMI_SND_SRC_DSD:
data = 0x2 << 3;
break;
case HDMI_SND_SRC_HBR:
data = 0x3 << 3;
break;
}
hdmi_write(hdmi, data, HDMI_AUDIO_SETTING_1);
/* [3:0] set sending channel number for channel status */
hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2);
@ -891,6 +964,11 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
return -ENOMEM;
}
ret = snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
if (ret < 0)
goto esndreg;
hdmi->dev = &pdev->dev;
hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
@ -976,6 +1054,8 @@ eclkenable:
erate:
clk_put(hdmi->hdmi_clk);
egetclk:
snd_soc_unregister_codec(&pdev->dev);
esndreg:
kfree(hdmi);
return ret;
@ -988,6 +1068,8 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0);
snd_soc_unregister_codec(&pdev->dev);
pdata->lcd_chan->board_cfg.display_on = NULL;
pdata->lcd_chan->board_cfg.display_off = NULL;
pdata->lcd_chan->board_cfg.board_data = NULL;

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

50
include/sound/max98088.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Platform data for MAX98088
*
* Copyright 2010 Maxim Integrated Products
*
* 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 __SOUND_MAX98088_PDATA_H__
#define __SOUND_MAX98088_PDATA_H__
/* Equalizer filter response configuration */
struct max98088_eq_cfg {
const char *name;
unsigned int rate;
u16 band1[5];
u16 band2[5];
u16 band3[5];
u16 band4[5];
u16 band5[5];
};
/* codec platform data */
struct max98088_pdata {
/* Equalizers for DAI1 and DAI2 */
struct max98088_eq_cfg *eq_cfg;
unsigned int eq_cfgcnt;
/* Receiver output can be configured as power amplifier or LINE out */
/* Set receiver_mode to:
* 0 = amplifier output, or
* 1 = LINE level output
*/
unsigned int receiver_mode:1;
/* Analog/digital microphone configuration:
* 0 = analog microphone input (normal setting)
* 1 = digital microphone input
*/
unsigned int digmic_left_mode:1;
unsigned int digmic_right_mode:1;
};
#endif

View File

@ -114,7 +114,4 @@ 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;
#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

@ -172,9 +172,19 @@
#define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
.reg = wreg, .shift = wshift, .invert = winvert }
#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wslot, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
.reg = wreg, .shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags }
#define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
.reg = wreg, .shift = wshift, .invert = winvert }
#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wslot, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
.reg = wreg, .shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags }
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
@ -322,14 +332,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

@ -214,10 +214,10 @@
* @OFF: Power Off. No restrictions on transition times.
*/
enum snd_soc_bias_level {
SND_SOC_BIAS_ON,
SND_SOC_BIAS_PREPARE,
SND_SOC_BIAS_STANDBY,
SND_SOC_BIAS_OFF,
SND_SOC_BIAS_STANDBY,
SND_SOC_BIAS_PREPARE,
SND_SOC_BIAS_ON,
};
struct snd_jack;
@ -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,
@ -382,7 +385,7 @@ struct snd_soc_jack_gpio {
int invert;
int debounce_time;
struct snd_soc_jack *jack;
struct work_struct work;
struct delayed_work work;
int (*jack_status_check)(void);
};
@ -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,36 @@ 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 ac97_created:1; /* Codec has been created by SoC */
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 +459,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 +467,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 +515,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 +547,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 +585,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 +642,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

32
include/sound/wm8962.h Normal file
View File

@ -0,0 +1,32 @@
/*
* wm8962.h -- WM8962 Soc Audio driver platform data
*
* 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 _WM8962_PDATA_H
#define _WM8962_PDATA_H
#define WM8962_MAX_GPIO 6
/* Use to set GPIO default values to zero */
#define WM8962_GPIO_SET 0x10000
struct wm8962_pdata {
int gpio_base;
u32 gpio_init[WM8962_MAX_GPIO];
/* Setup for microphone detection, raw value to be written to
* R48(0x30) - only microphone related bits will be updated.
* Detection may be enabled here for use with signals brought
* out on the GPIOs. */
u32 mic_cfg;
bool irq_active_low;
bool spk_mono; /* Speaker outputs tied together as mono */
};
#endif

View File

@ -14,9 +14,25 @@
struct sh_mobile_lcdc_chan_cfg;
struct device;
/*
* flags format
*
* 0x0000000A
*
* A: Audio source select
*/
/* Audio source select */
#define HDMI_SND_SRC_MASK (0xF << 0)
#define HDMI_SND_SRC_I2S (0 << 0) /* default */
#define HDMI_SND_SRC_SPDIF (1 << 0)
#define HDMI_SND_SRC_DSD (2 << 0)
#define HDMI_SND_SRC_HBR (3 << 0)
struct sh_mobile_hdmi_info {
struct sh_mobile_lcdc_chan_cfg *lcd_chan;
struct device *lcd_dev;
unsigned int flags;
};
#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,94 @@ 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));
BUG_ON(pdev->id < 0);
BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
}
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_dai(&pdev->dev);
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),
};
/**
* atmel_ssc_set_audio - Allocate the specified SSC for audio use.
*/
int atmel_ssc_set_audio(int ssc_id)
{
struct ssc_device *ssc;
static struct platform_device *dma_pdev;
struct platform_device *ssc_pdev;
int ret;
if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
return -EINVAL;
/* Allocate a dummy device for DMA if we don't have one already */
if (!dma_pdev) {
dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
if (!dma_pdev)
return -ENOMEM;
ret = platform_device_add(dma_pdev);
if (ret < 0) {
platform_device_put(dma_pdev);
dma_pdev = NULL;
return ret;
}
}
ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
if (!ssc_pdev) {
ssc_free(ssc);
return -ENOMEM;
}
/* If we can grab the SSC briefly to parent the DAI device off it */
ssc = ssc_request(ssc_id);
if (IS_ERR(ssc))
pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
PTR_ERR(ssc));
else
ssc_pdev->dev.parent = &(ssc->pdev->dev);
ssc_free(ssc);
ret = platform_device_add(ssc_pdev);
if (ret < 0)
platform_device_put(ssc_pdev);
return ret;
}
EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
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,7 @@ 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[];
int atmel_ssc_set_audio(int ssc);
#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,16 +136,17 @@ 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
"at91sam9g20ek_wm8731 "
": at91sam9g20ek_wm8731_init() called\n");
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
MCLK_RATE, SND_SOC_CLOCK_IN);
if (ret < 0) {
printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
@ -179,37 +180,37 @@ 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-001b",
.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;
if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
return -ENODEV;
ret = atmel_ssc_set_audio(0);
if (ret != 0) {
pr_err("Failed to set SSC 0 for audio: %d\n", ret);
return ret;
}
/*
* Codec MCLK is supplied by PCK0 - set it up.
*/
@ -235,18 +236,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 +243,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 +253,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 +262,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,
.codec_dai_name = "ac97-hifi",
.cpu_dai_name = "au1xpsc_ac97.1",
.platform_name = "au1xpsc-pcm.1",
.codec_name = "ac97-codec.1",
};
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,12 +44,12 @@ 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 */
snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
12000000, SND_SOC_CLOCK_IN);
/* codec is bitclock and lrclk master */
@ -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,
.codec_dai_name = "wm8731-hifi",
.cpu_dai_name = "au1xpsc_i2s.1",
.platform_name = "au1xpsc-pcm.1",
.codec_name = "wm8731-codec.0-001b",
.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 ---------------------------*/
@ -106,18 +97,16 @@ static int __init db1200_audio_load(void)
int ret;
ret = -ENOMEM;
db1200_asoc_dev = platform_device_alloc("soc-audio", -1);
db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */
if (!db1200_asoc_dev)
goto out;
/* 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

@ -10,9 +10,6 @@
*
* DMA glue for Au1x-PSC audio.
*
* NOTE: all of these drivers can only work with a SINGLE instance
* of a PSC. Multiple independent audio devices are impossible
* with ASoC v1.
*/
@ -61,9 +58,6 @@ struct au1xpsc_audio_dmadata {
int msbits;
};
/* instance data. There can be only one, MacLeod!!!! */
static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2];
/*
* These settings are somewhat okay, at least on my machine audio plays
* almost skip-free. Especially the 64kB buffer seems to help a LOT.
@ -199,6 +193,14 @@ out:
return 0;
}
static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss)
{
struct snd_soc_pcm_runtime *rtd = ss->private_data;
struct au1xpsc_audio_dmadata *pcd =
snd_soc_platform_get_drvdata(rtd->platform);
return &pcd[SUBSTREAM_TYPE(ss)];
}
static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@ -211,7 +213,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
goto out;
stype = SUBSTREAM_TYPE(substream);
pcd = au1xpsc_audio_pcmdma[stype];
pcd = to_dmadata(substream);
DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
"runtime->min_align %d\n",
@ -249,8 +251,7 @@ static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream)
static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
{
struct au1xpsc_audio_dmadata *pcd =
au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)];
struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
au1xxx_dbdma_reset(pcd->ddma_chan);
@ -267,7 +268,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
u32 c = au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->ddma_chan;
u32 c = to_dmadata(substream)->ddma_chan;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@ -287,8 +288,7 @@ static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t
au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
{
return bytes_to_frames(substream->runtime,
au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->pos);
return bytes_to_frames(substream->runtime, to_dmadata(substream)->pos);
}
static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
@ -299,7 +299,7 @@ static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
{
au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]);
au1x_pcm_dbdma_free(to_dmadata(substream));
return 0;
}
@ -329,42 +329,21 @@ static int au1xpsc_pcm_new(struct snd_card *card,
return 0;
}
static int au1xpsc_pcm_probe(struct platform_device *pdev)
{
if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
return -ENODEV;
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",
.probe = au1xpsc_pcm_probe,
.remove = au1xpsc_pcm_remove,
.pcm_ops = &au1xpsc_pcm_ops,
struct snd_soc_platform_driver au1xpsc_soc_platform = {
.ops = &au1xpsc_pcm_ops,
.pcm_new = au1xpsc_pcm_new,
.pcm_free = au1xpsc_pcm_free_dma_buffers,
};
EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
{
struct au1xpsc_audio_dmadata *dmadata;
struct resource *r;
int ret;
if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX])
return -EBUSY;
/* TX DMA */
au1xpsc_audio_pcmdma[PCM_TX]
= kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
if (!au1xpsc_audio_pcmdma[PCM_TX])
dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
if (!dmadata)
return -ENOMEM;
r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@ -372,47 +351,33 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
ret = -ENODEV;
goto out1;
}
(au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start;
dmadata[PCM_TX].ddma_id = r->start;
/* RX DMA */
au1xpsc_audio_pcmdma[PCM_RX]
= kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
if (!au1xpsc_audio_pcmdma[PCM_RX])
return -ENOMEM;
r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!r) {
ret = -ENODEV;
goto out2;
goto out1;
}
(au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
dmadata[PCM_RX].ddma_id = r->start;
ret = snd_soc_register_platform(&au1xpsc_soc_platform);
platform_set_drvdata(pdev, dmadata);
ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
if (!ret)
return ret;
out2:
kfree(au1xpsc_audio_pcmdma[PCM_RX]);
au1xpsc_audio_pcmdma[PCM_RX] = NULL;
out1:
kfree(au1xpsc_audio_pcmdma[PCM_TX]);
au1xpsc_audio_pcmdma[PCM_TX] = NULL;
kfree(dmadata);
return ret;
}
static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
{
int i;
struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev);
snd_soc_unregister_platform(&au1xpsc_soc_platform);
for (i = 0; i < 2; i++) {
if (au1xpsc_audio_pcmdma[i]) {
au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
kfree(au1xpsc_audio_pcmdma[i]);
au1xpsc_audio_pcmdma[i] = NULL;
}
}
snd_soc_unregister_platform(&pdev->dev);
kfree(dmadata);
return 0;
}
@ -428,8 +393,6 @@ static struct platform_driver au1xpsc_pcm_driver = {
static int __init au1xpsc_audio_dbdma_load(void)
{
au1xpsc_audio_pcmdma[PCM_TX] = NULL;
au1xpsc_audio_pcmdma[PCM_RX] = NULL;
return platform_driver_register(&au1xpsc_pcm_driver);
}
@ -467,7 +430,7 @@ struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
res[1].start = res[1].end = id[1];
res[0].flags = res[1].flags = IORESOURCE_DMA;
pd = platform_device_alloc("au1xpsc-pcm", -1);
pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
if (!pd)
goto out;

View File

@ -10,9 +10,6 @@
*
* Au1xxx-PSC AC97 glue.
*
* NOTE: all of these drivers can only work with a SINGLE instance
* of a PSC. Multiple independent audio devices are impossible
* with ASoC v1.
*/
#include <linux/init.h>
@ -56,12 +53,29 @@
/* instance data. There can be only one, MacLeod!!!! */
static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
#if 0
/* this could theoretically work, but ac97->bus->card->private_data can be NULL
* when snd_ac97_mixer() is called; I don't know if the rest further down the
* chain are always valid either.
*/
static inline struct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x)
{
struct snd_soc_card *c = x->bus->card->private_data;
return snd_soc_dai_get_drvdata(c->rtd->cpu_dai);
}
#else
#define ac97_to_pscdata(x) au1xpsc_ac97_workdata
#endif
/* AC97 controller reads codec register */
static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{
/* FIXME */
struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
unsigned short retry, tmo;
unsigned long data;
@ -102,8 +116,7 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
unsigned short val)
{
/* FIXME */
struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
unsigned int tmo, retry;
au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
@ -134,8 +147,7 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
/* AC97 controller asserts a warm reset */
static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
{
/* FIXME */
struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata));
au_sync();
@ -146,8 +158,7 @@ static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
{
/* FIXME */
struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
int i;
/* disable PSC during cold reset */
@ -202,8 +213,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
/* FIXME */
struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
unsigned long r, ro, stat;
int chans, t, stype = SUBSTREAM_TYPE(substream);
@ -283,8 +293,7 @@ out:
static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
/* FIXME */
struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
int ret, stype = SUBSTREAM_TYPE(substream);
ret = 0;
@ -315,27 +324,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",
static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
.ac97_control = 1,
.probe = au1xpsc_ac97_probe,
.remove = au1xpsc_ac97_remove,
.playback = {
.rates = AC97_RATES,
.formats = AC97_FMTS,
@ -350,7 +351,6 @@ struct snd_soc_dai au1xpsc_ac97_dai = {
},
.ops = &au1xpsc_ac97_dai_ops,
};
EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
{
@ -359,9 +359,6 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
unsigned long sel;
struct au1xpsc_audio_data *wd;
if (au1xpsc_ac97_workdata)
return -EBUSY;
wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
if (!wd)
return -ENOMEM;
@ -395,18 +392,24 @@ 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);
/* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */
memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template,
sizeof(struct snd_soc_dai_driver));
wd->dai_drv.name = dev_name(&pdev->dev);
platform_set_drvdata(pdev, wd);
ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
if (ret)
goto out1;
wd->dmapd = au1xpsc_pcm_add(pdev);
if (wd->dmapd) {
platform_set_drvdata(pdev, wd);
au1xpsc_ac97_workdata = wd; /* MDEV */
au1xpsc_ac97_workdata = wd;
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 +425,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));

View File

@ -10,9 +10,6 @@
*
* Au1xxx-PSC I2S glue.
*
* NOTE: all of these drivers can only work with a SINGLE instance
* of a PSC. Multiple independent audio devices are impossible
* with ASoC v1.
* NOTE: so far only PSC slave mode (bit- and frameclock) is supported.
*/
@ -54,13 +51,10 @@
((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
/* instance data. There can be only one, MacLeod!!!! */
static struct au1xpsc_audio_data *au1xpsc_i2s_workdata;
static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(cpu_dai);
unsigned long ct;
int ret;
@ -120,7 +114,7 @@ static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
int cfgbits;
unsigned long stat;
@ -245,7 +239,7 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
int ret, stype = SUBSTREAM_TYPE(substream);
switch (cmd) {
@ -263,27 +257,13 @@ 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)
{
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",
.probe = au1xpsc_i2s_probe,
.remove = au1xpsc_i2s_remove,
static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
.playback = {
.rates = AU1XPSC_I2S_RATES,
.formats = AU1XPSC_I2S_FMTS,
@ -298,7 +278,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)
{
@ -307,9 +286,6 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
int ret;
struct au1xpsc_audio_data *wd;
if (au1xpsc_i2s_workdata)
return -EBUSY;
wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
if (!wd)
return -ENOMEM;
@ -346,19 +322,23 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
* time out.
*/
ret = snd_soc_register_dai(&au1xpsc_i2s_dai);
/* name the DAI like this device instance ("au1xpsc-i2s.PSCINDEX") */
memcpy(&wd->dai_drv, &au1xpsc_i2s_dai_template,
sizeof(struct snd_soc_dai_driver));
wd->dai_drv.name = dev_name(&pdev->dev);
platform_set_drvdata(pdev, wd);
ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
if (ret)
goto out1;
/* finally add the DMA device for this PSC */
wd->dmapd = au1xpsc_pcm_add(pdev);
if (wd->dmapd) {
platform_set_drvdata(pdev, wd);
au1xpsc_i2s_workdata = wd;
if (wd->dmapd)
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 +354,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();
@ -385,8 +365,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
release_mem_region(r->start, resource_size(r));
kfree(wd);
au1xpsc_i2s_workdata = NULL; /* MDEV */
return 0;
}
@ -446,7 +424,6 @@ static struct platform_driver au1xpsc_i2s_driver = {
static int __init au1xpsc_i2s_load(void)
{
au1xpsc_i2s_workdata = NULL;
return platform_driver_register(&au1xpsc_i2s_driver);
}

View File

@ -8,19 +8,11 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* NOTE: all of these drivers can only work with a SINGLE instance
* of a PSC. Multiple independent audio devices are impossible
* with ASoC v1.
*/
#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 */
extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
@ -31,6 +23,8 @@ struct au1xpsc_audio_data {
unsigned long cfg;
unsigned long rate;
struct snd_soc_dai_driver dai_drv;
unsigned long pm[2];
struct mutex lock;
struct platform_device *dmapd;

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

@ -56,10 +56,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;
}
@ -70,23 +70,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)
@ -97,8 +93,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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
/*
* 88pm860x-codec.h -- 88PM860x ALSA SoC Audio Driver
*
* Copyright 2010 Marvell International Ltd.
* Haojian Zhuang <haojian.zhuang@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __88PM860X_H
#define __88PM860X_H
/* The offset of these registers are 0xb0 */
#define PM860X_PCM_IFACE_1 0x00
#define PM860X_PCM_IFACE_2 0x01
#define PM860X_PCM_IFACE_3 0x02
#define PM860X_PCM_RATE 0x03
#define PM860X_EC_PATH 0x04
#define PM860X_SIDETONE_L_GAIN 0x05
#define PM860X_SIDETONE_R_GAIN 0x06
#define PM860X_SIDETONE_SHIFT 0x07
#define PM860X_ADC_OFFSET_1 0x08
#define PM860X_ADC_OFFSET_2 0x09
#define PM860X_DMIC_DELAY 0x0a
#define PM860X_I2S_IFACE_1 0x0b
#define PM860X_I2S_IFACE_2 0x0c
#define PM860X_I2S_IFACE_3 0x0d
#define PM860X_I2S_IFACE_4 0x0e
#define PM860X_EQUALIZER_N0_1 0x0f
#define PM860X_EQUALIZER_N0_2 0x10
#define PM860X_EQUALIZER_N1_1 0x11
#define PM860X_EQUALIZER_N1_2 0x12
#define PM860X_EQUALIZER_D1_1 0x13
#define PM860X_EQUALIZER_D1_2 0x14
#define PM860X_LOFI_GAIN_LEFT 0x15
#define PM860X_LOFI_GAIN_RIGHT 0x16
#define PM860X_HIFIL_GAIN_LEFT 0x17
#define PM860X_HIFIL_GAIN_RIGHT 0x18
#define PM860X_HIFIR_GAIN_LEFT 0x19
#define PM860X_HIFIR_GAIN_RIGHT 0x1a
#define PM860X_DAC_OFFSET 0x1b
#define PM860X_OFFSET_LEFT_1 0x1c
#define PM860X_OFFSET_LEFT_2 0x1d
#define PM860X_OFFSET_RIGHT_1 0x1e
#define PM860X_OFFSET_RIGHT_2 0x1f
#define PM860X_ADC_ANA_1 0x20
#define PM860X_ADC_ANA_2 0x21
#define PM860X_ADC_ANA_3 0x22
#define PM860X_ADC_ANA_4 0x23
#define PM860X_ANA_TO_ANA 0x24
#define PM860X_HS1_CTRL 0x25
#define PM860X_HS2_CTRL 0x26
#define PM860X_LO1_CTRL 0x27
#define PM860X_LO2_CTRL 0x28
#define PM860X_EAR_CTRL_1 0x29
#define PM860X_EAR_CTRL_2 0x2a
#define PM860X_AUDIO_SUPPLIES_1 0x2b
#define PM860X_AUDIO_SUPPLIES_2 0x2c
#define PM860X_ADC_EN_1 0x2d
#define PM860X_ADC_EN_2 0x2e
#define PM860X_DAC_EN_1 0x2f
#define PM860X_DAC_EN_2 0x31
#define PM860X_AUDIO_CAL_1 0x32
#define PM860X_AUDIO_CAL_2 0x33
#define PM860X_AUDIO_CAL_3 0x34
#define PM860X_AUDIO_CAL_4 0x35
#define PM860X_AUDIO_CAL_5 0x36
#define PM860X_ANA_INPUT_SEL_1 0x37
#define PM860X_ANA_INPUT_SEL_2 0x38
#define PM860X_PCM_IFACE_4 0x39
#define PM860X_I2S_IFACE_5 0x3a
#define PM860X_SHORTS 0x3b
#define PM860X_PLL_ADJ_1 0x3c
#define PM860X_PLL_ADJ_2 0x3d
/* bits definition */
#define PM860X_CLK_DIR_IN 0
#define PM860X_CLK_DIR_OUT 1
#define PM860X_DET_HEADSET (1 << 0)
#define PM860X_DET_MIC (1 << 1)
#define PM860X_DET_HOOK (1 << 2)
#define PM860X_SHORT_HEADSET (1 << 3)
#define PM860X_SHORT_LINEOUT (1 << 4)
#define PM860X_DET_MASK 0x1F
extern int pm860x_hs_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
int, int, int, int);
extern int pm860x_mic_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
int);
#endif /* __88PM860X_H */

View File

@ -10,6 +10,7 @@ config SND_SOC_I2C_AND_SPI
config SND_SOC_ALL_CODECS
tristate "Build all ASoC CODEC drivers"
select SND_SOC_88PM860X if MFD_88PM860X
select SND_SOC_L3
select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
select SND_SOC_AD1836 if SPI_MASTER
@ -26,6 +27,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS4270 if I2C
select SND_SOC_DA7210 if I2C
select SND_SOC_JZ4740 if SOC_JZ4740
select SND_SOC_MAX98088 if I2C
select SND_SOC_MAX9877 if I2C
select SND_SOC_PCM3008
select SND_SOC_SPDIF
@ -40,6 +42,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TWL6040 if TWL4030_CORE
select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C
select SND_SOC_WL1273 if WL1273_CORE
select SND_SOC_WM2000 if I2C
select SND_SOC_WM8350 if MFD_WM8350
select SND_SOC_WM8400 if MFD_WM8400
@ -54,6 +57,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
select SND_SOC_WM8903 if I2C
select SND_SOC_WM8904 if I2C
@ -61,9 +65,11 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8955 if I2C
select SND_SOC_WM8960 if I2C
select SND_SOC_WM8961 if I2C
select SND_SOC_WM8962 if I2C
select SND_SOC_WM8971 if I2C
select SND_SOC_WM8974 if I2C
select SND_SOC_WM8978 if I2C
select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8990 if I2C
select SND_SOC_WM8993 if I2C
@ -84,6 +90,9 @@ config SND_SOC_ALL_CODECS
If unsure select "N".
config SND_SOC_88PM860X
tristate
config SND_SOC_WM_HUBS
tristate
default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
@ -150,6 +159,9 @@ config SND_SOC_L3
config SND_SOC_DA7210
tristate
config SND_SOC_MAX98088
tristate
config SND_SOC_PCM3008
tristate
@ -188,6 +200,9 @@ config SND_SOC_UDA134X
config SND_SOC_UDA1380
tristate
config SND_SOC_WL1273
tristate
config SND_SOC_WM8350
tristate
@ -227,6 +242,9 @@ config SND_SOC_WM8753
config SND_SOC_WM8776
tristate
config SND_SOC_WM8804
tristate
config SND_SOC_WM8900
tristate
@ -248,6 +266,9 @@ config SND_SOC_WM8960
config SND_SOC_WM8961
tristate
config SND_SOC_WM8962
tristate
config SND_SOC_WM8971
tristate
@ -257,6 +278,9 @@ config SND_SOC_WM8974
config SND_SOC_WM8978
tristate
config SND_SOC_WM8985
tristate
config SND_SOC_WM8988
tristate

View File

@ -1,3 +1,4 @@
snd-soc-88pm860x-objs := 88pm860x-codec.o
snd-soc-ac97-objs := ac97.o
snd-soc-ad1836-objs := ad1836.o
snd-soc-ad193x-objs := ad193x.o
@ -14,6 +15,7 @@ snd-soc-cs4270-objs := cs4270.o
snd-soc-cx20442-objs := cx20442.o
snd-soc-da7210-objs := da7210.o
snd-soc-l3-objs := l3.o
snd-soc-max98088-objs := max98088.o
snd-soc-pcm3008-objs := pcm3008.o
snd-soc-spdif-objs := spdif_transciever.o
snd-soc-ssm2602-objs := ssm2602.o
@ -26,6 +28,7 @@ snd-soc-twl4030-objs := twl4030.o
snd-soc-twl6040-objs := twl6040.o
snd-soc-uda134x-objs := uda134x.o
snd-soc-uda1380-objs := uda1380.o
snd-soc-wl1273-objs := wl1273.o
snd-soc-wm8350-objs := wm8350.o
snd-soc-wm8400-objs := wm8400.o
snd-soc-wm8510-objs := wm8510.o
@ -39,6 +42,7 @@ snd-soc-wm8741-objs := wm8741.o
snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
snd-soc-wm8776-objs := wm8776.o
snd-soc-wm8804-objs := wm8804.o
snd-soc-wm8900-objs := wm8900.o
snd-soc-wm8903-objs := wm8903.o
snd-soc-wm8904-objs := wm8904.o
@ -46,9 +50,11 @@ snd-soc-wm8940-objs := wm8940.o
snd-soc-wm8955-objs := wm8955.o
snd-soc-wm8960-objs := wm8960.o
snd-soc-wm8961-objs := wm8961.o
snd-soc-wm8962-objs := wm8962.o
snd-soc-wm8971-objs := wm8971.o
snd-soc-wm8974-objs := wm8974.o
snd-soc-wm8978-objs := wm8978.o
snd-soc-wm8985-objs := wm8985.o
snd-soc-wm8988-objs := wm8988.o
snd-soc-wm8990-objs := wm8990.o
snd-soc-wm8993-objs := wm8993.o
@ -66,6 +72,7 @@ snd-soc-tpa6130a2-objs := tpa6130a2.o
snd-soc-wm2000-objs := wm2000.o
snd-soc-wm9090-objs := wm9090.o
obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
@ -83,6 +90,7 @@ obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
@ -95,6 +103,7 @@ obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
@ -108,6 +117,7 @@ obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
@ -115,9 +125,11 @@ obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
obj-$(CONFIG_SND_SOC_WM8962) += snd-soc-wm8962.o
obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o

View File

@ -21,17 +21,13 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
#include "ac97.h"
#define AC97_VERSION "0.6"
static int ac97_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
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 +42,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 +59,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 +73,41 @@ 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;
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;
int 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,14 +116,50 @@ 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");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ac97-codec");

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

@ -33,11 +33,6 @@
#include "ad1980.h"
static unsigned int ac97_read(struct snd_soc_codec *codec,
unsigned int reg);
static int ac97_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int val);
/*
* AD1980 register cache
*/
@ -138,8 +133,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
return 0;
}
struct snd_soc_dai ad1980_dai = {
.name = "AC97",
static struct snd_soc_dai_driver ad1980_dai = {
.name = "ad1980-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "Playback",
@ -185,53 +180,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");
@ -270,41 +232,60 @@ 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_default = ad1980_reg,
.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 (Obsolete)");
MODULE_AUTHOR("Roy Huang, Cliff Cai");

View File

@ -23,7 +23,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
@ -74,6 +72,12 @@
#define AK4642_CACHEREGNUM 0x25
/* PW_MGMT1*/
#define PMVCM (1 << 6) /* VCOM Power Management */
#define PMMIN (1 << 5) /* MIN Input Power Management */
#define PMDAC (1 << 2) /* DAC Power Management */
#define PMADL (1 << 0) /* MIC Amp Lch and ADC Lch Power Management */
/* PW_MGMT2 */
#define HPMTN (1 << 6)
#define PMHPL (1 << 5)
@ -85,6 +89,23 @@
#define PMHP_MASK (PMHPL | PMHPR)
#define PMHP PMHP_MASK
/* PW_MGMT3 */
#define PMADR (1 << 0) /* MIC L / ADC R Power Management */
/* SG_SL1 */
#define MINS (1 << 6) /* Switch from MIN to Speaker */
#define DACL (1 << 4) /* Switch from DAC to Stereo or Receiver */
#define PMMP (1 << 2) /* MPWR pin Power Management */
#define MGAIN0 (1 << 0) /* MIC amp gain*/
/* TIMER */
#define ZTM(param) ((param & 0x3) << 4) /* ALC Zoro Crossing TimeOut */
#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2))
/* ALC_CTL1 */
#define ALC (1 << 5) /* ALC Enable */
#define LMTH0 (1 << 0) /* ALC Limiter / Recovery Level */
/* MD_CTL1 */
#define PLL3 (1 << 7)
#define PLL2 (1 << 6)
@ -102,7 +123,11 @@
#define FS3 (1 << 5)
#define FS_MASK (FS0 | FS1 | FS2 | FS3)
struct snd_soc_codec_device soc_codec_dev_ak4642;
/* MD_CTL3 */
#define BST1 (1 << 3)
/* MD_CTL4 */
#define DACH (1 << 0)
/*
* Playback Volume (table 39)
@ -123,11 +148,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
*/
@ -219,11 +244,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
* This operation came from example code of
* "ASAHI KASEI AK4642" (japanese) manual p97.
*/
ak4642_write(codec, 0x0f, 0x09);
ak4642_write(codec, 0x0e, 0x19);
ak4642_write(codec, 0x09, 0x91);
ak4642_write(codec, 0x0c, 0x91);
ak4642_write(codec, 0x00, 0x64);
snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
ak4642_write(codec, L_IVC, 0x91); /* volume */
ak4642_write(codec, R_IVC, 0x91); /* volume */
snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
PMVCM | PMMIN | PMDAC);
snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
} else {
@ -240,13 +266,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
* This operation came from example code of
* "ASAHI KASEI AK4642" (japanese) manual p94.
*/
ak4642_write(codec, 0x02, 0x05);
ak4642_write(codec, 0x06, 0x3c);
ak4642_write(codec, 0x08, 0xe1);
ak4642_write(codec, 0x0b, 0x00);
ak4642_write(codec, 0x07, 0x21);
ak4642_write(codec, 0x00, 0x41);
ak4642_write(codec, 0x10, 0x01);
ak4642_write(codec, SG_SL1, PMMP | MGAIN0);
ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
ak4642_write(codec, ALC_CTL1, ALC | LMTH0);
snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
PMVCM | PMADL);
snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
}
return 0;
@ -262,14 +287,14 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
/* stop headphone output */
snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
ak4642_write(codec, 0x00, 0x40);
ak4642_write(codec, 0x0e, 0x11);
ak4642_write(codec, 0x0f, 0x08);
snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0);
snd_soc_update_bits(codec, MD_CTL3, BST1, 0);
snd_soc_update_bits(codec, MD_CTL4, DACH, 0);
} else {
/* stop stereo input */
ak4642_write(codec, 0x00, 0x40);
ak4642_write(codec, 0x10, 0x00);
ak4642_write(codec, 0x07, 0x01);
snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0);
snd_soc_update_bits(codec, ALC_CTL1, ALC, 0);
}
}
@ -393,8 +418,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 +435,65 @@ 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;
snd_soc_add_controls(codec, ak4642_snd_controls,
ARRAY_SIZE(ak4642_snd_controls));
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)
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 +506,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,
.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,18 @@ 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;
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 +656,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 +709,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

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