Merge series "Add support for SOF on i.MX8M" from Daniel Baluta <daniel.baluta@oss...
[sfrench/cifs-2.6.git] / sound / soc / soc-pcm.c
index e256d438ee6896d5c509cc25128e1756d42f5618..77a680da366f2792788b951025e9f3c090ffaede 100644 (file)
@@ -136,7 +136,7 @@ static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
                return -ENOMEM;
 
        for_each_pcm_streams(stream)
-               if (snd_soc_dai_stream_valid(fe->cpu_dai, stream))
+               if (snd_soc_dai_stream_valid(asoc_rtd_to_cpu(fe, 0), stream))
                        offset += dpcm_show_state(fe, stream,
                                                  buf + offset,
                                                  out_count - offset);
@@ -836,10 +836,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
        soc_pcm_init_runtime_hw(substream);
 
        if (rtd->num_codecs == 1)
-               codec_dai_name = rtd->codec_dai->name;
+               codec_dai_name = asoc_rtd_to_codec(rtd, 0)->name;
 
        if (rtd->num_cpus == 1)
-               cpu_dai_name = rtd->cpu_dai->name;
+               cpu_dai_name = asoc_rtd_to_cpu(rtd, 0)->name;
 
        if (soc_pcm_has_symmetry(substream))
                runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
@@ -1483,7 +1483,7 @@ static bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget,
 int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
        int stream, struct snd_soc_dapm_widget_list **list)
 {
-       struct snd_soc_dai *cpu_dai = fe->cpu_dai;
+       struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
        int paths;
 
        if (fe->num_cpus > 1) {
@@ -1842,7 +1842,7 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream,
                 * DAIs connected to a single CPU DAI, use CPU DAI's directly
                 */
                if (be->num_codecs == 1) {
-                       codec_stream = snd_soc_dai_get_pcm_stream(be->codec_dais[0], stream);
+                       codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream);
 
                        *channels_min = max(*channels_min,
                                            codec_stream->channels_min);
@@ -2324,7 +2324,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
                switch (cmd) {
                case SNDRV_PCM_TRIGGER_START:
                        if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
-                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
+                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
+                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
                                continue;
 
                        ret = dpcm_do_trigger(dpcm, be_substream, cmd);
@@ -2354,7 +2355,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
                        be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
                        break;
                case SNDRV_PCM_TRIGGER_STOP:
-                       if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
+                       if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) &&
+                           (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
                                continue;
 
                        if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
@@ -2757,7 +2759,7 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
                return 0;
 
        /* only check active links */
-       if (!fe->cpu_dai->active)
+       if (!asoc_rtd_to_cpu(fe, 0)->active)
                return 0;
 
        /* DAPM sync will call this to update DSP paths */
@@ -2767,13 +2769,13 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
        for_each_pcm_streams(stream) {
 
                /* skip if FE doesn't have playback/capture capability */
-               if (!snd_soc_dai_stream_valid(fe->cpu_dai,   stream) ||
-                   !snd_soc_dai_stream_valid(fe->codec_dai, stream))
+               if (!snd_soc_dai_stream_valid(asoc_rtd_to_cpu(fe, 0),   stream) ||
+                   !snd_soc_dai_stream_valid(asoc_rtd_to_codec(fe, 0), stream))
                        continue;
 
                /* skip if FE isn't currently playing/capturing */
-               if (!fe->cpu_dai->stream_active[stream] ||
-                   !fe->codec_dai->stream_active[stream])
+               if (!asoc_rtd_to_cpu(fe, 0)->stream_active[stream] ||
+                   !asoc_rtd_to_codec(fe, 0)->stream_active[stream])
                        continue;
 
                paths = dpcm_path_get(fe, stream, &list);
@@ -2909,8 +2911,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
        int i;
 
        if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
-               playback = rtd->dai_link->dpcm_playback;
-               capture = rtd->dai_link->dpcm_capture;
+               cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+               if (rtd->num_cpus > 1) {
+                       dev_err(rtd->dev,
+                               "DPCM doesn't support Multi CPU yet\n");
+                       return -EINVAL;
+               }
+
+               playback = rtd->dai_link->dpcm_playback &&
+                          snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK);
+               capture = rtd->dai_link->dpcm_capture &&
+                         snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE);
        } else {
                /* Adapt stream for codec2codec links */
                int cpu_capture = rtd->dai_link->params ?
@@ -2920,9 +2931,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 
                for_each_rtd_codec_dais(rtd, i, codec_dai) {
                        if (rtd->num_cpus == 1) {
-                               cpu_dai = rtd->cpu_dais[0];
+                               cpu_dai = asoc_rtd_to_cpu(rtd, 0);
                        } else if (rtd->num_cpus == rtd->num_codecs) {
-                               cpu_dai = rtd->cpu_dais[i];
+                               cpu_dai = asoc_rtd_to_cpu(rtd, i);
                        } else {
                                dev_err(rtd->card->dev,
                                        "N cpus to M codecs link is not supported yet\n");
@@ -2969,7 +2980,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
                        snprintf(new_name, sizeof(new_name), "%s %s-%d",
                                rtd->dai_link->stream_name,
                                (rtd->num_codecs > 1) ?
-                               "multicodec" : rtd->codec_dai->name, num);
+                               "multicodec" : asoc_rtd_to_codec(rtd, 0)->name, num);
 
                ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
                        capture, &pcm);
@@ -3048,8 +3059,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
        pcm->no_device_suspend = true;
 out:
        dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
-                (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
-                (rtd->num_cpus > 1) ? "multicpu" : rtd->cpu_dai->name);
+                (rtd->num_codecs > 1) ? "multicodec" : asoc_rtd_to_codec(rtd, 0)->name,
+                (rtd->num_cpus > 1)   ? "multicpu"   : asoc_rtd_to_cpu(rtd, 0)->name);
        return ret;
 }