soc-pcm.c (57b8628bb0ac4e47c806e45c5bbd89282e93869b) soc-pcm.c (01d7584cd2e5a93a2b959c9dddaa0d93ec205404)
1/*
2 * soc-pcm.c -- ALSA SoC PCM
3 *
4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd.
6 * Copyright (C) 2010 Slimlogic Ltd.
7 * Copyright (C) 2010 Texas Instruments Inc.
8 *

--- 8 unchanged lines hidden (view full) ---

17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm_runtime.h>
23#include <linux/slab.h>
24#include <linux/workqueue.h>
1/*
2 * soc-pcm.c -- ALSA SoC PCM
3 *
4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd.
6 * Copyright (C) 2010 Slimlogic Ltd.
7 * Copyright (C) 2010 Texas Instruments Inc.
8 *

--- 8 unchanged lines hidden (view full) ---

17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm_runtime.h>
23#include <linux/slab.h>
24#include <linux/workqueue.h>
25#include <linux/export.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/soc-dpcm.h>
29#include <sound/initval.h>
30
31#include <sound/initval.h>
32
33#define DPCM_MAX_BE_USERS 8
34
35/* DPCM stream event, send event to FE and all active BEs. */
36static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
37 int event)
38{
39 struct snd_soc_dpcm *dpcm;
40
41 list_for_each_entry(dpcm, &fe->dpcm[dir].be_clients, list_be) {
42
43 struct snd_soc_pcm_runtime *be = dpcm->be;
44
45 dev_dbg(be->dev, "pm: BE %s event %d dir %d\n",
46 be->dai_link->name, event, dir);
47
48 snd_soc_dapm_stream_event(be, dir, event);
49 }
50
51 snd_soc_dapm_stream_event(fe, dir, event);
52
53 return 0;
54}
55
31static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
32 struct snd_soc_dai *soc_dai)
33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 int ret;
36
37 if (!soc_dai->driver->symmetric_rates &&
38 !rtd->dai_link->symmetric_rates)

--- 112 unchanged lines hidden (view full) ---

151 ret = rtd->dai_link->ops->startup(substream);
152 if (ret < 0) {
153 pr_err("asoc: %s startup failed: %d\n",
154 rtd->dai_link->name, ret);
155 goto machine_err;
156 }
157 }
158
56static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
57 struct snd_soc_dai *soc_dai)
58{
59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
60 int ret;
61
62 if (!soc_dai->driver->symmetric_rates &&
63 !rtd->dai_link->symmetric_rates)

--- 112 unchanged lines hidden (view full) ---

176 ret = rtd->dai_link->ops->startup(substream);
177 if (ret < 0) {
178 pr_err("asoc: %s startup failed: %d\n",
179 rtd->dai_link->name, ret);
180 goto machine_err;
181 }
182 }
183
184 /* Dynamic PCM DAI links compat checks use dynamic capabilities */
185 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm)
186 goto dynamic;
187
159 /* Check that the codec and cpu DAIs are compatible */
160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
161 runtime->hw.rate_min =
162 max(codec_dai_drv->playback.rate_min,
163 cpu_dai_drv->playback.rate_min);
164 runtime->hw.rate_max =
165 min(codec_dai_drv->playback.rate_max,
166 cpu_dai_drv->playback.rate_max);

--- 76 unchanged lines hidden (view full) ---

243 pr_debug("asoc: %s <-> %s info:\n",
244 codec_dai->name, cpu_dai->name);
245 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
246 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
247 runtime->hw.channels_max);
248 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
249 runtime->hw.rate_max);
250
188 /* Check that the codec and cpu DAIs are compatible */
189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
190 runtime->hw.rate_min =
191 max(codec_dai_drv->playback.rate_min,
192 cpu_dai_drv->playback.rate_min);
193 runtime->hw.rate_max =
194 min(codec_dai_drv->playback.rate_max,
195 cpu_dai_drv->playback.rate_max);

--- 76 unchanged lines hidden (view full) ---

272 pr_debug("asoc: %s <-> %s info:\n",
273 codec_dai->name, cpu_dai->name);
274 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
275 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
276 runtime->hw.channels_max);
277 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
278 runtime->hw.rate_max);
279
280dynamic:
251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
252 cpu_dai->playback_active++;
253 codec_dai->playback_active++;
254 } else {
255 cpu_dai->capture_active++;
256 codec_dai->capture_active++;
257 }
258 cpu_dai->active++;

--- 44 unchanged lines hidden (view full) ---

303 codec_dai->driver->playback.stream_name,
304 codec_dai->playback_active ? "active" : "inactive",
305 codec_dai->pop_wait ? "yes" : "no");
306
307 /* are we waiting on this codec DAI stream */
308 if (codec_dai->pop_wait == 1) {
309 codec_dai->pop_wait = 0;
310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
282 cpu_dai->playback_active++;
283 codec_dai->playback_active++;
284 } else {
285 cpu_dai->capture_active++;
286 codec_dai->capture_active++;
287 }
288 cpu_dai->active++;

--- 44 unchanged lines hidden (view full) ---

333 codec_dai->driver->playback.stream_name,
334 codec_dai->playback_active ? "active" : "inactive",
335 codec_dai->pop_wait ? "yes" : "no");
336
337 /* are we waiting on this codec DAI stream */
338 if (codec_dai->pop_wait == 1) {
339 codec_dai->pop_wait = 0;
340 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
311 codec_dai, SND_SOC_DAPM_STREAM_STOP);
341 SND_SOC_DAPM_STREAM_STOP);
312 }
313
314 mutex_unlock(&rtd->pcm_mutex);
315}
316
317/*
318 * Called by ALSA when a PCM substream is closed. Private data can be
319 * freed here. The cpu DAI, codec DAI, machine and platform are also

--- 48 unchanged lines hidden (view full) ---

368 cpu_dai->runtime = NULL;
369
370 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
371 if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
372 rtd->dai_link->ignore_pmdown_time) {
373 /* powered down playback stream now */
374 snd_soc_dapm_stream_event(rtd,
375 SNDRV_PCM_STREAM_PLAYBACK,
342 }
343
344 mutex_unlock(&rtd->pcm_mutex);
345}
346
347/*
348 * Called by ALSA when a PCM substream is closed. Private data can be
349 * freed here. The cpu DAI, codec DAI, machine and platform are also

--- 48 unchanged lines hidden (view full) ---

398 cpu_dai->runtime = NULL;
399
400 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
401 if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
402 rtd->dai_link->ignore_pmdown_time) {
403 /* powered down playback stream now */
404 snd_soc_dapm_stream_event(rtd,
405 SNDRV_PCM_STREAM_PLAYBACK,
376 codec_dai,
377 SND_SOC_DAPM_STREAM_STOP);
378 } else {
379 /* start delayed pop wq here for playback streams */
380 codec_dai->pop_wait = 1;
381 schedule_delayed_work(&rtd->delayed_work,
382 msecs_to_jiffies(rtd->pmdown_time));
383 }
384 } else {
385 /* capture streams can be powered down now */
386 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
406 SND_SOC_DAPM_STREAM_STOP);
407 } else {
408 /* start delayed pop wq here for playback streams */
409 codec_dai->pop_wait = 1;
410 schedule_delayed_work(&rtd->delayed_work,
411 msecs_to_jiffies(rtd->pmdown_time));
412 }
413 } else {
414 /* capture streams can be powered down now */
415 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
387 codec_dai, SND_SOC_DAPM_STREAM_STOP);
416 SND_SOC_DAPM_STREAM_STOP);
388 }
389
390 mutex_unlock(&rtd->pcm_mutex);
391
392 pm_runtime_put(platform->dev);
393 pm_runtime_put(codec_dai->dev);
394 pm_runtime_put(cpu_dai->dev);
395

--- 52 unchanged lines hidden (view full) ---

448
449 /* cancel any delayed stream shutdown that is pending */
450 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
451 codec_dai->pop_wait) {
452 codec_dai->pop_wait = 0;
453 cancel_delayed_work(&rtd->delayed_work);
454 }
455
417 }
418
419 mutex_unlock(&rtd->pcm_mutex);
420
421 pm_runtime_put(platform->dev);
422 pm_runtime_put(codec_dai->dev);
423 pm_runtime_put(cpu_dai->dev);
424

--- 52 unchanged lines hidden (view full) ---

477
478 /* cancel any delayed stream shutdown that is pending */
479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
480 codec_dai->pop_wait) {
481 codec_dai->pop_wait = 0;
482 cancel_delayed_work(&rtd->delayed_work);
483 }
484
456 snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai,
457 SND_SOC_DAPM_STREAM_START);
485 snd_soc_dapm_stream_event(rtd, substream->stream,
486 SND_SOC_DAPM_STREAM_START);
458
459 snd_soc_dai_digital_mute(codec_dai, 0);
460
461out:
462 mutex_unlock(&rtd->pcm_mutex);
463 return ret;
464}
465

--- 163 unchanged lines hidden (view full) ---

629 if (platform->driver->delay)
630 delay += platform->driver->delay(substream, codec_dai);
631
632 runtime->delay = delay;
633
634 return offset;
635}
636
487
488 snd_soc_dai_digital_mute(codec_dai, 0);
489
490out:
491 mutex_unlock(&rtd->pcm_mutex);
492 return ret;
493}
494

--- 163 unchanged lines hidden (view full) ---

658 if (platform->driver->delay)
659 delay += platform->driver->delay(substream, codec_dai);
660
661 runtime->delay = delay;
662
663 return offset;
664}
665
666/* connect a FE and BE */
667static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
668 struct snd_soc_pcm_runtime *be, int stream)
669{
670 struct snd_soc_dpcm *dpcm;
671
672 /* only add new dpcms */
673 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
674 if (dpcm->be == be && dpcm->fe == fe)
675 return 0;
676 }
677
678 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL);
679 if (!dpcm)
680 return -ENOMEM;
681
682 dpcm->be = be;
683 dpcm->fe = fe;
684 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
685 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
686 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
687 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
688
689 dev_dbg(fe->dev, " connected new DPCM %s path %s %s %s\n",
690 stream ? "capture" : "playback", fe->dai_link->name,
691 stream ? "<-" : "->", be->dai_link->name);
692
693 return 1;
694}
695
696/* reparent a BE onto another FE */
697static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
698 struct snd_soc_pcm_runtime *be, int stream)
699{
700 struct snd_soc_dpcm *dpcm;
701 struct snd_pcm_substream *fe_substream, *be_substream;
702
703 /* reparent if BE is connected to other FEs */
704 if (!be->dpcm[stream].users)
705 return;
706
707 be_substream = snd_soc_dpcm_get_substream(be, stream);
708
709 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
710 if (dpcm->fe == fe)
711 continue;
712
713 dev_dbg(fe->dev, " reparent %s path %s %s %s\n",
714 stream ? "capture" : "playback",
715 dpcm->fe->dai_link->name,
716 stream ? "<-" : "->", dpcm->be->dai_link->name);
717
718 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream);
719 be_substream->runtime = fe_substream->runtime;
720 break;
721 }
722}
723
724/* disconnect a BE and FE */
725static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
726{
727 struct snd_soc_dpcm *dpcm, *d;
728
729 list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) {
730 dev_dbg(fe->dev, "BE %s disconnect check for %s\n",
731 stream ? "capture" : "playback",
732 dpcm->be->dai_link->name);
733
734 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
735 continue;
736
737 dev_dbg(fe->dev, " freed DSP %s path %s %s %s\n",
738 stream ? "capture" : "playback", fe->dai_link->name,
739 stream ? "<-" : "->", dpcm->be->dai_link->name);
740
741 /* BEs still alive need new FE */
742 dpcm_be_reparent(fe, dpcm->be, stream);
743
744 list_del(&dpcm->list_be);
745 list_del(&dpcm->list_fe);
746 kfree(dpcm);
747 }
748}
749
750/* get BE for DAI widget and stream */
751static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
752 struct snd_soc_dapm_widget *widget, int stream)
753{
754 struct snd_soc_pcm_runtime *be;
755 int i;
756
757 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
758 for (i = 0; i < card->num_links; i++) {
759 be = &card->rtd[i];
760
761 if (be->cpu_dai->playback_widget == widget ||
762 be->codec_dai->playback_widget == widget)
763 return be;
764 }
765 } else {
766
767 for (i = 0; i < card->num_links; i++) {
768 be = &card->rtd[i];
769
770 if (be->cpu_dai->capture_widget == widget ||
771 be->codec_dai->capture_widget == widget)
772 return be;
773 }
774 }
775
776 dev_err(card->dev, "can't get %s BE for %s\n",
777 stream ? "capture" : "playback", widget->name);
778 return NULL;
779}
780
781static inline struct snd_soc_dapm_widget *
782 rtd_get_cpu_widget(struct snd_soc_pcm_runtime *rtd, int stream)
783{
784 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
785 return rtd->cpu_dai->playback_widget;
786 else
787 return rtd->cpu_dai->capture_widget;
788}
789
790static inline struct snd_soc_dapm_widget *
791 rtd_get_codec_widget(struct snd_soc_pcm_runtime *rtd, int stream)
792{
793 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
794 return rtd->codec_dai->playback_widget;
795 else
796 return rtd->codec_dai->capture_widget;
797}
798
799static int widget_in_list(struct snd_soc_dapm_widget_list *list,
800 struct snd_soc_dapm_widget *widget)
801{
802 int i;
803
804 for (i = 0; i < list->num_widgets; i++) {
805 if (widget == list->widgets[i])
806 return 1;
807 }
808
809 return 0;
810}
811
812static int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
813 int stream, struct snd_soc_dapm_widget_list **list_)
814{
815 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
816 struct snd_soc_dapm_widget_list *list;
817 int paths;
818
819 list = kzalloc(sizeof(struct snd_soc_dapm_widget_list) +
820 sizeof(struct snd_soc_dapm_widget *), GFP_KERNEL);
821 if (list == NULL)
822 return -ENOMEM;
823
824 /* get number of valid DAI paths and their widgets */
825 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list);
826
827 dev_dbg(fe->dev, "found %d audio %s paths\n", paths,
828 stream ? "capture" : "playback");
829
830 *list_ = list;
831 return paths;
832}
833
834static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
835{
836 kfree(*list);
837}
838
839static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
840 struct snd_soc_dapm_widget_list **list_)
841{
842 struct snd_soc_dpcm *dpcm;
843 struct snd_soc_dapm_widget_list *list = *list_;
844 struct snd_soc_dapm_widget *widget;
845 int prune = 0;
846
847 /* Destroy any old FE <--> BE connections */
848 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
849
850 /* is there a valid CPU DAI widget for this BE */
851 widget = rtd_get_cpu_widget(dpcm->be, stream);
852
853 /* prune the BE if it's no longer in our active list */
854 if (widget && widget_in_list(list, widget))
855 continue;
856
857 /* is there a valid CODEC DAI widget for this BE */
858 widget = rtd_get_codec_widget(dpcm->be, stream);
859
860 /* prune the BE if it's no longer in our active list */
861 if (widget && widget_in_list(list, widget))
862 continue;
863
864 dev_dbg(fe->dev, "pruning %s BE %s for %s\n",
865 stream ? "capture" : "playback",
866 dpcm->be->dai_link->name, fe->dai_link->name);
867 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
868 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
869 prune++;
870 }
871
872 dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune);
873 return prune;
874}
875
876static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
877 struct snd_soc_dapm_widget_list **list_)
878{
879 struct snd_soc_card *card = fe->card;
880 struct snd_soc_dapm_widget_list *list = *list_;
881 struct snd_soc_pcm_runtime *be;
882 int i, new = 0, err;
883
884 /* Create any new FE <--> BE connections */
885 for (i = 0; i < list->num_widgets; i++) {
886
887 if (list->widgets[i]->id != snd_soc_dapm_dai)
888 continue;
889
890 /* is there a valid BE rtd for this widget */
891 be = dpcm_get_be(card, list->widgets[i], stream);
892 if (!be) {
893 dev_err(fe->dev, "no BE found for %s\n",
894 list->widgets[i]->name);
895 continue;
896 }
897
898 /* make sure BE is a real BE */
899 if (!be->dai_link->no_pcm)
900 continue;
901
902 /* don't connect if FE is not running */
903 if (!fe->dpcm[stream].runtime)
904 continue;
905
906 /* newly connected FE and BE */
907 err = dpcm_be_connect(fe, be, stream);
908 if (err < 0) {
909 dev_err(fe->dev, "can't connect %s\n",
910 list->widgets[i]->name);
911 break;
912 } else if (err == 0) /* already connected */
913 continue;
914
915 /* new */
916 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
917 new++;
918 }
919
920 dev_dbg(fe->dev, "found %d new BE paths\n", new);
921 return new;
922}
923
924/*
925 * Find the corresponding BE DAIs that source or sink audio to this
926 * FE substream.
927 */
928static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
929 int stream, struct snd_soc_dapm_widget_list **list, int new)
930{
931 if (new)
932 return dpcm_add_paths(fe, stream, list);
933 else
934 return dpcm_prune_paths(fe, stream, list);
935}
936
937static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
938{
939 struct snd_soc_dpcm *dpcm;
940
941 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
942 dpcm->be->dpcm[stream].runtime_update =
943 SND_SOC_DPCM_UPDATE_NO;
944}
945
946static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
947 int stream)
948{
949 struct snd_soc_dpcm *dpcm;
950
951 /* disable any enabled and non active backends */
952 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
953
954 struct snd_soc_pcm_runtime *be = dpcm->be;
955 struct snd_pcm_substream *be_substream =
956 snd_soc_dpcm_get_substream(be, stream);
957
958 if (be->dpcm[stream].users == 0)
959 dev_err(be->dev, "no users %s at close - state %d\n",
960 stream ? "capture" : "playback",
961 be->dpcm[stream].state);
962
963 if (--be->dpcm[stream].users != 0)
964 continue;
965
966 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
967 continue;
968
969 soc_pcm_close(be_substream);
970 be_substream->runtime = NULL;
971 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
972 }
973}
974
975static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
976{
977 struct snd_soc_dpcm *dpcm;
978 int err, count = 0;
979
980 /* only startup BE DAIs that are either sinks or sources to this FE DAI */
981 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
982
983 struct snd_soc_pcm_runtime *be = dpcm->be;
984 struct snd_pcm_substream *be_substream =
985 snd_soc_dpcm_get_substream(be, stream);
986
987 /* is this op for this BE ? */
988 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
989 continue;
990
991 /* first time the dpcm is open ? */
992 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
993 dev_err(be->dev, "too many users %s at open %d\n",
994 stream ? "capture" : "playback",
995 be->dpcm[stream].state);
996
997 if (be->dpcm[stream].users++ != 0)
998 continue;
999
1000 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
1001 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
1002 continue;
1003
1004 dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name);
1005
1006 be_substream->runtime = be->dpcm[stream].runtime;
1007 err = soc_pcm_open(be_substream);
1008 if (err < 0) {
1009 dev_err(be->dev, "BE open failed %d\n", err);
1010 be->dpcm[stream].users--;
1011 if (be->dpcm[stream].users < 0)
1012 dev_err(be->dev, "no users %s at unwind %d\n",
1013 stream ? "capture" : "playback",
1014 be->dpcm[stream].state);
1015
1016 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1017 goto unwind;
1018 }
1019
1020 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1021 count++;
1022 }
1023
1024 return count;
1025
1026unwind:
1027 /* disable any enabled and non active backends */
1028 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1029 struct snd_soc_pcm_runtime *be = dpcm->be;
1030 struct snd_pcm_substream *be_substream =
1031 snd_soc_dpcm_get_substream(be, stream);
1032
1033 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1034 continue;
1035
1036 if (be->dpcm[stream].users == 0)
1037 dev_err(be->dev, "no users %s at close %d\n",
1038 stream ? "capture" : "playback",
1039 be->dpcm[stream].state);
1040
1041 if (--be->dpcm[stream].users != 0)
1042 continue;
1043
1044 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1045 continue;
1046
1047 soc_pcm_close(be_substream);
1048 be_substream->runtime = NULL;
1049 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1050 }
1051
1052 return err;
1053}
1054
1055void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1056{
1057 struct snd_pcm_runtime *runtime = substream->runtime;
1058 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1059 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1060 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1061
1062 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1063 runtime->hw.rate_min = cpu_dai_drv->playback.rate_min;
1064 runtime->hw.rate_max = cpu_dai_drv->playback.rate_max;
1065 runtime->hw.channels_min = cpu_dai_drv->playback.channels_min;
1066 runtime->hw.channels_max = cpu_dai_drv->playback.channels_max;
1067 runtime->hw.formats &= cpu_dai_drv->playback.formats;
1068 runtime->hw.rates = cpu_dai_drv->playback.rates;
1069 } else {
1070 runtime->hw.rate_min = cpu_dai_drv->capture.rate_min;
1071 runtime->hw.rate_max = cpu_dai_drv->capture.rate_max;
1072 runtime->hw.channels_min = cpu_dai_drv->capture.channels_min;
1073 runtime->hw.channels_max = cpu_dai_drv->capture.channels_max;
1074 runtime->hw.formats &= cpu_dai_drv->capture.formats;
1075 runtime->hw.rates = cpu_dai_drv->capture.rates;
1076 }
1077}
1078
1079static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1080{
1081 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1082 struct snd_pcm_runtime *runtime = fe_substream->runtime;
1083 int stream = fe_substream->stream, ret = 0;
1084
1085 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1086
1087 ret = dpcm_be_dai_startup(fe, fe_substream->stream);
1088 if (ret < 0) {
1089 dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret);
1090 goto be_err;
1091 }
1092
1093 dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name);
1094
1095 /* start the DAI frontend */
1096 ret = soc_pcm_open(fe_substream);
1097 if (ret < 0) {
1098 dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret);
1099 goto unwind;
1100 }
1101
1102 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1103
1104 dpcm_set_fe_runtime(fe_substream);
1105 snd_pcm_limit_hw_rates(runtime);
1106
1107 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1108 return 0;
1109
1110unwind:
1111 dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
1112be_err:
1113 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1114 return ret;
1115}
1116
1117static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1118{
1119 struct snd_soc_dpcm *dpcm;
1120
1121 /* only shutdown BEs that are either sinks or sources to this FE DAI */
1122 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1123
1124 struct snd_soc_pcm_runtime *be = dpcm->be;
1125 struct snd_pcm_substream *be_substream =
1126 snd_soc_dpcm_get_substream(be, stream);
1127
1128 /* is this op for this BE ? */
1129 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1130 continue;
1131
1132 if (be->dpcm[stream].users == 0)
1133 dev_err(be->dev, "no users %s at close - state %d\n",
1134 stream ? "capture" : "playback",
1135 be->dpcm[stream].state);
1136
1137 if (--be->dpcm[stream].users != 0)
1138 continue;
1139
1140 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1141 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
1142 continue;
1143
1144 dev_dbg(be->dev, "dpcm: close BE %s\n",
1145 dpcm->fe->dai_link->name);
1146
1147 soc_pcm_close(be_substream);
1148 be_substream->runtime = NULL;
1149
1150 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1151 }
1152 return 0;
1153}
1154
1155static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
1156{
1157 struct snd_soc_pcm_runtime *fe = substream->private_data;
1158 int stream = substream->stream;
1159
1160 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1161
1162 /* shutdown the BEs */
1163 dpcm_be_dai_shutdown(fe, substream->stream);
1164
1165 dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name);
1166
1167 /* now shutdown the frontend */
1168 soc_pcm_close(substream);
1169
1170 /* run the stream event for each BE */
1171 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
1172
1173 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1174 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1175 return 0;
1176}
1177
1178static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
1179{
1180 struct snd_soc_dpcm *dpcm;
1181
1182 /* only hw_params backends that are either sinks or sources
1183 * to this frontend DAI */
1184 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1185
1186 struct snd_soc_pcm_runtime *be = dpcm->be;
1187 struct snd_pcm_substream *be_substream =
1188 snd_soc_dpcm_get_substream(be, stream);
1189
1190 /* is this op for this BE ? */
1191 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1192 continue;
1193
1194 /* only free hw when no longer used - check all FEs */
1195 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1196 continue;
1197
1198 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1199 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1200 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1201 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1202 continue;
1203
1204 dev_dbg(be->dev, "dpcm: hw_free BE %s\n",
1205 dpcm->fe->dai_link->name);
1206
1207 soc_pcm_hw_free(be_substream);
1208
1209 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1210 }
1211
1212 return 0;
1213}
1214
1215int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
1216{
1217 struct snd_soc_pcm_runtime *fe = substream->private_data;
1218 int err, stream = substream->stream;
1219
1220 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1221 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1222
1223 dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name);
1224
1225 /* call hw_free on the frontend */
1226 err = soc_pcm_hw_free(substream);
1227 if (err < 0)
1228 dev_err(fe->dev,"dpcm: hw_free FE %s failed\n",
1229 fe->dai_link->name);
1230
1231 /* only hw_params backends that are either sinks or sources
1232 * to this frontend DAI */
1233 err = dpcm_be_dai_hw_free(fe, stream);
1234
1235 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1236 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1237
1238 mutex_unlock(&fe->card->mutex);
1239 return 0;
1240}
1241
1242static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
1243{
1244 struct snd_soc_dpcm *dpcm;
1245 int ret;
1246
1247 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1248
1249 struct snd_soc_pcm_runtime *be = dpcm->be;
1250 struct snd_pcm_substream *be_substream =
1251 snd_soc_dpcm_get_substream(be, stream);
1252
1253 /* is this op for this BE ? */
1254 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1255 continue;
1256
1257 /* only allow hw_params() if no connected FEs are running */
1258 if (!snd_soc_dpcm_can_be_params(fe, be, stream))
1259 continue;
1260
1261 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1262 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1263 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
1264 continue;
1265
1266 dev_dbg(be->dev, "dpcm: hw_params BE %s\n",
1267 dpcm->fe->dai_link->name);
1268
1269 /* copy params for each dpcm */
1270 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params,
1271 sizeof(struct snd_pcm_hw_params));
1272
1273 /* perform any hw_params fixups */
1274 if (be->dai_link->be_hw_params_fixup) {
1275 ret = be->dai_link->be_hw_params_fixup(be,
1276 &dpcm->hw_params);
1277 if (ret < 0) {
1278 dev_err(be->dev,
1279 "dpcm: hw_params BE fixup failed %d\n",
1280 ret);
1281 goto unwind;
1282 }
1283 }
1284
1285 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
1286 if (ret < 0) {
1287 dev_err(dpcm->be->dev,
1288 "dpcm: hw_params BE failed %d\n", ret);
1289 goto unwind;
1290 }
1291
1292 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1293 }
1294 return 0;
1295
1296unwind:
1297 /* disable any enabled and non active backends */
1298 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1299 struct snd_soc_pcm_runtime *be = dpcm->be;
1300 struct snd_pcm_substream *be_substream =
1301 snd_soc_dpcm_get_substream(be, stream);
1302
1303 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1304 continue;
1305
1306 /* only allow hw_free() if no connected FEs are running */
1307 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1308 continue;
1309
1310 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1311 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1312 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1313 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1314 continue;
1315
1316 soc_pcm_hw_free(be_substream);
1317 }
1318
1319 return ret;
1320}
1321
1322int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
1323 struct snd_pcm_hw_params *params)
1324{
1325 struct snd_soc_pcm_runtime *fe = substream->private_data;
1326 int ret, stream = substream->stream;
1327
1328 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1329 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1330
1331 memcpy(&fe->dpcm[substream->stream].hw_params, params,
1332 sizeof(struct snd_pcm_hw_params));
1333 ret = dpcm_be_dai_hw_params(fe, substream->stream);
1334 if (ret < 0) {
1335 dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret);
1336 goto out;
1337 }
1338
1339 dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n",
1340 fe->dai_link->name, params_rate(params),
1341 params_channels(params), params_format(params));
1342
1343 /* call hw_params on the frontend */
1344 ret = soc_pcm_hw_params(substream, params);
1345 if (ret < 0) {
1346 dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret);
1347 dpcm_be_dai_hw_free(fe, stream);
1348 } else
1349 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1350
1351out:
1352 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1353 mutex_unlock(&fe->card->mutex);
1354 return ret;
1355}
1356
1357static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
1358 struct snd_pcm_substream *substream, int cmd)
1359{
1360 int ret;
1361
1362 dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n",
1363 dpcm->fe->dai_link->name, cmd);
1364
1365 ret = soc_pcm_trigger(substream, cmd);
1366 if (ret < 0)
1367 dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret);
1368
1369 return ret;
1370}
1371
1372int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd)
1373{
1374 struct snd_soc_dpcm *dpcm;
1375 int ret = 0;
1376
1377 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1378
1379 struct snd_soc_pcm_runtime *be = dpcm->be;
1380 struct snd_pcm_substream *be_substream =
1381 snd_soc_dpcm_get_substream(be, stream);
1382
1383 /* is this op for this BE ? */
1384 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1385 continue;
1386
1387 switch (cmd) {
1388 case SNDRV_PCM_TRIGGER_START:
1389 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1390 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1391 continue;
1392
1393 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1394 if (ret)
1395 return ret;
1396
1397 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1398 break;
1399 case SNDRV_PCM_TRIGGER_RESUME:
1400 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
1401 continue;
1402
1403 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1404 if (ret)
1405 return ret;
1406
1407 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1408 break;
1409 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1410 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
1411 continue;
1412
1413 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1414 if (ret)
1415 return ret;
1416
1417 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1418 break;
1419 case SNDRV_PCM_TRIGGER_STOP:
1420 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1421 continue;
1422
1423 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1424 continue;
1425
1426 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1427 if (ret)
1428 return ret;
1429
1430 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1431 break;
1432 case SNDRV_PCM_TRIGGER_SUSPEND:
1433 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)
1434 continue;
1435
1436 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1437 continue;
1438
1439 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1440 if (ret)
1441 return ret;
1442
1443 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND;
1444 break;
1445 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1446 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1447 continue;
1448
1449 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1450 continue;
1451
1452 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1453 if (ret)
1454 return ret;
1455
1456 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
1457 break;
1458 }
1459 }
1460
1461 return ret;
1462}
1463EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
1464
1465int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
1466{
1467 struct snd_soc_pcm_runtime *fe = substream->private_data;
1468 int stream = substream->stream, ret;
1469 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1470
1471 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1472
1473 switch (trigger) {
1474 case SND_SOC_DPCM_TRIGGER_PRE:
1475 /* call trigger on the frontend before the backend. */
1476
1477 dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n",
1478 fe->dai_link->name, cmd);
1479
1480 ret = soc_pcm_trigger(substream, cmd);
1481 if (ret < 0) {
1482 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1483 goto out;
1484 }
1485
1486 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1487 break;
1488 case SND_SOC_DPCM_TRIGGER_POST:
1489 /* call trigger on the frontend after the backend. */
1490
1491 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1492 if (ret < 0) {
1493 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1494 goto out;
1495 }
1496
1497 dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n",
1498 fe->dai_link->name, cmd);
1499
1500 ret = soc_pcm_trigger(substream, cmd);
1501 break;
1502 default:
1503 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd,
1504 fe->dai_link->name);
1505 ret = -EINVAL;
1506 goto out;
1507 }
1508
1509 switch (cmd) {
1510 case SNDRV_PCM_TRIGGER_START:
1511 case SNDRV_PCM_TRIGGER_RESUME:
1512 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1513 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1514 break;
1515 case SNDRV_PCM_TRIGGER_STOP:
1516 case SNDRV_PCM_TRIGGER_SUSPEND:
1517 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1518 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1519 break;
1520 }
1521
1522out:
1523 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1524 return ret;
1525}
1526
1527static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
1528{
1529 struct snd_soc_dpcm *dpcm;
1530 int ret = 0;
1531
1532 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1533
1534 struct snd_soc_pcm_runtime *be = dpcm->be;
1535 struct snd_pcm_substream *be_substream =
1536 snd_soc_dpcm_get_substream(be, stream);
1537
1538 /* is this op for this BE ? */
1539 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1540 continue;
1541
1542 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1543 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1544 continue;
1545
1546 dev_dbg(be->dev, "dpcm: prepare BE %s\n",
1547 dpcm->fe->dai_link->name);
1548
1549 ret = soc_pcm_prepare(be_substream);
1550 if (ret < 0) {
1551 dev_err(be->dev, "dpcm: backend prepare failed %d\n",
1552 ret);
1553 break;
1554 }
1555
1556 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1557 }
1558 return ret;
1559}
1560
1561int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
1562{
1563 struct snd_soc_pcm_runtime *fe = substream->private_data;
1564 int stream = substream->stream, ret = 0;
1565
1566 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1567
1568 dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name);
1569
1570 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1571
1572 /* there is no point preparing this FE if there are no BEs */
1573 if (list_empty(&fe->dpcm[stream].be_clients)) {
1574 dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n",
1575 fe->dai_link->name);
1576 ret = -EINVAL;
1577 goto out;
1578 }
1579
1580 ret = dpcm_be_dai_prepare(fe, substream->stream);
1581 if (ret < 0)
1582 goto out;
1583
1584 /* call prepare on the frontend */
1585 ret = soc_pcm_prepare(substream);
1586 if (ret < 0) {
1587 dev_err(fe->dev,"dpcm: prepare FE %s failed\n",
1588 fe->dai_link->name);
1589 goto out;
1590 }
1591
1592 /* run the stream event for each BE */
1593 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
1594 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1595
1596out:
1597 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1598 mutex_unlock(&fe->card->mutex);
1599
1600 return ret;
1601}
1602
1603
1604int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
1605{
1606 struct snd_soc_dpcm *dpcm;
1607 struct list_head *clients =
1608 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients;
1609
1610 list_for_each_entry(dpcm, clients, list_be) {
1611
1612 struct snd_soc_pcm_runtime *be = dpcm->be;
1613 struct snd_soc_dai *dai = be->codec_dai;
1614 struct snd_soc_dai_driver *drv = dai->driver;
1615
1616 if (be->dai_link->ignore_suspend)
1617 continue;
1618
1619 dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name);
1620
1621 if (drv->ops->digital_mute && dai->playback_active)
1622 drv->ops->digital_mute(dai, mute);
1623 }
1624
1625 return 0;
1626}
1627
1628int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
1629{
1630 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1631 struct snd_soc_dpcm *dpcm;
1632 struct snd_soc_dapm_widget_list *list;
1633 int ret;
1634 int stream = fe_substream->stream;
1635
1636 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1637 fe->dpcm[stream].runtime = fe_substream->runtime;
1638
1639 if (dpcm_path_get(fe, stream, &list) <= 0) {
1640 dev_warn(fe->dev, "asoc: %s no valid %s route\n",
1641 fe->dai_link->name, stream ? "capture" : "playback");
1642 mutex_unlock(&fe->card->mutex);
1643 return -EINVAL;
1644 }
1645
1646 /* calculate valid and active FE <-> BE dpcms */
1647 dpcm_process_paths(fe, stream, &list, 1);
1648
1649 ret = dpcm_fe_dai_startup(fe_substream);
1650 if (ret < 0) {
1651 /* clean up all links */
1652 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1653 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1654
1655 dpcm_be_disconnect(fe, stream);
1656 fe->dpcm[stream].runtime = NULL;
1657 }
1658
1659 dpcm_clear_pending_state(fe, stream);
1660 dpcm_path_put(&list);
1661 mutex_unlock(&fe->card->mutex);
1662 return ret;
1663}
1664
1665int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
1666{
1667 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1668 struct snd_soc_dpcm *dpcm;
1669 int stream = fe_substream->stream, ret;
1670
1671 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1672 ret = dpcm_fe_dai_shutdown(fe_substream);
1673
1674 /* mark FE's links ready to prune */
1675 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1676 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1677
1678 dpcm_be_disconnect(fe, stream);
1679
1680 fe->dpcm[stream].runtime = NULL;
1681 mutex_unlock(&fe->card->mutex);
1682 return ret;
1683}
1684
637/* create a new pcm */
638int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
639{
640 struct snd_soc_codec *codec = rtd->codec;
641 struct snd_soc_platform *platform = rtd->platform;
642 struct snd_soc_dai *codec_dai = rtd->codec_dai;
643 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1685/* create a new pcm */
1686int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
1687{
1688 struct snd_soc_codec *codec = rtd->codec;
1689 struct snd_soc_platform *platform = rtd->platform;
1690 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1691 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
644 struct snd_pcm_ops *soc_pcm_ops = &rtd->ops;
645 struct snd_pcm *pcm;
646 char new_name[64];
647 int ret = 0, playback = 0, capture = 0;
648
1692 struct snd_pcm *pcm;
1693 char new_name[64];
1694 int ret = 0, playback = 0, capture = 0;
1695
649 soc_pcm_ops->open = soc_pcm_open;
650 soc_pcm_ops->close = soc_pcm_close;
651 soc_pcm_ops->hw_params = soc_pcm_hw_params;
652 soc_pcm_ops->hw_free = soc_pcm_hw_free;
653 soc_pcm_ops->prepare = soc_pcm_prepare;
654 soc_pcm_ops->trigger = soc_pcm_trigger;
655 soc_pcm_ops->pointer = soc_pcm_pointer;
1696 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
1697 if (cpu_dai->driver->playback.channels_min)
1698 playback = 1;
1699 if (cpu_dai->driver->capture.channels_min)
1700 capture = 1;
1701 } else {
1702 if (codec_dai->driver->playback.channels_min)
1703 playback = 1;
1704 if (codec_dai->driver->capture.channels_min)
1705 capture = 1;
1706 }
656
1707
657 /* check client and interface hw capabilities */
658 snprintf(new_name, sizeof(new_name), "%s %s-%d",
659 rtd->dai_link->stream_name, codec_dai->name, num);
1708 /* create the PCM */
1709 if (rtd->dai_link->no_pcm) {
1710 snprintf(new_name, sizeof(new_name), "(%s)",
1711 rtd->dai_link->stream_name);
660
1712
661 if (codec_dai->driver->playback.channels_min)
662 playback = 1;
663 if (codec_dai->driver->capture.channels_min)
664 capture = 1;
1713 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
1714 playback, capture, &pcm);
1715 } else {
1716 if (rtd->dai_link->dynamic)
1717 snprintf(new_name, sizeof(new_name), "%s (*)",
1718 rtd->dai_link->stream_name);
1719 else
1720 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1721 rtd->dai_link->stream_name, codec_dai->name, num);
665
1722
666 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name);
667 ret = snd_pcm_new(rtd->card->snd_card, new_name,
668 num, playback, capture, &pcm);
1723 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
1724 capture, &pcm);
1725 }
669 if (ret < 0) {
670 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
671 return ret;
672 }
1726 if (ret < 0) {
1727 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
1728 return ret;
1729 }
1730 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
673
674 /* DAPM dai link stream work */
675 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
676
677 rtd->pcm = pcm;
678 pcm->private_data = rtd;
1731
1732 /* DAPM dai link stream work */
1733 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1734
1735 rtd->pcm = pcm;
1736 pcm->private_data = rtd;
1737
1738 if (rtd->dai_link->no_pcm) {
1739 if (playback)
1740 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
1741 if (capture)
1742 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
1743 goto out;
1744 }
1745
1746 /* ASoC PCM operations */
1747 if (rtd->dai_link->dynamic) {
1748 rtd->ops.open = dpcm_fe_dai_open;
1749 rtd->ops.hw_params = dpcm_fe_dai_hw_params;
1750 rtd->ops.prepare = dpcm_fe_dai_prepare;
1751 rtd->ops.trigger = dpcm_fe_dai_trigger;
1752 rtd->ops.hw_free = dpcm_fe_dai_hw_free;
1753 rtd->ops.close = dpcm_fe_dai_close;
1754 rtd->ops.pointer = soc_pcm_pointer;
1755 } else {
1756 rtd->ops.open = soc_pcm_open;
1757 rtd->ops.hw_params = soc_pcm_hw_params;
1758 rtd->ops.prepare = soc_pcm_prepare;
1759 rtd->ops.trigger = soc_pcm_trigger;
1760 rtd->ops.hw_free = soc_pcm_hw_free;
1761 rtd->ops.close = soc_pcm_close;
1762 rtd->ops.pointer = soc_pcm_pointer;
1763 }
1764
679 if (platform->driver->ops) {
1765 if (platform->driver->ops) {
680 soc_pcm_ops->mmap = platform->driver->ops->mmap;
681 soc_pcm_ops->pointer = platform->driver->ops->pointer;
682 soc_pcm_ops->ioctl = platform->driver->ops->ioctl;
683 soc_pcm_ops->copy = platform->driver->ops->copy;
684 soc_pcm_ops->silence = platform->driver->ops->silence;
685 soc_pcm_ops->ack = platform->driver->ops->ack;
686 soc_pcm_ops->page = platform->driver->ops->page;
1766 rtd->ops.ack = platform->driver->ops->ack;
1767 rtd->ops.copy = platform->driver->ops->copy;
1768 rtd->ops.silence = platform->driver->ops->silence;
1769 rtd->ops.page = platform->driver->ops->page;
1770 rtd->ops.mmap = platform->driver->ops->mmap;
687 }
688
689 if (playback)
1771 }
1772
1773 if (playback)
690 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops);
1774 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops);
691
692 if (capture)
1775
1776 if (capture)
693 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops);
1777 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
694
695 if (platform->driver->pcm_new) {
696 ret = platform->driver->pcm_new(rtd);
697 if (ret < 0) {
698 pr_err("asoc: platform pcm constructor failed\n");
699 return ret;
700 }
701 }
702
703 pcm->private_free = platform->driver->pcm_free;
1778
1779 if (platform->driver->pcm_new) {
1780 ret = platform->driver->pcm_new(rtd);
1781 if (ret < 0) {
1782 pr_err("asoc: platform pcm constructor failed\n");
1783 return ret;
1784 }
1785 }
1786
1787 pcm->private_free = platform->driver->pcm_free;
1788out:
704 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
705 cpu_dai->name);
706 return ret;
707}
1789 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
1790 cpu_dai->name);
1791 return ret;
1792}
1793
1794/* is the current PCM operation for this FE ? */
1795int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream)
1796{
1797 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE)
1798 return 1;
1799 return 0;
1800}
1801EXPORT_SYMBOL_GPL(snd_soc_dpcm_fe_can_update);
1802
1803/* is the current PCM operation for this BE ? */
1804int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
1805 struct snd_soc_pcm_runtime *be, int stream)
1806{
1807 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) ||
1808 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) &&
1809 be->dpcm[stream].runtime_update))
1810 return 1;
1811 return 0;
1812}
1813EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_can_update);
1814
1815/* get the substream for this BE */
1816struct snd_pcm_substream *
1817 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream)
1818{
1819 return be->pcm->streams[stream].substream;
1820}
1821EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream);
1822
1823/* get the BE runtime state */
1824enum snd_soc_dpcm_state
1825 snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream)
1826{
1827 return be->dpcm[stream].state;
1828}
1829EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_get_state);
1830
1831/* set the BE runtime state */
1832void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be,
1833 int stream, enum snd_soc_dpcm_state state)
1834{
1835 be->dpcm[stream].state = state;
1836}
1837EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_set_state);
1838
1839/*
1840 * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE
1841 * are not running, paused or suspended for the specified stream direction.
1842 */
1843int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
1844 struct snd_soc_pcm_runtime *be, int stream)
1845{
1846 struct snd_soc_dpcm *dpcm;
1847 int state;
1848
1849 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
1850
1851 if (dpcm->fe == fe)
1852 continue;
1853
1854 state = dpcm->fe->dpcm[stream].state;
1855 if (state == SND_SOC_DPCM_STATE_START ||
1856 state == SND_SOC_DPCM_STATE_PAUSED ||
1857 state == SND_SOC_DPCM_STATE_SUSPEND)
1858 return 0;
1859 }
1860
1861 /* it's safe to free/stop this BE DAI */
1862 return 1;
1863}
1864EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop);
1865
1866/*
1867 * We can only change hw params a BE DAI if any of it's FE are not prepared,
1868 * running, paused or suspended for the specified stream direction.
1869 */
1870int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
1871 struct snd_soc_pcm_runtime *be, int stream)
1872{
1873 struct snd_soc_dpcm *dpcm;
1874 int state;
1875
1876 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
1877
1878 if (dpcm->fe == fe)
1879 continue;
1880
1881 state = dpcm->fe->dpcm[stream].state;
1882 if (state == SND_SOC_DPCM_STATE_START ||
1883 state == SND_SOC_DPCM_STATE_PAUSED ||
1884 state == SND_SOC_DPCM_STATE_SUSPEND ||
1885 state == SND_SOC_DPCM_STATE_PREPARE)
1886 return 0;
1887 }
1888
1889 /* it's safe to change hw_params */
1890 return 1;
1891}
1892EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);