[alsa-devel] [PATCH] ASoC: fsl_asrc: sound is wrong after suspend/resume
The register ASRCFG is volatile, but some bits need to be recovered after suspend/resume.
Signed-off-by: Zidan Wang zidan.wang@freescale.com --- sound/soc/fsl/fsl_asrc.c | 6 ++++++ sound/soc/fsl/fsl_asrc.h | 2 ++ 2 files changed, 8 insertions(+)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 3e404ba..942e74bc 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -990,6 +990,9 @@ static int fsl_asrc_suspend(struct device *dev) { struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
+ regmap_read(asrc_priv->regmap, REG_ASRCFG, + &asrc_priv->regcache_cfg); + regcache_cache_only(asrc_priv->regmap, true); regcache_mark_dirty(asrc_priv->regmap);
@@ -1010,6 +1013,9 @@ static int fsl_asrc_resume(struct device *dev) regcache_cache_only(asrc_priv->regmap, false); regcache_sync(asrc_priv->regmap);
+ regmap_update_bits(asrc_priv->regmap, REG_ASRCFG, + 0x1FFFC0, asrc_priv->regcache_cfg); + /* Restart enabled pairs */ regmap_update_bits(asrc_priv->regmap, REG_ASRCTR, ASRCTR_ASRCEi_ALL_MASK, asrctr); diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 68802cd..3695ca9 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -453,6 +453,8 @@ struct fsl_asrc {
int asrc_rate; int asrc_width; + + u32 regcache_cfg; };
extern struct snd_soc_platform_driver fsl_asrc_platform;
Add 8kHz, 11.025kHz, 16kHz, 22.05kHz output sample rate support.
According referance menual, "Limited support for the case when output sampling rates is between 8kHz and 30kHz. The limitation is the supported ratio (Fsin/Fsout) range as between 1/24 to 8."
Signed-off-by: Zidan Wang zidan.wang@freescale.com --- sound/soc/fsl/fsl_asrc.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 942e74bc..cf17a1f 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -31,21 +31,21 @@ dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
/* Sample rates are aligned with that defined in pcm.h file */ -static const u8 process_option[][8][2] = { - /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */ - {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */ - {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */ - {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */ - {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */ - {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */ - {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */ - {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */ - {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */ - {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */ - {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */ +static const u8 process_option[][12][2] = { + /* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */ + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */ + {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */ + {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */ + {{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */ + {{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */ + {{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */ + {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */ + {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */ + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */ + {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */ + {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */ + {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */ + {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */ };
/* Corresponding to process_option */ @@ -55,7 +55,7 @@ static int supported_input_rate[] = { };
static int supported_asrc_rate[] = { - 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000, + 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000, };
/** @@ -287,6 +287,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair) return -EINVAL; }
+ if ((outrate > 8000 && outrate < 30000) && + (outrate/inrate > 24 || inrate/outrate > 8)) { + pair_err("exceed supported ratio range [1/24, 8] for \ + inrate/outrate: %d/%d\n", inrate, outrate); + return -EINVAL; + } + /* Validate input and output clock sources */ clk_index[IN] = clk_map[IN][config->inclk]; clk_index[OUT] = clk_map[OUT][config->outclk];
On Thu, Dec 10, 2015 at 07:02:49PM +0800, Zidan Wang wrote:
@@ -287,6 +287,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair) return -EINVAL; }
- if ((outrate > 8000 && outrate < 30000) &&
(outrate/inrate > 24 || inrate/outrate > 8)) {
Indentation
According to the referance menual, the bclk rate must be never greater than 1/5 IPG clock rate. But clkrate is the system clock, afreq is the bit clock.
Signed-off-by: Zidan Wang zidan.wang@freescale.com --- sound/soc/fsl/fsl_ssi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e3abad5..4466bcb 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -677,16 +677,16 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, else clkrate = clk_round_rate(ssi_private->baudclk, tmprate);
+ clkrate /= factor; + afreq = clkrate / (i + 1); + /* * Hardware limitation: The bclk rate must be * never greater than 1/5 IPG clock rate */ - if (clkrate * 5 > clk_get_rate(ssi_private->clk)) + if (afreq * 5 > clk_get_rate(ssi_private->clk)) continue;
- clkrate /= factor; - afreq = clkrate / (i + 1); - if (freq == afreq) sub = 0; else if (freq / afreq == 1)
On Thu, Dec 10, 2015 at 07:02:50PM +0800, Zidan Wang wrote:
According to the referance menual, the bclk rate must be never greater than 1/5 IPG clock rate. But clkrate is the system clock, afreq is the bit clock.
Signed-off-by: Zidan Wang zidan.wang@freescale.com
There's already a similar fix under review.
Thanks Nicolin
sound/soc/fsl/fsl_ssi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e3abad5..4466bcb 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -677,16 +677,16 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, else clkrate = clk_round_rate(ssi_private->baudclk, tmprate);
clkrate /= factor;
afreq = clkrate / (i + 1);
- /*
*/
- Hardware limitation: The bclk rate must be
- never greater than 1/5 IPG clock rate
if (clkrate * 5 > clk_get_rate(ssi_private->clk))
if (afreq * 5 > clk_get_rate(ssi_private->clk)) continue;
clkrate /= factor;
afreq = clkrate / (i + 1);
- if (freq == afreq) sub = 0; else if (freq / afreq == 1)
-- 1.9.1
On Thu, Dec 10, 2015 at 07:02:48PM +0800, Zidan Wang wrote:
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 3e404ba..942e74bc 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -990,6 +990,9 @@ static int fsl_asrc_suspend(struct device *dev) { struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
- regmap_read(asrc_priv->regmap, REG_ASRCFG,
&asrc_priv->regcache_cfg);
Indentation.
- regcache_cache_only(asrc_priv->regmap, true); regcache_mark_dirty(asrc_priv->regmap);
@@ -1010,6 +1013,9 @@ static int fsl_asrc_resume(struct device *dev) regcache_cache_only(asrc_priv->regmap, false); regcache_sync(asrc_priv->regmap);
- regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
0x1FFFC0, asrc_priv->regcache_cfg);
Either add a macro or a comment for the magic number.
- /* Restart enabled pairs */ regmap_update_bits(asrc_priv->regmap, REG_ASRCTR, ASRCTR_ASRCEi_ALL_MASK, asrctr);
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 68802cd..3695ca9 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -453,6 +453,8 @@ struct fsl_asrc {
int asrc_rate; int asrc_width;
- u32 regcache_cfg;
};
extern struct snd_soc_platform_driver fsl_asrc_platform;
1.9.1
participants (2)
-
Nicolin Chen
-
Zidan Wang