aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/au1x/psc-i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/au1x/psc-i2s.c')
-rw-r--r--sound/soc/au1x/psc-i2s.c53
1 files changed, 15 insertions, 38 deletions
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 6083fe7799fa..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,27 +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 platform_device *pdev,
267 struct snd_soc_dai *dai)
268{
269 return au1xpsc_i2s_workdata ? 0 : -ENODEV;
270}
271
272static void au1xpsc_i2s_remove(struct platform_device *pdev,
273 struct snd_soc_dai *dai)
274{
275}
276
277static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 260static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
278 .trigger = au1xpsc_i2s_trigger, 261 .trigger = au1xpsc_i2s_trigger,
279 .hw_params = au1xpsc_i2s_hw_params, 262 .hw_params = au1xpsc_i2s_hw_params,
280 .set_fmt = au1xpsc_i2s_set_fmt, 263 .set_fmt = au1xpsc_i2s_set_fmt,
281}; 264};
282 265
283struct snd_soc_dai au1xpsc_i2s_dai = { 266static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
284 .name = "au1xpsc_i2s",
285 .probe = au1xpsc_i2s_probe,
286 .remove = au1xpsc_i2s_remove,
287 .playback = { 267 .playback = {
288 .rates = AU1XPSC_I2S_RATES, 268 .rates = AU1XPSC_I2S_RATES,
289 .formats = AU1XPSC_I2S_FMTS, 269 .formats = AU1XPSC_I2S_FMTS,
@@ -298,7 +278,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
298 }, 278 },
299 .ops = &au1xpsc_i2s_dai_ops, 279 .ops = &au1xpsc_i2s_dai_ops,
300}; 280};
301EXPORT_SYMBOL(au1xpsc_i2s_dai);
302 281
303static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) 282static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
304{ 283{
@@ -307,9 +286,6 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
307 int ret; 286 int ret;
308 struct au1xpsc_audio_data *wd; 287 struct au1xpsc_audio_data *wd;
309 288
310 if (au1xpsc_i2s_workdata)
311 return -EBUSY;
312
313 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 289 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
314 if (!wd) 290 if (!wd)
315 return -ENOMEM; 291 return -ENOMEM;
@@ -346,19 +322,23 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
346 * time out. 322 * time out.
347 */ 323 */
348 324
349 ret = snd_soc_register_dai(&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);
350 if (ret) 333 if (ret)
351 goto out1; 334 goto out1;
352 335
353 /* finally add the DMA device for this PSC */ 336 /* finally add the DMA device for this PSC */
354 wd->dmapd = au1xpsc_pcm_add(pdev); 337 wd->dmapd = au1xpsc_pcm_add(pdev);
355 if (wd->dmapd) { 338 if (wd->dmapd)
356 platform_set_drvdata(pdev, wd);
357 au1xpsc_i2s_workdata = wd;
358 return 0; 339 return 0;
359 }
360 340
361 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 341 snd_soc_unregister_dai(&pdev->dev);
362out1: 342out1:
363 release_mem_region(r->start, resource_size(r)); 343 release_mem_region(r->start, resource_size(r));
364out0: 344out0:
@@ -374,7 +354,7 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
374 if (wd->dmapd) 354 if (wd->dmapd)
375 au1xpsc_pcm_destroy(wd->dmapd); 355 au1xpsc_pcm_destroy(wd->dmapd);
376 356
377 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 357 snd_soc_unregister_dai(&pdev->dev);
378 358
379 au_writel(0, I2S_CFG(wd)); 359 au_writel(0, I2S_CFG(wd));
380 au_sync(); 360 au_sync();
@@ -385,8 +365,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
385 release_mem_region(r->start, resource_size(r)); 365 release_mem_region(r->start, resource_size(r));
386 kfree(wd); 366 kfree(wd);
387 367
388 au1xpsc_i2s_workdata = NULL; /* MDEV */
389
390 return 0; 368 return 0;
391} 369}
392 370
@@ -446,7 +424,6 @@ static struct platform_driver au1xpsc_i2s_driver = {
446 424
447static int __init au1xpsc_i2s_load(void) 425static int __init au1xpsc_i2s_load(void)
448{ 426{
449 au1xpsc_i2s_workdata = NULL;
450 return platform_driver_register(&au1xpsc_i2s_driver); 427 return platform_driver_register(&au1xpsc_i2s_driver);
451} 428}
452 429