summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-compress.c
diff options
context:
space:
mode:
authorLinus Torvalds2017-11-15 03:01:46 +0100
committerLinus Torvalds2017-11-15 03:01:46 +0100
commit4e4510fec4af08ead21f6934c1410af1f19a8cad (patch)
tree2bafab4f7cc2cdf2983186b24140f6303d4dfc8c /sound/soc/soc-compress.c
parentMerge branch 'i2c/for-4.15' of ssh://gitolite.kernel.org/pub/scm/linux/kernel... (diff)
parentDocumentation: sound: hd-audio: notes.rst (diff)
downloadkernel-qcow2-linux-4e4510fec4af08ead21f6934c1410af1f19a8cad.tar.gz
kernel-qcow2-linux-4e4510fec4af08ead21f6934c1410af1f19a8cad.tar.xz
kernel-qcow2-linux-4e4510fec4af08ead21f6934c1410af1f19a8cad.zip
Merge tag 'sound-4.15-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "There are no big surprising changes in this cycle, yet not too boring, either. The biggest change from diffstat POV is the removal of the legacy OSS driver codes that have been already disabled for a long time. This will bring a few trivial merge conflicts. As new features in ASoC side, there are two things: a new AC97 bus implementation and AMD Stony platform support. Both include the relevant changes shared with other subsystems, e.g. AC97 MFD changes and DRM AMD changes. Some other highlighted topics are: - A bunch of USB-audio drivers got the hardening against the malicious device accesses with a new helper code for endpoint sanity check - Lots of cleanups for ASoC Intel platform code, including support for their open source audio firmware - Continued ASoC core componentization works - Support for scaling MCLK with sample rate in ASoC simple-card - Stabler PCM hot-unplug capability, especially for ASoC usages" * tag 'sound-4.15-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (302 commits) Documentation: sound: hd-audio: notes.rst ASoC: bcm2835: Support left/right justified and DSP modes ASoC: bcm2835: Enforce full symmetry ASoC: bcm2835: Support additional samplerates up to 384kHz ASoC: bcm2835: Add support for TDM modes ASoC: add mclk-fs support to audio graph card ASoC: add mclk-fs to audio graph card binding ASoC: rt5514: work around link error ASoC: rt5514: mark PM functions as __maybe_unused ASoC: rt5663: Check the JD status in the button pushing ASoC: amd: Modified DMA transfer Mechanism for Playback ASoC: rt5645: Wait for 400msec before concluding on value of RT5645_VENDOR_ID2 ASoC: sun4i-codec: fixed 32bit audio capture support for H3/H2+ ASoC: da7213: add support for DSP modes ASoC: sun8i-codec: Add a comment on the LRCK inversion ASoC: sun8i-codec: Set the BCLK divider ASoC: rt5663: Delay and retry reading rt5663 ID register ASoC: amd: use do_div rather than 64 bit division to fix 32 bit builds ASoC: cs42l56: Fix reset GPIO name in example DT binding ASoC: rt5514-spi: check irq status to schedule data copy in resume function ...
Diffstat (limited to 'sound/soc/soc-compress.c')
-rw-r--r--sound/soc/soc-compress.c461
1 files changed, 427 insertions, 34 deletions
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 2cb8d3b55fbc..d9b1e6417fb9 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -30,8 +30,10 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -44,7 +46,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
ret = platform->driver->compr_ops->open(cstream);
if (ret < 0) {
pr_err("compress asoc: can't open platform %s\n",
@@ -53,6 +55,27 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->open)
+ continue;
+
+ __ret = component->driver->compr_ops->open(cstream);
+ if (__ret < 0) {
+ pr_err("compress asoc: can't open platform %s\n",
+ component->name);
+ ret = __ret;
+ }
+ }
+ if (ret < 0)
+ goto machine_err;
+
if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
ret = rtd->dai_link->compr_ops->startup(cstream);
if (ret < 0) {
@@ -68,7 +91,21 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
return 0;
machine_err:
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
plat_err:
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
@@ -84,11 +121,13 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
struct snd_pcm_substream *fe_substream =
fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
struct snd_soc_dpcm *dpcm;
struct snd_soc_dapm_widget_list *list;
int stream;
- int ret = 0;
+ int ret = 0, __ret;
if (cstream->direction == SND_COMPRESS_PLAYBACK)
stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -107,7 +146,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
ret = platform->driver->compr_ops->open(cstream);
if (ret < 0) {
pr_err("compress asoc: can't open platform %s\n",
@@ -116,6 +155,27 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
}
}
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->open)
+ continue;
+
+ __ret = component->driver->compr_ops->open(cstream);
+ if (__ret < 0) {
+ pr_err("compress asoc: can't open platform %s\n",
+ component->name);
+ ret = __ret;
+ }
+ }
+ if (ret < 0)
+ goto machine_err;
+
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
ret = fe->dai_link->compr_ops->startup(cstream);
if (ret < 0) {
@@ -167,7 +227,21 @@ fe_err:
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
fe->dai_link->compr_ops->shutdown(cstream);
machine_err:
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
plat_err:
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
@@ -210,6 +284,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int stream;
@@ -235,7 +311,21 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
rtd->dai_link->compr_ops->shutdown(cstream);
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
@@ -267,6 +357,8 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
struct snd_soc_dpcm *dpcm;
int stream, ret;
@@ -304,9 +396,23 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
fe->dai_link->compr_ops->shutdown(cstream);
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
@@ -319,18 +425,38 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
ret = platform->driver->compr_ops->trigger(cstream, cmd);
if (ret < 0)
goto out;
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->trigger)
+ continue;
+
+ __ret = component->driver->compr_ops->trigger(cstream, cmd);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto out;
+
if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
@@ -353,16 +479,36 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
- int ret = 0, stream;
+ int ret = 0, __ret, stream;
if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
cmd == SND_COMPR_TRIGGER_DRAIN) {
- if (platform->driver->compr_ops &&
+ if (platform &&
+ platform->driver->compr_ops &&
platform->driver->compr_ops->trigger)
return platform->driver->compr_ops->trigger(cstream,
cmd);
+
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->trigger)
+ continue;
+
+ __ret = component->driver->compr_ops->trigger(cstream, cmd);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ return ret;
}
if (cstream->direction == SND_COMPRESS_PLAYBACK)
@@ -379,12 +525,30 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
goto out;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
ret = platform->driver->compr_ops->trigger(cstream, cmd);
if (ret < 0)
goto out;
}
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->trigger)
+ continue;
+
+ __ret = component->driver->compr_ops->trigger(cstream, cmd);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto out;
+
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
ret = dpcm_be_dai_trigger(fe, stream, cmd);
@@ -415,8 +579,10 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -432,12 +598,30 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
goto err;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
ret = platform->driver->compr_ops->set_params(cstream, params);
if (ret < 0)
goto err;
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->set_params)
+ continue;
+
+ __ret = component->driver->compr_ops->set_params(cstream, params);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto err;
+
if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
ret = rtd->dai_link->compr_ops->set_params(cstream);
if (ret < 0)
@@ -471,8 +655,10 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
struct snd_pcm_substream *fe_substream =
fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
- int ret = 0, stream;
+ int ret = 0, __ret, stream;
if (cstream->direction == SND_COMPRESS_PLAYBACK)
stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -487,12 +673,30 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
goto out;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
ret = platform->driver->compr_ops->set_params(cstream, params);
if (ret < 0)
goto out;
}
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->set_params)
+ continue;
+
+ __ret = component->driver->compr_ops->set_params(cstream, params);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto out;
+
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
ret = fe->dai_link->compr_ops->set_params(cstream);
if (ret < 0)
@@ -531,8 +735,10 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -542,8 +748,27 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
goto err;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_params) {
ret = platform->driver->compr_ops->get_params(cstream, params);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_params)
+ continue;
+
+ __ret = component->driver->compr_ops->get_params(cstream, params);
+ if (__ret < 0)
+ ret = __ret;
+ }
err:
mutex_unlock(&rtd->pcm_mutex);
@@ -555,13 +780,35 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_caps) {
ret = platform->driver->compr_ops->get_caps(cstream, caps);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_caps)
+ continue;
+
+ __ret = component->driver->compr_ops->get_caps(cstream, caps);
+ if (__ret < 0)
+ ret = __ret;
+ }
+
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -571,13 +818,35 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) {
ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_codec_caps)
+ continue;
+
+ __ret = component->driver->compr_ops->get_codec_caps(cstream, codec);
+ if (__ret < 0)
+ ret = __ret;
+ }
+
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -586,8 +855,10 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -597,8 +868,27 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
goto err;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->ack) {
ret = platform->driver->compr_ops->ack(cstream, bytes);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->ack)
+ continue;
+
+ __ret = component->driver->compr_ops->ack(cstream, bytes);
+ if (__ret < 0)
+ ret = __ret;
+ }
err:
mutex_unlock(&rtd->pcm_mutex);
@@ -610,7 +900,9 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -618,9 +910,29 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
- if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->pointer) {
ret = platform->driver->compr_ops->pointer(cstream, tstamp);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->pointer)
+ continue;
+ __ret = component->driver->compr_ops->pointer(cstream, tstamp);
+ if (__ret < 0)
+ ret = __ret;
+ }
+
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -630,13 +942,34 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy) {
ret = platform->driver->compr_ops->copy(cstream, buf, count);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->copy)
+ continue;
+ __ret = component->driver->compr_ops->copy(cstream, buf, count);
+ if (__ret < 0)
+ ret = __ret;
+ }
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -646,8 +979,10 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
@@ -655,8 +990,27 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
return ret;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) {
ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
+ if (ret < 0)
+ return ret;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->set_metadata)
+ continue;
+
+ __ret = component->driver->compr_ops->set_metadata(cstream, metadata);
+ if (__ret < 0)
+ ret = __ret;
+ }
return ret;
}
@@ -666,8 +1020,10 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
@@ -675,8 +1031,27 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
return ret;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) {
ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
+ if (ret < 0)
+ return ret;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_metadata)
+ continue;
+
+ __ret = component->driver->compr_ops->get_metadata(cstream, metadata);
+ if (__ret < 0)
+ ret = __ret;
+ }
return ret;
}
@@ -723,6 +1098,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_compr *compr;
@@ -798,9 +1175,25 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
}
+
/* Add copy callback for not memory mapped DSPs */
- if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy)
+ compr->ops->copy = soc_compr_copy;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->copy)
+ continue;
+
compr->ops->copy = soc_compr_copy;
+ }
+
mutex_init(&compr->lock);
ret = snd_compress_new(rtd->card->snd_card, num, direction,