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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.