diff options
-rw-r--r-- | sound/soc/fsl/fsl_asrc.c | 9 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc.h | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc_m2m.c | 15 |
3 files changed, 14 insertions, 12 deletions
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 817adbfa27fa..26050427b7ff 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -525,6 +525,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, return ret; } + asrc_priv->pair_streams |= BIT(substream->stream); pair->config = &config; if (width == 16) @@ -573,11 +574,15 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai); struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_asrc_pair *pair = runtime->private_data; - if (pair) - fsl_asrc_release_pair(pair); + if (asrc_priv->pair_streams & BIT(substream->stream)) { + if (pair) + fsl_asrc_release_pair(pair); + asrc_priv->pair_streams &= ~BIT(substream->stream); + } return 0; } diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 1fb06410d86f..034d10dc11e9 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -341,6 +341,7 @@ struct fsl_asrc_pair { * @pair: pair pointers * @channel_bits: width of ASRCNCR register for each pair * @channel_avail: non-occupied channel numbers + * @pair_streams:indicat which substream is running * @asrc_rate: default sample rate for ASoC Back-Ends * @asrc_width: default sample width for ASoC Back-Ends * @regcache_cfg: store register value of REG_ASRCFG @@ -360,6 +361,7 @@ struct fsl_asrc { struct fsl_asrc_pair *pair[ASRC_PAIR_MAX_NUM]; unsigned int channel_bits; unsigned int channel_avail; + unsigned int pair_streams; int asrc_rate; int asrc_width; diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c index 9ee0f503e8c5..7363dc003aa6 100644 --- a/sound/soc/fsl/fsl_asrc_m2m.c +++ b/sound/soc/fsl/fsl_asrc_m2m.c @@ -274,7 +274,8 @@ static int fsl_asrc_prepare_io_buffer(struct fsl_asrc_pair *pair, word_size = 2; if (buf_len < word_size * pair->channels * wm || - buf_len > ASRC_DMA_BUFFER_SIZE) { + buf_len > ASRC_DMA_BUFFER_SIZE || + (dir == OUT && buf_len < word_size * pair->channels * last_period_size)) { pair_err("%sput buffer size is error: [%d]\n", DIR_STR(dir), buf_len); return -EINVAL; @@ -557,7 +558,9 @@ static long fsl_asrc_ioctl_config_pair(struct fsl_asrc_pair *pair, m2m->rate[IN] = config.input_sample_rate; m2m->rate[OUT] = config.output_sample_rate; - if (m2m->rate[OUT] > m2m->rate[IN]) + if (m2m->rate[OUT] >= m2m->rate[IN] * 8) + m2m->last_period_size = (m2m->rate[OUT] / m2m->rate[IN]) * 5; + else if (m2m->rate[OUT] > m2m->rate[IN]) m2m->last_period_size = ASRC_OUTPUT_LAST_SAMPLE_MAX; else m2m->last_period_size = ASRC_OUTPUT_LAST_SAMPLE; @@ -852,14 +855,6 @@ static int fsl_asrc_close(struct inode *inode, struct file *file) struct fsl_asrc *asrc_priv = pair->asrc_priv; struct device *dev = &asrc_priv->pdev->dev; unsigned long lock_flags; - int i; - - /* Make sure we have clear the pointer */ - spin_lock_irqsave(&asrc_priv->lock, lock_flags); - for (i = 0; i < ASRC_PAIR_MAX_NUM; i++) - if (asrc_priv->pair[i] == pair) - asrc_priv->pair[i] = NULL; - spin_unlock_irqrestore(&asrc_priv->lock, lock_flags); if (m2m->asrc_active) { m2m->asrc_active = 0; |