From: Daniel Mack <daniel@caiaq.de>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Paul Shen <boshen9@gmail.com>,
alsa-devel@alsa-project.org, Eric Miao <eric.y.miao@gmail.com>,
Daniel Ribeiro <drwyrm@gmail.com>,
Philipp Zabel <philipp.zabel@gmail.com>
Subject: Re: [PATCH 2/3] ASoC: pxa-ssp.c, Automatically set TDM when needed
Date: Wed, 12 Aug 2009 20:17:24 +0200 [thread overview]
Message-ID: <20090812181724.GZ19257@buzzloop.caiaq.de> (raw)
In-Reply-To: <1249570519-32622-2-git-send-email-broonie@opensource.wolfsonmicro.com>
Ok, I spent some time in debugging this again, and here are my
findings.
Again, to summarize what this is all about - what I need the code to
produce is the following output:
- syncronous LRCLK
- 64fs on I2SCLK
- I2S data on the first 16bits of each LRCLK edge
-> http://caiaq.de/download/tmp/2.png
So I applied all three patches and added the following call to my board
support code:
snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, 16);
Which translates into "give me 2 slots with 16 bits each, and distribute
them over the timeline as a 0-1-0-1 pattern". Which is exactly what I
need, right?
But unfortunately, the code didn't make the SSP port do that. I ended up
having a asynchronous clock and the data somewhere where I wouldn't have
expected them: http://caiaq.de/download/tmp/1.png
I did some minor modifications to the patches 2/3 and 3/3 which made it
work for me eventually - find them inline.
Not sure whether I got the theory about the API right, and of course I
didn't test on any other hardware than the one I have.
On Thu, Aug 06, 2009 at 03:55:18PM +0100, Mark Brown wrote:
> * Automatically sets TDM mode for frame_width larger than 32 bits, if
> the user doesn't setup the TDM slots with set_tdm_slot().
> * Reset SSCR0_EDSS and SSCR0_DSS on pxa_ssp_set_dai_fmt.
> * Makes SSCR0_MOD optional.
> * Clears SSCR1_RWOT case SSCR0_MOD is set.
>
> Signed-off-by: Daniel Ribeiro <drwyrm@gmail.com>
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
> sound/soc/pxa/pxa-ssp.c | 92 +++++++++++++++++++++++++++--------------------
> 1 files changed, 53 insertions(+), 39 deletions(-)
>
> diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
> index 5b9ed64..d60492e 100644
> --- a/sound/soc/pxa/pxa-ssp.c
> +++ b/sound/soc/pxa/pxa-ssp.c
[...]
> @@ -532,48 +532,70 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
> struct ssp_priv *priv = cpu_dai->private_data;
> struct ssp_device *ssp = priv->dev.ssp;
> int chn = params_channels(params);
> - u32 sscr0;
> - u32 sspsp;
> + u32 sscr0, sscr1, sspsp;
> int width = snd_pcm_format_physical_width(params_format(params));
> - int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
> + int slot_width, frame_width = 0;
> +
> + /* check if the user explicitly set a slot_width */
> + sscr0 = ssp_read_reg(ssp, SSCR0);
> +
> + if (sscr0 & (SSCR0_EDSS | SSCR0_DSS))
> + slot_width = (sscr0 & SSCR0_DSS) +
> + (sscr0 & SSCR0_EDSS ? 17 : 1);
> + else
> + frame_width = slot_width = width * chn;
>
> /* generate correct DMA params */
> if (cpu_dai->dma_data)
> kfree(cpu_dai->dma_data);
>
> - /* Network mode with one active slot (ttsa == 1) can be used
> - * to force 16-bit frame width on the wire (for S16_LE), even
> - * with two channels. Use 16-bit DMA transfers for this case.
> - */
> - cpu_dai->dma_data = ssp_get_dma_params(ssp,
> - ((chn == 2) && (ttsa != 1)) || (width == 32),
> + cpu_dai->dma_data = ssp_get_dma_params(ssp, slot_width > 16,
> substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
The condition for the width4 parameter needs to be
(slot_width * slots) > 16 for me. With that parameter set to 0, audio
plays at half speed on my system.
And in patch 3/3,
> diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
> index d60492e..aac85fe 100644
> --- a/sound/soc/pxa/pxa-ssp.c
> +++ b/sound/soc/pxa/pxa-ssp.c
[...]
> @@ -561,6 +543,59 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
> sscr0 |= SSCR0_FPCKE;
> #endif
>
> + sspsp = ssp_read_reg(ssp, SSPSP);
> + switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> + case SND_SOC_DAIFMT_I2S:
> + /*
> + * I2S and LEFT_J are stereo only, we have to send data for
> + * both channels.
> + */
> + if (chn == 1)
> + frame_width *= 2;
> +
> + /*
> + * If the user did not use network mode, we assume the codec
> + * is I2S compliant.
> + */
> + if (frame_width > 0) {
> + sspsp |= SSPSP_SFRMWDTH(frame_width / 2);
> + sspsp |= SSPSP_FSRT;
> + } else {
> + /*
> + * Otherwise we assume that it is a single TDM slot, and
> + * the user is abusing set_tdm_slot to support an
> + * out of spec codec.
> + */
> + int slots = ((sscr0 & SSCR0_SlotsPerFrm(8)) >> 24) + 1;
> +
> + /* PXA2XX doesn't support DMYSTOP > 3 */
> + if (slot_width != (width * 2) && !cpu_is_pxa3xx())
> + return -EINVAL;
> +
> + sspsp |= SSPSP_DMYSTRT(1);
> + sspsp |= SSPSP_DMYSTOP(
> + (slot_width * slots) / 2 - width - 1);
> + sspsp |= SSPSP_SFRMWDTH((slot_width * slots) / 2);
These two calculations are wrong my case. What works here is
sspsp |= SSPSP_DMYSTOP(
(slot_width * slots * chn) / 2 - width - 1);
sspsp |= SSPSP_SFRMWDTH((slot_width * slots * chn) / 2);
... which is another multiplication by factor 2. But I'm not sure if I
got the wrong variable with value 2 :)
I then end up having the following register contents:
SSCR0 0xa10003ff
SSCR1 0x00601d08
SSPSP 0x31a00084
SSACD 0x00000060
SSTSA 0x00000003
SSRSA 0x00000003
Daniel
next prev parent reply other threads:[~2009-08-12 18:17 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-06 14:55 [PATCH 1/3] ASoC: change set_tdm_slot api to allow slot_width override Mark Brown
2009-08-06 14:55 ` [PATCH 2/3] ASoC: pxa-ssp.c, Automatically set TDM when needed Mark Brown
2009-08-12 18:17 ` Daniel Mack [this message]
2009-08-14 16:17 ` Daniel Ribeiro
2009-08-15 9:51 ` Mark Brown
2009-08-15 11:48 ` Daniel Ribeiro
2009-08-17 15:35 ` Daniel Mack
2009-08-17 16:08 ` Mark Brown
2009-08-17 18:09 ` Daniel Ribeiro
2009-08-13 1:28 ` Daniel Mack
2009-08-06 14:55 ` [PATCH 3/3] ASoC: pxa-ssp.c handle the I2S and LEFT_J cases Mark Brown
2009-08-06 14:59 ` [PATCH 1/3] ASoC: change set_tdm_slot api to allow slot_width override Daniel Mack
2009-08-11 12:04 ` Mark Brown
-- strict thread matches above, loose matches on Subject: below --
2009-06-16 0:44 [PATCH 2/3] ASoC: pxa-ssp.c, Automatically set TDM when needed Daniel Ribeiro
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=20090812181724.GZ19257@buzzloop.caiaq.de \
--to=daniel@caiaq.de \
--cc=alsa-devel@alsa-project.org \
--cc=boshen9@gmail.com \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=drwyrm@gmail.com \
--cc=eric.y.miao@gmail.com \
--cc=philipp.zabel@gmail.com \
/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