summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/fsl/fsl_asrc.c9
-rw-r--r--sound/soc/fsl/fsl_asrc.h2
-rw-r--r--sound/soc/fsl/fsl_asrc_m2m.c15
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;