From f0fba2ad1b6b53d5360125c41953b7afcd6deff0 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 17 Mar 2010 20:15:21 +0000 Subject: ASoC: multi-component - ASoC Multi-Component Support This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi Signed-off-by: Janusz Krzysztofik Signed-off-by: Jarkko Nikula Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Reviewed-by: Jassi Brar Signed-off-by: Seungwhan Youn MPC8610 and PPC fixes. Signed-off-by: Timur Tabi i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen CC: Tony Lindgren CC: Nicolas Ferre CC: Kevin Hilman CC: Sascha Hauer CC: Atsushi Nemoto CC: Kuninori Morimoto CC: Daniel Gloeckner CC: Manuel Lauss CC: Mike Frysinger CC: Arnaud Patard CC: Wan ZongShun Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/s3c24xx/s3c-ac97.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'sound/soc/s3c24xx/s3c-ac97.c') diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index 31f6d45..86f4a9b 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -222,7 +222,7 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { 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; struct s3c_dma_params *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -241,7 +241,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, u32 ac_glbctrl; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) @@ -277,7 +277,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { 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; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; @@ -293,7 +293,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, u32 ac_glbctrl; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; @@ -328,10 +328,9 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { .trigger = s3c_ac97_mic_trigger, }; -struct snd_soc_dai s3c_ac97_dai[] = { +static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { .name = "s3c-ac97", - .id = S3C_AC97_DAI_PCM, .ac97_control = 1, .playback = { .stream_name = "AC97 Playback", @@ -349,7 +348,6 @@ struct snd_soc_dai s3c_ac97_dai[] = { }, [S3C_AC97_DAI_MIC] = { .name = "s3c-ac97-mic", - .id = S3C_AC97_DAI_MIC, .ac97_control = 1, .capture = { .stream_name = "AC97 Mic Capture", @@ -360,7 +358,6 @@ struct snd_soc_dai s3c_ac97_dai[] = { .ops = &s3c_ac97_mic_dai_ops, }, }; -EXPORT_SYMBOL_GPL(s3c_ac97_dai); static __devinit int s3c_ac97_probe(struct platform_device *pdev) { @@ -449,10 +446,8 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) goto err4; } - s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev; - s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev; - - ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); + ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, + ARRAY_SIZE(s3c_ac97_dai)); if (ret) goto err5; @@ -476,7 +471,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev) { struct resource *mem_res, *irq_res; - snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_res) -- cgit v1.1 From 960d0697919aef453273e3a0ccc87daf52d808ac Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 12 Aug 2010 11:02:19 +0100 Subject: ASoC: Add MODULE_ALIAS to Samsung DAI drivers Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/s3c24xx/s3c-ac97.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/s3c24xx/s3c-ac97.c') diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index 86f4a9b..26f4ed9 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -513,3 +513,4 @@ module_exit(s3c_ac97_exit); MODULE_AUTHOR("Jaswinder Singh, "); MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c-ac97"); -- cgit v1.1 From 4a6f998ebb1e434ce83c6169a1afbe6a39015bea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 23 Sep 2010 16:48:54 +0100 Subject: ASoC: Convert s3c-ac97 to pr_() macros Could use dev_() but we'd have to remember the struct device somewhere and it wouldn't make the logging clearer. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/s3c24xx/s3c-ac97.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'sound/soc/s3c24xx/s3c-ac97.c') diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index 26f4ed9..31e2b3d 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -89,7 +89,7 @@ static void s3c_ac97_activate(struct snd_ac97 *ac97) writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - printk(KERN_ERR "AC97: Unable to activate!"); + pr_err("AC97: Unable to activate!"); } static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, @@ -115,14 +115,15 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - printk(KERN_ERR "AC97: Unable to read!"); + pr_err("AC97: Unable to read!"); stat = readl(s3c_ac97.regs + S3C_AC97_STAT); addr = (stat >> 16) & 0x7f; data = (stat & 0xffff); if (addr != reg) - printk(KERN_ERR "s3c-ac97: req addr = %02x, rep addr = %02x\n", reg, addr); + pr_err("s3c-ac97: req addr = %02x, rep addr = %02x\n", + reg, addr); mutex_unlock(&s3c_ac97.lock); @@ -151,7 +152,7 @@ static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - printk(KERN_ERR "AC97: Unable to write!"); + pr_err("AC97: Unable to write!"); ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; @@ -442,7 +443,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) ret = request_irq(irq_res->start, s3c_ac97_irq, IRQF_DISABLED, "AC97", NULL); if (ret < 0) { - printk(KERN_ERR "s3c-ac97: interrupt request failed.\n"); + dev_err(&pdev->dev, "s3c-ac97: interrupt request failed.\n"); goto err4; } -- cgit v1.1 From 8d85d7414a681ad17f6bfc7564e310caee2c868d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 23 Sep 2010 17:41:46 +0100 Subject: ASoC: Add debug logging for s3c-ac97 resets Helps tracing errors further up the stack. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/s3c24xx/s3c-ac97.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/soc/s3c24xx/s3c-ac97.c') diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index 31e2b3d..f891eb7 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -163,6 +163,7 @@ static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) { + pr_debug("AC97: Cold reset\n"); writel(S3C_AC97_GLBCTRL_COLDRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); msleep(1); @@ -179,6 +180,8 @@ static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) return; /* Return if already active */ + pr_debug("AC97: Warm reset\n"); + writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); msleep(1); -- cgit v1.1