From: Daniel Ribeiro <drwyrm@gmail.com>
To: Liam Girdwood <lrg@kernel.org>
Cc: alsa-devel@alsa-project.org, Mark Brown <broonie@sirena.org.uk>
Subject: Re: ASoC: pxa2xx-ssp
Date: Sat, 25 Oct 2008 03:32:47 -0200 [thread overview]
Message-ID: <1224912767.5426.19.camel@brutus> (raw)
In-Reply-To: <1224863678.28382.54.camel@dell-desktop.example.com>
[-- Attachment #1: Type: text/plain, Size: 1642 bytes --]
Em Sex, 2008-10-24 às 16:54 +0100, Liam Girdwood escreveu:
> On Thu, 2008-10-23 at 22:54 -0200, Daniel Ribeiro wrote:
> > Hi!
> >
> > What is needed for [0] to be accepted on mainline linux?
> >
> > [0]http://opensource.wolfsonmicro.com/cgi-bin/gitweb.cgi?p=linux-2.6-asoc.git;a=blob;f=sound/soc/pxa/pxa2xx-ssp.c;h=6b1baeece184e990c4254e2f43495013d4562c95;hb=e4d89cdd854b4a40c963adf434d261070c67b6bb
> >
>
> When I last worked on this it was in need of updates for SSP register
> IO, clk API and more testing. It has the IO and clk stuff now.
>
> Does this code work well on your platform/board ?
Not as it is.
My sound codec needs 32bit ssp frames, even considering that it only
supports 16bit mono/stereo audio. I guess that it works with I2S
emulation mode, which pxa2xx-ssp.c dont support yet.
After some time trying to understand the very poorly documented I2S/SSP
emulation on the pxa manual, i ended up with [1]. It works perfectly on
my board, with SND_SOC_DAIFMT_MSB.
To ease your reading, attached is a diff against [0]. It is updated to
build on the latest linus tree and handles DAIFMT_I2S and DAIFMT_MSB
differently.
>
> If so, I guess we could scratch off the more testing part and consider
> it for the next merge window. Iirc it was also waiting on some pxa
> dependencies going upstream, so it may wait a little longer.
>
> I'm sure it's on Mark's long todo list....
>
> Liam
>
[1]http://git.openezx.org/?p=openezx.git;a=blob;f=sound/soc/pxa/pxa2xx-ssp.c;h=cdbc15e243094fd232119b342c39be26c8ac4c7d;hb=cacec205c17b9924db3ca625347a33d0ddd2b694
--
Daniel Ribeiro
[-- Attachment #2: pxa2xx-ssp-i2s-ezx.patch --]
[-- Type: text/x-patch, Size: 11008 bytes --]
--- /tmp/pxa2xx-ssp.c 2008-10-25 03:22:44.000000000 -0200
+++ pxa2xx-ssp.c 2008-10-24 20:19:29.000000000 -0200
@@ -28,12 +28,13 @@
#include <sound/initval.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <sound/pxa2xx-lib.h>
-#include <asm/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/regs-ssp.h>
-#include <asm/arch/audio.h>
-#include <asm/arch/ssp.h>
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <mach/regs-ssp.h>
+#include <mach/audio.h>
+#include <mach/ssp.h>
#include "pxa2xx-pcm.h"
#include "pxa2xx-ssp.h"
@@ -58,7 +59,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_mono_out = {
.name = "SSP1 PCM Mono out",
.dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMRTXSSDR,
+ .drcmr = &DRCMR(14),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH2,
};
@@ -66,7 +67,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_mono_in = {
.name = "SSP1 PCM Mono in",
.dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMRRXSSDR,
+ .drcmr = &DRCMR(13),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH2,
};
@@ -74,7 +75,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_stereo_out = {
.name = "SSP1 PCM Stereo out",
.dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMRTXSSDR,
+ .drcmr = &DRCMR(14),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH4,
};
@@ -82,7 +83,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_stereo_in = {
.name = "SSP1 PCM Stereo in",
.dev_addr = PXA2xx_SSP1_BASE + SSDR,
- .drcmr = &DRCMRRXSSDR,
+ .drcmr = &DRCMR(13),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH4,
};
@@ -90,7 +91,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_mono_out = {
.name = "SSP2 PCM Mono out",
.dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMRTXSS2DR,
+ .drcmr = &DRCMR(16),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH2,
};
@@ -98,7 +99,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_mono_in = {
.name = "SSP2 PCM Mono in",
.dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMRRXSS2DR,
+ .drcmr = &DRCMR(15),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH2,
};
@@ -106,7 +107,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_stereo_out = {
.name = "SSP2 PCM Stereo out",
.dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMRTXSS2DR,
+ .drcmr = &DRCMR(16),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH4,
};
@@ -114,7 +115,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_stereo_in = {
.name = "SSP2 PCM Stereo in",
.dev_addr = PXA27x_SSP2_BASE + SSDR,
- .drcmr = &DRCMRRXSS2DR,
+ .drcmr = &DRCMR(15),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH4,
};
@@ -122,7 +123,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_mono_out = {
.name = "SSP3 PCM Mono out",
.dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMRTXSS3DR,
+ .drcmr = &DRCMR(67),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH2,
};
@@ -130,7 +131,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_mono_in = {
.name = "SSP3 PCM Mono in",
.dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMRRXSS3DR,
+ .drcmr = &DRCMR(66),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH2,
};
@@ -138,7 +139,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_stereo_out = {
.name = "SSP3 PCM Stereo out",
.dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMRTXSS3DR,
+ .drcmr = &DRCMR(67),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH4,
};
@@ -146,7 +147,7 @@
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_stereo_in = {
.name = "SSP3 PCM Stereo in",
.dev_addr = PXA27x_SSP3_BASE + SSDR,
- .drcmr = &DRCMRRXSS3DR,
+ .drcmr = &DRCMR(66),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH4,
};
@@ -163,7 +164,7 @@
static int pxa2xx_ssp_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int ret = 0;
if (!rtd->dai->cpu_dai->active) {
@@ -179,7 +180,7 @@
static void pxa2xx_ssp_shutdown(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
if (!cpu_dai->active) {
ssp_disable(&ssp[cpu_dai->id]);
@@ -190,7 +191,7 @@
#ifdef CONFIG_PM
static int pxa2xx_ssp_suspend(struct platform_device *pdev,
- struct snd_soc_cpu_dai *dai)
+ struct snd_soc_dai *dai)
{
if (!dai->active)
return 0;
@@ -201,7 +202,7 @@
}
static int pxa2xx_ssp_resume(struct platform_device *pdev,
- struct snd_soc_cpu_dai *dai)
+ struct snd_soc_dai *dai)
{
if (!dai->active)
return 0;
@@ -233,7 +234,7 @@
/*
* Set the SSP ports SYSCLK.
*/
-static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
+static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
{
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
@@ -283,7 +284,7 @@
/*
* Set the SSP clock dividers.
*/
-static int pxa2xx_ssp_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
+static int pxa2xx_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
int div_id, int div)
{
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
@@ -313,7 +314,7 @@
/*
* Configure the PLL frequency pxa27x and (afaik - pxa320 only)
*/
-static int pxa2xx_ssp_set_dai_pll(struct snd_soc_cpu_dai *cpu_dai,
+static int pxa2xx_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
int pll_id, unsigned int freq_in, unsigned int freq_out)
{
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
@@ -346,7 +347,7 @@
/*
* Set the active slots in TDM/Network mode
*/
-static int pxa2xx_ssp_set_dai_tdm_slot(struct snd_soc_cpu_dai *cpu_dai,
+static int pxa2xx_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
unsigned int mask, int slots)
{
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
@@ -367,7 +368,7 @@
/*
* Tristate the SSP DAI lines
*/
-static int pxa2xx_ssp_set_dai_tristate(struct snd_soc_cpu_dai *cpu_dai,
+static int pxa2xx_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
int tristate)
{
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
@@ -388,53 +389,23 @@
* The SSP Port must be inactive before calling this function as the
* physical interface format is changed.
*/
-static int pxa2xx_ssp_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
+static int pxa2xx_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
- int val;
+ int val, tmp;
/* reset port settings */
__raw_writel(0, mmio_base + SSCR0);
__raw_writel(0, mmio_base + SSCR1);
__raw_writel(0, mmio_base + SSPSP);
- /* NOTE: I2S emulation is still very much work in progress here */
-
- /* FIXME: this is what wince uses for msb */
- if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_MSB) {
- __raw_writel(SSCR0_EDSS | SSCR0_TISSP | SSCR0_DataSize(16),
- mmio_base + SSCR0);
- goto master;
- }
-
- /* check for I2S emulation mode - handle it separately */
- if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) {
- /* 8.4.11 */
-
- /* Only SSCR0[NCS] or SSCR0[ECS] bit fields settings are optional */
- __raw_writel(SSCR0_EDSS | SSCR0_PSP | SSCR0_DataSize(16),
- mmio_base + SSCR0);
-
- /* set FIFO thresholds */
- __raw_writel(SSCR1_RxTresh(14) | SSCR1_TxTresh(1),
- mmio_base + SSCR1);
-
- /* normal: */
- /* all bit fields must be cleared except: FSRT = 1 and
- * SFRMWDTH = 16, DMYSTART=0,1) */
- __raw_writel(SSPSP_FSRT | SSPSP_SFRMWDTH(16) | SSPSP_DMYSTRT(0),
- mmio_base + SSPSP);
- goto master;
- }
-
val = __raw_readl(mmio_base + SSCR0) | SSCR0_PSP;
__raw_writel(val, mmio_base + SSCR0);
__raw_writel(SSCR1_RxTresh(14) | SSCR1_TxTresh(1) |
SSCR1_TRAIL | SSCR1_RWOT,
mmio_base + SSCR1);
-master:
val = __raw_readl(mmio_base + SSCR1);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
@@ -465,15 +436,20 @@
}
val = __raw_readl(mmio_base + SSPSP);
+ val |= SSPSP_SCMODE(2);
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A:
val |= SSPSP_DMYSTRT(1);
case SND_SOC_DAIFMT_DSP_B:
- val |= SSPSP_SCMODE(2);
break;
case SND_SOC_DAIFMT_I2S:
+ val |= SSPSP_FSRT;
case SND_SOC_DAIFMT_MSB:
- /* handled above */
+ val |= SSPSP_SFRMWDTH(16);
+
+ tmp = __raw_readl(mmio_base + SSCR0) | SSCR0_EDSS |
+ SSCR0_DataSize(16);
+ __raw_writel(tmp, mmio_base + SSCR0);
break;
default:
return -EINVAL;
@@ -491,7 +467,7 @@
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int dma = 0, chn = params_channels(params);
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
u32 sscr0;
@@ -505,12 +481,20 @@
pr_debug("pxa2xx_ssp_hw_params: dma %d", dma);
+ sscr0 = __raw_readl(mmio_base + SSCR0);
+
/* we can only change the settings if the port is not in use */
- if (__raw_readl(mmio_base + SSCR0) & SSCR0_SSE)
- return 0;
+ if (sscr0 & SSCR0_SSE)
+ goto ret;
+
+ /* check if we are running on I2S mode */
+ /* FIXME: Is there a better way to check this? */
+ if ((sscr0 & (SSCR0_EDSS | SSCR0_DataSize(16) | SSCR0_PSP)) ==
+ (SSCR0_EDSS | SSCR0_DataSize(16) | SSCR0_PSP))
+ goto ret;
/* clear selected SSP bits */
- sscr0 = __raw_readl(mmio_base + SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+ sscr0 &= ~(SSCR0_DSS | SSCR0_EDSS);
__raw_writel(sscr0, mmio_base + SSCR0);
/* bit size */
@@ -530,6 +514,7 @@
}
__raw_writel(sscr0, mmio_base + SSCR0);
+ret:
pr_debug("SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x",
__raw_readl(mmio_base + SSCR0), __raw_readl(mmio_base + SSCR1),
__raw_readl(mmio_base + SSTO), __raw_readl(mmio_base + SSPSP),
@@ -541,7 +526,7 @@
static int pxa2xx_ssp_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int ret = 0;
void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
int val;
@@ -609,7 +594,7 @@
#define PXA2XX_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-struct snd_soc_cpu_dai pxa_ssp_dai[] = {
+struct snd_soc_dai pxa_ssp_dai[] = {
{ .name = "pxa2xx-ssp1",
.id = 0,
.type = SND_SOC_DAI_PCM,
[-- Attachment #3: 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:[~2008-10-25 5:33 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-24 0:54 ASoC: pxa2xx-ssp Daniel Ribeiro
2008-10-24 15:54 ` Liam Girdwood
2008-10-24 18:14 ` Mark Brown
2008-10-25 5:32 ` Daniel Ribeiro [this message]
2008-10-27 12:47 ` Mark Brown
2008-10-27 13:19 ` Daniel Ribeiro
2008-10-27 13:44 ` Mark Brown
2008-10-30 11:40 ` Daniel Ribeiro
2008-10-30 12:06 ` Mark Brown
2008-10-30 12:24 ` 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=1224912767.5426.19.camel@brutus \
--to=drwyrm@gmail.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@sirena.org.uk \
--cc=lrg@kernel.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