From: Daniel Ribeiro <drwyrm@gmail.com>
To: Daniel Mack <daniel@caiaq.de>
Cc: alsa-devel@alsa-project.org,
Mark Brown <broonie@opensource.wolfsonmicro.com>,
Eric Miao <eric.y.miao@gmail.com>,
linux-arm-kernel <linux-arm-kernel@lists.arm.linux.org.uk>,
pHilipp Zabel <philipp.zabel@gmail.com>
Subject: Re: [RFC] I2S and LEFT_J
Date: Fri, 26 Jun 2009 21:28:28 -0300 [thread overview]
Message-ID: <1246062508.10360.358.camel@brutus> (raw)
In-Reply-To: <20090622221430.GH29236@buzzloop.caiaq.de>
[-- Attachment #1.1: Type: text/plain, Size: 7669 bytes --]
Hi Daniel, sorry for the delay on this.
Em Ter, 2009-06-23 às 00:14 +0200, Daniel Mack escreveu:
> And on the oscilloscope, I see an asynchronous LRCLK[1].
> What's worth mentioning is this quote from the PXA datasheet - the code
> does not currently follow that rule:
>
> "When using Programmable Serial Protocol (PSP) format in network
> mode, the parameters SFRMDLY, STRTDLY, DMYSTP, EDMYSTP, DMYSTRT, and
> EDMYSTRT must be set to 0b0; the other parameters SFRMP, SCMODE, FSRT,
> and SFRMWDTH are programmable."
> (4.5.8 SSP Programmable Serial Protocol Registers (SSPSP_x))
Yes, and very likely this is what caused the asynchronous LRCLK.
> Without network mode, these are the register values that do what I need:
>
> SSCR0 0x2100037F
> SSCR1 0x00C01d08
> SSPSP 0x31a08084
> (SSTSA/SSRSA don't matter in this case)
Thanks for the testing. If you don't mind, can you please replace the
third patch, and try this one instead?
Use set_tdm_slot(5, 5, 4, 16), if this works for you we can just drop
the pxa3xx special case and use SSCR0_FSRT and network mode for both
pxa2xx and pxa3xx.
If not, use set_tdm_slot(1, 1, 1, 16), and tweak the
(slots == 1 && slot_width == 16) special case as needed. This condition
should give you a config without SSCR0_MOD, and you should be able to
match the register values above.
---
arch/arm/mach-pxa/include/mach/regs-ssp.h | 14 ++--
sound/soc/pxa/pxa-ssp.c | 125 ++++++++++++++---------------
2 files changed, 67 insertions(+), 72 deletions(-)
diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h
index 6a2ed35..060e23b 100644
--- a/arch/arm/mach-pxa/include/mach/regs-ssp.h
+++ b/arch/arm/mach-pxa/include/mach/regs-ssp.h
@@ -108,21 +108,21 @@
#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */
#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */
-#if defined(CONFIG_PXA3xx)
-#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */
-#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */
-#endif
-
#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */
-#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */
#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */
#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */
-#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */
#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */
#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */
#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */
#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */
+/* NOTE: PXA3xx extends the bit number of dummy start and stop, the macros
+ * below are compatible with PXA25x/27x as long as the parameter is within
+ * the correct limits, driver code has to take care of this.
+ */
+#define SSPSP_DMYSTRT(x) ((((x) & 3) << 7) | ((((x) >> 2) & 3) << 26))
+#define SSPSP_DMYSTOP(x) ((((x) & 3) << 23) | ((((x) >> 2) & 7) << 28))
+
#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */
#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */
#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d60492e..6efead5 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -179,21 +179,6 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div)
ssp_write_reg(ssp, SSCR0, sscr0);
}
-/**
- * ssp_get_clkdiv - get SSP clock divider
- */
-static u32 ssp_get_scr(struct ssp_device *ssp)
-{
- u32 sscr0 = ssp_read_reg(ssp, SSCR0);
- u32 div;
-
- if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
- div = ((sscr0 >> 8) & 0xff) * 2 + 2;
- else
- div = ((sscr0 >> 8) & 0xfff) + 1;
- return div;
-}
-
/*
* Set the SSP ports SYSCLK.
*/
@@ -487,17 +472,14 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- sscr0 |= SSCR0_PSP;
- sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
- /* See hw_params() */
- break;
-
case SND_SOC_DAIFMT_DSP_A:
sspsp |= SSPSP_FSRT;
case SND_SOC_DAIFMT_DSP_B:
+ case SND_SOC_DAIFMT_LEFT_J:
+ case SND_SOC_DAIFMT_I2S:
sscr0 |= SSCR0_PSP;
sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
+ /* See hw_params() for I2S and LEFT_J */
break;
default:
@@ -561,6 +543,63 @@ 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;
+
+ if (slots == 1 && slot_width == 16) {
+ if (!cpu_is_pxa3xx())
+ return -EINVAL;
+
+ sspsp |= SSPSP_DMYSTRT(1);
+ sspsp |= SSPSP_DMYSTOP(
+ slot_width * 2 - width - 1);
+ sspsp |= SSPSP_SFRMWDTH(slot_width * 2);
+ } else {
+ sspsp |= SSPSP_SFRMWDTH(slot_width * slots / 2);
+ sspsp |= SSPSP_FSRT;
+ }
+ }
+ break;
+
+ case SND_SOC_DAIFMT_LEFT_J:
+ if (chn == 1)
+ frame_width *= 2;
+
+ if (frame_width > 0) {
+ sspsp |= SSPSP_SFRMWDTH(frame_width / 2);
+ } else {
+ int slots = ((sscr0 & SSCR0_SlotsPerFrm(8)) >> 24) + 1;
+
+ sspsp |= SSPSP_SFRMWDTH((slot_width * slots) / 2);
+ }
+ break;
+ default:
+ break;
+ }
+ ssp_write_reg(ssp, SSPSP, sspsp);
+
if (frame_width > 0) {
/* Not using network mode */
if (frame_width > 16)
@@ -598,50 +637,6 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
ssp_write_reg(ssp, SSCR0, sscr0);
- switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- sspsp = ssp_read_reg(ssp, SSPSP);
-
- if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
- /* This is a special case where the bitclk is 64fs
- * and we're not dealing with 2*32 bits of audio
- * samples.
- *
- * The SSP values used for that are all found out by
- * trying and failing a lot; some of the registers
- * needed for that mode are only available on PXA3xx.
- */
-
-#ifdef CONFIG_PXA3xx
- if (!cpu_is_pxa3xx())
- return -EINVAL;
-
- sspsp |= SSPSP_SFRMWDTH(width * 2);
- sspsp |= SSPSP_SFRMDLY(width * 4);
- sspsp |= SSPSP_EDMYSTOP(3);
- sspsp |= SSPSP_DMYSTOP(3);
- sspsp |= SSPSP_DMYSTRT(1);
-#else
- return -EINVAL;
-#endif
- } else {
- /* The frame width is the width the LRCLK is
- * asserted for; the delay is expressed in
- * half cycle units. We need the extra cycle
- * because the data starts clocking out one BCLK
- * after LRCLK changes polarity.
- */
- sspsp |= SSPSP_SFRMWDTH(width + 1);
- sspsp |= SSPSP_SFRMDLY((width + 1) * 2);
- sspsp |= SSPSP_DMYSTRT(1);
- }
-
- ssp_write_reg(ssp, SSPSP, sspsp);
- break;
- default:
- break;
- }
-
dump_registers(ssp);
return 0;
--
tg: (2d97ff5..) asoc/leftj-and-i2s (depends on: asoc/ssp-internals)
--
Daniel Ribeiro
[-- Attachment #1.2: Esta é uma parte de mensagem assinada digitalmente --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
[-- Attachment #2: Type: text/plain, Size: 160 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
next prev parent reply other threads:[~2009-06-27 0:28 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-03 12:33 [PATCH 1/4] ASoC: pxa-ssp: enhance I2S and add Left_J support Eric Miao
2009-06-03 13:18 ` Daniel Mack
2009-06-03 14:22 ` Eric Miao
2009-06-03 14:23 ` Mark Brown
2009-06-03 14:24 ` Daniel Mack
[not found] ` <37b631400906040207o169abbc2ob33100879ac68911@mail.gmail.com>
2009-06-04 9:44 ` Paul Shen
2009-06-05 17:26 ` Daniel Mack
2009-06-05 22:47 ` Mark Brown
2009-06-04 12:36 ` Mark Brown
2009-06-04 13:12 ` Daniel Mack
2009-06-06 8:26 ` Daniel Ribeiro
2009-06-09 9:39 ` Paul Shen
2009-06-09 9:54 ` Daniel Mack
2009-06-09 10:10 ` Daniel Ribeiro
2009-06-06 20:12 ` Mark Brown
2009-06-08 12:12 ` pHilipp Zabel
2009-06-08 12:40 ` Mark Brown
2009-06-08 15:58 ` pHilipp Zabel
2009-06-08 16:25 ` Daniel Ribeiro
2009-06-08 16:38 ` Mark Brown
2009-06-08 17:18 ` pHilipp Zabel
2009-06-08 17:41 ` Mark Brown
2009-06-08 18:59 ` pHilipp Zabel
2009-06-08 16:03 ` Daniel Ribeiro
2009-06-08 16:53 ` Mark Brown
2009-06-08 17:26 ` Daniel Ribeiro
2009-06-08 18:06 ` Mark Brown
2009-06-08 20:52 ` Daniel Ribeiro
2009-06-09 9:39 ` Eric Miao
2009-06-09 9:41 ` Eric Miao
2009-06-09 9:58 ` Mark Brown
2009-06-09 11:40 ` pHilipp Zabel
2009-06-10 22:24 ` Daniel Ribeiro
2009-06-11 9:00 ` Mark Brown
2009-06-11 15:13 ` Daniel Mack
2009-06-11 13:34 ` Eric Miao
2009-06-11 14:36 ` [RFC] I2S and LEFT_J (was: ASoC: pxa-ssp: enhance I2S and add Left_J support) Daniel Ribeiro
2009-06-15 8:45 ` Eric Miao
2009-06-15 14:57 ` Daniel Ribeiro
2009-06-15 15:04 ` Mark Brown
2009-06-15 17:20 ` Daniel Ribeiro
2009-06-15 17:40 ` Daniel Mack
2009-06-16 2:11 ` Daniel Ribeiro
2009-06-15 18:00 ` Mark Brown
2009-06-18 7:58 ` [RFC] I2S and LEFT_J Eric Miao
2009-06-18 12:30 ` Daniel Ribeiro
2009-06-22 22:14 ` Daniel Mack
2009-06-27 0:28 ` Daniel Ribeiro [this message]
2009-07-01 12:17 ` Daniel Mack
2009-06-08 21:07 ` [RFC] Auto setup TDM when needed. Add frame_width and rx/tx masks to set_tdm_slots Daniel Ribeiro
2009-06-09 9:10 ` Mark Brown
2009-06-08 14:13 ` [PATCH 1/4] ASoC: pxa-ssp: enhance I2S and add Left_J support Eric Miao
2009-06-08 15:06 ` 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=1246062508.10360.358.camel@brutus \
--to=drwyrm@gmail.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=daniel@caiaq.de \
--cc=eric.y.miao@gmail.com \
--cc=linux-arm-kernel@lists.arm.linux.org.uk \
--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