aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2016-11-13 01:40:02 -0500
committerMark Brown <broonie@kernel.org>2016-11-13 04:35:35 -0500
commit2e622ae41e653cd71a6d3bc5a4685b01eacbee8d (patch)
tree2356ab4bf6579ef8c8c4250f0554c1a006bcfe41
parent1001354ca34179f3db924eb66672442a173147dc (diff)
ASoC: compress: Add support for compress dai ops
ASoC Compress ops have only platform ops and no DAI ops unlike PCM device where we have both platform ops as well as DAI ops. So add compress dai ops and add this new structure to the ASoC core to make compressed devices a first class ASoC citizen Again like PCM ops, drivers are free to implement either or both of these ops based on device needs. Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc-dai.h25
-rw-r--r--sound/soc/soc-compress.c98
2 files changed, 121 insertions, 2 deletions
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 964b7de1a1cc..756ee1b78ffc 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -207,6 +207,30 @@ struct snd_soc_dai_ops {
207 struct snd_soc_dai *); 207 struct snd_soc_dai *);
208}; 208};
209 209
210struct snd_soc_cdai_ops {
211 /*
212 * for compress ops
213 */
214 int (*startup)(struct snd_compr_stream *,
215 struct snd_soc_dai *);
216 int (*shutdown)(struct snd_compr_stream *,
217 struct snd_soc_dai *);
218 int (*set_params)(struct snd_compr_stream *,
219 struct snd_compr_params *, struct snd_soc_dai *);
220 int (*get_params)(struct snd_compr_stream *,
221 struct snd_codec *, struct snd_soc_dai *);
222 int (*set_metadata)(struct snd_compr_stream *,
223 struct snd_compr_metadata *, struct snd_soc_dai *);
224 int (*get_metadata)(struct snd_compr_stream *,
225 struct snd_compr_metadata *, struct snd_soc_dai *);
226 int (*trigger)(struct snd_compr_stream *, int,
227 struct snd_soc_dai *);
228 int (*pointer)(struct snd_compr_stream *,
229 struct snd_compr_tstamp *, struct snd_soc_dai *);
230 int (*ack)(struct snd_compr_stream *, size_t,
231 struct snd_soc_dai *);
232};
233
210/* 234/*
211 * Digital Audio Interface Driver. 235 * Digital Audio Interface Driver.
212 * 236 *
@@ -236,6 +260,7 @@ struct snd_soc_dai_driver {
236 260
237 /* ops */ 261 /* ops */
238 const struct snd_soc_dai_ops *ops; 262 const struct snd_soc_dai_ops *ops;
263 const struct snd_soc_cdai_ops *cops;
239 264
240 /* DAI capabilities */ 265 /* DAI capabilities */
241 struct snd_soc_pcm_stream capture; 266 struct snd_soc_pcm_stream capture;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index bf7b52fce597..bfd71b873ca2 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -30,16 +30,26 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
30{ 30{
31 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 31 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
32 struct snd_soc_platform *platform = rtd->platform; 32 struct snd_soc_platform *platform = rtd->platform;
33 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
33 int ret = 0; 34 int ret = 0;
34 35
35 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 36 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
36 37
38 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
39 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
40 if (ret < 0) {
41 dev_err(cpu_dai->dev, "Compress ASoC: can't open interface %s: %d\n",
42 cpu_dai->name, ret);
43 goto out;
44 }
45 }
46
37 if (platform->driver->compr_ops && platform->driver->compr_ops->open) { 47 if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
38 ret = platform->driver->compr_ops->open(cstream); 48 ret = platform->driver->compr_ops->open(cstream);
39 if (ret < 0) { 49 if (ret < 0) {
40 pr_err("compress asoc: can't open platform %s\n", 50 pr_err("compress asoc: can't open platform %s\n",
41 platform->component.name); 51 platform->component.name);
42 goto out; 52 goto plat_err;
43 } 53 }
44 } 54 }
45 55
@@ -60,6 +70,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
60machine_err: 70machine_err:
61 if (platform->driver->compr_ops && platform->driver->compr_ops->free) 71 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
62 platform->driver->compr_ops->free(cstream); 72 platform->driver->compr_ops->free(cstream);
73plat_err:
74 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
75 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
63out: 76out:
64 mutex_unlock(&rtd->pcm_mutex); 77 mutex_unlock(&rtd->pcm_mutex);
65 return ret; 78 return ret;
@@ -70,6 +83,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
70 struct snd_soc_pcm_runtime *fe = cstream->private_data; 83 struct snd_soc_pcm_runtime *fe = cstream->private_data;
71 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; 84 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
72 struct snd_soc_platform *platform = fe->platform; 85 struct snd_soc_platform *platform = fe->platform;
86 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
73 struct snd_soc_dpcm *dpcm; 87 struct snd_soc_dpcm *dpcm;
74 struct snd_soc_dapm_widget_list *list; 88 struct snd_soc_dapm_widget_list *list;
75 int stream; 89 int stream;
@@ -82,12 +96,22 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
82 96
83 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 97 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
84 98
99 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
100 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
101 if (ret < 0) {
102 dev_err(cpu_dai->dev, "Compress ASoC: can't open interface %s: %d\n",
103 cpu_dai->name, ret);
104 goto out;
105 }
106 }
107
108
85 if (platform->driver->compr_ops && platform->driver->compr_ops->open) { 109 if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
86 ret = platform->driver->compr_ops->open(cstream); 110 ret = platform->driver->compr_ops->open(cstream);
87 if (ret < 0) { 111 if (ret < 0) {
88 pr_err("compress asoc: can't open platform %s\n", 112 pr_err("compress asoc: can't open platform %s\n",
89 platform->component.name); 113 platform->component.name);
90 goto out; 114 goto plat_err;
91 } 115 }
92 } 116 }
93 117
@@ -144,6 +168,9 @@ fe_err:
144machine_err: 168machine_err:
145 if (platform->driver->compr_ops && platform->driver->compr_ops->free) 169 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
146 platform->driver->compr_ops->free(cstream); 170 platform->driver->compr_ops->free(cstream);
171plat_err:
172 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
173 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
147out: 174out:
148 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 175 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
149 mutex_unlock(&fe->card->mutex); 176 mutex_unlock(&fe->card->mutex);
@@ -210,6 +237,9 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
210 if (platform->driver->compr_ops && platform->driver->compr_ops->free) 237 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
211 platform->driver->compr_ops->free(cstream); 238 platform->driver->compr_ops->free(cstream);
212 239
240 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
241 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
242
213 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 243 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
214 if (snd_soc_runtime_ignore_pmdown_time(rtd)) { 244 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
215 snd_soc_dapm_stream_event(rtd, 245 snd_soc_dapm_stream_event(rtd,
@@ -236,6 +266,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
236{ 266{
237 struct snd_soc_pcm_runtime *fe = cstream->private_data; 267 struct snd_soc_pcm_runtime *fe = cstream->private_data;
238 struct snd_soc_platform *platform = fe->platform; 268 struct snd_soc_platform *platform = fe->platform;
269 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
239 struct snd_soc_dpcm *dpcm; 270 struct snd_soc_dpcm *dpcm;
240 int stream, ret; 271 int stream, ret;
241 272
@@ -275,6 +306,9 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
275 if (platform->driver->compr_ops && platform->driver->compr_ops->free) 306 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
276 platform->driver->compr_ops->free(cstream); 307 platform->driver->compr_ops->free(cstream);
277 308
309 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
310 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
311
278 mutex_unlock(&fe->card->mutex); 312 mutex_unlock(&fe->card->mutex);
279 return 0; 313 return 0;
280} 314}
@@ -285,6 +319,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
285 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 319 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
286 struct snd_soc_platform *platform = rtd->platform; 320 struct snd_soc_platform *platform = rtd->platform;
287 struct snd_soc_dai *codec_dai = rtd->codec_dai; 321 struct snd_soc_dai *codec_dai = rtd->codec_dai;
322 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
288 int ret = 0; 323 int ret = 0;
289 324
290 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 325 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -295,6 +330,10 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
295 goto out; 330 goto out;
296 } 331 }
297 332
333 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
334 cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
335
336
298 switch (cmd) { 337 switch (cmd) {
299 case SNDRV_PCM_TRIGGER_START: 338 case SNDRV_PCM_TRIGGER_START:
300 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction); 339 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
@@ -313,6 +352,7 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
313{ 352{
314 struct snd_soc_pcm_runtime *fe = cstream->private_data; 353 struct snd_soc_pcm_runtime *fe = cstream->private_data;
315 struct snd_soc_platform *platform = fe->platform; 354 struct snd_soc_platform *platform = fe->platform;
355 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
316 int ret = 0, stream; 356 int ret = 0, stream;
317 357
318 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN || 358 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
@@ -332,6 +372,12 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
332 372
333 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 373 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
334 374
375 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
376 ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
377 if (ret < 0)
378 goto out;
379 }
380
335 if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) { 381 if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
336 ret = platform->driver->compr_ops->trigger(cstream, cmd); 382 ret = platform->driver->compr_ops->trigger(cstream, cmd);
337 if (ret < 0) 383 if (ret < 0)
@@ -368,6 +414,7 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
368{ 414{
369 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 415 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
370 struct snd_soc_platform *platform = rtd->platform; 416 struct snd_soc_platform *platform = rtd->platform;
417 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
371 int ret = 0; 418 int ret = 0;
372 419
373 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 420 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -378,6 +425,12 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
378 * expectation is that platform and machine will configure everything 425 * expectation is that platform and machine will configure everything
379 * for this compress path, like configuring pcm port for codec 426 * for this compress path, like configuring pcm port for codec
380 */ 427 */
428 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
429 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
430 if (ret < 0)
431 goto err;
432 }
433
381 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { 434 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
382 ret = platform->driver->compr_ops->set_params(cstream, params); 435 ret = platform->driver->compr_ops->set_params(cstream, params);
383 if (ret < 0) 436 if (ret < 0)
@@ -416,6 +469,7 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
416 struct snd_soc_pcm_runtime *fe = cstream->private_data; 469 struct snd_soc_pcm_runtime *fe = cstream->private_data;
417 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; 470 struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
418 struct snd_soc_platform *platform = fe->platform; 471 struct snd_soc_platform *platform = fe->platform;
472 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
419 int ret = 0, stream; 473 int ret = 0, stream;
420 474
421 if (cstream->direction == SND_COMPRESS_PLAYBACK) 475 if (cstream->direction == SND_COMPRESS_PLAYBACK)
@@ -425,6 +479,12 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
425 479
426 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 480 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
427 481
482 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
483 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
484 if (ret < 0)
485 goto out;
486 }
487
428 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { 488 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
429 ret = platform->driver->compr_ops->set_params(cstream, params); 489 ret = platform->driver->compr_ops->set_params(cstream, params);
430 if (ret < 0) 490 if (ret < 0)
@@ -469,13 +529,21 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
469{ 529{
470 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 530 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
471 struct snd_soc_platform *platform = rtd->platform; 531 struct snd_soc_platform *platform = rtd->platform;
532 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
472 int ret = 0; 533 int ret = 0;
473 534
474 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 535 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
475 536
537 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
538 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
539 if (ret < 0)
540 goto err;
541 }
542
476 if (platform->driver->compr_ops && platform->driver->compr_ops->get_params) 543 if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
477 ret = platform->driver->compr_ops->get_params(cstream, params); 544 ret = platform->driver->compr_ops->get_params(cstream, params);
478 545
546err:
479 mutex_unlock(&rtd->pcm_mutex); 547 mutex_unlock(&rtd->pcm_mutex);
480 return ret; 548 return ret;
481} 549}
@@ -516,13 +584,21 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
516{ 584{
517 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 585 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
518 struct snd_soc_platform *platform = rtd->platform; 586 struct snd_soc_platform *platform = rtd->platform;
587 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
519 int ret = 0; 588 int ret = 0;
520 589
521 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 590 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
522 591
592 if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
593 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
594 if (ret < 0)
595 goto err;
596 }
597
523 if (platform->driver->compr_ops && platform->driver->compr_ops->ack) 598 if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
524 ret = platform->driver->compr_ops->ack(cstream, bytes); 599 ret = platform->driver->compr_ops->ack(cstream, bytes);
525 600
601err:
526 mutex_unlock(&rtd->pcm_mutex); 602 mutex_unlock(&rtd->pcm_mutex);
527 return ret; 603 return ret;
528} 604}
@@ -533,9 +609,13 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
533 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 609 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
534 struct snd_soc_platform *platform = rtd->platform; 610 struct snd_soc_platform *platform = rtd->platform;
535 int ret = 0; 611 int ret = 0;
612 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
536 613
537 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 614 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
538 615
616 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
617 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
618
539 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer) 619 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
540 ret = platform->driver->compr_ops->pointer(cstream, tstamp); 620 ret = platform->driver->compr_ops->pointer(cstream, tstamp);
541 621
@@ -564,8 +644,15 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
564{ 644{
565 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 645 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
566 struct snd_soc_platform *platform = rtd->platform; 646 struct snd_soc_platform *platform = rtd->platform;
647 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
567 int ret = 0; 648 int ret = 0;
568 649
650 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
651 ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
652 if (ret < 0)
653 return ret;
654 }
655
569 if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) 656 if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata)
570 ret = platform->driver->compr_ops->set_metadata(cstream, metadata); 657 ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
571 658
@@ -577,8 +664,15 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
577{ 664{
578 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 665 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
579 struct snd_soc_platform *platform = rtd->platform; 666 struct snd_soc_platform *platform = rtd->platform;
667 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
580 int ret = 0; 668 int ret = 0;
581 669
670 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
671 ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
672 if (ret < 0)
673 return ret;
674 }
675
582 if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) 676 if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata)
583 ret = platform->driver->compr_ops->get_metadata(cstream, metadata); 677 ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
584 678