[alsa-devel] [PATCH, RFC] ASoC: update pxa2xx-ssp to work with current mainline
Philipp Zabel
philipp.zabel at gmail.com
Sat May 10 14:50:13 CEST 2008
This patch against the ASoC dev branch updates pxa2xx-ssp to work with
current mainline. I only made minimal changes to clock/register access
and some dbg->pr_debug cleanup, I guess the DMA setup should be reworked
properly, but I'm not familiar enough with that.
Signed-off-by: Philipp Zabel <philipp.zabel at gmail.com>
---
sound/soc/pxa/pxa2xx-ssp.c | 266 +++++++++++++++++++++++++-------------------
1 files changed, 151 insertions(+), 115 deletions(-)
diff --git a/sound/soc/pxa/pxa2xx-ssp.c b/sound/soc/pxa/pxa2xx-ssp.c
index 25118cc..6b1baee 100644
--- a/sound/soc/pxa/pxa2xx-ssp.c
+++ b/sound/soc/pxa/pxa2xx-ssp.c
@@ -20,8 +20,9 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
-#include <sound/driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
@@ -30,21 +31,13 @@
#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 "pxa2xx-pcm.h"
#include "pxa2xx-ssp.h"
-#define PXA_SSP_DEBUG 0
-
-#if PXA_SSP_DEBUG
-#define dbg(format, arg...) \
- printk(KERN_DEBUG format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-
/*
* SSP audio private data
*/
@@ -58,9 +51,13 @@ static struct ssp_dev ssp[3];
static struct ssp_state ssp_state[3];
#endif
+#define PXA2xx_SSP1_BASE 0x41000000
+#define PXA27x_SSP2_BASE 0x41700000
+#define PXA27x_SSP3_BASE 0x41900000
+
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_mono_out = {
.name = "SSP1 PCM Mono out",
- .dev_addr = __PREG(SSDR_P1),
+ .dev_addr = PXA2xx_SSP1_BASE + SSDR,
.drcmr = &DRCMRTXSSDR,
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH2,
@@ -68,7 +65,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_mono_out = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_mono_in = {
.name = "SSP1 PCM Mono in",
- .dev_addr = __PREG(SSDR_P1),
+ .dev_addr = PXA2xx_SSP1_BASE + SSDR,
.drcmr = &DRCMRRXSSDR,
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH2,
@@ -76,7 +73,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_mono_in = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_stereo_out = {
.name = "SSP1 PCM Stereo out",
- .dev_addr = __PREG(SSDR_P1),
+ .dev_addr = PXA2xx_SSP1_BASE + SSDR,
.drcmr = &DRCMRTXSSDR,
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH4,
@@ -84,7 +81,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_stereo_out = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_stereo_in = {
.name = "SSP1 PCM Stereo in",
- .dev_addr = __PREG(SSDR_P1),
+ .dev_addr = PXA2xx_SSP1_BASE + SSDR,
.drcmr = &DRCMRRXSSDR,
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH4,
@@ -92,7 +89,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp1_pcm_stereo_in = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_mono_out = {
.name = "SSP2 PCM Mono out",
- .dev_addr = __PREG(SSDR_P2),
+ .dev_addr = PXA27x_SSP2_BASE + SSDR,
.drcmr = &DRCMRTXSS2DR,
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH2,
@@ -100,7 +97,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_mono_out = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_mono_in = {
.name = "SSP2 PCM Mono in",
- .dev_addr = __PREG(SSDR_P2),
+ .dev_addr = PXA27x_SSP2_BASE + SSDR,
.drcmr = &DRCMRRXSS2DR,
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH2,
@@ -108,7 +105,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_mono_in = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_stereo_out = {
.name = "SSP2 PCM Stereo out",
- .dev_addr = __PREG(SSDR_P2),
+ .dev_addr = PXA27x_SSP2_BASE + SSDR,
.drcmr = &DRCMRTXSS2DR,
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH4,
@@ -116,7 +113,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_stereo_out = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_stereo_in = {
.name = "SSP2 PCM Stereo in",
- .dev_addr = __PREG(SSDR_P2),
+ .dev_addr = PXA27x_SSP2_BASE + SSDR,
.drcmr = &DRCMRRXSS2DR,
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH4,
@@ -124,7 +121,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp2_pcm_stereo_in = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_mono_out = {
.name = "SSP3 PCM Mono out",
- .dev_addr = __PREG(SSDR_P3),
+ .dev_addr = PXA27x_SSP3_BASE + SSDR,
.drcmr = &DRCMRTXSS3DR,
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH2,
@@ -132,7 +129,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_mono_out = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_mono_in = {
.name = "SSP3 PCM Mono in",
- .dev_addr = __PREG(SSDR_P3),
+ .dev_addr = PXA27x_SSP3_BASE + SSDR,
.drcmr = &DRCMRRXSS3DR,
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH2,
@@ -140,7 +137,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_mono_in = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_stereo_out = {
.name = "SSP3 PCM Stereo out",
- .dev_addr = __PREG(SSDR_P3),
+ .dev_addr = PXA27x_SSP3_BASE + SSDR,
.drcmr = &DRCMRTXSS3DR,
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST16 | DCMD_WIDTH4,
@@ -148,7 +145,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_stereo_out = {
static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_stereo_in = {
.name = "SSP3 PCM Stereo in",
- .dev_addr = __PREG(SSDR_P3),
+ .dev_addr = PXA27x_SSP3_BASE + SSDR,
.drcmr = &DRCMRRXSS3DR,
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST16 | DCMD_WIDTH4,
@@ -156,11 +153,11 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ssp3_pcm_stereo_in = {
static struct pxa2xx_pcm_dma_params *ssp_dma_params[3][4] = {
{&pxa2xx_ssp1_pcm_mono_out, &pxa2xx_ssp1_pcm_mono_in,
- &pxa2xx_ssp1_pcm_stereo_out,&pxa2xx_ssp1_pcm_stereo_in,},
+ &pxa2xx_ssp1_pcm_stereo_out, &pxa2xx_ssp1_pcm_stereo_in,},
{&pxa2xx_ssp2_pcm_mono_out, &pxa2xx_ssp2_pcm_mono_in,
&pxa2xx_ssp2_pcm_stereo_out, &pxa2xx_ssp2_pcm_stereo_in,},
{&pxa2xx_ssp3_pcm_mono_out, &pxa2xx_ssp3_pcm_mono_in,
- &pxa2xx_ssp3_pcm_stereo_out,&pxa2xx_ssp3_pcm_stereo_in,},
+ &pxa2xx_ssp3_pcm_stereo_out, &pxa2xx_ssp3_pcm_stereo_in,},
};
static int pxa2xx_ssp_startup(struct snd_pcm_substream *substream)
@@ -170,7 +167,7 @@ static int pxa2xx_ssp_startup(struct snd_pcm_substream *substream)
int ret = 0;
if (!rtd->dai->cpu_dai->active) {
- ret = ssp_init (&ssp[cpu_dai->id], cpu_dai->id + 1,
+ ret = ssp_init(&ssp[cpu_dai->id], cpu_dai->id + 1,
SSP_NO_IRQ);
if (ret < 0)
return ret;
@@ -190,12 +187,6 @@ static void pxa2xx_ssp_shutdown(struct snd_pcm_substream *substream)
}
}
-#if defined (CONFIG_PXA27x)
-static int cken[3] = {CKEN_SSP1, CKEN_SSP2, CKEN_SSP3};
-#else
-static int cken[3] = {CKEN_SSP, CKEN_NSSP, CKEN_ASSP};
-#endif
-
#ifdef CONFIG_PM
static int pxa2xx_ssp_suspend(struct platform_device *pdev,
@@ -205,7 +196,7 @@ static int pxa2xx_ssp_suspend(struct platform_device *pdev,
return 0;
ssp_save_state(&ssp[dai->id], &ssp_state[dai->id]);
- pxa_set_cken(cken[dai->id], 0);
+ clk_disable(ssp[dai->id].ssp->clk);
return 0;
}
@@ -215,7 +206,7 @@ static int pxa2xx_ssp_resume(struct platform_device *pdev,
if (!dai->active)
return 0;
- pxa_set_cken(cken[dai->id], 1);
+ clk_enable(ssp[dai->id].ssp->clk);
ssp_restore_state(&ssp[dai->id], &ssp_state[dai->id]);
ssp_enable(&ssp[dai->id]);
@@ -227,17 +218,31 @@ static int pxa2xx_ssp_resume(struct platform_device *pdev,
#define pxa2xx_ssp_resume NULL
#endif
+/**
+ * ssp_set_clkdiv - set SSP clock divider
+ * @div: serial clock rate divider
+ */
+void ssp_set_scr(struct ssp_dev *dev, u32 div)
+{
+ struct ssp_device *ssp = dev->ssp;
+ u32 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SCR;
+
+ __raw_writel(sscr0 | SSCR0_SerClkDiv(div), ssp->mmio_base + SSCR0);
+}
+
/*
* Set the SSP ports SYSCLK.
*/
static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
{
- int port = cpu_dai->id + 1;
- u32 sscr0 = SSCR0_P(port) &
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ int val;
+
+ u32 sscr0 = __raw_readl(mmio_base + SSCR0) &
~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
- dbg("pxa2xx_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d",
+ pr_debug("pxa2xx_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d",
cpu_dai->id, clk_id, freq);
switch (clk_id) {
@@ -245,11 +250,10 @@ static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
sscr0 |= SSCR0_MOD;
case PXA2XX_SSP_CLK_PLL:
/* Internal PLL is fixed on pxa25x and pxa27x */
-#ifdef CONFIG_PXA27x
- ssp_clk[cpu_dai->id].sysclk = 13000000;
-#else
- ssp_clk[cpu_dai->id].sysclk = 1843200;
-#endif
+ if (cpu_is_pxa25x())
+ ssp_clk[cpu_dai->id].sysclk = 1843200;
+ else
+ ssp_clk[cpu_dai->id].sysclk = 13000000;
break;
case PXA2XX_SSP_CLK_EXT:
ssp_clk[cpu_dai->id].sysclk = freq;
@@ -261,7 +265,7 @@ static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
break;
case PXA2XX_SSP_CLK_AUDIO:
ssp_clk[cpu_dai->id].sysclk = 0;
- SSCR0_P(port) |= SSCR0_SerClkDiv(1);
+ ssp_set_scr(&ssp[cpu_dai->id], 1);
sscr0 |= SSCR0_ADC;
break;
default:
@@ -269,9 +273,10 @@ static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
}
/* the SSP CKEN clock must be disabled when changing SSP clock mode */
- pxa_set_cken(cken[cpu_dai->id], 0);
- SSCR0_P(port) |= sscr0;
- pxa_set_cken(cken[cpu_dai->id], 1);
+ clk_disable(ssp[cpu_dai->id].ssp->clk);
+ val = __raw_readl(mmio_base + SSCR0) | sscr0;
+ __raw_writel(val, mmio_base + SSCR0);
+ clk_enable(ssp[cpu_dai->id].ssp->clk);
return 0;
}
@@ -281,21 +286,22 @@ static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
static int pxa2xx_ssp_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
int div_id, int div)
{
- int port = cpu_dai->id + 1;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ int val;
switch (div_id) {
case PXA2XX_SSP_AUDIO_DIV_ACDS:
- SSACD_P(port) &= ~ 0x7;
- SSACD_P(port) |= SSACD_ACDS(div);
+ val = (__raw_readl(mmio_base + SSACD) & ~0x7) | SSACD_ACDS(div);
+ __raw_writel(val, mmio_base + SSACD);
break;
case PXA2XX_SSP_AUDIO_DIV_SCDB:
- SSACD_P(port) &= ~0x8;
+ val = __raw_readl(mmio_base + SSACD) & ~0x8;
if (div == PXA2XX_SSP_CLK_SCDB_1)
- SSACD_P(port) |= SSACD_SCDB;
+ val |= SSACD_SCDB;
+ __raw_writel(val, mmio_base + SSACD);
break;
case PXA2XX_SSP_DIV_SCR:
- SSCR0_P(port) &= ~SSCR0_SCR;
- SSCR0_P(port) |= SSCR0_SerClkDiv(div);
+ ssp_set_scr(&ssp[cpu_dai->id], div);
break;
default:
return -ENODEV;
@@ -310,28 +316,30 @@ static int pxa2xx_ssp_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
static int pxa2xx_ssp_set_dai_pll(struct snd_soc_cpu_dai *cpu_dai,
int pll_id, unsigned int freq_in, unsigned int freq_out)
{
- int port = cpu_dai->id + 1;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ u32 ssacd;
- SSACD_P(port) &= ~0x70;
+ ssacd = __raw_readl(mmio_base + SSACD) & ~0x70;
switch (freq_out) {
case 5622000:
break;
case 11345000:
- SSACD_P(port) |= (0x1 << 4);
+ ssacd |= (0x1 << 4);
break;
case 12235000:
- SSACD_P(port) |= (0x2 << 4);
+ ssacd |= (0x2 << 4);
break;
case 14857000:
- SSACD_P(port) |= (0x3 << 4);
+ ssacd |= (0x3 << 4);
break;
case 32842000:
- SSACD_P(port) |= (0x4 << 4);
+ ssacd |= (0x4 << 4);
break;
case 48000000:
- SSACD_P(port) |= (0x5 << 4);
+ ssacd |= (0x5 << 4);
break;
}
+ __raw_writel(ssacd, mmio_base + SSACD);
return 0;
}
@@ -341,16 +349,18 @@ static int pxa2xx_ssp_set_dai_pll(struct snd_soc_cpu_dai *cpu_dai,
static int pxa2xx_ssp_set_dai_tdm_slot(struct snd_soc_cpu_dai *cpu_dai,
unsigned int mask, int slots)
{
- int port = cpu_dai->id + 1;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ u32 sscr0;
- SSCR0_P(port) &= ~SSCR0_SlotsPerFrm(7);
+ sscr0 = __raw_readl(mmio_base + SSCR0) & ~SSCR0_SlotsPerFrm(7);
/* set number of active slots */
- SSCR0_P(port) |= SSCR0_SlotsPerFrm(slots);
+ sscr0 |= SSCR0_SlotsPerFrm(slots);
+ __raw_writel(sscr0, mmio_base + SSCR0);
/* set active slot mask */
- SSTSA_P(port) = mask;
- SSRSA_P(port) = mask;
+ __raw_writel(mask, mmio_base + SSTSA);
+ __raw_writel(mask, mmio_base + SSRSA);
return 0;
}
@@ -360,12 +370,15 @@ static int pxa2xx_ssp_set_dai_tdm_slot(struct snd_soc_cpu_dai *cpu_dai,
static int pxa2xx_ssp_set_dai_tristate(struct snd_soc_cpu_dai *cpu_dai,
int tristate)
{
- int port = cpu_dai->id + 1;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ u32 sscr1;
+ sscr1 = __raw_readl(mmio_base + SSCR1);
if (tristate)
- SSCR1_P(port) &= ~SSCR1_TTE;
+ sscr1 &= ~SSCR1_TTE;
else
- SSCR1_P(port) |= SSCR1_TTE;
+ sscr1 |= SSCR1_TTE;
+ __raw_writel(sscr1, mmio_base + SSCR1);
return 0;
}
@@ -378,22 +391,20 @@ static int pxa2xx_ssp_set_dai_tristate(struct snd_soc_cpu_dai *cpu_dai,
static int pxa2xx_ssp_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
unsigned int fmt)
{
- int port = cpu_dai->id + 1;
-
- /* we can only change the settings if the port is not in use */
- if (SSCR0_P(port) & SSCR0_SSE)
- return 0;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ int val;
/* reset port settings */
- SSCR0_P(port) = 0;
- SSCR1_P(port) = 0;
- SSPSP_P(port) = 0;
+ __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) {
- SSCR0_P(port) = SSCR0_EDSS | SSCR0_TISSP | SSCR0_DataSize(16);
+ __raw_writel(SSCR0_EDSS | SSCR0_TISSP | SSCR0_DataSize(16),
+ mmio_base + SSCR0);
goto master;
}
@@ -402,42 +413,50 @@ static int pxa2xx_ssp_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
/* 8.4.11 */
/* Only SSCR0[NCS] or SSCR0[ECS] bit fields settings are optional */
- SSCR0_P(port) = SSCR0_EDSS | SSCR0_PSP | SSCR0_DataSize(16);
+ __raw_writel(SSCR0_EDSS | SSCR0_PSP | SSCR0_DataSize(16),
+ mmio_base + SSCR0);
/* set FIFO thresholds */
- SSCR1_P(port) = SSCR1_RxTresh(14) | SSCR1_TxTresh(1);
+ __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) */
- SSPSP_P(port) = SSPSP_FSRT | SSPSP_SFRMWDTH(16) | SSPSP_DMYSTRT(0);
+ __raw_writel(SSPSP_FSRT | SSPSP_SFRMWDTH(16) | SSPSP_DMYSTRT(0),
+ mmio_base + SSPSP);
goto master;
}
- SSCR0_P(port) |= SSCR0_PSP;
- SSCR1_P(port) = SSCR1_RxTresh(14) | SSCR1_TxTresh(1) |
- SSCR1_TRAIL | SSCR1_RWOT;
+ 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:
- switch(fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ val = __raw_readl(mmio_base + SSCR1);
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
- SSCR1_P(port) |= (SSCR1_SCLKDIR | SSCR1_SFRMDIR);
+ val |= (SSCR1_SCLKDIR | SSCR1_SFRMDIR);
break;
case SND_SOC_DAIFMT_CBM_CFS:
- SSCR1_P(port) |= SSCR1_SCLKDIR;
+ val |= SSCR1_SCLKDIR;
break;
case SND_SOC_DAIFMT_CBS_CFM:
- SSCR1_P(port) |= SSCR1_SFRMDIR;
+ val |= SSCR1_SFRMDIR;
break;
case SND_SOC_DAIFMT_CBS_CFS:
break;
default:
return -EINVAL;
}
+ __raw_writel(val, mmio_base + SSCR1);
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
- SSPSP_P(port) |= SSPSP_SFRMP | SSPSP_FSRT;
+ val = __raw_readl(mmio_base + SSPSP) | SSPSP_SFRMP | SSPSP_FSRT;
+ __raw_writel(val, mmio_base + SSPSP);
break;
case SND_SOC_DAIFMT_IB_IF:
break;
@@ -445,11 +464,12 @@ master:
return -EINVAL;
}
+ val = __raw_readl(mmio_base + SSPSP);
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A:
- SSPSP_P(port) |= SSPSP_DMYSTRT(1);
+ val |= SSPSP_DMYSTRT(1);
case SND_SOC_DAIFMT_DSP_B:
- SSPSP_P(port) |= SSPSP_SCMODE(2);
+ val |= SSPSP_SCMODE(2);
break;
case SND_SOC_DAIFMT_I2S:
case SND_SOC_DAIFMT_MSB:
@@ -458,6 +478,7 @@ master:
default:
return -EINVAL;
}
+ __raw_writel(val, mmio_base + SSPSP);
return 0;
}
@@ -472,7 +493,8 @@ static int pxa2xx_ssp_hw_params(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;
int dma = 0, chn = params_channels(params);
- int port = cpu_dai->id + 1;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ u32 sscr0;
/* select correct DMA params */
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
@@ -481,34 +503,37 @@ static int pxa2xx_ssp_hw_params(struct snd_pcm_substream *substream,
dma += 2; /* stereo DMA offset is 2, mono is 0 */
cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
- dbg("pxa2xx_ssp_hw_params: dma %d", dma);
+ pr_debug("pxa2xx_ssp_hw_params: dma %d", dma);
/* we can only change the settings if the port is not in use */
- if (SSCR0_P(port) & SSCR0_SSE)
+ if (__raw_readl(mmio_base + SSCR0) & SSCR0_SSE)
return 0;
/* clear selected SSP bits */
- SSCR0_P(port) &= ~(SSCR0_DSS | SSCR0_EDSS);
+ sscr0 = __raw_readl(mmio_base + SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+ __raw_writel(sscr0, mmio_base + SSCR0);
/* bit size */
- switch(params_format(params)) {
+ sscr0 = __raw_readl(mmio_base + SSCR0);
+ switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
- SSCR0_P(port) |= SSCR0_DataSize(16);
+ sscr0 |= SSCR0_DataSize(16);
break;
case SNDRV_PCM_FORMAT_S24_LE:
- SSCR0_P(port) |=(SSCR0_EDSS | SSCR0_DataSize(8));
+ sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
/* we must be in network mode (2 slots) for 24 bit stereo */
break;
case SNDRV_PCM_FORMAT_S32_LE:
- SSCR0_P(port) |= (SSCR0_EDSS | SSCR0_DataSize(16));
+ sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
/* we must be in network mode (2 slots) for 32 bit stereo */
break;
}
+ __raw_writel(sscr0, mmio_base + SSCR0);
- dbg("SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x",
- SSCR0_P(port), SSCR1_P(port),
- SSTO_P(port), SSPSP_P(port),
- SSSR_P(port), SSACD_P(port));
+ 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),
+ __raw_readl(mmio_base + SSSR), __raw_readl(mmio_base + SSACD));
return 0;
}
@@ -518,50 +543,61 @@ 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;
int ret = 0;
- int port = cpu_dai->id + 1;
+ void __iomem *mmio_base = ssp[cpu_dai->id].ssp->mmio_base;
+ int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
ssp_enable(&ssp[cpu_dai->id]);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ val = __raw_readl(mmio_base + SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- SSCR1_P(port) |= SSCR1_TSRE;
+ val |= SSCR1_TSRE;
else
- SSCR1_P(port) |= SSCR1_RSRE;
- SSSR_P(port) |= SSSR_P(port);
+ val |= SSCR1_RSRE;
+ __raw_writel(val, mmio_base + SSCR1);
+ /* SSSR_P(port) |= SSSR_P(port); */
+ val = __raw_readl(mmio_base + SSSR);
+ __raw_writel(val, mmio_base + SSSR);
break;
case SNDRV_PCM_TRIGGER_START:
+ val = __raw_readl(mmio_base + SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- SSCR1_P(port) |= SSCR1_TSRE;
+ val |= SSCR1_TSRE;
else
- SSCR1_P(port) |= SSCR1_RSRE;
+ val |= SSCR1_RSRE;
+ __raw_writel(val, mmio_base + SSCR1);
ssp_enable(&ssp[cpu_dai->id]);
break;
case SNDRV_PCM_TRIGGER_STOP:
+ val = __raw_readl(mmio_base + SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- SSCR1_P(port) &= ~SSCR1_TSRE;
+ val &= ~SSCR1_TSRE;
else
- SSCR1_P(port) &= ~SSCR1_RSRE;
+ val &= ~SSCR1_RSRE;
+ __raw_writel(val, mmio_base + SSCR1);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
ssp_disable(&ssp[cpu_dai->id]);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ val = __raw_readl(mmio_base + SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- SSCR1_P(port) &= ~SSCR1_TSRE;
+ val &= ~SSCR1_TSRE;
else
- SSCR1_P(port) &= ~SSCR1_RSRE;
+ val &= ~SSCR1_RSRE;
+ __raw_writel(val, mmio_base + SSCR1);
break;
default:
ret = -EINVAL;
}
- dbg("SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x SSPSP 0x%08x SSSR 0x%08x",
- SSCR0_P(port), SSCR1_P(port),
- SSTO_P(port), SSPSP_P(port),
- SSSR_P(port));
+ pr_debug("SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x SSPSP 0x%08x SSSR 0x%08x",
+ __raw_readl(mmio_base + SSCR0), __raw_readl(mmio_base + SSCR1),
+ __raw_readl(mmio_base + SSTO), __raw_readl(mmio_base + SSPSP),
+ __raw_readl(mmio_base + SSSR));
return ret;
}
--
1.5.5.1
More information about the Alsa-devel
mailing list