aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@googlemail.com>2010-08-26 08:53:51 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-31 08:06:31 -0400
commitffc4fdbbe1b4be79e98340ebcd5a0ade6f5de318 (patch)
treee4f16ef2561497482df5ac9039ba7bdb21212b2d
parent0bb5f267af41c39af895faee3abe2d9ab8c562e0 (diff)
ASoC: fix au1x platform
This patch fixes up the au1x audio platform after the multi-component merge: - compile fixes and updates to get DB1200 platform audio working again, - removal of global variables in AC97/I2S/DMA(PCM) modules. The AC97 part is limited to one instance only for now due to issues with getting at driver data in the soc_ac97_ops. Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--arch/mips/alchemy/devboards/db1200/platform.c6
-rw-r--r--sound/soc/au1x/db1200.c16
-rw-r--r--sound/soc/au1x/dbdma2.c82
-rw-r--r--sound/soc/au1x/psc-ac97.c59
-rw-r--r--sound/soc/au1x/psc-i2s.c42
-rw-r--r--sound/soc/au1x/psc.h7
6 files changed, 91 insertions, 121 deletions
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
index 3fa34c3abc04..fbb55935b99e 100644
--- a/arch/mips/alchemy/devboards/db1200/platform.c
+++ b/arch/mips/alchemy/devboards/db1200/platform.c
@@ -429,6 +429,11 @@ static struct platform_device db1200_audio_dev = {
429 .resource = au1200_psc1_res, 429 .resource = au1200_psc1_res,
430}; 430};
431 431
432static struct platform_device db1200_stac_dev = {
433 .name = "ac97-codec",
434 .id = 1, /* on PSC1 */
435};
436
432static struct platform_device *db1200_devs[] __initdata = { 437static struct platform_device *db1200_devs[] __initdata = {
433 NULL, /* PSC0, selected by S6.8 */ 438 NULL, /* PSC0, selected by S6.8 */
434 &db1200_ide_dev, 439 &db1200_ide_dev,
@@ -436,6 +441,7 @@ static struct platform_device *db1200_devs[] __initdata = {
436 &db1200_rtc_dev, 441 &db1200_rtc_dev,
437 &db1200_nand_dev, 442 &db1200_nand_dev,
438 &db1200_audio_dev, 443 &db1200_audio_dev,
444 &db1200_stac_dev,
439}; 445};
440 446
441static int __init db1200_dev_init(void) 447static int __init db1200_dev_init(void)
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index d8dc8225576a..b62fcd33e586 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -27,10 +27,10 @@
27static struct snd_soc_dai_link db1200_ac97_dai = { 27static struct snd_soc_dai_link db1200_ac97_dai = {
28 .name = "AC97", 28 .name = "AC97",
29 .stream_name = "AC97 HiFi", 29 .stream_name = "AC97 HiFi",
30 .cpu_dai_name = "au1xpsc-ac97",
31 .codec_dai_name = "ac97-hifi", 30 .codec_dai_name = "ac97-hifi",
32 .platform_name = "au1xpsc-pcm-audio", 31 .cpu_dai_name = "au1xpsc_ac97.1",
33 .codec_name = "ac97-codec", 32 .platform_name = "au1xpsc-pcm.1",
33 .codec_name = "ac97-codec.1",
34}; 34};
35 35
36static struct snd_soc_card db1200_ac97_machine = { 36static struct snd_soc_card db1200_ac97_machine = {
@@ -75,10 +75,10 @@ static struct snd_soc_ops db1200_i2s_wm8731_ops = {
75static struct snd_soc_dai_link db1200_i2s_dai = { 75static struct snd_soc_dai_link db1200_i2s_dai = {
76 .name = "WM8731", 76 .name = "WM8731",
77 .stream_name = "WM8731 PCM", 77 .stream_name = "WM8731 PCM",
78 .cpu_dai_name = "au1xpsc", 78 .codec_dai_name = "wm8731-hifi",
79 .codec_dai_name = "wm8731-hifi" 79 .cpu_dai_name = "au1xpsc_i2s.1",
80 .platform_name = "au1xpsc-pcm-audio", 80 .platform_name = "au1xpsc-pcm.1",
81 .codec_name = "wm8731-codec.0-001a", 81 .codec_name = "wm8731-codec.0-001b",
82 .ops = &db1200_i2s_wm8731_ops, 82 .ops = &db1200_i2s_wm8731_ops,
83}; 83};
84 84
@@ -97,7 +97,7 @@ static int __init db1200_audio_load(void)
97 int ret; 97 int ret;
98 98
99 ret = -ENOMEM; 99 ret = -ENOMEM;
100 db1200_asoc_dev = platform_device_alloc("soc-audio", -1); 100 db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */
101 if (!db1200_asoc_dev) 101 if (!db1200_asoc_dev)
102 goto out; 102 goto out;
103 103
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 00fdb9cbfc2d..10fdd2854e58 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -10,9 +10,6 @@
10 * 10 *
11 * DMA glue for Au1x-PSC audio. 11 * DMA glue for Au1x-PSC audio.
12 * 12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 */ 13 */
17 14
18 15
@@ -61,9 +58,6 @@ struct au1xpsc_audio_dmadata {
61 int msbits; 58 int msbits;
62}; 59};
63 60
64/* instance data. There can be only one, MacLeod!!!! */
65static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2];
66
67/* 61/*
68 * These settings are somewhat okay, at least on my machine audio plays 62 * These settings are somewhat okay, at least on my machine audio plays
69 * almost skip-free. Especially the 64kB buffer seems to help a LOT. 63 * almost skip-free. Especially the 64kB buffer seems to help a LOT.
@@ -199,6 +193,14 @@ out:
199 return 0; 193 return 0;
200} 194}
201 195
196static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss)
197{
198 struct snd_soc_pcm_runtime *rtd = ss->private_data;
199 struct au1xpsc_audio_dmadata *pcd =
200 snd_soc_platform_get_drvdata(rtd->platform);
201 return &pcd[SUBSTREAM_TYPE(ss)];
202}
203
202static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, 204static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params) 205 struct snd_pcm_hw_params *params)
204{ 206{
@@ -211,7 +213,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
211 goto out; 213 goto out;
212 214
213 stype = SUBSTREAM_TYPE(substream); 215 stype = SUBSTREAM_TYPE(substream);
214 pcd = au1xpsc_audio_pcmdma[stype]; 216 pcd = to_dmadata(substream);
215 217
216 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " 218 DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
217 "runtime->min_align %d\n", 219 "runtime->min_align %d\n",
@@ -249,8 +251,7 @@ static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream)
249 251
250static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) 252static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
251{ 253{
252 struct au1xpsc_audio_dmadata *pcd = 254 struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
253 au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)];
254 255
255 au1xxx_dbdma_reset(pcd->ddma_chan); 256 au1xxx_dbdma_reset(pcd->ddma_chan);
256 257
@@ -267,7 +268,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
267 268
268static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 269static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
269{ 270{
270 u32 c = au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->ddma_chan; 271 u32 c = to_dmadata(substream)->ddma_chan;
271 272
272 switch (cmd) { 273 switch (cmd) {
273 case SNDRV_PCM_TRIGGER_START: 274 case SNDRV_PCM_TRIGGER_START:
@@ -287,8 +288,7 @@ static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
287static snd_pcm_uframes_t 288static snd_pcm_uframes_t
288au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) 289au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
289{ 290{
290 return bytes_to_frames(substream->runtime, 291 return bytes_to_frames(substream->runtime, to_dmadata(substream)->pos);
291 au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->pos);
292} 292}
293 293
294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) 294static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
@@ -299,7 +299,7 @@ static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
299 299
300static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) 300static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
301{ 301{
302 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]); 302 au1x_pcm_dbdma_free(to_dmadata(substream));
303 return 0; 303 return 0;
304} 304}
305 305
@@ -329,35 +329,21 @@ static int au1xpsc_pcm_new(struct snd_card *card,
329 return 0; 329 return 0;
330} 330}
331 331
332static int au1xpsc_pcm_probe(struct snd_soc_platform *platform)
333{
334 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
335 return -ENODEV;
336
337 return 0;
338}
339
340/* au1xpsc audio platform */ 332/* au1xpsc audio platform */
341struct snd_soc_platform_driver au1xpsc_soc_platform = { 333struct snd_soc_platform_driver au1xpsc_soc_platform = {
342 .probe = au1xpsc_pcm_probe,
343 .ops = &au1xpsc_pcm_ops, 334 .ops = &au1xpsc_pcm_ops,
344 .pcm_new = au1xpsc_pcm_new, 335 .pcm_new = au1xpsc_pcm_new,
345 .pcm_free = au1xpsc_pcm_free_dma_buffers, 336 .pcm_free = au1xpsc_pcm_free_dma_buffers,
346}; 337};
347EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
348 338
349static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) 339static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
350{ 340{
341 struct au1xpsc_audio_dmadata *dmadata;
351 struct resource *r; 342 struct resource *r;
352 int ret; 343 int ret;
353 344
354 if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX]) 345 dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
355 return -EBUSY; 346 if (!dmadata)
356
357 /* TX DMA */
358 au1xpsc_audio_pcmdma[PCM_TX]
359 = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
360 if (!au1xpsc_audio_pcmdma[PCM_TX])
361 return -ENOMEM; 347 return -ENOMEM;
362 348
363 r = platform_get_resource(pdev, IORESOURCE_DMA, 0); 349 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -365,54 +351,40 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
365 ret = -ENODEV; 351 ret = -ENODEV;
366 goto out1; 352 goto out1;
367 } 353 }
368 (au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start; 354 dmadata[PCM_TX].ddma_id = r->start;
369 355
370 /* RX DMA */ 356 /* RX DMA */
371 au1xpsc_audio_pcmdma[PCM_RX]
372 = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
373 if (!au1xpsc_audio_pcmdma[PCM_RX])
374 return -ENOMEM;
375
376 r = platform_get_resource(pdev, IORESOURCE_DMA, 1); 357 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
377 if (!r) { 358 if (!r) {
378 ret = -ENODEV; 359 ret = -ENODEV;
379 goto out2; 360 goto out1;
380 } 361 }
381 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; 362 dmadata[PCM_RX].ddma_id = r->start;
363
364 platform_set_drvdata(pdev, dmadata);
382 365
383 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); 366 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
384 if (!ret) 367 if (!ret)
385 return ret; 368 return ret;
386 369
387out2:
388 kfree(au1xpsc_audio_pcmdma[PCM_RX]);
389 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
390out1: 370out1:
391 kfree(au1xpsc_audio_pcmdma[PCM_TX]); 371 kfree(dmadata);
392 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
393 return ret; 372 return ret;
394} 373}
395 374
396static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) 375static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
397{ 376{
398 int i; 377 struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev);
399 378
400 snd_soc_unregister_platform(&pdev->dev); 379 snd_soc_unregister_platform(&pdev->dev);
401 380 kfree(dmadata);
402 for (i = 0; i < 2; i++) {
403 if (au1xpsc_audio_pcmdma[i]) {
404 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
405 kfree(au1xpsc_audio_pcmdma[i]);
406 au1xpsc_audio_pcmdma[i] = NULL;
407 }
408 }
409 381
410 return 0; 382 return 0;
411} 383}
412 384
413static struct platform_driver au1xpsc_pcm_driver = { 385static struct platform_driver au1xpsc_pcm_driver = {
414 .driver = { 386 .driver = {
415 .name = "au1xpsc-pcm-audio", 387 .name = "au1xpsc-pcm",
416 .owner = THIS_MODULE, 388 .owner = THIS_MODULE,
417 }, 389 },
418 .probe = au1xpsc_pcm_drvprobe, 390 .probe = au1xpsc_pcm_drvprobe,
@@ -421,8 +393,6 @@ static struct platform_driver au1xpsc_pcm_driver = {
421 393
422static int __init au1xpsc_audio_dbdma_load(void) 394static int __init au1xpsc_audio_dbdma_load(void)
423{ 395{
424 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
425 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
426 return platform_driver_register(&au1xpsc_pcm_driver); 396 return platform_driver_register(&au1xpsc_pcm_driver);
427} 397}
428 398
@@ -460,7 +430,7 @@ struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
460 res[1].start = res[1].end = id[1]; 430 res[1].start = res[1].end = id[1];
461 res[0].flags = res[1].flags = IORESOURCE_DMA; 431 res[0].flags = res[1].flags = IORESOURCE_DMA;
462 432
463 pd = platform_device_alloc("au1xpsc-pcm", -1); 433 pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
464 if (!pd) 434 if (!pd)
465 goto out; 435 goto out;
466 436
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 6a9516cbe424..d0db66f24a00 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -10,9 +10,6 @@
10 * 10 *
11 * Au1xxx-PSC AC97 glue. 11 * Au1xxx-PSC AC97 glue.
12 * 12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 */ 13 */
17 14
18#include <linux/init.h> 15#include <linux/init.h>
@@ -56,12 +53,29 @@
56/* instance data. There can be only one, MacLeod!!!! */ 53/* instance data. There can be only one, MacLeod!!!! */
57static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; 54static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
58 55
56#if 0
57
58/* this could theoretically work, but ac97->bus->card->private_data can be NULL
59 * when snd_ac97_mixer() is called; I don't know if the rest further down the
60 * chain are always valid either.
61 */
62static inline struct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x)
63{
64 struct snd_soc_card *c = x->bus->card->private_data;
65 return snd_soc_dai_get_drvdata(c->rtd->cpu_dai);
66}
67
68#else
69
70#define ac97_to_pscdata(x) au1xpsc_ac97_workdata
71
72#endif
73
59/* AC97 controller reads codec register */ 74/* AC97 controller reads codec register */
60static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, 75static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
61 unsigned short reg) 76 unsigned short reg)
62{ 77{
63 /* FIXME */ 78 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
64 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
65 unsigned short retry, tmo; 79 unsigned short retry, tmo;
66 unsigned long data; 80 unsigned long data;
67 81
@@ -102,8 +116,7 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
102static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 116static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
103 unsigned short val) 117 unsigned short val)
104{ 118{
105 /* FIXME */ 119 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
106 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
107 unsigned int tmo, retry; 120 unsigned int tmo, retry;
108 121
109 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 122 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
@@ -134,8 +147,7 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
134/* AC97 controller asserts a warm reset */ 147/* AC97 controller asserts a warm reset */
135static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) 148static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
136{ 149{
137 /* FIXME */ 150 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
138 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
139 151
140 au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); 152 au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata));
141 au_sync(); 153 au_sync();
@@ -146,8 +158,7 @@ static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
146 158
147static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) 159static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
148{ 160{
149 /* FIXME */ 161 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
150 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
151 int i; 162 int i;
152 163
153 /* disable PSC during cold reset */ 164 /* disable PSC during cold reset */
@@ -202,8 +213,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
202 struct snd_pcm_hw_params *params, 213 struct snd_pcm_hw_params *params,
203 struct snd_soc_dai *dai) 214 struct snd_soc_dai *dai)
204{ 215{
205 /* FIXME */ 216 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
206 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
207 unsigned long r, ro, stat; 217 unsigned long r, ro, stat;
208 int chans, t, stype = SUBSTREAM_TYPE(substream); 218 int chans, t, stype = SUBSTREAM_TYPE(substream);
209 219
@@ -283,8 +293,7 @@ out:
283static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, 293static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
284 int cmd, struct snd_soc_dai *dai) 294 int cmd, struct snd_soc_dai *dai)
285{ 295{
286 /* FIXME */ 296 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
287 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
288 int ret, stype = SUBSTREAM_TYPE(substream); 297 int ret, stype = SUBSTREAM_TYPE(substream);
289 298
290 ret = 0; 299 ret = 0;
@@ -325,7 +334,7 @@ static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
325 .hw_params = au1xpsc_ac97_hw_params, 334 .hw_params = au1xpsc_ac97_hw_params,
326}; 335};
327 336
328struct snd_soc_dai_driver au1xpsc_ac97_dai = { 337static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
329 .ac97_control = 1, 338 .ac97_control = 1,
330 .probe = au1xpsc_ac97_probe, 339 .probe = au1xpsc_ac97_probe,
331 .playback = { 340 .playback = {
@@ -342,7 +351,6 @@ struct snd_soc_dai_driver au1xpsc_ac97_dai = {
342 }, 351 },
343 .ops = &au1xpsc_ac97_dai_ops, 352 .ops = &au1xpsc_ac97_dai_ops,
344}; 353};
345EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
346 354
347static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) 355static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
348{ 356{
@@ -351,9 +359,6 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
351 unsigned long sel; 359 unsigned long sel;
352 struct au1xpsc_audio_data *wd; 360 struct au1xpsc_audio_data *wd;
353 361
354 if (au1xpsc_ac97_workdata)
355 return -EBUSY;
356
357 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 362 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
358 if (!wd) 363 if (!wd)
359 return -ENOMEM; 364 return -ENOMEM;
@@ -387,14 +392,20 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
387 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); 392 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
388 au_sync(); 393 au_sync();
389 394
390 ret = snd_soc_register_dai(&pdev->dev, &au1xpsc_ac97_dai); 395 /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */
396 memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template,
397 sizeof(struct snd_soc_dai_driver));
398 wd->dai_drv.name = dev_name(&pdev->dev);
399
400 platform_set_drvdata(pdev, wd);
401
402 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
391 if (ret) 403 if (ret)
392 goto out1; 404 goto out1;
393 405
394 wd->dmapd = au1xpsc_pcm_add(pdev); 406 wd->dmapd = au1xpsc_pcm_add(pdev);
395 if (wd->dmapd) { 407 if (wd->dmapd) {
396 platform_set_drvdata(pdev, wd); 408 au1xpsc_ac97_workdata = wd;
397 au1xpsc_ac97_workdata = wd; /* MDEV */
398 return 0; 409 return 0;
399 } 410 }
400 411
@@ -477,7 +488,7 @@ static struct dev_pm_ops au1xpscac97_pmops = {
477 488
478static struct platform_driver au1xpsc_ac97_driver = { 489static struct platform_driver au1xpsc_ac97_driver = {
479 .driver = { 490 .driver = {
480 .name = "au1xpsc-ac97", 491 .name = "au1xpsc_ac97",
481 .owner = THIS_MODULE, 492 .owner = THIS_MODULE,
482 .pm = AU1XPSCAC97_PMOPS, 493 .pm = AU1XPSCAC97_PMOPS,
483 }, 494 },
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 94e560a8756d..fca091276320 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -10,9 +10,6 @@
10 * 10 *
11 * Au1xxx-PSC I2S glue. 11 * Au1xxx-PSC I2S glue.
12 * 12 *
13 * NOTE: all of these drivers can only work with a SINGLE instance
14 * of a PSC. Multiple independent audio devices are impossible
15 * with ASoC v1.
16 * NOTE: so far only PSC slave mode (bit- and frameclock) is supported. 13 * NOTE: so far only PSC slave mode (bit- and frameclock) is supported.
17 */ 14 */
18 15
@@ -54,13 +51,10 @@
54 ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) 51 ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
55 52
56 53
57/* instance data. There can be only one, MacLeod!!!! */
58static struct au1xpsc_audio_data *au1xpsc_i2s_workdata;
59
60static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 54static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
61 unsigned int fmt) 55 unsigned int fmt)
62{ 56{
63 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 57 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(cpu_dai);
64 unsigned long ct; 58 unsigned long ct;
65 int ret; 59 int ret;
66 60
@@ -120,7 +114,7 @@ static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params, 114 struct snd_pcm_hw_params *params,
121 struct snd_soc_dai *dai) 115 struct snd_soc_dai *dai)
122{ 116{
123 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 117 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
124 118
125 int cfgbits; 119 int cfgbits;
126 unsigned long stat; 120 unsigned long stat;
@@ -245,7 +239,7 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
245static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 239static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
246 struct snd_soc_dai *dai) 240 struct snd_soc_dai *dai)
247{ 241{
248 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 242 struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
249 int ret, stype = SUBSTREAM_TYPE(substream); 243 int ret, stype = SUBSTREAM_TYPE(substream);
250 244
251 switch (cmd) { 245 switch (cmd) {
@@ -263,19 +257,13 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
263 return ret; 257 return ret;
264} 258}
265 259
266static int au1xpsc_i2s_probe(struct snd_soc_dai *dai)
267{
268 return au1xpsc_i2s_workdata ? 0 : -ENODEV;
269}
270
271static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 260static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
272 .trigger = au1xpsc_i2s_trigger, 261 .trigger = au1xpsc_i2s_trigger,
273 .hw_params = au1xpsc_i2s_hw_params, 262 .hw_params = au1xpsc_i2s_hw_params,
274 .set_fmt = au1xpsc_i2s_set_fmt, 263 .set_fmt = au1xpsc_i2s_set_fmt,
275}; 264};
276 265
277static struct snd_soc_dai_driver au1xpsc_i2s_dai = { 266static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
278 .probe = au1xpsc_i2s_probe,
279 .playback = { 267 .playback = {
280 .rates = AU1XPSC_I2S_RATES, 268 .rates = AU1XPSC_I2S_RATES,
281 .formats = AU1XPSC_I2S_FMTS, 269 .formats = AU1XPSC_I2S_FMTS,
@@ -298,9 +286,6 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
298 int ret; 286 int ret;
299 struct au1xpsc_audio_data *wd; 287 struct au1xpsc_audio_data *wd;
300 288
301 if (au1xpsc_i2s_workdata)
302 return -EBUSY;
303
304 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 289 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
305 if (!wd) 290 if (!wd)
306 return -ENOMEM; 291 return -ENOMEM;
@@ -337,17 +322,21 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
337 * time out. 322 * time out.
338 */ 323 */
339 324
340 ret = snd_soc_register_dai(&pdev->dev, &au1xpsc_i2s_dai); 325 /* name the DAI like this device instance ("au1xpsc-i2s.PSCINDEX") */
326 memcpy(&wd->dai_drv, &au1xpsc_i2s_dai_template,
327 sizeof(struct snd_soc_dai_driver));
328 wd->dai_drv.name = dev_name(&pdev->dev);
329
330 platform_set_drvdata(pdev, wd);
331
332 ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
341 if (ret) 333 if (ret)
342 goto out1; 334 goto out1;
343 335
344 /* finally add the DMA device for this PSC */ 336 /* finally add the DMA device for this PSC */
345 wd->dmapd = au1xpsc_pcm_add(pdev); 337 wd->dmapd = au1xpsc_pcm_add(pdev);
346 if (wd->dmapd) { 338 if (wd->dmapd)
347 platform_set_drvdata(pdev, wd);
348 au1xpsc_i2s_workdata = wd;
349 return 0; 339 return 0;
350 }
351 340
352 snd_soc_unregister_dai(&pdev->dev); 341 snd_soc_unregister_dai(&pdev->dev);
353out1: 342out1:
@@ -376,8 +365,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
376 release_mem_region(r->start, resource_size(r)); 365 release_mem_region(r->start, resource_size(r));
377 kfree(wd); 366 kfree(wd);
378 367
379 au1xpsc_i2s_workdata = NULL; /* MDEV */
380
381 return 0; 368 return 0;
382} 369}
383 370
@@ -427,7 +414,7 @@ static struct dev_pm_ops au1xpsci2s_pmops = {
427 414
428static struct platform_driver au1xpsc_i2s_driver = { 415static struct platform_driver au1xpsc_i2s_driver = {
429 .driver = { 416 .driver = {
430 .name = "au1xpsc", 417 .name = "au1xpsc_i2s",
431 .owner = THIS_MODULE, 418 .owner = THIS_MODULE,
432 .pm = AU1XPSCI2S_PMOPS, 419 .pm = AU1XPSCI2S_PMOPS,
433 }, 420 },
@@ -437,7 +424,6 @@ static struct platform_driver au1xpsc_i2s_driver = {
437 424
438static int __init au1xpsc_i2s_load(void) 425static int __init au1xpsc_i2s_load(void)
439{ 426{
440 au1xpsc_i2s_workdata = NULL;
441 return platform_driver_register(&au1xpsc_i2s_driver); 427 return platform_driver_register(&au1xpsc_i2s_driver);
442} 428}
443 429
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index f281443fd52f..b30eadd422a7 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -8,16 +8,11 @@
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 * 10 *
11 * NOTE: all of these drivers can only work with a SINGLE instance
12 * of a PSC. Multiple independent audio devices are impossible
13 * with ASoC v1.
14 */ 11 */
15 12
16#ifndef _AU1X_PCM_H 13#ifndef _AU1X_PCM_H
17#define _AU1X_PCM_H 14#define _AU1X_PCM_H
18 15
19extern struct snd_ac97_bus_ops soc_ac97_ops;
20
21/* DBDMA helpers */ 16/* DBDMA helpers */
22extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev); 17extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
23extern void au1xpsc_pcm_destroy(struct platform_device *dmapd); 18extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
@@ -28,6 +23,8 @@ struct au1xpsc_audio_data {
28 unsigned long cfg; 23 unsigned long cfg;
29 unsigned long rate; 24 unsigned long rate;
30 25
26 struct snd_soc_dai_driver dai_drv;
27
31 unsigned long pm[2]; 28 unsigned long pm[2];
32 struct mutex lock; 29 struct mutex lock;
33 struct platform_device *dmapd; 30 struct platform_device *dmapd;