[alsa-devel] [PATCH 1/7] ASoC: Handle ignore_pmdown_time for CODEC to CODEC links
For CODEC to CODEC links we should only immediately power down if both CODECs are configured to ignore the power down delay. Factor the logic for this into a helper function that can be used for both compressed and normal PCMs.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- include/sound/soc.h | 2 ++ sound/soc/soc-compress.c | 3 +-- sound/soc/soc-pcm.c | 27 +++++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 9a00147..93c31c7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -413,6 +413,8 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, const char *dai_link);
+bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd); + /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 5e9690c..ef585af 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -235,8 +235,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) cpu_dai->runtime = NULL;
if (cstream->direction == SND_COMPRESS_PLAYBACK) { - if (!rtd->pmdown_time || codec->ignore_pmdown_time || - rtd->dai_link->ignore_pmdown_time) { + if (snd_soc_runtime_ignore_pmdown_time(rtd)) { snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, SND_SOC_DAPM_STREAM_STOP); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 47e1ce7..f098c80 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -35,6 +35,30 @@ #define DPCM_MAX_BE_USERS 8
/** + * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay + * @rtd: The ASoC PCM runtime that should be checked. + * + * This function checks whether the power down delay should be ignored for a + * specific PCM runtime. Returns true if the delay is 0, if it the DAI link has + * been configured to ignore the delay, or if none of the components benefits + * from having the delay. + */ +bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd) +{ + bool ignore = true; + + if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time) + return true; + + if (rtd->cpu_dai->codec) + ignore &= rtd->cpu_dai->codec->ignore_pmdown_time; + + ignore &= rtd->codec_dai->codec->ignore_pmdown_time; + + return ignore; +} + +/** * snd_soc_set_runtime_hwparams - set the runtime hardware parameters * @substream: the pcm substream * @hw: the hardware parameters @@ -496,8 +520,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) cpu_dai->runtime = NULL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (!rtd->pmdown_time || codec->ignore_pmdown_time || - rtd->dai_link->ignore_pmdown_time) { + if (snd_soc_runtime_ignore_pmdown_time(rtd)) { /* powered down playback stream now */ snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
We have the same code that increments and decrements the active field of the various PCM runtime components (all with the same bugs). Factor this out into common helper functions.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- include/sound/soc.h | 2 ++ sound/soc/soc-compress.c | 62 +++++++--------------------------- sound/soc/soc-pcm.c | 86 +++++++++++++++++++++++++++++++++++------------- 3 files changed, 78 insertions(+), 72 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 93c31c7..53d15e0 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -414,6 +414,8 @@ struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, const char *dai_link);
bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd); +void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream); +void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
/* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index ef585af..91083e6 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -30,8 +30,6 @@ 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_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; int ret = 0;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); @@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) } }
- if (cstream->direction == SND_COMPRESS_PLAYBACK) { - cpu_dai->playback_active++; - codec_dai->playback_active++; - } else { - cpu_dai->capture_active++; - codec_dai->capture_active++; - } - - cpu_dai->active++; - codec_dai->active++; - rtd->codec->active++; + snd_soc_runtime_activate(rtd, cstream->direction);
mutex_unlock(&rtd->pcm_mutex);
@@ -81,8 +69,6 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) struct snd_soc_pcm_runtime *fe = cstream->private_data; struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; struct snd_soc_platform *platform = fe->platform; - struct snd_soc_dai *cpu_dai = fe->cpu_dai; - struct snd_soc_dai *codec_dai = fe->codec_dai; struct snd_soc_dpcm *dpcm; struct snd_soc_dapm_widget_list *list; int stream; @@ -140,17 +126,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
- if (cstream->direction == SND_COMPRESS_PLAYBACK) { - cpu_dai->playback_active++; - codec_dai->playback_active++; - } else { - cpu_dai->capture_active++; - codec_dai->capture_active++; - } - - cpu_dai->active++; - codec_dai->active++; - fe->codec->active++; + snd_soc_runtime_activate(fe, stream);
mutex_unlock(&fe->card->mutex);
@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream) struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec; + int stream;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (cstream->direction == SND_COMPRESS_PLAYBACK) { - cpu_dai->playback_active--; - codec_dai->playback_active--; - } else { - cpu_dai->capture_active--; - codec_dai->capture_active--; - } + if (cstream->direction == SND_COMPRESS_PLAYBACK) + stream = SNDRV_PCM_STREAM_PLAYBACK; + else + stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); + snd_soc_runtime_deactivate(rtd, stream);
- cpu_dai->active--; - codec_dai->active--; - codec->active--; + snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
if (!cpu_dai->active) cpu_dai->rate = 0; @@ -260,26 +231,17 @@ 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_dai *cpu_dai = fe->cpu_dai; - struct snd_soc_dai *codec_dai = fe->codec_dai; struct snd_soc_dpcm *dpcm; int stream, ret;
mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
- if (cstream->direction == SND_COMPRESS_PLAYBACK) { + if (cstream->direction == SND_COMPRESS_PLAYBACK) stream = SNDRV_PCM_STREAM_PLAYBACK; - cpu_dai->playback_active--; - codec_dai->playback_active--; - } else { + else stream = SNDRV_PCM_STREAM_CAPTURE; - cpu_dai->capture_active--; - codec_dai->capture_active--; - }
- cpu_dai->active--; - codec_dai->active--; - fe->codec->active--; + snd_soc_runtime_deactivate(fe, stream);
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index f098c80..1a98575 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -35,6 +35,66 @@ #define DPCM_MAX_BE_USERS 8
/** + * snd_soc_runtime_activate() - Increment active count for PCM runtime components + * @rtd: ASoC PCM runtime that is activated + * @stream: Direction of the PCM stream + * + * Increments the active count for all the DAIs and components attached to a PCM + * runtime. Should typically be called when a stream is opened. + * + * Must be called with the rtd->pcm_mutex being held + */ +void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + lockdep_assert_held(&rtd->pcm_mutex); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + cpu_dai->playback_active++; + codec_dai->playback_active++; + } else { + cpu_dai->capture_active++; + codec_dai->capture_active++; + } + + cpu_dai->active++; + codec_dai->active++; + rtd->codec->active++; +} + +/** + * snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components + * @rtd: ASoC PCM runtime that is deactivated + * @stream: Direction of the PCM stream + * + * Decrements the active count for all the DAIs and components attached to a PCM + * runtime. Should typically be called when a stream is closed. + * + * Must be called with the rtd->pcm_mutex being held + */ +void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + lockdep_assert_held(&rtd->pcm_mutex); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + cpu_dai->playback_active--; + codec_dai->playback_active--; + } else { + cpu_dai->capture_active--; + codec_dai->capture_active--; + } + + cpu_dai->active--; + codec_dai->active--; + rtd->codec->active--; +} + +/** * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay * @rtd: The ASoC PCM runtime that should be checked. * @@ -402,16 +462,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) runtime->hw.rate_max);
dynamic: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - cpu_dai->playback_active++; - codec_dai->playback_active++; - } else { - cpu_dai->capture_active++; - codec_dai->capture_active++; - } - cpu_dai->active++; - codec_dai->active++; - rtd->codec->active++; + + snd_soc_runtime_activate(rtd, substream->stream); + mutex_unlock(&rtd->pcm_mutex); return 0;
@@ -483,21 +536,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - cpu_dai->playback_active--; - codec_dai->playback_active--; - } else { - cpu_dai->capture_active--; - codec_dai->capture_active--; - } - - cpu_dai->active--; - codec_dai->active--; - codec->active--; + snd_soc_runtime_deactivate(rtd, substream->stream);
/* clear the corresponding DAIs rate when inactive */ if (!cpu_dai->active)
For CODEC to CODEC links we need to make sure to also manage the 'active' field of the cpu_dai CODEC.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/soc-pcm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1a98575..71a01dd 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -61,7 +61,9 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
cpu_dai->active++; codec_dai->active++; - rtd->codec->active++; + if (cpu_dai->codec) + cpu_dai->codec->active++; + codec_dai->codec->active++; }
/** @@ -91,7 +93,9 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
cpu_dai->active--; codec_dai->active--; - rtd->codec->active--; + if (cpu_dai->codec) + cpu_dai->codec->active--; + codec_dai->codec->active--; }
/**
Instead of directly checking the 'active' field of the CODEC struct add a new helper function that will return either true or false depending on whether the CODEC is active. This will make the migration to the component level easier.
The patch also updates all CODEC drivers that check the active attribute to use the new helper function.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- include/sound/soc.h | 5 +++++ sound/soc/codecs/adav80x.c | 4 ++-- sound/soc/codecs/tlv320aic23.c | 2 +- sound/soc/codecs/tlv320dac33.c | 2 +- sound/soc/codecs/uda1380.c | 2 +- sound/soc/codecs/wl1273.c | 2 +- sound/soc/codecs/wm8711.c | 2 +- sound/soc/codecs/wm8753.c | 4 ++-- 8 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 53d15e0..5c2b4f4 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1172,6 +1172,11 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) return 1; }
+static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec) +{ + return codec->active != 0; +} + int snd_soc_util_init(void); void snd_soc_util_exit(void);
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index f78b27a..d50cf5b 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -722,7 +722,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- if (!codec->active || !adav80x->rate) + if (!snd_soc_codec_is_active(codec) || !adav80x->rate) return 0;
return snd_pcm_hw_constraint_minmax(substream->runtime, @@ -735,7 +735,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- if (!codec->active) + if (!snd_soc_codec_is_active(codec)) adav80x->rate = 0; }
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 5d430cc..458a6ae 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
/* deactivate */ - if (!codec->active) { + if (!snd_soc_codec_is_active(codec)) { udelay(50); snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); } diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 4f35839..35b2d24 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, if (dac33->fifo_mode == ucontrol->value.integer.value[0]) return 0; /* Do not allow changes while stream is running*/ - if (codec->active) + if (snd_soc_codec_is_active(codec)) return -EPERM;
if (ucontrol->value.integer.value[0] < 0 || diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 726df6d..8e3940d 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, /* the interpolator & decimator regs must only be written when the * codec DAI is active. */ - if (!codec->active && (reg >= UDA1380_MVOL)) + if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) return 0; pr_debug("uda1380: hw write %x val %x\n", reg, value); if (codec->hw_write(codec->control_data, data, 3) == 3) { diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index b7ab2ef..47e96ff 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, return 0;
/* Do not allow changes while stream is running */ - if (codec->active) + if (snd_soc_codec_is_active(codec)) return -EPERM;
if (ucontrol->value.integer.value[0] < 0 || diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index d99f948..6efcc40 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec;
/* deactivate */ - if (!codec->active) { + if (!snd_soc_codec_is_active(codec)) { udelay(50); snd_soc_write(codec, WM8711_ACTIVE, 0x0); } diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index be85da9..5cf4beb 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, if (wm8753->dai_func == ucontrol->value.integer.value[0]) return 0;
- if (codec->active) + if (snd_soc_codec_is_active(codec)) return -EBUSY;
ioctl = snd_soc_read(codec, WM8753_IOCTL); @@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute) /* the digital mute covers the HiFi and Voice DAC's on the WM8753. * make sure we check if they are not both active when we mute */ if (mute && wm8753->dai_func == 1) { - if (!codec->active) + if (!snd_soc_codec_is_active(codec)) snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); } else { if (mute)
Keep track of which component registered a DAI. We'll need this as componentization progresses.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- include/sound/soc-dai.h | 1 + sound/soc/soc-core.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 71f27c4..8763e53 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -270,6 +270,7 @@ struct snd_soc_dai { /* parent platform/codec */ struct snd_soc_platform *platform; struct snd_soc_codec *codec; + struct snd_soc_component *component;
struct snd_soc_card *card;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index fe1df50..6401e97 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3884,11 +3884,13 @@ static inline char *fmt_multiple_name(struct device *dev, /** * snd_soc_register_dai - Register a DAI with the ASoC core * - * @dai: DAI to register + * @component: The component the DAIs are registered for + * @dai_drv: DAI driver to use for the DAIs */ -static int snd_soc_register_dai(struct device *dev, +static int snd_soc_register_dai(struct snd_soc_component *component, struct snd_soc_dai_driver *dai_drv) { + struct device *dev = component->dev; struct snd_soc_codec *codec; struct snd_soc_dai *dai;
@@ -3905,6 +3907,7 @@ static int snd_soc_register_dai(struct device *dev, return -ENOMEM; }
+ dai->component = component; dai->dev = dev; dai->driver = dai_drv; dai->dapm.dev = dev; @@ -3962,12 +3965,14 @@ found: /** * snd_soc_register_dais - Register multiple DAIs with the ASoC core * - * @dai: Array of DAIs to register + * @component: The component the DAIs are registered for + * @dai_drv: DAI driver to use for the DAIs * @count: Number of DAIs */ -static int snd_soc_register_dais(struct device *dev, +static int snd_soc_register_dais(struct snd_soc_component *component, struct snd_soc_dai_driver *dai_drv, size_t count) { + struct device *dev = component->dev; struct snd_soc_codec *codec; struct snd_soc_dai *dai; int i, ret = 0; @@ -3990,6 +3995,7 @@ static int snd_soc_register_dais(struct device *dev, goto err; }
+ dai->component = component; dai->dev = dev; dai->driver = &dai_drv[i]; if (dai->driver->id) @@ -4086,9 +4092,9 @@ __snd_soc_register_component(struct device *dev, * since it had been used snd_soc_register_dais(), */ if ((1 == num_dai) && allow_single_dai) - ret = snd_soc_register_dai(dev, dai_drv); + ret = snd_soc_register_dai(cmpnt, dai_drv); else - ret = snd_soc_register_dais(dev, dai_drv, num_dai); + ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai); if (ret < 0) { dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); goto error_component_name;
There is no reason why active count tracking should only be done for CODECs but not for other components. Moving the active count from the snd_soc_codec struct to the snd_soc_component struct reduces the differences between CODECs and other components and will eventually allow component to component DAI links (Which is a prerequisite for converting CODECs to components).
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- include/sound/soc.h | 12 ++++++++++-- sound/soc/soc-pcm.c | 10 ++++------ 2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 5c2b4f4..0495b4a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -660,6 +660,9 @@ struct snd_soc_component { const char *name; int id; struct device *dev; + + unsigned int active; + struct list_head list;
struct snd_soc_dai_driver *dai_drv; @@ -687,7 +690,6 @@ struct snd_soc_codec {
/* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ - unsigned int active; unsigned int cache_bypass:1; /* Suppress access to the cache */ unsigned int suspended:1; /* Codec is in suspend PM state */ unsigned int probed:1; /* Codec has been probed */ @@ -1172,9 +1174,15 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) return 1; }
+static inline bool snd_soc_component_is_active( + struct snd_soc_component *component) +{ + return component->active != 0; +} + static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec) { - return codec->active != 0; + return snd_soc_component_is_active(&codec->component); }
int snd_soc_util_init(void); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 71a01dd..98b4629 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -61,9 +61,8 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
cpu_dai->active++; codec_dai->active++; - if (cpu_dai->codec) - cpu_dai->codec->active++; - codec_dai->codec->active++; + cpu_dai->component->active++; + codec_dai->component->active++; }
/** @@ -93,9 +92,8 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
cpu_dai->active--; codec_dai->active--; - if (cpu_dai->codec) - cpu_dai->codec->active--; - codec_dai->codec->active--; + cpu_dai->component->active--; + codec_dai->component->active--; }
/**
In preparation for componentization move the ignore_pmdown_time field from the snd_soc_codec struct to the snd_soc_component struct. Set it to true for non CODEC components for now.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- include/sound/soc.h | 3 ++- sound/soc/soc-core.c | 4 +++- sound/soc/soc-pcm.c | 10 ++-------- 3 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 0495b4a..b14acd8 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -663,6 +663,8 @@ struct snd_soc_component {
unsigned int active;
+ unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ + struct list_head list;
struct snd_soc_dai_driver *dai_drv; @@ -715,7 +717,6 @@ struct snd_soc_codec {
/* dapm */ struct snd_soc_dapm_context dapm; - unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
#ifdef CONFIG_DEBUG_FS struct dentry *debugfs_codec_root; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 6401e97..18aecd2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4127,6 +4127,8 @@ int snd_soc_register_component(struct device *dev, return -ENOMEM; }
+ cmpnt->ignore_pmdown_time = true; + return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, dai_drv, num_dai, true); } @@ -4325,7 +4327,7 @@ int snd_soc_register_codec(struct device *dev, codec->volatile_register = codec_drv->volatile_register; codec->readable_register = codec_drv->readable_register; codec->writable_register = codec_drv->writable_register; - codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time; + codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; codec->dapm.bias_level = SND_SOC_BIAS_OFF; codec->dapm.dev = dev; codec->dapm.codec = codec; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 98b4629..2cedf09 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -107,17 +107,11 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream) */ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd) { - bool ignore = true; - if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time) return true;
- if (rtd->cpu_dai->codec) - ignore &= rtd->cpu_dai->codec->ignore_pmdown_time; - - ignore &= rtd->codec_dai->codec->ignore_pmdown_time; - - return ignore; + return rtd->cpu_dai->component->ignore_pmdown_time && + rtd->codec_dai->component->ignore_pmdown_time; }
/**
On Wed, Mar 05, 2014 at 01:17:42PM +0100, Lars-Peter Clausen wrote:
For CODEC to CODEC links we should only immediately power down if both CODECs are configured to ignore the power down delay. Factor the logic for this into a helper function that can be used for both compressed and normal PCMs.
Applied all, thanks.
participants (2)
-
Lars-Peter Clausen
-
Mark Brown