Commit da8ab21c authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/core' into asoc-next

parents c6c12422 5c1d5f09
...@@ -2240,6 +2240,18 @@ int regmap_get_val_bytes(struct regmap *map) ...@@ -2240,6 +2240,18 @@ int regmap_get_val_bytes(struct regmap *map)
} }
EXPORT_SYMBOL_GPL(regmap_get_val_bytes); EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
int regmap_parse_val(struct regmap *map, const void *buf,
unsigned int *val)
{
if (!map->format.parse_val)
return -EINVAL;
*val = map->format.parse_val(buf);
return 0;
}
EXPORT_SYMBOL_GPL(regmap_parse_val);
static int __init regmap_initcall(void) static int __init regmap_initcall(void)
{ {
regmap_debugfs_initcall(); regmap_debugfs_initcall();
......
...@@ -423,6 +423,8 @@ bool regmap_check_range_table(struct regmap *map, unsigned int reg, ...@@ -423,6 +423,8 @@ bool regmap_check_range_table(struct regmap *map, unsigned int reg,
int regmap_register_patch(struct regmap *map, const struct reg_default *regs, int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
int num_regs); int num_regs);
int regmap_parse_val(struct regmap *map, const void *buf,
unsigned int *val);
static inline bool regmap_reg_in_range(unsigned int reg, static inline bool regmap_reg_in_range(unsigned int reg,
const struct regmap_range *range) const struct regmap_range *range)
...@@ -695,6 +697,13 @@ static inline int regmap_register_patch(struct regmap *map, ...@@ -695,6 +697,13 @@ static inline int regmap_register_patch(struct regmap *map,
return -EINVAL; return -EINVAL;
} }
static inline int regmap_parse_val(struct regmap *map, const void *buf,
unsigned int *val)
{
WARN_ONCE(1, "regmap API is disabled");
return -EINVAL;
}
static inline struct regmap *dev_get_regmap(struct device *dev, static inline struct regmap *dev_get_regmap(struct device *dev,
const char *name) const char *name)
{ {
......
...@@ -270,6 +270,7 @@ struct snd_soc_dai { ...@@ -270,6 +270,7 @@ struct snd_soc_dai {
/* parent platform/codec */ /* parent platform/codec */
struct snd_soc_platform *platform; struct snd_soc_platform *platform;
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct snd_soc_component *component;
struct snd_soc_card *card; struct snd_soc_card *card;
......
...@@ -413,6 +413,10 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, ...@@ -413,6 +413,10 @@ 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, struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
const char *dai_link); 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 */ /* 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_calc_frame_size(int sample_size, int channels, int tdm_slots);
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
...@@ -656,12 +660,19 @@ struct snd_soc_component { ...@@ -656,12 +660,19 @@ struct snd_soc_component {
const char *name; const char *name;
int id; int id;
struct device *dev; struct device *dev;
unsigned int active;
unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
struct list_head list; struct list_head list;
struct snd_soc_dai_driver *dai_drv; struct snd_soc_dai_driver *dai_drv;
int num_dai; int num_dai;
const struct snd_soc_component_driver *driver; const struct snd_soc_component_driver *driver;
struct list_head dai_list;
}; };
/* SoC Audio Codec device */ /* SoC Audio Codec device */
...@@ -683,7 +694,6 @@ struct snd_soc_codec { ...@@ -683,7 +694,6 @@ struct snd_soc_codec {
/* runtime */ /* runtime */
struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
unsigned int active;
unsigned int cache_bypass:1; /* Suppress access to the cache */ unsigned int cache_bypass:1; /* Suppress access to the cache */
unsigned int suspended:1; /* Codec is in suspend PM state */ unsigned int suspended:1; /* Codec is in suspend PM state */
unsigned int probed:1; /* Codec has been probed */ unsigned int probed:1; /* Codec has been probed */
...@@ -709,7 +719,6 @@ struct snd_soc_codec { ...@@ -709,7 +719,6 @@ struct snd_soc_codec {
/* dapm */ /* dapm */
struct snd_soc_dapm_context dapm; struct snd_soc_dapm_context dapm;
unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_codec_root; struct dentry *debugfs_codec_root;
...@@ -1168,6 +1177,17 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) ...@@ -1168,6 +1177,17 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
return 1; 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 snd_soc_component_is_active(&codec->component);
}
int snd_soc_util_init(void); int snd_soc_util_init(void);
void snd_soc_util_exit(void); void snd_soc_util_exit(void);
......
...@@ -722,7 +722,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream, ...@@ -722,7 +722,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct adav80x *adav80x = snd_soc_codec_get_drvdata(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 0;
return snd_pcm_hw_constraint_minmax(substream->runtime, return snd_pcm_hw_constraint_minmax(substream->runtime,
...@@ -735,7 +735,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream, ...@@ -735,7 +735,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
if (!codec->active) if (!snd_soc_codec_is_active(codec))
adav80x->rate = 0; adav80x->rate = 0;
} }
......
...@@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, ...@@ -400,7 +400,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
/* deactivate */ /* deactivate */
if (!codec->active) { if (!snd_soc_codec_is_active(codec)) {
udelay(50); udelay(50);
snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
} }
......
...@@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, ...@@ -461,7 +461,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
if (dac33->fifo_mode == ucontrol->value.integer.value[0]) if (dac33->fifo_mode == ucontrol->value.integer.value[0])
return 0; return 0;
/* Do not allow changes while stream is running*/ /* Do not allow changes while stream is running*/
if (codec->active) if (snd_soc_codec_is_active(codec))
return -EPERM; return -EPERM;
if (ucontrol->value.integer.value[0] < 0 || if (ucontrol->value.integer.value[0] < 0 ||
......
...@@ -108,7 +108,7 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -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 /* the interpolator & decimator regs must only be written when the
* codec DAI is active. * codec DAI is active.
*/ */
if (!codec->active && (reg >= UDA1380_MVOL)) if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL))
return 0; return 0;
pr_debug("uda1380: hw write %x val %x\n", reg, value); pr_debug("uda1380: hw write %x val %x\n", reg, value);
if (codec->hw_write(codec->control_data, data, 3) == 3) { if (codec->hw_write(codec->control_data, data, 3) == 3) {
......
...@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, ...@@ -197,7 +197,7 @@ static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
return 0; return 0;
/* Do not allow changes while stream is running */ /* Do not allow changes while stream is running */
if (codec->active) if (snd_soc_codec_is_active(codec))
return -EPERM; return -EPERM;
if (ucontrol->value.integer.value[0] < 0 || if (ucontrol->value.integer.value[0] < 0 ||
......
...@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream, ...@@ -201,7 +201,7 @@ static void wm8711_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
/* deactivate */ /* deactivate */
if (!codec->active) { if (!snd_soc_codec_is_active(codec)) {
udelay(50); udelay(50);
snd_soc_write(codec, WM8711_ACTIVE, 0x0); snd_soc_write(codec, WM8711_ACTIVE, 0x0);
} }
......
...@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, ...@@ -251,7 +251,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
if (wm8753->dai_func == ucontrol->value.integer.value[0]) if (wm8753->dai_func == ucontrol->value.integer.value[0])
return 0; return 0;
if (codec->active) if (snd_soc_codec_is_active(codec))
return -EBUSY; return -EBUSY;
ioctl = snd_soc_read(codec, WM8753_IOCTL); ioctl = snd_soc_read(codec, WM8753_IOCTL);
...@@ -1314,7 +1314,7 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute) ...@@ -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. /* 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 */ * make sure we check if they are not both active when we mute */
if (mute && wm8753->dai_func == 1) { 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); snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
} else { } else {
if (mute) if (mute)
......
...@@ -96,8 +96,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) ...@@ -96,8 +96,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
{ {
dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n", dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
codec->name); codec->name);
if (!codec->reg_cache)
return 0;
kfree(codec->reg_cache); kfree(codec->reg_cache);
codec->reg_cache = NULL; codec->reg_cache = NULL;
return 0; return 0;
...@@ -117,8 +116,9 @@ int snd_soc_cache_read(struct snd_soc_codec *codec, ...@@ -117,8 +116,9 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
return -EINVAL; return -EINVAL;
mutex_lock(&codec->cache_rw_mutex); mutex_lock(&codec->cache_rw_mutex);
*value = snd_soc_get_cache_val(codec->reg_cache, reg, if (!ZERO_OR_NULL_PTR(codec->reg_cache))
codec->driver->reg_word_size); *value = snd_soc_get_cache_val(codec->reg_cache, reg,
codec->driver->reg_word_size);
mutex_unlock(&codec->cache_rw_mutex); mutex_unlock(&codec->cache_rw_mutex);
return 0; return 0;
...@@ -136,8 +136,9 @@ int snd_soc_cache_write(struct snd_soc_codec *codec, ...@@ -136,8 +136,9 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value) unsigned int reg, unsigned int value)
{ {
mutex_lock(&codec->cache_rw_mutex); mutex_lock(&codec->cache_rw_mutex);
snd_soc_set_cache_val(codec->reg_cache, reg, value, if (!ZERO_OR_NULL_PTR(codec->reg_cache))
codec->driver->reg_word_size); snd_soc_set_cache_val(codec->reg_cache, reg, value,
codec->driver->reg_word_size);
mutex_unlock(&codec->cache_rw_mutex); mutex_unlock(&codec->cache_rw_mutex);
return 0; return 0;
......
...@@ -30,8 +30,6 @@ static int soc_compr_open(struct snd_compr_stream *cstream) ...@@ -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_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform; 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; int ret = 0;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
...@@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) ...@@ -52,17 +50,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
} }
} }
if (cstream->direction == SND_COMPRESS_PLAYBACK) { snd_soc_runtime_activate(rtd, cstream->direction);
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++;
mutex_unlock(&rtd->pcm_mutex); mutex_unlock(&rtd->pcm_mutex);
...@@ -81,8 +69,6 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) ...@@ -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_soc_pcm_runtime *fe = cstream->private_data;
struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
struct snd_soc_platform *platform = fe->platform; 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_dpcm *dpcm;
struct snd_soc_dapm_widget_list *list; struct snd_soc_dapm_widget_list *list;
int stream; int stream;
...@@ -140,17 +126,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) ...@@ -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].state = SND_SOC_DPCM_STATE_OPEN;
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
if (cstream->direction == SND_COMPRESS_PLAYBACK) { snd_soc_runtime_activate(fe, stream);
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++;
mutex_unlock(&fe->card->mutex); mutex_unlock(&fe->card->mutex);
...@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream) ...@@ -202,23 +178,18 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
struct snd_soc_platform *platform = rtd->platform; struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_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); mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
if (cstream->direction == SND_COMPRESS_PLAYBACK) { if (cstream->direction == SND_COMPRESS_PLAYBACK)
cpu_dai->playback_active--; stream = SNDRV_PCM_STREAM_PLAYBACK;
codec_dai->playback_active--; else
} else { stream = SNDRV_PCM_STREAM_CAPTURE;
cpu_dai->capture_active--;
codec_dai->capture_active--;
}
snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction); snd_soc_runtime_deactivate(rtd, stream);
cpu_dai->active--; snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
codec_dai->active--;
codec->active--;
if (!cpu_dai->active) if (!cpu_dai->active)
cpu_dai->rate = 0; cpu_dai->rate = 0;
...@@ -235,8 +206,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) ...@@ -235,8 +206,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
cpu_dai->runtime = NULL; cpu_dai->runtime = NULL;
if (cstream->direction == SND_COMPRESS_PLAYBACK) { if (cstream->direction == SND_COMPRESS_PLAYBACK) {
if (!rtd->pmdown_time || codec->ignore_pmdown_time || if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
rtd->dai_link->ignore_pmdown_time) {
snd_soc_dapm_stream_event(rtd, snd_soc_dapm_stream_event(rtd,
SNDRV_PCM_STREAM_PLAYBACK, SNDRV_PCM_STREAM_PLAYBACK,
SND_SOC_DAPM_STREAM_STOP); SND_SOC_DAPM_STREAM_STOP);
...@@ -261,26 +231,17 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) ...@@ -261,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_pcm_runtime *fe = cstream->private_data;
struct snd_soc_platform *platform = fe->platform; 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_dpcm *dpcm;
int stream, ret; int stream, ret;
mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 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; stream = SNDRV_PCM_STREAM_PLAYBACK;
cpu_dai->playback_active--; else
codec_dai->playback_active--;
} else {
stream = SNDRV_PCM_STREAM_CAPTURE; stream = SNDRV_PCM_STREAM_CAPTURE;
cpu_dai->capture_active--;
codec_dai->capture_active--;
}
cpu_dai->active--; snd_soc_runtime_deactivate(fe, stream);
codec_dai->active--;
fe->codec->active--;
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
......
This diff is collapsed.
...@@ -34,6 +34,86 @@ ...@@ -34,6 +34,86 @@
#define DPCM_MAX_BE_USERS 8 #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++;
cpu_dai->component->active++;
codec_dai->component->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--;
cpu_dai->component->active--;
codec_dai->component->active--;
}
/**
* 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)
{
if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
return true;
return rtd->cpu_dai->component->ignore_pmdown_time &&
rtd->codec_dai->component->ignore_pmdown_time;
}
/** /**
* snd_soc_set_runtime_hwparams - set the runtime hardware parameters * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
* @substream: the pcm substream * @substream: the pcm substream
...@@ -378,16 +458,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) ...@@ -378,16 +458,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
runtime->hw.rate_max); runtime->hw.rate_max);
dynamic: dynamic:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
cpu_dai->playback_active++; snd_soc_runtime_activate(rtd, substream->stream);
codec_dai->playback_active++;
} else {
cpu_dai->capture_active++;
codec_dai->capture_active++;
}
cpu_dai->active++;
codec_dai->active++;
rtd->codec->active++;
mutex_unlock(&rtd->pcm_mutex); mutex_unlock(&rtd->pcm_mutex);
return 0; return 0;
...@@ -459,21 +532,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) ...@@ -459,21 +532,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
struct snd_soc_platform *platform = rtd->platform; struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_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); mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { snd_soc_runtime_deactivate(rtd, substream->stream);
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--;
/* clear the corresponding DAIs rate when inactive */ /* clear the corresponding DAIs rate when inactive */
if (!cpu_dai->active) if (!cpu_dai->active)
...@@ -496,8 +558,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) ...@@ -496,8 +558,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
cpu_dai->runtime = NULL; cpu_dai->runtime = NULL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (!rtd->pmdown_time || codec->ignore_pmdown_time || if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
rtd->dai_link->ignore_pmdown_time) {
/* powered down playback stream now */ /* powered down playback stream now */
snd_soc_dapm_stream_event(rtd, snd_soc_dapm_stream_event(rtd,
SNDRV_PCM_STREAM_PLAYBACK, SNDRV_PCM_STREAM_PLAYBACK,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment