^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // soc-compress.c -- ALSA SoC Compress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (C) 2012 Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Authors: Namarta Kohli <namartax.kohli@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Ramesh Babu K V <ramesh.babu@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) // Vinod Koul <vinod.koul@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/compress_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/compress_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/soc-dpcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/soc-link.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int soc_compr_components_open(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct snd_soc_component **last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) !component->driver->compress_ops->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ret = component->driver->compress_ops->open(component, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) dev_err(component->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "Compress ASoC: can't open platform %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) component->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *last = component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int soc_compr_components_free(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct snd_soc_component *last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (component == last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) !component->driver->compress_ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) component->driver->compress_ops->free(component, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int soc_compr_open(struct snd_compr_stream *cstream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct snd_soc_component *component = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ret = snd_soc_pcm_component_pm_runtime_get(rtd, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) goto pm_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ret = soc_compr_components_open(cstream, &component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto machine_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ret = snd_soc_link_compr_startup(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto machine_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) snd_soc_runtime_activate(rtd, cstream->direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) machine_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) soc_compr_components_free(cstream, component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) snd_soc_dai_compr_shutdown(cpu_dai, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pm_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) snd_soc_pcm_component_pm_runtime_put(rtd, cstream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int soc_compr_open_fe(struct snd_compr_stream *cstream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct snd_soc_pcm_runtime *fe = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct snd_pcm_substream *fe_substream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) fe->pcm->streams[cstream->direction].substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct snd_soc_dpcm *dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct snd_soc_dapm_widget_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (cstream->direction == SND_COMPRESS_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) stream = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) stream = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) fe->dpcm[stream].runtime = fe_substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = dpcm_path_get(fe, stream, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto be_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) fe->dai_link->name, stream ? "capture" : "playback");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* calculate valid and active FE <-> BE dpcms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dpcm_process_paths(fe, stream, &list, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) fe->dpcm[stream].runtime = fe_substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ret = dpcm_be_dai_startup(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* clean up all links */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) for_each_dpcm_be(fe, stream, dpcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dpcm_be_disconnect(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) fe->dpcm[stream].runtime = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ret = soc_compr_components_open(cstream, &component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) goto open_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = snd_soc_link_compr_startup(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto machine_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dpcm_clear_pending_state(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dpcm_path_put(&list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) snd_soc_runtime_activate(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mutex_unlock(&fe->card->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) machine_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) soc_compr_components_free(cstream, component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) open_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) snd_soc_dai_compr_shutdown(cpu_dai, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dpcm_path_put(&list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) be_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mutex_unlock(&fe->card->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int soc_compr_free(struct snd_compr_stream *cstream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (cstream->direction == SND_COMPRESS_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) stream = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) stream = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) snd_soc_runtime_deactivate(rtd, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (!snd_soc_dai_active(cpu_dai))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) cpu_dai->rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!snd_soc_dai_active(codec_dai))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) codec_dai->rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) snd_soc_link_compr_shutdown(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) soc_compr_components_free(cstream, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) snd_soc_dai_compr_shutdown(cpu_dai, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) snd_soc_dapm_stream_stop(rtd, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) snd_soc_pcm_component_pm_runtime_put(rtd, cstream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int soc_compr_free_fe(struct snd_compr_stream *cstream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct snd_soc_pcm_runtime *fe = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct snd_soc_dpcm *dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int stream, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (cstream->direction == SND_COMPRESS_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) stream = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) stream = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) snd_soc_runtime_deactivate(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = dpcm_be_dai_hw_free(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = dpcm_be_dai_shutdown(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* mark FE's links ready to prune */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) for_each_dpcm_be(fe, stream, dpcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dpcm_be_disconnect(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) fe->dpcm[stream].runtime = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) snd_soc_link_compr_shutdown(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) soc_compr_components_free(cstream, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) snd_soc_dai_compr_shutdown(cpu_dai, cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mutex_unlock(&fe->card->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static int soc_compr_components_trigger(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) !component->driver->compress_ops->trigger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret = component->driver->compress_ops->trigger(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) component, cstream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = soc_compr_components_trigger(cstream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct snd_soc_pcm_runtime *fe = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int ret, stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cmd == SND_COMPR_TRIGGER_DRAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return soc_compr_components_trigger(cstream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (cstream->direction == SND_COMPRESS_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) stream = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) stream = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = soc_compr_components_trigger(cstream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ret = dpcm_be_dai_trigger(fe, stream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mutex_unlock(&fe->card->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static int soc_compr_components_set_params(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct snd_compr_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) !component->driver->compress_ops->set_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = component->driver->compress_ops->set_params(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) component, cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int soc_compr_set_params(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct snd_compr_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * First we call set_params for the CPU DAI, then the component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * driver this should configure the SoC side. If the machine has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * compressed ops then we call that as well. The expectation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * that these callbacks will configure everything for this compress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * path, like configuring a PCM port for a CODEC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = soc_compr_components_set_params(cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = snd_soc_link_compr_set_params(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (cstream->direction == SND_COMPRESS_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) SND_SOC_DAPM_STREAM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) SND_SOC_DAPM_STREAM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* cancel any delayed stream shutdown that is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) rtd->pop_wait = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) cancel_delayed_work_sync(&rtd->delayed_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct snd_compr_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct snd_soc_pcm_runtime *fe = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct snd_pcm_substream *fe_substream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) fe->pcm->streams[cstream->direction].substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int ret, stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (cstream->direction == SND_COMPRESS_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) stream = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) stream = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * Create an empty hw_params for the BE as the machine driver must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * fix this up to match DSP decoder and ASRC configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * I.e. machine driver fixup for compressed BE is mandatory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) sizeof(struct snd_pcm_hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ret = dpcm_be_dai_hw_params(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = dpcm_be_dai_prepare(fe, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = soc_compr_components_set_params(cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = snd_soc_link_compr_set_params(cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) mutex_unlock(&fe->card->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int soc_compr_get_params(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct snd_codec *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) !component->driver->compress_ops->get_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ret = component->driver->compress_ops->get_params(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) component, cstream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int soc_compr_get_caps(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct snd_compr_caps *caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) !component->driver->compress_ops->get_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = component->driver->compress_ops->get_caps(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) component, cstream, caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct snd_compr_codec_caps *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) !component->driver->compress_ops->get_codec_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = component->driver->compress_ops->get_codec_caps(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) component, cstream, codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) !component->driver->compress_ops->ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ret = component->driver->compress_ops->ack(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) component, cstream, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static int soc_compr_pointer(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct snd_compr_tstamp *tstamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) !component->driver->compress_ops->pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = component->driver->compress_ops->pointer(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) component, cstream, tstamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static int soc_compr_copy(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) !component->driver->compress_ops->copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ret = component->driver->compress_ops->copy(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) component, cstream, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) mutex_unlock(&rtd->card->pcm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct snd_compr_metadata *metadata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) !component->driver->compress_ops->set_metadata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = component->driver->compress_ops->set_metadata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) component, cstream, metadata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct snd_compr_metadata *metadata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct snd_soc_pcm_runtime *rtd = cstream->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) !component->driver->compress_ops->get_metadata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return component->driver->compress_ops->get_metadata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) component, cstream, metadata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* ASoC Compress operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static struct snd_compr_ops soc_compr_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .open = soc_compr_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) .free = soc_compr_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) .set_params = soc_compr_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) .set_metadata = soc_compr_set_metadata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) .get_metadata = soc_compr_get_metadata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) .get_params = soc_compr_get_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .trigger = soc_compr_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .pointer = soc_compr_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .ack = soc_compr_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .get_caps = soc_compr_get_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .get_codec_caps = soc_compr_get_codec_caps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /* ASoC Dynamic Compress operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static struct snd_compr_ops soc_compr_dyn_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .open = soc_compr_open_fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .free = soc_compr_free_fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .set_params = soc_compr_set_params_fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .get_params = soc_compr_get_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .set_metadata = soc_compr_set_metadata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .get_metadata = soc_compr_get_metadata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .trigger = soc_compr_trigger_fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) .pointer = soc_compr_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) .ack = soc_compr_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) .get_caps = soc_compr_get_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .get_codec_caps = soc_compr_get_codec_caps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * snd_soc_new_compress - create a new compress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * @rtd: The runtime for which we will create compress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * @num: the device index number (zero based - shared with normal PCMs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * Return: 0 for success, else error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct snd_soc_component *component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct snd_compr *compr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct snd_pcm *be_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) char new_name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int ret = 0, direction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int playback = 0, capture = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (rtd->num_cpus > 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) rtd->num_codecs > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) dev_err(rtd->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) "Compress ASoC: Multi CPU/Codec not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (!codec_dai) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) dev_err(rtd->card->dev, "Missing codec\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* check client and interface hw capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) playback = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) capture = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * Compress devices are unidirectional so only one of the directions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * should be set, check for that (xor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (playback + capture != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) dev_err(rtd->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) "Compress ASoC: Invalid direction for P %d, C %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) playback, capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (playback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) direction = SND_COMPRESS_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) direction = SND_COMPRESS_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!compr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (!compr->ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (rtd->dai_link->dynamic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) snprintf(new_name, sizeof(new_name), "(%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) rtd->dai_link->stream_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) rtd->dai_link->dpcm_playback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) rtd->dai_link->dpcm_capture, &be_pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) dev_err(rtd->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) "Compress ASoC: can't create compressed for %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) rtd->dai_link->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) rtd->pcm = be_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) rtd->fe_compr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (rtd->dai_link->dpcm_playback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) else if (rtd->dai_link->dpcm_capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) snprintf(new_name, sizeof(new_name), "%s %s-%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) rtd->dai_link->stream_name, codec_dai->name, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) for_each_rtd_components(rtd, i, component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (!component->driver->compress_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) !component->driver->compress_ops->copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) compr->ops->copy = soc_compr_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) mutex_init(&compr->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) ret = snd_compress_new(rtd->card->snd_card, num, direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) new_name, compr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) component = asoc_rtd_to_codec(rtd, 0)->component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dev_err(component->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) "Compress ASoC: can't create compress for codec %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) component->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* DAPM dai link stream work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) rtd->close_delayed_work_func = snd_soc_close_delayed_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) rtd->compr = compr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) compr->private_data = rtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) codec_dai->name, cpu_dai->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) EXPORT_SYMBOL_GPL(snd_soc_new_compress);