aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcpdm.c
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/omap/omap-mcpdm.c
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
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 <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/omap/omap-mcpdm.c')
-rw-r--r--sound/soc/omap/omap-mcpdm.c71
1 files changed, 46 insertions, 25 deletions
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index b7f4f7e015f3..f161c2f5ed36 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -36,7 +36,6 @@
36#include <plat/dma.h> 36#include <plat/dma.h>
37#include <plat/mcbsp.h> 37#include <plat/mcbsp.h>
38#include "mcpdm.h" 38#include "mcpdm.h"
39#include "omap-mcpdm.h"
40#include "omap-pcm.h" 39#include "omap-pcm.h"
41 40
42struct omap_mcpdm_data { 41struct omap_mcpdm_data {
@@ -89,11 +88,9 @@ static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
89static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, 88static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
90 struct snd_soc_dai *dai) 89 struct snd_soc_dai *dai)
91{ 90{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
94 int err = 0; 91 int err = 0;
95 92
96 if (!cpu_dai->active) 93 if (!dai->active)
97 err = omap_mcpdm_request(); 94 err = omap_mcpdm_request();
98 95
99 return err; 96 return err;
@@ -102,19 +99,14 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
102static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, 99static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai) 100 struct snd_soc_dai *dai)
104{ 101{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 102 if (!dai->active)
106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
107
108 if (!cpu_dai->active)
109 omap_mcpdm_free(); 103 omap_mcpdm_free();
110} 104}
111 105
112static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd, 106static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
113 struct snd_soc_dai *dai) 107 struct snd_soc_dai *dai)
114{ 108{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai);
116 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
117 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
118 int stream = substream->stream; 110 int stream = substream->stream;
119 int err = 0; 111 int err = 0;
120 112
@@ -143,14 +135,12 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params, 135 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai) 136 struct snd_soc_dai *dai)
145{ 137{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data; 138 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai);
147 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
148 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
149 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; 139 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
150 int stream = substream->stream; 140 int stream = substream->stream;
151 int channels, err, link_mask = 0; 141 int channels, err, link_mask = 0;
152 142
153 snd_soc_dai_set_dma_data(cpu_dai, substream, 143 snd_soc_dai_set_dma_data(dai, substream,
154 &omap_mcpdm_dai_dma_params[stream]); 144 &omap_mcpdm_dai_dma_params[stream]);
155 145
156 channels = params_channels(params); 146 channels = params_channels(params);
@@ -189,9 +179,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
189static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream, 179static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream,
190 struct snd_soc_dai *dai) 180 struct snd_soc_dai *dai)
191{ 181{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 182 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai);
193 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
194 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
195 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; 183 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
196 int stream = substream->stream; 184 int stream = substream->stream;
197 int err; 185 int err;
@@ -215,9 +203,14 @@ static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
215#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 203#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
216#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 204#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
217 205
218struct snd_soc_dai omap_mcpdm_dai = { 206static int omap_mcpdm_dai_probe(struct snd_soc_dai *dai)
219 .name = "omap-mcpdm", 207{
220 .id = -1, 208 snd_soc_dai_set_drvdata(dai, &mcpdm_data);
209 return 0;
210}
211
212static struct snd_soc_dai_driver omap_mcpdm_dai = {
213 .probe = omap_mcpdm_dai_probe,
221 .playback = { 214 .playback = {
222 .channels_min = 1, 215 .channels_min = 1,
223 .channels_max = 4, 216 .channels_max = 4,
@@ -231,19 +224,47 @@ struct snd_soc_dai omap_mcpdm_dai = {
231 .formats = OMAP_MCPDM_FORMATS, 224 .formats = OMAP_MCPDM_FORMATS,
232 }, 225 },
233 .ops = &omap_mcpdm_dai_ops, 226 .ops = &omap_mcpdm_dai_ops,
234 .private_data = &mcpdm_data,
235}; 227};
236EXPORT_SYMBOL_GPL(omap_mcpdm_dai); 228
229static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
230{
231 int ret;
232
233 ret = omap_mcpdm_probe(pdev);
234 if (ret < 0)
235 return ret;
236 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
237 if (ret < 0)
238 omap_mcpdm_remove(pdev);
239 return ret;
240}
241
242static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
243{
244 snd_soc_unregister_dai(&pdev->dev);
245 omap_mcpdm_remove(pdev);
246 return 0;
247}
248
249static struct platform_driver asoc_mcpdm_driver = {
250 .driver = {
251 .name = "omap-mcpdm-dai",
252 .owner = THIS_MODULE,
253 },
254
255 .probe = asoc_mcpdm_probe,
256 .remove = __devexit_p(asoc_mcpdm_remove),
257};
237 258
238static int __init snd_omap_mcpdm_init(void) 259static int __init snd_omap_mcpdm_init(void)
239{ 260{
240 return snd_soc_register_dai(&omap_mcpdm_dai); 261 return platform_driver_register(&asoc_mcpdm_driver);
241} 262}
242module_init(snd_omap_mcpdm_init); 263module_init(snd_omap_mcpdm_init);
243 264
244static void __exit snd_omap_mcpdm_exit(void) 265static void __exit snd_omap_mcpdm_exit(void)
245{ 266{
246 snd_soc_unregister_dai(&omap_mcpdm_dai); 267 platform_driver_unregister(&asoc_mcpdm_driver);
247} 268}
248module_exit(snd_omap_mcpdm_exit); 269module_exit(snd_omap_mcpdm_exit);
249 270