From: subaparts@yandex.ru (Alexander)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/3] ASoC: EP93xx I2S and PCM fixes
Date: Wed, 08 Dec 2010 15:01:33 +0300 [thread overview]
Message-ID: <1291809693.31916.2.camel@r60e> (raw)
From: Alexander Sverdlin <subaparts@yandex.ru>
Changes to I2S code:
- MCLK is turned on on driver probe. This is done for several codecs that need this for
registers access (like CS4271).
- SCLK and LRCLK rates are corrected, assuming we always send 32 bits * 2 channels to codec.
- Formats list shortened to just S32_LE, this makes all the DMA transactions right,
while ALSA will do all sample format translation for us.
Changes to both I2S and PCM code:
- Rates list extended up to 96kHz, it's tested on EDB9302 and works for both capture and
playback.
Signed-off-by: Alexander Sverdlin <subaparts@yandex.ru>
---
sound/soc/ep93xx/ep93xx-i2s.c | 37 +++++++++++++++++++++++--------------
sound/soc/ep93xx/ep93xx-pcm.c | 4 ++--
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 4f48733..e5e9b9a 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -98,7 +98,6 @@ static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
(ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
/* Enable clocks */
- clk_enable(info->mclk);
clk_enable(info->sclk);
clk_enable(info->lrclk);
@@ -136,7 +135,6 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
/* Disable clocks */
clk_disable(info->lrclk);
clk_disable(info->sclk);
- clk_disable(info->mclk);
}
}
@@ -267,14 +265,16 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
ep93xx_i2s_write_reg(info, EP93XX_I2S_RXWRDLEN, word_len);
/*
- * Calculate the sdiv (bit clock) and lrdiv (left/right clock) values.
- * If the lrclk is pulse length is larger than the word size, then the
- * bit clock will be gated for the unused bits.
+ * EP93xx I2S module can be setup so SCLK / LRCLK value can be
+ * 32, 64, 128. MCLK / SCLK value can be 2 and 4.
+ * We set LRCLK equal to `rate' and minimum SCLK / LRCLK
+ * value is 64, because our sample size is 32 bit * 2 channels.
+ * I2S standard permits us to transmit more bits than
+ * the codec uses.
*/
- div = (clk_get_rate(info->mclk) / params_rate(params)) *
- params_channels(params);
+ div = clk_get_rate(info->mclk) / params_rate(params);
for (sdiv = 2; sdiv <= 4; sdiv += 2)
- for (lrdiv = 32; lrdiv <= 128; lrdiv <<= 1)
+ for (lrdiv = 64; lrdiv <= 128; lrdiv <<= 1)
if (sdiv * lrdiv == div) {
found = 1;
goto out;
@@ -316,6 +316,7 @@ static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
+ clk_disable(info->mclk);
}
static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
@@ -325,6 +326,7 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
if (!dai->active)
return;
+ clk_enable(info->mclk);
ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
}
@@ -341,9 +343,7 @@ static struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
.set_fmt = ep93xx_i2s_set_dai_fmt,
};
-#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
+#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
static struct snd_soc_dai_driver ep93xx_i2s_dai = {
.symmetric_rates= 1,
@@ -352,13 +352,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
.playback = {
.channels_min = 2,
.channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.formats = EP93XX_I2S_FORMATS,
},
.capture = {
.channels_min = 2,
.channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.formats = EP93XX_I2S_FORMATS,
},
.ops = &ep93xx_i2s_dai_ops,
@@ -404,10 +404,16 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
goto fail_unmap_mem;
}
+ /* Minimal MCLK freq to enable some codecs */
+ err = clk_set_rate(info->mclk, 8000 * 64 * 4);
+ if (err)
+ goto fail_put_mclk;
+ clk_enable(info->mclk);
+
info->sclk = clk_get(&pdev->dev, "sclk");
if (IS_ERR(info->sclk)) {
err = PTR_ERR(info->sclk);
- goto fail_put_mclk;
+ goto fail_disable_mclk;
}
info->lrclk = clk_get(&pdev->dev, "lrclk");
@@ -426,6 +432,8 @@ fail_put_lrclk:
clk_put(info->lrclk);
fail_put_sclk:
clk_put(info->sclk);
+fail_disable_mclk:
+ clk_disable(info->mclk);
fail_put_mclk:
clk_put(info->mclk);
fail_unmap_mem:
@@ -444,6 +452,7 @@ static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
snd_soc_unregister_dai(&pdev->dev);
clk_put(info->lrclk);
clk_put(info->sclk);
+ clk_disable(info->mclk);
clk_put(info->mclk);
iounmap(info->regs);
release_mem_region(info->mem->start, resource_size(info->mem));
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 2f121dd..0667077 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .rates = SNDRV_PCM_RATE_8000_48000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
.rate_min = SNDRV_PCM_RATE_8000,
- .rate_max = SNDRV_PCM_RATE_48000,
+ .rate_max = SNDRV_PCM_RATE_96000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
next reply other threads:[~2010-12-08 12:01 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-08 12:01 Alexander [this message]
2010-12-08 12:46 ` [PATCH 1/3] ASoC: EP93xx I2S and PCM fixes Mark Brown
2010-12-09 0:37 ` Alexander
2010-12-09 10:54 ` Mark Brown
2010-12-09 12:17 ` Alexander
2010-12-09 12:34 ` Mark Brown
2010-12-09 21:14 ` Alexander
2010-12-10 15:07 ` Mark Brown
2011-01-16 11:21 ` Alexander
2011-01-16 11:27 ` Mark Brown
2010-12-09 0:43 ` [PATCH] ASoC: EP93xx: sampling rate range extended Alexander
2010-12-09 10:07 ` [alsa-devel] " Liam Girdwood
2010-12-09 11:10 ` Mark Brown
2010-12-09 0:59 ` [PATCH] ASoC: EP93xx: fixed LRCLK rate and DMA oper. in I2S code Alexander
2010-12-09 10:08 ` [alsa-devel] " Liam Girdwood
2011-01-16 12:48 ` Alexander
2011-01-17 14:05 ` [alsa-devel] " Liam Girdwood
2011-01-17 14:07 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1291809693.31916.2.camel@r60e \
--to=subaparts@yandex.ru \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).