Alsa-devel
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
March 2010
- 110 participants
- 233 discussions
Since basic SSP features are shared between PXA2xx and PXA168, the difference
is focused on clock generating. Now split ssp code into two parts. One is for
general ssp feature. The other is for pxa2xx parts.
Update the SSP timing configuration in hw_params(). The SSP timing is verified
on I2S and Left J interface of PXA168 with 16-bit sample stream.
Signed-off-by: Haojian Zhuang <haojian.zhuang(a)marvell.com>
---
sound/soc/pxa/Kconfig | 8 +-
sound/soc/pxa/Makefile | 4 +-
sound/soc/pxa/magician.c | 38 ++--
sound/soc/pxa/pxa-ssp.c | 728 +++++++++++---------------------------------
sound/soc/pxa/pxa-ssp.h | 52 ++--
sound/soc/pxa/pxa2xx-ssp.c | 318 +++++++++++++++++++
sound/soc/pxa/pxa2xx-ssp.h | 48 +++
sound/soc/pxa/raumfeld.c | 14 +-
sound/soc/pxa/zylonite.c | 6 +-
9 files changed, 603 insertions(+), 613 deletions(-)
create mode 100644 sound/soc/pxa/pxa2xx-ssp.c
create mode 100644 sound/soc/pxa/pxa2xx-ssp.h
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 78e6121..7be1d5f 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -21,7 +21,7 @@ config SND_PXA2XX_SOC_AC97
config SND_PXA2XX_SOC_I2S
tristate
-config SND_PXA_SOC_SSP
+config SND_PXA2XX_SOC_SSP
tristate
select PXA_SSP
@@ -113,7 +113,7 @@ config SND_SOC_ZYLONITE
tristate "SoC Audio support for Marvell Zylonite"
depends on SND_PXA2XX_SOC && MACH_ZYLONITE
select SND_PXA2XX_SOC_AC97
- select SND_PXA_SOC_SSP
+ select SND_PXA2XX_SOC_SSP
select SND_SOC_WM9713
help
Say Y if you want to add support for SoC audio on the
@@ -122,7 +122,7 @@ config SND_SOC_ZYLONITE
config SND_SOC_RAUMFELD
tristate "SoC Audio support Raumfeld audio adapter"
depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER ||
MACH_RAUMFELD_CONNECTOR)
- select SND_PXA_SOC_SSP
+ select SND_PXA2XX_SOC_SSP
select SND_SOC_CS4270
select SND_SOC_AK4104
help
@@ -132,7 +132,7 @@ config SND_PXA2XX_SOC_MAGICIAN
tristate "SoC Audio support for HTC Magician"
depends on SND_PXA2XX_SOC && MACH_MAGICIAN
select SND_PXA2XX_SOC_I2S
- select SND_PXA_SOC_SSP
+ select SND_PXA2XX_SOC_SSP
select SND_SOC_UDA1380
help
Say Y if you want to add support for SoC audio on the
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index f3e08fd..33c1579 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -2,12 +2,12 @@
snd-soc-pxa2xx-objs := pxa2xx-pcm.o
snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
-snd-soc-pxa-ssp-objs := pxa-ssp.o
+snd-soc-pxa2xx-ssp-objs := pxa-ssp.o pxa2xx-ssp.o
obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
-obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
+obj-$(CONFIG_SND_PXA2XX_SOC_SSP) += snd-soc-pxa2xx-ssp.o
# PXA Machine Support
snd-soc-corgi-objs := corgi.o
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 4c8d99a..da6ff83 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -34,7 +34,7 @@
#include "../codecs/uda1380.h"
#include "pxa2xx-pcm.h"
#include "pxa2xx-i2s.h"
-#include "pxa-ssp.h"
+#include "pxa2xx-ssp.h"
#define MAGICIAN_MIC 0
#define MAGICIAN_MIC_EXT 1
@@ -89,7 +89,7 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
unsigned int acps, acds, width, rate;
- unsigned int div4 = PXA_SSP_CLK_SCDB_4;
+ unsigned int div4 = PXA2XX_SSP_CLK_SCDB_4;
int ret = 0;
rate = params_rate(params);
@@ -106,11 +106,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_16;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_16;
break;
default: /* 32 */
/* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_8;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_8;
}
break;
case 11025:
@@ -118,11 +118,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_4;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_4;
break;
default: /* 32 */
/* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
}
break;
case 22050:
@@ -130,11 +130,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
break;
default: /* 32 */
/* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
}
break;
case 44100:
@@ -142,11 +142,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
break;
default: /* 32 */
/* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
}
break;
case 48000:
@@ -154,11 +154,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
break;
default: /* 32 */
/* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
}
break;
case 96000:
@@ -167,12 +167,12 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
break;
default: /* 32 */
/* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- div4 = PXA_SSP_CLK_SCDB_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
+ div4 = PXA2XX_SSP_CLK_SCDB_1;
break;
}
break;
@@ -195,20 +195,20 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
return ret;
/* set audio clock as clock source */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0,
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_AUDIO, 0,
SND_SOC_CLOCK_OUT);
if (ret < 0)
return ret;
/* set the SSP audio system clock ACDS divider */
ret = snd_soc_dai_set_clkdiv(cpu_dai,
- PXA_SSP_AUDIO_DIV_ACDS, acds);
+ PXA2XX_SSP_AUDIO_DIV_ACDS, acds);
if (ret < 0)
return ret;
/* set the SSP audio system clock SCDB divider4 */
ret = snd_soc_dai_set_clkdiv(cpu_dai,
- PXA_SSP_AUDIO_DIV_SCDB, div4);
+ PXA2XX_SSP_AUDIO_DIV_SCDB, div4);
if (ret < 0)
return ret;
@@ -427,7 +427,7 @@ static struct snd_soc_dai_link magician_dai[] = {
{
.name = "uda1380",
.stream_name = "UDA1380 Playback",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP1],
.codec_dai = &uda1380_dai[UDA1380_DAI_PLAYBACK],
.init = magician_uda1380_init,
.ops = &magician_playback_ops,
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index ed54bef..bd5e800 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -5,6 +5,9 @@
* Author: Liam Girdwood
* Mark Brown <broonie(a)opensource.wolfsonmicro.com>
*
+ * Copyright 2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang(a)marvell.com>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -14,44 +17,20 @@
* o Test network mode for > 16bit sample size
*/
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-
#include <sound/core.h>
+#include <sound/soc.h>
#include <sound/pcm.h>
-#include <sound/initval.h>
#include <sound/pcm_params.h>
-#include <sound/soc.h>
#include <sound/pxa2xx-lib.h>
#include <mach/hardware.h>
#include <mach/dma.h>
-#include <mach/audio.h>
#include <plat/ssp.h>
#include "pxa2xx-pcm.h"
#include "pxa-ssp.h"
-/*
- * SSP audio private data
- */
-struct ssp_priv {
- struct ssp_device *ssp;
- unsigned int sysclk;
- int dai_fmt;
-#ifdef CONFIG_PM
- uint32_t cr0;
- uint32_t cr1;
- uint32_t to;
- uint32_t psp;
-#endif
-};
-
static void dump_registers(struct ssp_device *ssp)
{
dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
@@ -63,7 +42,7 @@ static void dump_registers(struct ssp_device *ssp)
pxa_ssp_read_reg(ssp, SSACD));
}
-static void pxa_ssp_enable(struct ssp_device *ssp)
+void pxa_ssp_enable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -71,7 +50,7 @@ static void pxa_ssp_enable(struct ssp_device *ssp)
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}
-static void pxa_ssp_disable(struct ssp_device *ssp)
+void pxa_ssp_disable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -84,7 +63,7 @@ struct pxa2xx_pcm_dma_data {
char name[20];
};
-static struct pxa2xx_pcm_dma_params *
+struct pxa2xx_pcm_dma_params *
pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
{
struct pxa2xx_pcm_dma_data *dma;
@@ -105,6 +84,102 @@ pxa_ssp_get_dma_params(struct ssp_device *ssp,
int width4, int out)
return &dma->params;
}
+EXPORT_SYMBOL_GPL(pxa_ssp_get_dma_params);
+
+/*
+ * Set up the SSP DAI format.
+ * The SSP Port must be inactive before calling this function as the
+ * physical interface format is changed.
+ */
+static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ u32 sscr0;
+ u32 sscr1;
+ u32 sspsp;
+
+ /* check if we need to change anything at all */
+ if (priv->dai_fmt == fmt)
+ return 0;
+
+ pxa_ssp_disable(ssp);
+
+ /* reset port settings */
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
+ (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
+ sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
+ sspsp = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ sscr1 |= SSCR1_SCLKDIR;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ sspsp |= SSPSP_SFRMP;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ sspsp |= SSPSP_SCMODE(2);
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ 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_LEFT_J:
+ 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:
+ sscr0 |= SSCR0_MOD | SSCR0_PSP;
+ sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_enable(ssp);
+
+ /* Since we are configuring the timings for the format by hand
+ * we have to defer some things until hw_params() where we
+ * know parameters like the sample size.
+ */
+ priv->dai_fmt = fmt;
+
+ dump_registers(ssp);
+
+ return 0;
+}
static int pxa_ssp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
@@ -193,212 +268,88 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
#define pxa_ssp_resume NULL
#endif
-/**
- * ssp_set_clkdiv - set SSP clock divider
- * @div: serial clock rate divider
- */
-static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
-{
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
-
- if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
- sscr0 &= ~0x0000ff00;
- sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
- } else {
- sscr0 &= ~0x000fff00;
- sscr0 |= (div - 1) << 8; /* 1..4096 */
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-}
-
-/**
- * pxa_ssp_get_clkdiv - get SSP clock divider
- */
-static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
-{
- u32 sscr0 = pxa_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.
+ * While configuring SSP timing, two formula on SSP clocks should be followed.
+ *
+ * 1) (frame delay + frame width) <= (start delay + dummy start
+ * + data size + dummy stop)
+ *
+ * 2) 1 <= frame width < (dummy start + data size + dummy stop)
*/
-static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
+static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct ssp_priv *priv = cpu_dai->private_data;
struct ssp_device *ssp = priv->ssp;
- int val;
+ int width = snd_pcm_format_physical_width(params_format(params));
+ int channels = params_channels(params);
+ int dma_32b = 0, stream_out = 0, data_size;
+ u32 sscr0, sspsp;
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
- ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
+ /* generate correct DMA params */
+ kfree(cpu_dai->dma_data);
- dev_dbg(&ssp->pdev->dev,
- "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
- cpu_dai->id, clk_id, freq);
+ if ((width == 32) || (channels == 1))
+ dma_32b = 1;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ stream_out = 1;
+ cpu_dai->dma_data = pxa_ssp_get_dma_params(ssp, dma_32b, stream_out);
- switch (clk_id) {
- case PXA_SSP_CLK_NET_PLL:
- sscr0 |= SSCR0_MOD;
- break;
- case PXA_SSP_CLK_PLL:
- /* Internal PLL is fixed */
- if (cpu_is_pxa25x())
- priv->sysclk = 1843200;
- else
- priv->sysclk = 13000000;
- break;
- case PXA_SSP_CLK_EXT:
- priv->sysclk = freq;
- sscr0 |= SSCR0_ECS;
- break;
- case PXA_SSP_CLK_NET:
- priv->sysclk = freq;
- sscr0 |= SSCR0_NCS | SSCR0_MOD;
+ /* clear selected SSP bits */
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+
+ /* data_size should only be 16-bit or 32-bit because of DMA.
+ * 24-bit data is treated as 32-bit data.
+ */
+ data_size = width * channels;
+ switch (data_size) {
+ case 16:
+ sscr0 |= SSCR0_DataSize(16);
break;
- case PXA_SSP_CLK_AUDIO:
- priv->sysclk = 0;
- pxa_ssp_set_scr(ssp, 1);
- sscr0 |= SSCR0_ACS;
+ case 32:
+ sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
break;
default:
- return -ENODEV;
+ dev_err(&ssp->pdev->dev, "Invalid data size:%d\n", data_size);
+ return -EINVAL;
}
- /* The SSP clock must be disabled when changing SSP clock mode
- * on PXA2xx. On PXA3xx it must be enabled when doing so. */
- if (!cpu_is_pxa3xx())
- clk_disable(ssp->clk);
- val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
- pxa_ssp_write_reg(ssp, SSCR0, val);
- if (!cpu_is_pxa3xx())
- clk_enable(ssp->clk);
-
- return 0;
-}
-
-/*
- * Set the SSP clock dividers.
- */
-static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- int val;
-
- switch (div_id) {
- case PXA_SSP_AUDIO_DIV_ACDS:
- val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
- pxa_ssp_write_reg(ssp, SSACD, val);
- break;
- case PXA_SSP_AUDIO_DIV_SCDB:
- val = pxa_ssp_read_reg(ssp, SSACD);
- val &= ~SSACD_SCDB;
-#if defined(CONFIG_PXA3xx)
- if (cpu_is_pxa3xx())
- val &= ~SSACD_SCDX8;
-#endif
- switch (div) {
- case PXA_SSP_CLK_SCDB_1:
- val |= SSACD_SCDB;
- break;
- case PXA_SSP_CLK_SCDB_4:
- break;
-#if defined(CONFIG_PXA3xx)
- case PXA_SSP_CLK_SCDB_8:
- if (cpu_is_pxa3xx())
- val |= SSACD_SCDX8;
- else
- return -EINVAL;
- break;
-#endif
- default:
- return -EINVAL;
+ pxa_ssp_disable(ssp);
+ sspsp = pxa_ssp_read_reg(ssp, SSPSP);
+ sspsp &= ~SSPSP_TIMING_MASK;
+ switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ if (channels == 1) {
+ sspsp |= SSPSP_DMYSTRT(1);
+ sspsp |= SSPSP_EDMYSTOP(((width - 1) >> 2) & 7);
+ sspsp |= SSPSP_DMYSTOP((width - 1) & 3);
+ sspsp |= SSPSP_SFRMDLY(width << 1);
+ sspsp |= SSPSP_SFRMWDTH(width);
+ } else {
+ /* channels == 2 */
+ sspsp |= SSPSP_SFRMWDTH(width);
+ /* Don't set any timing while FSRT is set */
+ sspsp |= SSPSP_FSRT;
}
- pxa_ssp_write_reg(ssp, SSACD, val);
break;
- case PXA_SSP_DIV_SCR:
- pxa_ssp_set_scr(ssp, div);
+ case SND_SOC_DAIFMT_LEFT_J:
+ if (channels == 1) {
+ sspsp |= SSPSP_EDMYSTOP((width >> 2) & 7);
+ sspsp |= SSPSP_DMYSTOP(width & 3);
+ }
+ sspsp |= SSPSP_SFRMWDTH(width);
break;
- default:
- return -ENODEV;
}
- return 0;
-}
-
-/*
- * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
- */
-static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
-
-#if defined(CONFIG_PXA3xx)
- if (cpu_is_pxa3xx())
- pxa_ssp_write_reg(ssp, SSACDD, 0);
-#endif
-
- switch (freq_out) {
- case 5622000:
- break;
- case 11345000:
- ssacd |= (0x1 << 4);
- break;
- case 12235000:
- ssacd |= (0x2 << 4);
- break;
- case 14857000:
- ssacd |= (0x3 << 4);
- break;
- case 32842000:
- ssacd |= (0x4 << 4);
- break;
- case 48000000:
- ssacd |= (0x5 << 4);
- break;
- case 0:
- /* Disable */
- break;
-
- default:
-#ifdef CONFIG_PXA3xx
- /* PXA3xx has a clock ditherer which can be used to generate
- * a wider range of frequencies - calculate a value for it.
- */
- if (cpu_is_pxa3xx()) {
- u32 val;
- u64 tmp = 19968;
- tmp *= 1000000;
- do_div(tmp, freq_out);
- val = tmp;
-
- val = (val << 16) | 64;
- pxa_ssp_write_reg(ssp, SSACDD, val);
-
- ssacd |= (0x6 << 4);
-
- dev_dbg(&ssp->pdev->dev,
- "Using SSACDD %x to supply %uHz\n",
- val, freq_out);
- break;
- }
-#endif
-
- return -EINVAL;
- }
+ /* update SSP register at the same time */
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_enable(ssp);
- pxa_ssp_write_reg(ssp, SSACD, ssacd);
+ dump_registers(ssp);
return 0;
}
@@ -458,213 +409,6 @@ static int pxa_ssp_set_dai_tristate(struct
snd_soc_dai *cpu_dai,
return 0;
}
-/*
- * Set up the SSP DAI format.
- * The SSP Port must be inactive before calling this function as the
- * physical interface format is changed.
- */
-static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- u32 sscr0;
- u32 sscr1;
- u32 sspsp;
-
- /* check if we need to change anything at all */
- if (priv->dai_fmt == fmt)
- return 0;
-
- /* we can only change the settings if the port is not in use */
- if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
- dev_err(&ssp->pdev->dev,
- "can't change hardware dai format: stream is in use");
- return -EINVAL;
- }
-
- /* reset port settings */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
- (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
- sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
- sspsp = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- sscr1 |= SSCR1_SCLKDIR;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- sspsp |= SSPSP_SFRMP;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- sspsp |= SSPSP_SCMODE(2);
- break;
- case SND_SOC_DAIFMT_IB_NF:
- sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
- break;
- default:
- return -EINVAL;
- }
-
- 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:
- sscr0 |= SSCR0_MOD | SSCR0_PSP;
- sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
- break;
-
- default:
- return -EINVAL;
- }
-
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
- pxa_ssp_write_reg(ssp, SSCR1, sscr1);
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
-
- dump_registers(ssp);
-
- /* Since we are configuring the timings for the format by hand
- * we have to defer some things until hw_params() where we
- * know parameters like the sample size.
- */
- priv->dai_fmt = fmt;
-
- return 0;
-}
-
-/*
- * Set the SSP audio DMA parameters and sample size.
- * Can be called multiple times by oss emulation.
- */
-static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- int chn = params_channels(params);
- u32 sscr0;
- u32 sspsp;
- int width = snd_pcm_format_physical_width(params_format(params));
- int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
-
- /* 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 = pxa_ssp_get_dma_params(ssp,
- ((chn == 2) && (ttsa != 1)) || (width == 32),
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-
- /* we can only change the settings if the port is not in use */
- if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
- return 0;
-
- /* clear selected SSP bits */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-
- /* bit size */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
-#ifdef CONFIG_PXA3xx
- if (cpu_is_pxa3xx())
- sscr0 |= SSCR0_FPCKE;
-#endif
- sscr0 |= SSCR0_DataSize(16);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
- break;
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-
- switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- sspsp = pxa_ssp_read_reg(ssp, SSPSP);
-
- if ((pxa_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);
- }
-
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
- break;
- default:
- break;
- }
-
- /* When we use a network mode, we always require TDM slots
- * - complain loudly and fail if they've not been set up yet.
- */
- if ((sscr0 & SSCR0_MOD) && !ttsa) {
- dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
- return -EINVAL;
- }
-
- dump_registers(ssp);
-
- return 0;
-}
-
static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
@@ -760,128 +504,22 @@ static void pxa_ssp_remove(struct platform_device *pdev,
pxa_ssp_free(priv->ssp);
}
-#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
- .startup = pxa_ssp_startup,
- .shutdown = pxa_ssp_shutdown,
- .trigger = pxa_ssp_trigger,
- .hw_params = pxa_ssp_hw_params,
- .set_sysclk = pxa_ssp_set_dai_sysclk,
- .set_clkdiv = pxa_ssp_set_dai_clkdiv,
- .set_pll = pxa_ssp_set_dai_pll,
- .set_fmt = pxa_ssp_set_dai_fmt,
- .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
- .set_tristate = pxa_ssp_set_dai_tristate,
-};
-
-struct snd_soc_dai pxa_ssp_dai[] = {
- {
- .name = "pxa2xx-ssp1",
- .id = 0,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
- { .name = "pxa2xx-ssp2",
- .id = 1,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
- {
- .name = "pxa2xx-ssp3",
- .id = 2,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
- {
- .name = "pxa2xx-ssp4",
- .id = 3,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
-};
-EXPORT_SYMBOL_GPL(pxa_ssp_dai);
-
-static int __init pxa_ssp_init(void)
-{
- return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
-}
-module_init(pxa_ssp_init);
-
-static void __exit pxa_ssp_exit(void)
+int pxa_ssp_register_dai(struct snd_soc_dai *dai)
{
- snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
+ struct snd_soc_dai_ops *ops = dai->ops;
+
+ ops->startup = pxa_ssp_startup;
+ ops->shutdown = pxa_ssp_shutdown;
+ ops->trigger = pxa_ssp_trigger;
+ ops->hw_params = pxa_ssp_hw_params;
+ ops->set_fmt = pxa_ssp_set_dai_fmt;
+ ops->set_tdm_slot = pxa_ssp_set_dai_tdm_slot;
+ ops->set_tristate = pxa_ssp_set_dai_tristate;
+
+ dai->probe = pxa_ssp_probe;
+ dai->remove = pxa_ssp_remove;
+ dai->suspend = pxa_ssp_suspend;
+ dai->resume = pxa_ssp_resume;
+
+ return snd_soc_register_dai(dai);
}
-module_exit(pxa_ssp_exit);
-
-/* Module information */
-MODULE_AUTHOR("Mark Brown <broonie(a)opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
index 91deadd..af4a09b 100644
--- a/sound/soc/pxa/pxa-ssp.h
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -9,39 +9,25 @@
#ifndef _PXA_SSP_H
#define _PXA_SSP_H
-/* pxa DAI SSP IDs */
-#define PXA_DAI_SSP1 0
-#define PXA_DAI_SSP2 1
-#define PXA_DAI_SSP3 2
-#define PXA_DAI_SSP4 3
-
-/* SSP clock sources */
-#define PXA_SSP_CLK_PLL 0
-#define PXA_SSP_CLK_EXT 1
-#define PXA_SSP_CLK_NET 2
-#define PXA_SSP_CLK_AUDIO 3
-#define PXA_SSP_CLK_NET_PLL 4
-
-/* SSP audio dividers */
-#define PXA_SSP_AUDIO_DIV_ACDS 0
-#define PXA_SSP_AUDIO_DIV_SCDB 1
-#define PXA_SSP_DIV_SCR 2
-
-/* SSP ACDS audio dividers values */
-#define PXA_SSP_CLK_AUDIO_DIV_1 0
-#define PXA_SSP_CLK_AUDIO_DIV_2 1
-#define PXA_SSP_CLK_AUDIO_DIV_4 2
-#define PXA_SSP_CLK_AUDIO_DIV_8 3
-#define PXA_SSP_CLK_AUDIO_DIV_16 4
-#define PXA_SSP_CLK_AUDIO_DIV_32 5
-
-/* SSP divider bypass */
-#define PXA_SSP_CLK_SCDB_4 0
-#define PXA_SSP_CLK_SCDB_1 1
-#define PXA_SSP_CLK_SCDB_8 2
-
-#define PXA_SSP_PLL_OUT 0
+/*
+ * SSP audio data
+ */
+struct ssp_priv {
+ struct ssp_device *ssp;
+ unsigned int sysclk;
+ int dai_fmt;
+#ifdef CONFIG_PM
+ uint32_t cr0;
+ uint32_t cr1;
+ uint32_t to;
+ uint32_t psp;
+#endif
+};
-extern struct snd_soc_dai pxa_ssp_dai[4];
+extern void pxa_ssp_enable(struct ssp_device *ssp);
+extern void pxa_ssp_disable(struct ssp_device *ssp);
+extern struct pxa2xx_pcm_dma_params *
+pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out);
+extern int pxa_ssp_register_dai(struct snd_soc_dai *dai);
#endif
diff --git a/sound/soc/pxa/pxa2xx-ssp.c b/sound/soc/pxa/pxa2xx-ssp.c
new file mode 100644
index 0000000..eff5334
--- /dev/null
+++ b/sound/soc/pxa/pxa2xx-ssp.c
@@ -0,0 +1,318 @@
+/*
+ * pxa2xx-ssp.c -- ALSA Soc Audio Layer
+ *
+ * Copyright 2005,2008 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ * Mark Brown <broonie(a)opensource.wolfsonmicro.com>
+ *
+ * Copyright 2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang(a)marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * TODO:
+ * o Test network mode for > 16bit sample size
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/pxa2xx-lib.h>
+
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <plat/ssp.h>
+
+#include "pxa2xx-pcm.h"
+#include "pxa2xx-ssp.h"
+#include "pxa-ssp.h"
+
+/**
+ * pxa_ssp_set_clkdiv - set SSP clock divider
+ * @div: serial clock rate divider
+ */
+static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
+{
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
+
+ if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
+ sscr0 &= ~0x0000ff00;
+ sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
+ } else {
+ sscr0 &= ~0x000fff00;
+ sscr0 |= (div - 1) << 8; /* 1..4096 */
+ }
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+}
+
+/**
+ * pxa_ssp_get_clkdiv - get SSP clock divider
+ */
+static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
+{
+ u32 sscr0 = pxa_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.
+ */
+static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ int val;
+
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
+ ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
+
+ dev_dbg(&ssp->pdev->dev,
+ "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
+ cpu_dai->id, clk_id, freq);
+
+ switch (clk_id) {
+ case PXA2XX_SSP_CLK_NET_PLL:
+ sscr0 |= SSCR0_MOD;
+ break;
+ case PXA2XX_SSP_CLK_PLL:
+ /* Internal PLL is fixed */
+ if (cpu_is_pxa25x())
+ priv->sysclk = 1843200;
+ else
+ priv->sysclk = 13000000;
+ break;
+ case PXA2XX_SSP_CLK_EXT:
+ priv->sysclk = freq;
+ sscr0 |= SSCR0_ECS;
+ break;
+ case PXA2XX_SSP_CLK_NET:
+ priv->sysclk = freq;
+ sscr0 |= SSCR0_NCS | SSCR0_MOD;
+ break;
+ case PXA2XX_SSP_CLK_AUDIO:
+ priv->sysclk = 0;
+ pxa_ssp_set_scr(ssp, 1);
+ sscr0 |= SSCR0_ACS;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ /* The SSP clock must be disabled when changing SSP clock mode
+ * on PXA2xx. On PXA3xx it must be enabled when doing so. */
+ if (!cpu_is_pxa3xx())
+ clk_disable(ssp->clk);
+ val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
+ pxa_ssp_write_reg(ssp, SSCR0, val);
+ if (!cpu_is_pxa3xx())
+ clk_enable(ssp->clk);
+
+ return 0;
+}
+
+/*
+ * Set the SSP clock dividers.
+ */
+static int pxa2xx_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
+ int div_id, int div)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ int val;
+
+ switch (div_id) {
+ case PXA2XX_SSP_AUDIO_DIV_ACDS:
+ val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+ pxa_ssp_write_reg(ssp, SSACD, val);
+ break;
+ case PXA2XX_SSP_AUDIO_DIV_SCDB:
+ val = pxa_ssp_read_reg(ssp, SSACD);
+ val &= ~SSACD_SCDB;
+#if defined(CONFIG_PXA3xx)
+ if (cpu_is_pxa3xx())
+ val &= ~SSACD_SCDX8;
+#endif
+ switch (div) {
+ case PXA2XX_SSP_CLK_SCDB_1:
+ val |= SSACD_SCDB;
+ break;
+ case PXA2XX_SSP_CLK_SCDB_4:
+ break;
+#if defined(CONFIG_PXA3xx)
+ case PXA2XX_SSP_CLK_SCDB_8:
+ if (cpu_is_pxa3xx())
+ val |= SSACD_SCDX8;
+ else
+ return -EINVAL;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+ pxa_ssp_write_reg(ssp, SSACD, val);
+ break;
+ case PXA2XX_SSP_DIV_SCR:
+ pxa_ssp_set_scr(ssp, div);
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/*
+ * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
+ */
+static int pxa2xx_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
+ int source, unsigned int freq_in,
+ unsigned int freq_out)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
+
+#if defined(CONFIG_PXA3xx)
+ if (cpu_is_pxa3xx())
+ pxa_ssp_write_reg(ssp, SSACDD, 0);
+#endif
+
+ switch (freq_out) {
+ case 5622000:
+ break;
+ case 11345000:
+ ssacd |= (0x1 << 4);
+ break;
+ case 12235000:
+ ssacd |= (0x2 << 4);
+ break;
+ case 14857000:
+ ssacd |= (0x3 << 4);
+ break;
+ case 32842000:
+ ssacd |= (0x4 << 4);
+ break;
+ case 48000000:
+ ssacd |= (0x5 << 4);
+ break;
+ case 0:
+ /* Disable */
+ break;
+
+ default:
+#ifdef CONFIG_PXA3xx
+ /* PXA3xx has a clock ditherer which can be used to generate
+ * a wider range of frequencies - calculate a value for it.
+ */
+ if (cpu_is_pxa3xx()) {
+ u32 val;
+ u64 tmp = 19968;
+ tmp *= 1000000;
+ do_div(tmp, freq_out);
+ val = tmp;
+
+ val = (val << 16) | 64;
+ pxa_ssp_write_reg(ssp, SSACDD, val);
+
+ ssacd |= (0x6 << 4);
+
+ dev_dbg(&ssp->pdev->dev,
+ "Using SSACDD %x to supply %uHz\n",
+ val, freq_out);
+ break;
+ }
+#endif
+
+ return -EINVAL;
+ }
+
+ pxa_ssp_write_reg(ssp, SSACD, ssacd);
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops pxa2xx_ssp_dai_ops = {
+ .set_sysclk = pxa2xx_ssp_set_dai_sysclk,
+ .set_clkdiv = pxa2xx_ssp_set_dai_clkdiv,
+ .set_pll = pxa2xx_ssp_set_dai_pll,
+};
+
+#define PXA2XX_SSP_RATES SNDRV_PCM_RATE_8000_96000
+#define PXA2XX_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+#define PXA2XX_SSP_DAI(_id) \
+{ \
+ .name = "pxa2xx-ssp", \
+ .id = _id, \
+ .playback = { \
+ .channels_min = 1, \
+ .channels_max = 8, \
+ .rates = PXA2XX_SSP_RATES, \
+ .formats = PXA2XX_SSP_FORMATS, \
+ }, \
+ .capture = { \
+ .channels_min = 1, \
+ .channels_max = 8, \
+ .rates = PXA2XX_SSP_RATES, \
+ .formats = PXA2XX_SSP_FORMATS, \
+ }, \
+ .ops = &pxa2xx_ssp_dai_ops, \
+}
+
+struct snd_soc_dai pxa2xx_ssp_dai[] = {
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP1),
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP2),
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP3),
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP4),
+};
+EXPORT_SYMBOL_GPL(pxa2xx_ssp_dai);
+
+static int __init pxa2xx_ssp_init(void)
+{
+ struct snd_soc_dai *dai;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(pxa2xx_ssp_dai); i++) {
+ dai = &pxa2xx_ssp_dai[i];
+ ret = pxa_ssp_register_dai(dai);
+ if (ret)
+ return ret;
+ }
+ return ret;
+}
+module_init(pxa2xx_ssp_init);
+
+static void __exit pxa2xx_ssp_exit(void)
+{
+ struct snd_soc_dai *dai = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pxa2xx_ssp_dai); i++) {
+ dai = &pxa2xx_ssp_dai[i];
+ snd_soc_unregister_dai(dai);
+ }
+}
+module_exit(pxa2xx_ssp_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie(a)opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("PXA2xx SSP/PCM SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-ssp.h b/sound/soc/pxa/pxa2xx-ssp.h
new file mode 100644
index 0000000..c24e0b5
--- /dev/null
+++ b/sound/soc/pxa/pxa2xx-ssp.h
@@ -0,0 +1,48 @@
+
+/*
+ * ASoC PXA SSP port support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PXA2XX_SOC_SSP_H
+#define __PXA2XX_SOC_SSP_H
+
+/* pxa DAI SSP IDs */
+#define PXA2XX_DAI_SSP1 0
+#define PXA2XX_DAI_SSP2 1
+#define PXA2XX_DAI_SSP3 2
+#define PXA2XX_DAI_SSP4 3
+
+/* SSP clock sources */
+#define PXA2XX_SSP_CLK_PLL 0
+#define PXA2XX_SSP_CLK_EXT 1
+#define PXA2XX_SSP_CLK_NET 2
+#define PXA2XX_SSP_CLK_AUDIO 3
+#define PXA2XX_SSP_CLK_NET_PLL 4
+
+/* SSP audio dividers */
+#define PXA2XX_SSP_AUDIO_DIV_ACDS 0
+#define PXA2XX_SSP_AUDIO_DIV_SCDB 1
+#define PXA2XX_SSP_DIV_SCR 2
+
+/* SSP ACDS audio dividers values */
+#define PXA2XX_SSP_CLK_AUDIO_DIV_1 0
+#define PXA2XX_SSP_CLK_AUDIO_DIV_2 1
+#define PXA2XX_SSP_CLK_AUDIO_DIV_4 2
+#define PXA2XX_SSP_CLK_AUDIO_DIV_8 3
+#define PXA2XX_SSP_CLK_AUDIO_DIV_16 4
+#define PXA2XX_SSP_CLK_AUDIO_DIV_32 5
+
+/* SSP divider bypass */
+#define PXA2XX_SSP_CLK_SCDB_4 0
+#define PXA2XX_SSP_CLK_SCDB_1 1
+#define PXA2XX_SSP_CLK_SCDB_8 2
+
+#define PXA2XX_SSP_PLL_OUT 0
+
+extern struct snd_soc_dai pxa2xx_ssp_dai[];
+
+#endif /* __PXA2XX_SOC_SSP_H */
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 7e3f416..e66dc12 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -29,7 +29,7 @@
#include "../codecs/cs4270.h"
#include "../codecs/ak4104.h"
#include "pxa2xx-pcm.h"
-#include "pxa-ssp.h"
+#include "pxa2xx-ssp.h"
#define GPIO_SPDIF_RESET (38)
#define GPIO_MCLK_RESET (111)
@@ -138,11 +138,11 @@ static int raumfeld_cs4270_hw_params(struct
snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA2XX_SSP_DIV_SCR, 4);
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_EXT, clk, 1);
if (ret < 0)
return ret;
@@ -170,7 +170,7 @@ static int raumfeld_line_resume(struct
platform_device *pdev)
static struct snd_soc_dai_link raumfeld_line_dai = {
.name = "CS4270",
.stream_name = "CS4270",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP1],
.codec_dai = &cs4270_dai,
.ops = &raumfeld_cs4270_ops,
};
@@ -232,11 +232,11 @@ static int raumfeld_ak4104_hw_params(struct
snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA2XX_SSP_DIV_SCR, 4);
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_EXT, clk, 1);
if (ret < 0)
return ret;
@@ -250,7 +250,7 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
static struct snd_soc_dai_link raumfeld_spdif_dai = {
.name = "ak4104",
.stream_name = "Playback",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP2],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP2],
.codec_dai = &ak4104_dai,
.ops = &raumfeld_ak4104_ops,
};
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index dd678ae..c65e0db 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -25,7 +25,7 @@
#include "../codecs/wm9713.h"
#include "pxa2xx-pcm.h"
#include "pxa2xx-ac97.h"
-#include "pxa-ssp.h"
+#include "pxa2xx-ssp.h"
/*
* There is a physical switch SW15 on the board which changes the MCLK
@@ -125,7 +125,7 @@ static int zylonite_voice_hw_params(struct
snd_pcm_substream *substream,
/* Add 1 to the width for the leading clock cycle */
pll_out = rate * (width + 1) * 8;
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_AUDIO, 0, 1);
if (ret < 0)
return ret;
@@ -176,7 +176,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
{
.name = "WM9713 Voice",
.stream_name = "WM9713 Voice",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP3],
.codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
.ops = &zylonite_voice_ops,
},
--
1.5.6.5
1
0
Since basic SSP features are shared between PXA2xx and PXA168, the difference
is focused on clock generating. Now split ssp code into two parts. One is for
general ssp feature. The other is for pxa2xx parts.
Update the SSP timing configuration in hw_params(). The SSP timing is verified
on I2S and Left J interface of PXA168 with 16-bit sample stream.
Signed-off-by: Haojian Zhuang <haojian.zhuang(a)marvell.com>
---
sound/soc/pxa/Kconfig | 8 +-
sound/soc/pxa/Makefile | 4 +-
sound/soc/pxa/magician.c | 38 ++--
sound/soc/pxa/pxa-ssp.c | 728 +++++++++++---------------------------------
sound/soc/pxa/pxa-ssp.h | 52 ++--
sound/soc/pxa/pxa2xx-ssp.c | 318 +++++++++++++++++++
sound/soc/pxa/pxa2xx-ssp.h | 48 +++
sound/soc/pxa/raumfeld.c | 14 +-
sound/soc/pxa/zylonite.c | 6 +-
9 files changed, 603 insertions(+), 613 deletions(-)
create mode 100644 sound/soc/pxa/pxa2xx-ssp.c
create mode 100644 sound/soc/pxa/pxa2xx-ssp.h
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 78e6121..7be1d5f 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -21,7 +21,7 @@ config SND_PXA2XX_SOC_AC97
config SND_PXA2XX_SOC_I2S
tristate
-config SND_PXA_SOC_SSP
+config SND_PXA2XX_SOC_SSP
tristate
select PXA_SSP
@@ -113,7 +113,7 @@ config SND_SOC_ZYLONITE
tristate "SoC Audio support for Marvell Zylonite"
depends on SND_PXA2XX_SOC && MACH_ZYLONITE
select SND_PXA2XX_SOC_AC97
- select SND_PXA_SOC_SSP
+ select SND_PXA2XX_SOC_SSP
select SND_SOC_WM9713
help
Say Y if you want to add support for SoC audio on the
@@ -122,7 +122,7 @@ config SND_SOC_ZYLONITE
config SND_SOC_RAUMFELD
tristate "SoC Audio support Raumfeld audio adapter"
depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER ||
MACH_RAUMFELD_CONNECTOR)
- select SND_PXA_SOC_SSP
+ select SND_PXA2XX_SOC_SSP
select SND_SOC_CS4270
select SND_SOC_AK4104
help
@@ -132,7 +132,7 @@ config SND_PXA2XX_SOC_MAGICIAN
tristate "SoC Audio support for HTC Magician"
depends on SND_PXA2XX_SOC && MACH_MAGICIAN
select SND_PXA2XX_SOC_I2S
- select SND_PXA_SOC_SSP
+ select SND_PXA2XX_SOC_SSP
select SND_SOC_UDA1380
help
Say Y if you want to add support for SoC audio on the
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index f3e08fd..33c1579 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -2,12 +2,12 @@
snd-soc-pxa2xx-objs := pxa2xx-pcm.o
snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
-snd-soc-pxa-ssp-objs := pxa-ssp.o
+snd-soc-pxa2xx-ssp-objs := pxa-ssp.o pxa2xx-ssp.o
obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
-obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
+obj-$(CONFIG_SND_PXA2XX_SOC_SSP) += snd-soc-pxa2xx-ssp.o
# PXA Machine Support
snd-soc-corgi-objs := corgi.o
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 4c8d99a..da6ff83 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -34,7 +34,7 @@
#include "../codecs/uda1380.h"
#include "pxa2xx-pcm.h"
#include "pxa2xx-i2s.h"
-#include "pxa-ssp.h"
+#include "pxa2xx-ssp.h"
#define MAGICIAN_MIC 0
#define MAGICIAN_MIC_EXT 1
@@ -89,7 +89,7 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
unsigned int acps, acds, width, rate;
- unsigned int div4 = PXA_SSP_CLK_SCDB_4;
+ unsigned int div4 = PXA2XX_SSP_CLK_SCDB_4;
int ret = 0;
rate = params_rate(params);
@@ -106,11 +106,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_16;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_16;
break;
default: /* 32 */
/* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_8;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_8;
}
break;
case 11025:
@@ -118,11 +118,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_4;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_4;
break;
default: /* 32 */
/* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
}
break;
case 22050:
@@ -130,11 +130,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
break;
default: /* 32 */
/* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
}
break;
case 44100:
@@ -142,11 +142,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
break;
default: /* 32 */
/* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
}
break;
case 48000:
@@ -154,11 +154,11 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
break;
default: /* 32 */
/* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
}
break;
case 96000:
@@ -167,12 +167,12 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
switch (width) {
case 16:
/* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_1;
break;
default: /* 32 */
/* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- div4 = PXA_SSP_CLK_SCDB_1;
+ acds = PXA2XX_SSP_CLK_AUDIO_DIV_2;
+ div4 = PXA2XX_SSP_CLK_SCDB_1;
break;
}
break;
@@ -195,20 +195,20 @@ static int magician_playback_hw_params(struct
snd_pcm_substream *substream,
return ret;
/* set audio clock as clock source */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0,
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_AUDIO, 0,
SND_SOC_CLOCK_OUT);
if (ret < 0)
return ret;
/* set the SSP audio system clock ACDS divider */
ret = snd_soc_dai_set_clkdiv(cpu_dai,
- PXA_SSP_AUDIO_DIV_ACDS, acds);
+ PXA2XX_SSP_AUDIO_DIV_ACDS, acds);
if (ret < 0)
return ret;
/* set the SSP audio system clock SCDB divider4 */
ret = snd_soc_dai_set_clkdiv(cpu_dai,
- PXA_SSP_AUDIO_DIV_SCDB, div4);
+ PXA2XX_SSP_AUDIO_DIV_SCDB, div4);
if (ret < 0)
return ret;
@@ -427,7 +427,7 @@ static struct snd_soc_dai_link magician_dai[] = {
{
.name = "uda1380",
.stream_name = "UDA1380 Playback",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP1],
.codec_dai = &uda1380_dai[UDA1380_DAI_PLAYBACK],
.init = magician_uda1380_init,
.ops = &magician_playback_ops,
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index ed54bef..bd5e800 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -5,6 +5,9 @@
* Author: Liam Girdwood
* Mark Brown <broonie(a)opensource.wolfsonmicro.com>
*
+ * Copyright 2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang(a)marvell.com>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -14,44 +17,20 @@
* o Test network mode for > 16bit sample size
*/
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-
#include <sound/core.h>
+#include <sound/soc.h>
#include <sound/pcm.h>
-#include <sound/initval.h>
#include <sound/pcm_params.h>
-#include <sound/soc.h>
#include <sound/pxa2xx-lib.h>
#include <mach/hardware.h>
#include <mach/dma.h>
-#include <mach/audio.h>
#include <plat/ssp.h>
#include "pxa2xx-pcm.h"
#include "pxa-ssp.h"
-/*
- * SSP audio private data
- */
-struct ssp_priv {
- struct ssp_device *ssp;
- unsigned int sysclk;
- int dai_fmt;
-#ifdef CONFIG_PM
- uint32_t cr0;
- uint32_t cr1;
- uint32_t to;
- uint32_t psp;
-#endif
-};
-
static void dump_registers(struct ssp_device *ssp)
{
dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
@@ -63,7 +42,7 @@ static void dump_registers(struct ssp_device *ssp)
pxa_ssp_read_reg(ssp, SSACD));
}
-static void pxa_ssp_enable(struct ssp_device *ssp)
+void pxa_ssp_enable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -71,7 +50,7 @@ static void pxa_ssp_enable(struct ssp_device *ssp)
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}
-static void pxa_ssp_disable(struct ssp_device *ssp)
+void pxa_ssp_disable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -84,7 +63,7 @@ struct pxa2xx_pcm_dma_data {
char name[20];
};
-static struct pxa2xx_pcm_dma_params *
+struct pxa2xx_pcm_dma_params *
pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
{
struct pxa2xx_pcm_dma_data *dma;
@@ -105,6 +84,102 @@ pxa_ssp_get_dma_params(struct ssp_device *ssp,
int width4, int out)
return &dma->params;
}
+EXPORT_SYMBOL_GPL(pxa_ssp_get_dma_params);
+
+/*
+ * Set up the SSP DAI format.
+ * The SSP Port must be inactive before calling this function as the
+ * physical interface format is changed.
+ */
+static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+ unsigned int fmt)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ u32 sscr0;
+ u32 sscr1;
+ u32 sspsp;
+
+ /* check if we need to change anything at all */
+ if (priv->dai_fmt == fmt)
+ return 0;
+
+ pxa_ssp_disable(ssp);
+
+ /* reset port settings */
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
+ (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
+ sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
+ sspsp = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ sscr1 |= SSCR1_SCLKDIR;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ sspsp |= SSPSP_SFRMP;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ sspsp |= SSPSP_SCMODE(2);
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ 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_LEFT_J:
+ 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:
+ sscr0 |= SSCR0_MOD | SSCR0_PSP;
+ sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_enable(ssp);
+
+ /* Since we are configuring the timings for the format by hand
+ * we have to defer some things until hw_params() where we
+ * know parameters like the sample size.
+ */
+ priv->dai_fmt = fmt;
+
+ dump_registers(ssp);
+
+ return 0;
+}
static int pxa_ssp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
@@ -193,212 +268,88 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
#define pxa_ssp_resume NULL
#endif
-/**
- * ssp_set_clkdiv - set SSP clock divider
- * @div: serial clock rate divider
- */
-static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
-{
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
-
- if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
- sscr0 &= ~0x0000ff00;
- sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
- } else {
- sscr0 &= ~0x000fff00;
- sscr0 |= (div - 1) << 8; /* 1..4096 */
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-}
-
-/**
- * pxa_ssp_get_clkdiv - get SSP clock divider
- */
-static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
-{
- u32 sscr0 = pxa_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.
+ * While configuring SSP timing, two formula on SSP clocks should be followed.
+ *
+ * 1) (frame delay + frame width) <= (start delay + dummy start
+ * + data size + dummy stop)
+ *
+ * 2) 1 <= frame width < (dummy start + data size + dummy stop)
*/
-static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
+static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct ssp_priv *priv = cpu_dai->private_data;
struct ssp_device *ssp = priv->ssp;
- int val;
+ int width = snd_pcm_format_physical_width(params_format(params));
+ int channels = params_channels(params);
+ int dma_32b = 0, stream_out = 0, data_size;
+ u32 sscr0, sspsp;
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
- ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
+ /* generate correct DMA params */
+ kfree(cpu_dai->dma_data);
- dev_dbg(&ssp->pdev->dev,
- "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
- cpu_dai->id, clk_id, freq);
+ if ((width == 32) || (channels == 1))
+ dma_32b = 1;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ stream_out = 1;
+ cpu_dai->dma_data = pxa_ssp_get_dma_params(ssp, dma_32b, stream_out);
- switch (clk_id) {
- case PXA_SSP_CLK_NET_PLL:
- sscr0 |= SSCR0_MOD;
- break;
- case PXA_SSP_CLK_PLL:
- /* Internal PLL is fixed */
- if (cpu_is_pxa25x())
- priv->sysclk = 1843200;
- else
- priv->sysclk = 13000000;
- break;
- case PXA_SSP_CLK_EXT:
- priv->sysclk = freq;
- sscr0 |= SSCR0_ECS;
- break;
- case PXA_SSP_CLK_NET:
- priv->sysclk = freq;
- sscr0 |= SSCR0_NCS | SSCR0_MOD;
+ /* clear selected SSP bits */
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+
+ /* data_size should only be 16-bit or 32-bit because of DMA.
+ * 24-bit data is treated as 32-bit data.
+ */
+ data_size = width * channels;
+ switch (data_size) {
+ case 16:
+ sscr0 |= SSCR0_DataSize(16);
break;
- case PXA_SSP_CLK_AUDIO:
- priv->sysclk = 0;
- pxa_ssp_set_scr(ssp, 1);
- sscr0 |= SSCR0_ACS;
+ case 32:
+ sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
break;
default:
- return -ENODEV;
+ dev_err(&ssp->pdev->dev, "Invalid data size:%d\n", data_size);
+ return -EINVAL;
}
- /* The SSP clock must be disabled when changing SSP clock mode
- * on PXA2xx. On PXA3xx it must be enabled when doing so. */
- if (!cpu_is_pxa3xx())
- clk_disable(ssp->clk);
- val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
- pxa_ssp_write_reg(ssp, SSCR0, val);
- if (!cpu_is_pxa3xx())
- clk_enable(ssp->clk);
-
- return 0;
-}
-
-/*
- * Set the SSP clock dividers.
- */
-static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- int val;
-
- switch (div_id) {
- case PXA_SSP_AUDIO_DIV_ACDS:
- val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
- pxa_ssp_write_reg(ssp, SSACD, val);
- break;
- case PXA_SSP_AUDIO_DIV_SCDB:
- val = pxa_ssp_read_reg(ssp, SSACD);
- val &= ~SSACD_SCDB;
-#if defined(CONFIG_PXA3xx)
- if (cpu_is_pxa3xx())
- val &= ~SSACD_SCDX8;
-#endif
- switch (div) {
- case PXA_SSP_CLK_SCDB_1:
- val |= SSACD_SCDB;
- break;
- case PXA_SSP_CLK_SCDB_4:
- break;
-#if defined(CONFIG_PXA3xx)
- case PXA_SSP_CLK_SCDB_8:
- if (cpu_is_pxa3xx())
- val |= SSACD_SCDX8;
- else
- return -EINVAL;
- break;
-#endif
- default:
- return -EINVAL;
+ pxa_ssp_disable(ssp);
+ sspsp = pxa_ssp_read_reg(ssp, SSPSP);
+ sspsp &= ~SSPSP_TIMING_MASK;
+ switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ if (channels == 1) {
+ sspsp |= SSPSP_DMYSTRT(1);
+ sspsp |= SSPSP_EDMYSTOP(((width - 1) >> 2) & 7);
+ sspsp |= SSPSP_DMYSTOP((width - 1) & 3);
+ sspsp |= SSPSP_SFRMDLY(width << 1);
+ sspsp |= SSPSP_SFRMWDTH(width);
+ } else {
+ /* channels == 2 */
+ sspsp |= SSPSP_SFRMWDTH(width);
+ /* Don't set any timing while FSRT is set */
+ sspsp |= SSPSP_FSRT;
}
- pxa_ssp_write_reg(ssp, SSACD, val);
break;
- case PXA_SSP_DIV_SCR:
- pxa_ssp_set_scr(ssp, div);
+ case SND_SOC_DAIFMT_LEFT_J:
+ if (channels == 1) {
+ sspsp |= SSPSP_EDMYSTOP((width >> 2) & 7);
+ sspsp |= SSPSP_DMYSTOP(width & 3);
+ }
+ sspsp |= SSPSP_SFRMWDTH(width);
break;
- default:
- return -ENODEV;
}
- return 0;
-}
-
-/*
- * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
- */
-static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
-
-#if defined(CONFIG_PXA3xx)
- if (cpu_is_pxa3xx())
- pxa_ssp_write_reg(ssp, SSACDD, 0);
-#endif
-
- switch (freq_out) {
- case 5622000:
- break;
- case 11345000:
- ssacd |= (0x1 << 4);
- break;
- case 12235000:
- ssacd |= (0x2 << 4);
- break;
- case 14857000:
- ssacd |= (0x3 << 4);
- break;
- case 32842000:
- ssacd |= (0x4 << 4);
- break;
- case 48000000:
- ssacd |= (0x5 << 4);
- break;
- case 0:
- /* Disable */
- break;
-
- default:
-#ifdef CONFIG_PXA3xx
- /* PXA3xx has a clock ditherer which can be used to generate
- * a wider range of frequencies - calculate a value for it.
- */
- if (cpu_is_pxa3xx()) {
- u32 val;
- u64 tmp = 19968;
- tmp *= 1000000;
- do_div(tmp, freq_out);
- val = tmp;
-
- val = (val << 16) | 64;
- pxa_ssp_write_reg(ssp, SSACDD, val);
-
- ssacd |= (0x6 << 4);
-
- dev_dbg(&ssp->pdev->dev,
- "Using SSACDD %x to supply %uHz\n",
- val, freq_out);
- break;
- }
-#endif
-
- return -EINVAL;
- }
+ /* update SSP register at the same time */
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_enable(ssp);
- pxa_ssp_write_reg(ssp, SSACD, ssacd);
+ dump_registers(ssp);
return 0;
}
@@ -458,213 +409,6 @@ static int pxa_ssp_set_dai_tristate(struct
snd_soc_dai *cpu_dai,
return 0;
}
-/*
- * Set up the SSP DAI format.
- * The SSP Port must be inactive before calling this function as the
- * physical interface format is changed.
- */
-static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- u32 sscr0;
- u32 sscr1;
- u32 sspsp;
-
- /* check if we need to change anything at all */
- if (priv->dai_fmt == fmt)
- return 0;
-
- /* we can only change the settings if the port is not in use */
- if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
- dev_err(&ssp->pdev->dev,
- "can't change hardware dai format: stream is in use");
- return -EINVAL;
- }
-
- /* reset port settings */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
- (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
- sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
- sspsp = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- sscr1 |= SSCR1_SCLKDIR;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- sspsp |= SSPSP_SFRMP;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- sspsp |= SSPSP_SCMODE(2);
- break;
- case SND_SOC_DAIFMT_IB_NF:
- sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
- break;
- default:
- return -EINVAL;
- }
-
- 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:
- sscr0 |= SSCR0_MOD | SSCR0_PSP;
- sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
- break;
-
- default:
- return -EINVAL;
- }
-
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
- pxa_ssp_write_reg(ssp, SSCR1, sscr1);
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
-
- dump_registers(ssp);
-
- /* Since we are configuring the timings for the format by hand
- * we have to defer some things until hw_params() where we
- * know parameters like the sample size.
- */
- priv->dai_fmt = fmt;
-
- return 0;
-}
-
-/*
- * Set the SSP audio DMA parameters and sample size.
- * Can be called multiple times by oss emulation.
- */
-static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->ssp;
- int chn = params_channels(params);
- u32 sscr0;
- u32 sspsp;
- int width = snd_pcm_format_physical_width(params_format(params));
- int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
-
- /* 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 = pxa_ssp_get_dma_params(ssp,
- ((chn == 2) && (ttsa != 1)) || (width == 32),
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-
- /* we can only change the settings if the port is not in use */
- if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
- return 0;
-
- /* clear selected SSP bits */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-
- /* bit size */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
-#ifdef CONFIG_PXA3xx
- if (cpu_is_pxa3xx())
- sscr0 |= SSCR0_FPCKE;
-#endif
- sscr0 |= SSCR0_DataSize(16);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
- break;
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-
- switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- sspsp = pxa_ssp_read_reg(ssp, SSPSP);
-
- if ((pxa_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);
- }
-
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
- break;
- default:
- break;
- }
-
- /* When we use a network mode, we always require TDM slots
- * - complain loudly and fail if they've not been set up yet.
- */
- if ((sscr0 & SSCR0_MOD) && !ttsa) {
- dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
- return -EINVAL;
- }
-
- dump_registers(ssp);
-
- return 0;
-}
-
static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
@@ -760,128 +504,22 @@ static void pxa_ssp_remove(struct platform_device *pdev,
pxa_ssp_free(priv->ssp);
}
-#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
- .startup = pxa_ssp_startup,
- .shutdown = pxa_ssp_shutdown,
- .trigger = pxa_ssp_trigger,
- .hw_params = pxa_ssp_hw_params,
- .set_sysclk = pxa_ssp_set_dai_sysclk,
- .set_clkdiv = pxa_ssp_set_dai_clkdiv,
- .set_pll = pxa_ssp_set_dai_pll,
- .set_fmt = pxa_ssp_set_dai_fmt,
- .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
- .set_tristate = pxa_ssp_set_dai_tristate,
-};
-
-struct snd_soc_dai pxa_ssp_dai[] = {
- {
- .name = "pxa2xx-ssp1",
- .id = 0,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
- { .name = "pxa2xx-ssp2",
- .id = 1,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
- {
- .name = "pxa2xx-ssp3",
- .id = 2,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
- {
- .name = "pxa2xx-ssp4",
- .id = 3,
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
- },
-};
-EXPORT_SYMBOL_GPL(pxa_ssp_dai);
-
-static int __init pxa_ssp_init(void)
-{
- return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
-}
-module_init(pxa_ssp_init);
-
-static void __exit pxa_ssp_exit(void)
+int pxa_ssp_register_dai(struct snd_soc_dai *dai)
{
- snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
+ struct snd_soc_dai_ops *ops = dai->ops;
+
+ ops->startup = pxa_ssp_startup;
+ ops->shutdown = pxa_ssp_shutdown;
+ ops->trigger = pxa_ssp_trigger;
+ ops->hw_params = pxa_ssp_hw_params;
+ ops->set_fmt = pxa_ssp_set_dai_fmt;
+ ops->set_tdm_slot = pxa_ssp_set_dai_tdm_slot;
+ ops->set_tristate = pxa_ssp_set_dai_tristate;
+
+ dai->probe = pxa_ssp_probe;
+ dai->remove = pxa_ssp_remove;
+ dai->suspend = pxa_ssp_suspend;
+ dai->resume = pxa_ssp_resume;
+
+ return snd_soc_register_dai(dai);
}
-module_exit(pxa_ssp_exit);
-
-/* Module information */
-MODULE_AUTHOR("Mark Brown <broonie(a)opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
index 91deadd..af4a09b 100644
--- a/sound/soc/pxa/pxa-ssp.h
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -9,39 +9,25 @@
#ifndef _PXA_SSP_H
#define _PXA_SSP_H
-/* pxa DAI SSP IDs */
-#define PXA_DAI_SSP1 0
-#define PXA_DAI_SSP2 1
-#define PXA_DAI_SSP3 2
-#define PXA_DAI_SSP4 3
-
-/* SSP clock sources */
-#define PXA_SSP_CLK_PLL 0
-#define PXA_SSP_CLK_EXT 1
-#define PXA_SSP_CLK_NET 2
-#define PXA_SSP_CLK_AUDIO 3
-#define PXA_SSP_CLK_NET_PLL 4
-
-/* SSP audio dividers */
-#define PXA_SSP_AUDIO_DIV_ACDS 0
-#define PXA_SSP_AUDIO_DIV_SCDB 1
-#define PXA_SSP_DIV_SCR 2
-
-/* SSP ACDS audio dividers values */
-#define PXA_SSP_CLK_AUDIO_DIV_1 0
-#define PXA_SSP_CLK_AUDIO_DIV_2 1
-#define PXA_SSP_CLK_AUDIO_DIV_4 2
-#define PXA_SSP_CLK_AUDIO_DIV_8 3
-#define PXA_SSP_CLK_AUDIO_DIV_16 4
-#define PXA_SSP_CLK_AUDIO_DIV_32 5
-
-/* SSP divider bypass */
-#define PXA_SSP_CLK_SCDB_4 0
-#define PXA_SSP_CLK_SCDB_1 1
-#define PXA_SSP_CLK_SCDB_8 2
-
-#define PXA_SSP_PLL_OUT 0
+/*
+ * SSP audio data
+ */
+struct ssp_priv {
+ struct ssp_device *ssp;
+ unsigned int sysclk;
+ int dai_fmt;
+#ifdef CONFIG_PM
+ uint32_t cr0;
+ uint32_t cr1;
+ uint32_t to;
+ uint32_t psp;
+#endif
+};
-extern struct snd_soc_dai pxa_ssp_dai[4];
+extern void pxa_ssp_enable(struct ssp_device *ssp);
+extern void pxa_ssp_disable(struct ssp_device *ssp);
+extern struct pxa2xx_pcm_dma_params *
+pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out);
+extern int pxa_ssp_register_dai(struct snd_soc_dai *dai);
#endif
diff --git a/sound/soc/pxa/pxa2xx-ssp.c b/sound/soc/pxa/pxa2xx-ssp.c
new file mode 100644
index 0000000..eff5334
--- /dev/null
+++ b/sound/soc/pxa/pxa2xx-ssp.c
@@ -0,0 +1,318 @@
+/*
+ * pxa2xx-ssp.c -- ALSA Soc Audio Layer
+ *
+ * Copyright 2005,2008 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ * Mark Brown <broonie(a)opensource.wolfsonmicro.com>
+ *
+ * Copyright 2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang(a)marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * TODO:
+ * o Test network mode for > 16bit sample size
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/pxa2xx-lib.h>
+
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <plat/ssp.h>
+
+#include "pxa2xx-pcm.h"
+#include "pxa2xx-ssp.h"
+#include "pxa-ssp.h"
+
+/**
+ * pxa_ssp_set_clkdiv - set SSP clock divider
+ * @div: serial clock rate divider
+ */
+static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
+{
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
+
+ if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
+ sscr0 &= ~0x0000ff00;
+ sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
+ } else {
+ sscr0 &= ~0x000fff00;
+ sscr0 |= (div - 1) << 8; /* 1..4096 */
+ }
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+}
+
+/**
+ * pxa_ssp_get_clkdiv - get SSP clock divider
+ */
+static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
+{
+ u32 sscr0 = pxa_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.
+ */
+static int pxa2xx_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ int val;
+
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
+ ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
+
+ dev_dbg(&ssp->pdev->dev,
+ "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
+ cpu_dai->id, clk_id, freq);
+
+ switch (clk_id) {
+ case PXA2XX_SSP_CLK_NET_PLL:
+ sscr0 |= SSCR0_MOD;
+ break;
+ case PXA2XX_SSP_CLK_PLL:
+ /* Internal PLL is fixed */
+ if (cpu_is_pxa25x())
+ priv->sysclk = 1843200;
+ else
+ priv->sysclk = 13000000;
+ break;
+ case PXA2XX_SSP_CLK_EXT:
+ priv->sysclk = freq;
+ sscr0 |= SSCR0_ECS;
+ break;
+ case PXA2XX_SSP_CLK_NET:
+ priv->sysclk = freq;
+ sscr0 |= SSCR0_NCS | SSCR0_MOD;
+ break;
+ case PXA2XX_SSP_CLK_AUDIO:
+ priv->sysclk = 0;
+ pxa_ssp_set_scr(ssp, 1);
+ sscr0 |= SSCR0_ACS;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ /* The SSP clock must be disabled when changing SSP clock mode
+ * on PXA2xx. On PXA3xx it must be enabled when doing so. */
+ if (!cpu_is_pxa3xx())
+ clk_disable(ssp->clk);
+ val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
+ pxa_ssp_write_reg(ssp, SSCR0, val);
+ if (!cpu_is_pxa3xx())
+ clk_enable(ssp->clk);
+
+ return 0;
+}
+
+/*
+ * Set the SSP clock dividers.
+ */
+static int pxa2xx_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
+ int div_id, int div)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ int val;
+
+ switch (div_id) {
+ case PXA2XX_SSP_AUDIO_DIV_ACDS:
+ val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+ pxa_ssp_write_reg(ssp, SSACD, val);
+ break;
+ case PXA2XX_SSP_AUDIO_DIV_SCDB:
+ val = pxa_ssp_read_reg(ssp, SSACD);
+ val &= ~SSACD_SCDB;
+#if defined(CONFIG_PXA3xx)
+ if (cpu_is_pxa3xx())
+ val &= ~SSACD_SCDX8;
+#endif
+ switch (div) {
+ case PXA2XX_SSP_CLK_SCDB_1:
+ val |= SSACD_SCDB;
+ break;
+ case PXA2XX_SSP_CLK_SCDB_4:
+ break;
+#if defined(CONFIG_PXA3xx)
+ case PXA2XX_SSP_CLK_SCDB_8:
+ if (cpu_is_pxa3xx())
+ val |= SSACD_SCDX8;
+ else
+ return -EINVAL;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+ pxa_ssp_write_reg(ssp, SSACD, val);
+ break;
+ case PXA2XX_SSP_DIV_SCR:
+ pxa_ssp_set_scr(ssp, div);
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/*
+ * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
+ */
+static int pxa2xx_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
+ int source, unsigned int freq_in,
+ unsigned int freq_out)
+{
+ struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
+
+#if defined(CONFIG_PXA3xx)
+ if (cpu_is_pxa3xx())
+ pxa_ssp_write_reg(ssp, SSACDD, 0);
+#endif
+
+ switch (freq_out) {
+ case 5622000:
+ break;
+ case 11345000:
+ ssacd |= (0x1 << 4);
+ break;
+ case 12235000:
+ ssacd |= (0x2 << 4);
+ break;
+ case 14857000:
+ ssacd |= (0x3 << 4);
+ break;
+ case 32842000:
+ ssacd |= (0x4 << 4);
+ break;
+ case 48000000:
+ ssacd |= (0x5 << 4);
+ break;
+ case 0:
+ /* Disable */
+ break;
+
+ default:
+#ifdef CONFIG_PXA3xx
+ /* PXA3xx has a clock ditherer which can be used to generate
+ * a wider range of frequencies - calculate a value for it.
+ */
+ if (cpu_is_pxa3xx()) {
+ u32 val;
+ u64 tmp = 19968;
+ tmp *= 1000000;
+ do_div(tmp, freq_out);
+ val = tmp;
+
+ val = (val << 16) | 64;
+ pxa_ssp_write_reg(ssp, SSACDD, val);
+
+ ssacd |= (0x6 << 4);
+
+ dev_dbg(&ssp->pdev->dev,
+ "Using SSACDD %x to supply %uHz\n",
+ val, freq_out);
+ break;
+ }
+#endif
+
+ return -EINVAL;
+ }
+
+ pxa_ssp_write_reg(ssp, SSACD, ssacd);
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops pxa2xx_ssp_dai_ops = {
+ .set_sysclk = pxa2xx_ssp_set_dai_sysclk,
+ .set_clkdiv = pxa2xx_ssp_set_dai_clkdiv,
+ .set_pll = pxa2xx_ssp_set_dai_pll,
+};
+
+#define PXA2XX_SSP_RATES SNDRV_PCM_RATE_8000_96000
+#define PXA2XX_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+#define PXA2XX_SSP_DAI(_id) \
+{ \
+ .name = "pxa2xx-ssp", \
+ .id = _id, \
+ .playback = { \
+ .channels_min = 1, \
+ .channels_max = 8, \
+ .rates = PXA2XX_SSP_RATES, \
+ .formats = PXA2XX_SSP_FORMATS, \
+ }, \
+ .capture = { \
+ .channels_min = 1, \
+ .channels_max = 8, \
+ .rates = PXA2XX_SSP_RATES, \
+ .formats = PXA2XX_SSP_FORMATS, \
+ }, \
+ .ops = &pxa2xx_ssp_dai_ops, \
+}
+
+struct snd_soc_dai pxa2xx_ssp_dai[] = {
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP1),
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP2),
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP3),
+ PXA2XX_SSP_DAI(PXA2XX_DAI_SSP4),
+};
+EXPORT_SYMBOL_GPL(pxa2xx_ssp_dai);
+
+static int __init pxa2xx_ssp_init(void)
+{
+ struct snd_soc_dai *dai;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(pxa2xx_ssp_dai); i++) {
+ dai = &pxa2xx_ssp_dai[i];
+ ret = pxa_ssp_register_dai(dai);
+ if (ret)
+ return ret;
+ }
+ return ret;
+}
+module_init(pxa2xx_ssp_init);
+
+static void __exit pxa2xx_ssp_exit(void)
+{
+ struct snd_soc_dai *dai = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pxa2xx_ssp_dai); i++) {
+ dai = &pxa2xx_ssp_dai[i];
+ snd_soc_unregister_dai(dai);
+ }
+}
+module_exit(pxa2xx_ssp_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie(a)opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("PXA2xx SSP/PCM SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-ssp.h b/sound/soc/pxa/pxa2xx-ssp.h
new file mode 100644
index 0000000..c24e0b5
--- /dev/null
+++ b/sound/soc/pxa/pxa2xx-ssp.h
@@ -0,0 +1,48 @@
+
+/*
+ * ASoC PXA SSP port support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PXA2XX_SOC_SSP_H
+#define __PXA2XX_SOC_SSP_H
+
+/* pxa DAI SSP IDs */
+#define PXA2XX_DAI_SSP1 0
+#define PXA2XX_DAI_SSP2 1
+#define PXA2XX_DAI_SSP3 2
+#define PXA2XX_DAI_SSP4 3
+
+/* SSP clock sources */
+#define PXA2XX_SSP_CLK_PLL 0
+#define PXA2XX_SSP_CLK_EXT 1
+#define PXA2XX_SSP_CLK_NET 2
+#define PXA2XX_SSP_CLK_AUDIO 3
+#define PXA2XX_SSP_CLK_NET_PLL 4
+
+/* SSP audio dividers */
+#define PXA2XX_SSP_AUDIO_DIV_ACDS 0
+#define PXA2XX_SSP_AUDIO_DIV_SCDB 1
+#define PXA2XX_SSP_DIV_SCR 2
+
+/* SSP ACDS audio dividers values */
+#define PXA2XX_SSP_CLK_AUDIO_DIV_1 0
+#define PXA2XX_SSP_CLK_AUDIO_DIV_2 1
+#define PXA2XX_SSP_CLK_AUDIO_DIV_4 2
+#define PXA2XX_SSP_CLK_AUDIO_DIV_8 3
+#define PXA2XX_SSP_CLK_AUDIO_DIV_16 4
+#define PXA2XX_SSP_CLK_AUDIO_DIV_32 5
+
+/* SSP divider bypass */
+#define PXA2XX_SSP_CLK_SCDB_4 0
+#define PXA2XX_SSP_CLK_SCDB_1 1
+#define PXA2XX_SSP_CLK_SCDB_8 2
+
+#define PXA2XX_SSP_PLL_OUT 0
+
+extern struct snd_soc_dai pxa2xx_ssp_dai[];
+
+#endif /* __PXA2XX_SOC_SSP_H */
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 7e3f416..e66dc12 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -29,7 +29,7 @@
#include "../codecs/cs4270.h"
#include "../codecs/ak4104.h"
#include "pxa2xx-pcm.h"
-#include "pxa-ssp.h"
+#include "pxa2xx-ssp.h"
#define GPIO_SPDIF_RESET (38)
#define GPIO_MCLK_RESET (111)
@@ -138,11 +138,11 @@ static int raumfeld_cs4270_hw_params(struct
snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA2XX_SSP_DIV_SCR, 4);
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_EXT, clk, 1);
if (ret < 0)
return ret;
@@ -170,7 +170,7 @@ static int raumfeld_line_resume(struct
platform_device *pdev)
static struct snd_soc_dai_link raumfeld_line_dai = {
.name = "CS4270",
.stream_name = "CS4270",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP1],
.codec_dai = &cs4270_dai,
.ops = &raumfeld_cs4270_ops,
};
@@ -232,11 +232,11 @@ static int raumfeld_ak4104_hw_params(struct
snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA2XX_SSP_DIV_SCR, 4);
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_EXT, clk, 1);
if (ret < 0)
return ret;
@@ -250,7 +250,7 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
static struct snd_soc_dai_link raumfeld_spdif_dai = {
.name = "ak4104",
.stream_name = "Playback",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP2],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP2],
.codec_dai = &ak4104_dai,
.ops = &raumfeld_ak4104_ops,
};
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index dd678ae..c65e0db 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -25,7 +25,7 @@
#include "../codecs/wm9713.h"
#include "pxa2xx-pcm.h"
#include "pxa2xx-ac97.h"
-#include "pxa-ssp.h"
+#include "pxa2xx-ssp.h"
/*
* There is a physical switch SW15 on the board which changes the MCLK
@@ -125,7 +125,7 @@ static int zylonite_voice_hw_params(struct
snd_pcm_substream *substream,
/* Add 1 to the width for the leading clock cycle */
pll_out = rate * (width + 1) * 8;
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_SSP_CLK_AUDIO, 0, 1);
if (ret < 0)
return ret;
@@ -176,7 +176,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
{
.name = "WM9713 Voice",
.stream_name = "WM9713 Voice",
- .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
+ .cpu_dai = &pxa2xx_ssp_dai[PXA2XX_DAI_SSP3],
.codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
.ops = &zylonite_voice_ops,
},
--
1.5.6.5
1
0
In order to prevent code ambiguous, add namespace on functions in ssp driver.
Signed-off-by: Haojian Zhuang <haojian.zhuang(a)marvell.com>
---
arch/arm/plat-pxa/include/plat/ssp.h | 12 ++--
arch/arm/plat-pxa/ssp.c | 22 +++---
drivers/spi/pxa2xx_spi.c | 8 +-
sound/soc/pxa/pxa-ssp.c | 132 +++++++++++++++++-----------------
4 files changed, 87 insertions(+), 87 deletions(-)
diff --git a/arch/arm/plat-pxa/include/plat/ssp.h
b/arch/arm/plat-pxa/include/plat/ssp.h
index d16d79a..fe43150 100644
--- a/arch/arm/plat-pxa/include/plat/ssp.h
+++ b/arch/arm/plat-pxa/include/plat/ssp.h
@@ -159,28 +159,28 @@ struct ssp_device {
};
/**
- * ssp_write_reg - Write to a SSP register
+ * pxa_ssp_write_reg - Write to a SSP register
*
* @dev: SSP device to access
* @reg: Register to write to
* @val: Value to be written.
*/
-static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
+static inline void pxa_ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
{
__raw_writel(val, dev->mmio_base + reg);
}
/**
- * ssp_read_reg - Read from a SSP register
+ * pxa_ssp_read_reg - Read from a SSP register
*
* @dev: SSP device to access
* @reg: Register to read from
*/
-static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg)
+static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
{
return __raw_readl(dev->mmio_base + reg);
}
-struct ssp_device *ssp_request(int port, const char *label);
-void ssp_free(struct ssp_device *);
+struct ssp_device *pxa_ssp_request(int port, const char *label);
+void pxa_ssp_free(struct ssp_device *);
#endif /* __ASM_ARCH_SSP_H */
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
index cfebcd8..511805e 100644
--- a/arch/arm/plat-pxa/ssp.c
+++ b/arch/arm/plat-pxa/ssp.c
@@ -37,7 +37,7 @@
static DEFINE_MUTEX(ssp_lock);
static LIST_HEAD(ssp_list);
-struct ssp_device *ssp_request(int port, const char *label)
+struct ssp_device *pxa_ssp_request(int port, const char *label)
{
struct ssp_device *ssp = NULL;
@@ -58,9 +58,9 @@ struct ssp_device *ssp_request(int port, const char *label)
return ssp;
}
-EXPORT_SYMBOL(ssp_request);
+EXPORT_SYMBOL(pxa_ssp_request);
-void ssp_free(struct ssp_device *ssp)
+void pxa_ssp_free(struct ssp_device *ssp)
{
mutex_lock(&ssp_lock);
if (ssp->use_count) {
@@ -70,9 +70,9 @@ void ssp_free(struct ssp_device *ssp)
dev_err(&ssp->pdev->dev, "device already free\n");
mutex_unlock(&ssp_lock);
}
-EXPORT_SYMBOL(ssp_free);
+EXPORT_SYMBOL(pxa_ssp_free);
-static int __devinit ssp_probe(struct platform_device *pdev)
+static int __devinit pxa_ssp_probe(struct platform_device *pdev)
{
const struct platform_device_id *id = platform_get_device_id(pdev);
struct resource *res;
@@ -164,7 +164,7 @@ err_free:
return ret;
}
-static int __devexit ssp_remove(struct platform_device *pdev)
+static int __devexit pxa_ssp_remove(struct platform_device *pdev)
{
struct resource *res;
struct ssp_device *ssp;
@@ -196,9 +196,9 @@ static const struct platform_device_id ssp_id_table[] = {
{ },
};
-static struct platform_driver ssp_driver = {
- .probe = ssp_probe,
- .remove = __devexit_p(ssp_remove),
+static struct platform_driver pxa_ssp_driver = {
+ .probe = pxa_ssp_probe,
+ .remove = __devexit_p(pxa_ssp_remove),
.driver = {
.owner = THIS_MODULE,
.name = "pxa2xx-ssp",
@@ -208,12 +208,12 @@ static struct platform_driver ssp_driver = {
static int __init pxa_ssp_init(void)
{
- return platform_driver_register(&ssp_driver);
+ return platform_driver_register(&pxa_ssp_driver);
}
static void __exit pxa_ssp_exit(void)
{
- platform_driver_unregister(&ssp_driver);
+ platform_driver_unregister(&pxa_ssp_driver);
}
arch_initcall(pxa_ssp_init);
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 4a64da7..2fd7d5a 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1464,7 +1464,7 @@ static int __init pxa2xx_spi_probe(struct
platform_device *pdev)
platform_info = dev->platform_data;
- ssp = ssp_request(pdev->id, pdev->name);
+ ssp = pxa_ssp_request(pdev->id, pdev->name);
if (ssp == NULL) {
dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id);
return -ENODEV;
@@ -1474,7 +1474,7 @@ static int __init pxa2xx_spi_probe(struct
platform_device *pdev)
master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
if (!master) {
dev_err(&pdev->dev, "cannot alloc spi_master\n");
- ssp_free(ssp);
+ pxa_ssp_free(ssp);
return -ENOMEM;
}
drv_data = spi_master_get_devdata(master);
@@ -1603,7 +1603,7 @@ out_error_irq_alloc:
out_error_master_alloc:
spi_master_put(master);
- ssp_free(ssp);
+ pxa_ssp_free(ssp);
return status;
}
@@ -1647,7 +1647,7 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
free_irq(ssp->irq, drv_data);
/* Release SSP */
- ssp_free(ssp);
+ pxa_ssp_free(ssp);
/* Disconnect from the SPI framework */
spi_unregister_master(drv_data->master);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 4ca9245..ed54bef 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -55,15 +55,15 @@ struct ssp_priv {
static void dump_registers(struct ssp_device *ssp)
{
dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
- ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
- ssp_read_reg(ssp, SSTO));
+ pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
+ pxa_ssp_read_reg(ssp, SSTO));
dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
- ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
- ssp_read_reg(ssp, SSACD));
+ pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
+ pxa_ssp_read_reg(ssp, SSACD));
}
-static void ssp_enable(struct ssp_device *ssp)
+static void pxa_ssp_enable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -71,7 +71,7 @@ static void ssp_enable(struct ssp_device *ssp)
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}
-static void ssp_disable(struct ssp_device *ssp)
+static void pxa_ssp_disable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -85,7 +85,7 @@ struct pxa2xx_pcm_dma_data {
};
static struct pxa2xx_pcm_dma_params *
-ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
+pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
{
struct pxa2xx_pcm_dma_data *dma;
@@ -117,7 +117,7 @@ static int pxa_ssp_startup(struct
snd_pcm_substream *substream,
if (!cpu_dai->active) {
clk_enable(ssp->clk);
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
}
if (cpu_dai->dma_data) {
@@ -136,7 +136,7 @@ static void pxa_ssp_shutdown(struct
snd_pcm_substream *substream,
struct ssp_device *ssp = priv->ssp;
if (!cpu_dai->active) {
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
clk_disable(ssp->clk);
}
@@ -161,7 +161,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
priv->to = __raw_readl(ssp->mmio_base + SSTO);
priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
clk_disable(ssp->clk);
return 0;
}
@@ -181,7 +181,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
__raw_writel(priv->psp, ssp->mmio_base + SSPSP);
if (cpu_dai->active)
- ssp_enable(ssp);
+ pxa_ssp_enable(ssp);
else
clk_disable(ssp->clk);
@@ -197,9 +197,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
* ssp_set_clkdiv - set SSP clock divider
* @div: serial clock rate divider
*/
-static void ssp_set_scr(struct ssp_device *ssp, u32 div)
+static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
{
- u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
sscr0 &= ~0x0000ff00;
@@ -208,15 +208,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div)
sscr0 &= ~0x000fff00;
sscr0 |= (div - 1) << 8; /* 1..4096 */
}
- ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
}
/**
- * ssp_get_clkdiv - get SSP clock divider
+ * pxa_ssp_get_clkdiv - get SSP clock divider
*/
-static u32 ssp_get_scr(struct ssp_device *ssp)
+static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
{
- u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
u32 div;
if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
@@ -236,7 +236,7 @@ static int pxa_ssp_set_dai_sysclk(struct
snd_soc_dai *cpu_dai,
struct ssp_device *ssp = priv->ssp;
int val;
- u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
dev_dbg(&ssp->pdev->dev,
@@ -264,7 +264,7 @@ static int pxa_ssp_set_dai_sysclk(struct
snd_soc_dai *cpu_dai,
break;
case PXA_SSP_CLK_AUDIO:
priv->sysclk = 0;
- ssp_set_scr(ssp, 1);
+ pxa_ssp_set_scr(ssp, 1);
sscr0 |= SSCR0_ACS;
break;
default:
@@ -275,8 +275,8 @@ static int pxa_ssp_set_dai_sysclk(struct
snd_soc_dai *cpu_dai,
* on PXA2xx. On PXA3xx it must be enabled when doing so. */
if (!cpu_is_pxa3xx())
clk_disable(ssp->clk);
- val = ssp_read_reg(ssp, SSCR0) | sscr0;
- ssp_write_reg(ssp, SSCR0, val);
+ val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
+ pxa_ssp_write_reg(ssp, SSCR0, val);
if (!cpu_is_pxa3xx())
clk_enable(ssp->clk);
@@ -295,11 +295,11 @@ static int pxa_ssp_set_dai_clkdiv(struct
snd_soc_dai *cpu_dai,
switch (div_id) {
case PXA_SSP_AUDIO_DIV_ACDS:
- val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
- ssp_write_reg(ssp, SSACD, val);
+ val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+ pxa_ssp_write_reg(ssp, SSACD, val);
break;
case PXA_SSP_AUDIO_DIV_SCDB:
- val = ssp_read_reg(ssp, SSACD);
+ val = pxa_ssp_read_reg(ssp, SSACD);
val &= ~SSACD_SCDB;
#if defined(CONFIG_PXA3xx)
if (cpu_is_pxa3xx())
@@ -322,10 +322,10 @@ static int pxa_ssp_set_dai_clkdiv(struct
snd_soc_dai *cpu_dai,
default:
return -EINVAL;
}
- ssp_write_reg(ssp, SSACD, val);
+ pxa_ssp_write_reg(ssp, SSACD, val);
break;
case PXA_SSP_DIV_SCR:
- ssp_set_scr(ssp, div);
+ pxa_ssp_set_scr(ssp, div);
break;
default:
return -ENODEV;
@@ -342,11 +342,11 @@ static int pxa_ssp_set_dai_pll(struct
snd_soc_dai *cpu_dai, int pll_id,
{
struct ssp_priv *priv = cpu_dai->private_data;
struct ssp_device *ssp = priv->ssp;
- u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
+ u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
#if defined(CONFIG_PXA3xx)
if (cpu_is_pxa3xx())
- ssp_write_reg(ssp, SSACDD, 0);
+ pxa_ssp_write_reg(ssp, SSACDD, 0);
#endif
switch (freq_out) {
@@ -384,7 +384,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai
*cpu_dai, int pll_id,
val = tmp;
val = (val << 16) | 64;
- ssp_write_reg(ssp, SSACDD, val);
+ pxa_ssp_write_reg(ssp, SSACDD, val);
ssacd |= (0x6 << 4);
@@ -398,7 +398,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai
*cpu_dai, int pll_id,
return -EINVAL;
}
- ssp_write_reg(ssp, SSACD, ssacd);
+ pxa_ssp_write_reg(ssp, SSACD, ssacd);
return 0;
}
@@ -413,7 +413,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct
snd_soc_dai *cpu_dai,
struct ssp_device *ssp = priv->ssp;
u32 sscr0;
- sscr0 = ssp_read_reg(ssp, SSCR0);
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
/* set slot width */
@@ -430,10 +430,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct
snd_soc_dai *cpu_dai,
sscr0 |= SSCR0_SlotsPerFrm(slots);
/* set active slot mask */
- ssp_write_reg(ssp, SSTSA, tx_mask);
- ssp_write_reg(ssp, SSRSA, rx_mask);
+ pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
+ pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
}
- ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
return 0;
}
@@ -448,12 +448,12 @@ static int pxa_ssp_set_dai_tristate(struct
snd_soc_dai *cpu_dai,
struct ssp_device *ssp = priv->ssp;
u32 sscr1;
- sscr1 = ssp_read_reg(ssp, SSCR1);
+ sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
if (tristate)
sscr1 &= ~SSCR1_TTE;
else
sscr1 |= SSCR1_TTE;
- ssp_write_reg(ssp, SSCR1, sscr1);
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
return 0;
}
@@ -477,14 +477,14 @@ static int pxa_ssp_set_dai_fmt(struct
snd_soc_dai *cpu_dai,
return 0;
/* we can only change the settings if the port is not in use */
- if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
+ if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
dev_err(&ssp->pdev->dev,
"can't change hardware dai format: stream is in use");
return -EINVAL;
}
/* reset port settings */
- sscr0 = ssp_read_reg(ssp, SSCR0) &
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
sspsp = 0;
@@ -536,9 +536,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
return -EINVAL;
}
- ssp_write_reg(ssp, SSCR0, sscr0);
- ssp_write_reg(ssp, SSCR1, sscr1);
- ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
dump_registers(ssp);
@@ -567,7 +567,7 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
u32 sscr0;
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
- int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+ int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
/* generate correct DMA params */
if (cpu_dai->dma_data)
@@ -577,20 +577,20 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
* 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,
+ cpu_dai->dma_data = pxa_ssp_get_dma_params(ssp,
((chn == 2) && (ttsa != 1)) || (width == 32),
substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
/* we can only change the settings if the port is not in use */
- if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
+ if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
return 0;
/* clear selected SSP bits */
- sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
- ssp_write_reg(ssp, SSCR0, sscr0);
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
/* bit size */
- sscr0 = ssp_read_reg(ssp, SSCR0);
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
#ifdef CONFIG_PXA3xx
@@ -606,13 +606,13 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
break;
}
- ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_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);
+ sspsp = pxa_ssp_read_reg(ssp, SSPSP);
- if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
+ if ((pxa_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.
@@ -646,7 +646,7 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
sspsp |= SSPSP_DMYSTRT(1);
}
- ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
break;
default:
break;
@@ -677,45 +677,45 @@ static int pxa_ssp_trigger(struct
snd_pcm_substream *substream, int cmd,
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
- ssp_enable(ssp);
+ pxa_ssp_enable(ssp);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val |= SSCR1_TSRE;
else
val |= SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
- val = ssp_read_reg(ssp, SSSR);
- ssp_write_reg(ssp, SSSR, val);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
+ val = pxa_ssp_read_reg(ssp, SSSR);
+ pxa_ssp_write_reg(ssp, SSSR, val);
break;
case SNDRV_PCM_TRIGGER_START:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val |= SSCR1_TSRE;
else
val |= SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
- ssp_enable(ssp);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
+ pxa_ssp_enable(ssp);
break;
case SNDRV_PCM_TRIGGER_STOP:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val &= ~SSCR1_TSRE;
else
val &= ~SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val &= ~SSCR1_TSRE;
else
val &= ~SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
break;
default:
@@ -737,7 +737,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
if (!priv)
return -ENOMEM;
- priv->ssp = ssp_request(dai->id + 1, "SoC audio");
+ priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
if (priv->ssp == NULL) {
ret = -ENODEV;
goto err_priv;
@@ -757,7 +757,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
struct snd_soc_dai *dai)
{
struct ssp_priv *priv = dai->private_data;
- ssp_free(priv->ssp);
+ pxa_ssp_free(priv->ssp);
}
#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
--
1.5.6.5
1
0
In order to prevent code ambiguous, add namespace on functions in ssp driver.
Signed-off-by: Haojian Zhuang <haojian.zhuang(a)marvell.com>
---
arch/arm/plat-pxa/include/plat/ssp.h | 12 ++--
arch/arm/plat-pxa/ssp.c | 22 +++---
drivers/spi/pxa2xx_spi.c | 8 +-
sound/soc/pxa/pxa-ssp.c | 132 +++++++++++++++++-----------------
4 files changed, 87 insertions(+), 87 deletions(-)
diff --git a/arch/arm/plat-pxa/include/plat/ssp.h
b/arch/arm/plat-pxa/include/plat/ssp.h
index d16d79a..fe43150 100644
--- a/arch/arm/plat-pxa/include/plat/ssp.h
+++ b/arch/arm/plat-pxa/include/plat/ssp.h
@@ -159,28 +159,28 @@ struct ssp_device {
};
/**
- * ssp_write_reg - Write to a SSP register
+ * pxa_ssp_write_reg - Write to a SSP register
*
* @dev: SSP device to access
* @reg: Register to write to
* @val: Value to be written.
*/
-static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
+static inline void pxa_ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
{
__raw_writel(val, dev->mmio_base + reg);
}
/**
- * ssp_read_reg - Read from a SSP register
+ * pxa_ssp_read_reg - Read from a SSP register
*
* @dev: SSP device to access
* @reg: Register to read from
*/
-static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg)
+static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
{
return __raw_readl(dev->mmio_base + reg);
}
-struct ssp_device *ssp_request(int port, const char *label);
-void ssp_free(struct ssp_device *);
+struct ssp_device *pxa_ssp_request(int port, const char *label);
+void pxa_ssp_free(struct ssp_device *);
#endif /* __ASM_ARCH_SSP_H */
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
index cfebcd8..511805e 100644
--- a/arch/arm/plat-pxa/ssp.c
+++ b/arch/arm/plat-pxa/ssp.c
@@ -37,7 +37,7 @@
static DEFINE_MUTEX(ssp_lock);
static LIST_HEAD(ssp_list);
-struct ssp_device *ssp_request(int port, const char *label)
+struct ssp_device *pxa_ssp_request(int port, const char *label)
{
struct ssp_device *ssp = NULL;
@@ -58,9 +58,9 @@ struct ssp_device *ssp_request(int port, const char *label)
return ssp;
}
-EXPORT_SYMBOL(ssp_request);
+EXPORT_SYMBOL(pxa_ssp_request);
-void ssp_free(struct ssp_device *ssp)
+void pxa_ssp_free(struct ssp_device *ssp)
{
mutex_lock(&ssp_lock);
if (ssp->use_count) {
@@ -70,9 +70,9 @@ void ssp_free(struct ssp_device *ssp)
dev_err(&ssp->pdev->dev, "device already free\n");
mutex_unlock(&ssp_lock);
}
-EXPORT_SYMBOL(ssp_free);
+EXPORT_SYMBOL(pxa_ssp_free);
-static int __devinit ssp_probe(struct platform_device *pdev)
+static int __devinit pxa_ssp_probe(struct platform_device *pdev)
{
const struct platform_device_id *id = platform_get_device_id(pdev);
struct resource *res;
@@ -164,7 +164,7 @@ err_free:
return ret;
}
-static int __devexit ssp_remove(struct platform_device *pdev)
+static int __devexit pxa_ssp_remove(struct platform_device *pdev)
{
struct resource *res;
struct ssp_device *ssp;
@@ -196,9 +196,9 @@ static const struct platform_device_id ssp_id_table[] = {
{ },
};
-static struct platform_driver ssp_driver = {
- .probe = ssp_probe,
- .remove = __devexit_p(ssp_remove),
+static struct platform_driver pxa_ssp_driver = {
+ .probe = pxa_ssp_probe,
+ .remove = __devexit_p(pxa_ssp_remove),
.driver = {
.owner = THIS_MODULE,
.name = "pxa2xx-ssp",
@@ -208,12 +208,12 @@ static struct platform_driver ssp_driver = {
static int __init pxa_ssp_init(void)
{
- return platform_driver_register(&ssp_driver);
+ return platform_driver_register(&pxa_ssp_driver);
}
static void __exit pxa_ssp_exit(void)
{
- platform_driver_unregister(&ssp_driver);
+ platform_driver_unregister(&pxa_ssp_driver);
}
arch_initcall(pxa_ssp_init);
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 4a64da7..2fd7d5a 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1464,7 +1464,7 @@ static int __init pxa2xx_spi_probe(struct
platform_device *pdev)
platform_info = dev->platform_data;
- ssp = ssp_request(pdev->id, pdev->name);
+ ssp = pxa_ssp_request(pdev->id, pdev->name);
if (ssp == NULL) {
dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id);
return -ENODEV;
@@ -1474,7 +1474,7 @@ static int __init pxa2xx_spi_probe(struct
platform_device *pdev)
master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
if (!master) {
dev_err(&pdev->dev, "cannot alloc spi_master\n");
- ssp_free(ssp);
+ pxa_ssp_free(ssp);
return -ENOMEM;
}
drv_data = spi_master_get_devdata(master);
@@ -1603,7 +1603,7 @@ out_error_irq_alloc:
out_error_master_alloc:
spi_master_put(master);
- ssp_free(ssp);
+ pxa_ssp_free(ssp);
return status;
}
@@ -1647,7 +1647,7 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
free_irq(ssp->irq, drv_data);
/* Release SSP */
- ssp_free(ssp);
+ pxa_ssp_free(ssp);
/* Disconnect from the SPI framework */
spi_unregister_master(drv_data->master);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 4ca9245..ed54bef 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -55,15 +55,15 @@ struct ssp_priv {
static void dump_registers(struct ssp_device *ssp)
{
dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
- ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
- ssp_read_reg(ssp, SSTO));
+ pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
+ pxa_ssp_read_reg(ssp, SSTO));
dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
- ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
- ssp_read_reg(ssp, SSACD));
+ pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
+ pxa_ssp_read_reg(ssp, SSACD));
}
-static void ssp_enable(struct ssp_device *ssp)
+static void pxa_ssp_enable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -71,7 +71,7 @@ static void ssp_enable(struct ssp_device *ssp)
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}
-static void ssp_disable(struct ssp_device *ssp)
+static void pxa_ssp_disable(struct ssp_device *ssp)
{
uint32_t sscr0;
@@ -85,7 +85,7 @@ struct pxa2xx_pcm_dma_data {
};
static struct pxa2xx_pcm_dma_params *
-ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
+pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
{
struct pxa2xx_pcm_dma_data *dma;
@@ -117,7 +117,7 @@ static int pxa_ssp_startup(struct
snd_pcm_substream *substream,
if (!cpu_dai->active) {
clk_enable(ssp->clk);
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
}
if (cpu_dai->dma_data) {
@@ -136,7 +136,7 @@ static void pxa_ssp_shutdown(struct
snd_pcm_substream *substream,
struct ssp_device *ssp = priv->ssp;
if (!cpu_dai->active) {
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
clk_disable(ssp->clk);
}
@@ -161,7 +161,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
priv->to = __raw_readl(ssp->mmio_base + SSTO);
priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
clk_disable(ssp->clk);
return 0;
}
@@ -181,7 +181,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
__raw_writel(priv->psp, ssp->mmio_base + SSPSP);
if (cpu_dai->active)
- ssp_enable(ssp);
+ pxa_ssp_enable(ssp);
else
clk_disable(ssp->clk);
@@ -197,9 +197,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
* ssp_set_clkdiv - set SSP clock divider
* @div: serial clock rate divider
*/
-static void ssp_set_scr(struct ssp_device *ssp, u32 div)
+static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
{
- u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
sscr0 &= ~0x0000ff00;
@@ -208,15 +208,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div)
sscr0 &= ~0x000fff00;
sscr0 |= (div - 1) << 8; /* 1..4096 */
}
- ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
}
/**
- * ssp_get_clkdiv - get SSP clock divider
+ * pxa_ssp_get_clkdiv - get SSP clock divider
*/
-static u32 ssp_get_scr(struct ssp_device *ssp)
+static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
{
- u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
u32 div;
if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
@@ -236,7 +236,7 @@ static int pxa_ssp_set_dai_sysclk(struct
snd_soc_dai *cpu_dai,
struct ssp_device *ssp = priv->ssp;
int val;
- u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
+ u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
dev_dbg(&ssp->pdev->dev,
@@ -264,7 +264,7 @@ static int pxa_ssp_set_dai_sysclk(struct
snd_soc_dai *cpu_dai,
break;
case PXA_SSP_CLK_AUDIO:
priv->sysclk = 0;
- ssp_set_scr(ssp, 1);
+ pxa_ssp_set_scr(ssp, 1);
sscr0 |= SSCR0_ACS;
break;
default:
@@ -275,8 +275,8 @@ static int pxa_ssp_set_dai_sysclk(struct
snd_soc_dai *cpu_dai,
* on PXA2xx. On PXA3xx it must be enabled when doing so. */
if (!cpu_is_pxa3xx())
clk_disable(ssp->clk);
- val = ssp_read_reg(ssp, SSCR0) | sscr0;
- ssp_write_reg(ssp, SSCR0, val);
+ val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
+ pxa_ssp_write_reg(ssp, SSCR0, val);
if (!cpu_is_pxa3xx())
clk_enable(ssp->clk);
@@ -295,11 +295,11 @@ static int pxa_ssp_set_dai_clkdiv(struct
snd_soc_dai *cpu_dai,
switch (div_id) {
case PXA_SSP_AUDIO_DIV_ACDS:
- val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
- ssp_write_reg(ssp, SSACD, val);
+ val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+ pxa_ssp_write_reg(ssp, SSACD, val);
break;
case PXA_SSP_AUDIO_DIV_SCDB:
- val = ssp_read_reg(ssp, SSACD);
+ val = pxa_ssp_read_reg(ssp, SSACD);
val &= ~SSACD_SCDB;
#if defined(CONFIG_PXA3xx)
if (cpu_is_pxa3xx())
@@ -322,10 +322,10 @@ static int pxa_ssp_set_dai_clkdiv(struct
snd_soc_dai *cpu_dai,
default:
return -EINVAL;
}
- ssp_write_reg(ssp, SSACD, val);
+ pxa_ssp_write_reg(ssp, SSACD, val);
break;
case PXA_SSP_DIV_SCR:
- ssp_set_scr(ssp, div);
+ pxa_ssp_set_scr(ssp, div);
break;
default:
return -ENODEV;
@@ -342,11 +342,11 @@ static int pxa_ssp_set_dai_pll(struct
snd_soc_dai *cpu_dai, int pll_id,
{
struct ssp_priv *priv = cpu_dai->private_data;
struct ssp_device *ssp = priv->ssp;
- u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
+ u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
#if defined(CONFIG_PXA3xx)
if (cpu_is_pxa3xx())
- ssp_write_reg(ssp, SSACDD, 0);
+ pxa_ssp_write_reg(ssp, SSACDD, 0);
#endif
switch (freq_out) {
@@ -384,7 +384,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai
*cpu_dai, int pll_id,
val = tmp;
val = (val << 16) | 64;
- ssp_write_reg(ssp, SSACDD, val);
+ pxa_ssp_write_reg(ssp, SSACDD, val);
ssacd |= (0x6 << 4);
@@ -398,7 +398,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai
*cpu_dai, int pll_id,
return -EINVAL;
}
- ssp_write_reg(ssp, SSACD, ssacd);
+ pxa_ssp_write_reg(ssp, SSACD, ssacd);
return 0;
}
@@ -413,7 +413,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct
snd_soc_dai *cpu_dai,
struct ssp_device *ssp = priv->ssp;
u32 sscr0;
- sscr0 = ssp_read_reg(ssp, SSCR0);
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
/* set slot width */
@@ -430,10 +430,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct
snd_soc_dai *cpu_dai,
sscr0 |= SSCR0_SlotsPerFrm(slots);
/* set active slot mask */
- ssp_write_reg(ssp, SSTSA, tx_mask);
- ssp_write_reg(ssp, SSRSA, rx_mask);
+ pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
+ pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
}
- ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
return 0;
}
@@ -448,12 +448,12 @@ static int pxa_ssp_set_dai_tristate(struct
snd_soc_dai *cpu_dai,
struct ssp_device *ssp = priv->ssp;
u32 sscr1;
- sscr1 = ssp_read_reg(ssp, SSCR1);
+ sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
if (tristate)
sscr1 &= ~SSCR1_TTE;
else
sscr1 |= SSCR1_TTE;
- ssp_write_reg(ssp, SSCR1, sscr1);
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
return 0;
}
@@ -477,14 +477,14 @@ static int pxa_ssp_set_dai_fmt(struct
snd_soc_dai *cpu_dai,
return 0;
/* we can only change the settings if the port is not in use */
- if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
+ if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
dev_err(&ssp->pdev->dev,
"can't change hardware dai format: stream is in use");
return -EINVAL;
}
/* reset port settings */
- sscr0 = ssp_read_reg(ssp, SSCR0) &
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
sspsp = 0;
@@ -536,9 +536,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
return -EINVAL;
}
- ssp_write_reg(ssp, SSCR0, sscr0);
- ssp_write_reg(ssp, SSCR1, sscr1);
- ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_ssp_write_reg(ssp, SSCR1, sscr1);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
dump_registers(ssp);
@@ -567,7 +567,7 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
u32 sscr0;
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
- int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+ int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
/* generate correct DMA params */
if (cpu_dai->dma_data)
@@ -577,20 +577,20 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
* 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,
+ cpu_dai->dma_data = pxa_ssp_get_dma_params(ssp,
((chn == 2) && (ttsa != 1)) || (width == 32),
substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
/* we can only change the settings if the port is not in use */
- if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
+ if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
return 0;
/* clear selected SSP bits */
- sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
- ssp_write_reg(ssp, SSCR0, sscr0);
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+ pxa_ssp_write_reg(ssp, SSCR0, sscr0);
/* bit size */
- sscr0 = ssp_read_reg(ssp, SSCR0);
+ sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
#ifdef CONFIG_PXA3xx
@@ -606,13 +606,13 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
break;
}
- ssp_write_reg(ssp, SSCR0, sscr0);
+ pxa_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);
+ sspsp = pxa_ssp_read_reg(ssp, SSPSP);
- if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
+ if ((pxa_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.
@@ -646,7 +646,7 @@ static int pxa_ssp_hw_params(struct
snd_pcm_substream *substream,
sspsp |= SSPSP_DMYSTRT(1);
}
- ssp_write_reg(ssp, SSPSP, sspsp);
+ pxa_ssp_write_reg(ssp, SSPSP, sspsp);
break;
default:
break;
@@ -677,45 +677,45 @@ static int pxa_ssp_trigger(struct
snd_pcm_substream *substream, int cmd,
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
- ssp_enable(ssp);
+ pxa_ssp_enable(ssp);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val |= SSCR1_TSRE;
else
val |= SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
- val = ssp_read_reg(ssp, SSSR);
- ssp_write_reg(ssp, SSSR, val);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
+ val = pxa_ssp_read_reg(ssp, SSSR);
+ pxa_ssp_write_reg(ssp, SSSR, val);
break;
case SNDRV_PCM_TRIGGER_START:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val |= SSCR1_TSRE;
else
val |= SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
- ssp_enable(ssp);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
+ pxa_ssp_enable(ssp);
break;
case SNDRV_PCM_TRIGGER_STOP:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val &= ~SSCR1_TSRE;
else
val &= ~SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
- ssp_disable(ssp);
+ pxa_ssp_disable(ssp);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- val = ssp_read_reg(ssp, SSCR1);
+ val = pxa_ssp_read_reg(ssp, SSCR1);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
val &= ~SSCR1_TSRE;
else
val &= ~SSCR1_RSRE;
- ssp_write_reg(ssp, SSCR1, val);
+ pxa_ssp_write_reg(ssp, SSCR1, val);
break;
default:
@@ -737,7 +737,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
if (!priv)
return -ENOMEM;
- priv->ssp = ssp_request(dai->id + 1, "SoC audio");
+ priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
if (priv->ssp == NULL) {
ret = -ENODEV;
goto err_priv;
@@ -757,7 +757,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
struct snd_soc_dai *dai)
{
struct ssp_priv *priv = dai->private_data;
- ssp_free(priv->ssp);
+ pxa_ssp_free(priv->ssp);
}
#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
--
1.5.6.5
1
0
These patches are based on ssp_cleanup of pxa git tree.
They're verified on pxa168 aspenite platform. Support I2S and Left J interface.
1
0
31 Mar '10
1
0
31 Mar '10
Greetings,
Pulseaudio can no longer detect sound cards on kernel 2.6.34-rc1.
Note that 2.6.33 is OK.
I noticed that the related sysfs directories/files changed.
Note that the card0/ directory is gone in new kernel:
2.6.33
wfg@hp ~% ll /sys/class/sound
total 0
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 timer -> ../../devices/virtual/sound/timer
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 pcmC0D1p -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D1p
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 pcmC0D0p -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0p
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 pcmC0D0c -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/pcmC0D0c
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 mixer5 -> ../../devices/platform/thinkpad_acpi/sound/card5/mixer5
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 mixer -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/mixer
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 hwC0D0 -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/hwC0D0
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 dsp -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/dsp
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 controlC5 -> ../../devices/platform/thinkpad_acpi/sound/card5/controlC5
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 controlC0 -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/controlC0
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 card5 -> ../../devices/platform/thinkpad_acpi/sound/card5
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 card0 -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 audio -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/audio
lrwxrwxrwx 1 root root 0 2010-03-31 12:23 adsp -> ../../devices/pci0000:00/0000:00:1b.0/sound/card0/adsp
2.6.34-rc1
wfg@hp ~% ll /sys/class/sound
total 0
drwxr-xr-x 3 root root 0 2010-03-31 19:27 timer
drwxr-xr-x 3 root root 0 2010-03-31 19:27 pcmC0D7p
drwxr-xr-x 3 root root 0 2010-03-31 19:27 pcmC0D3p
drwxr-xr-x 3 root root 0 2010-03-31 19:27 pcmC0D0p
drwxr-xr-x 3 root root 0 2010-03-31 19:27 pcmC0D0c
drwxr-xr-x 3 root root 0 2010-03-31 19:27 hwC0D3
drwxr-xr-x 3 root root 0 2010-03-31 19:27 hwC0D0
drwxr-xr-x 3 root root 0 2010-03-31 19:27 controlC0
Any ideas?
Thanks,
Fengguang
2
2
[alsa-devel] [PATCH] ALSA: hda: Fix 0 dB offset for Lenovo Thinkpad models using AD1981
by Daniel Chen 31 Mar '10
by Daniel Chen 31 Mar '10
31 Mar '10
Hi,
Attached is a patch against sound-2.6 master HEAD (applicable to
2.6.32.y and 2.6.33.y) that clamps the 0 dB offset accordingly.
Best,
-Dan
2
1
On Tue, Mar 30, 2010 at 06:23:18PM +0200, Valentin Longchamp wrote:
> I have quickly hacked something based on what you had done for
> pcm037 with the MC13783 codec in some of your first sound patches. I
> know that this is not ready for mainline and I'm still struggling to
> debug my code, but I would like to have results quite soon so that
> my colleague could see what sounds (especially regarding to the
> volume) our system is capable to produce.
If you're struggling to find time to do full support for the CODEC a
good technique is often to get just very basic fixed function support
(say just DAC to headphone support) implemented and merged, then go back
and implement
I'd also suggest looking at the current Freescale BSPs - obviously this
device is used on a lot of Freescale reference boards and I believe
there's a reasonably mainlineish driver in the BSPs they have for
current devices.
2
1
Hi Valentin,
On Tue, Mar 30, 2010 at 06:23:18PM +0200, Valentin Longchamp wrote:
> Hi Sascha,
>
> For one of our experiments where our robots need to produce sound, I
> would need a sound driver for mx31moboard platform.
>
> I have quickly hacked something based on what you had done for pcm037
> with the MC13783 codec in some of your first sound patches. I know that
> this is not ready for mainline and I'm still struggling to debug my
> code, but I would like to have results quite soon so that my colleague
> could see what sounds (especially regarding to the volume) our system is
> capable to produce.
>
> I would like to know if by any chance you have some updates on this code
> ?
Find the latest version of my code here:
The following changes since commit 01e77706cdde7c0b47e5ca1f4284a795504c7c40:
Linus Torvalds (1):
Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
are available in the git repository at:
git://git.pengutronix.de/git/sha/linux-2.6.git mc13783
Sascha Hauer (3):
add a mc13783 codec driver
add phycore-mc13783 sound support
pcm038: add sound support
arch/arm/mach-mx2/mach-pcm038.c | 23 ++-
sound/soc/codecs/Kconfig | 4 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/mc13783.c | 727 +++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/mc13783.h | 32 ++
sound/soc/imx/Kconfig | 9 +
sound/soc/imx/Makefile | 3 +
sound/soc/imx/phycore-mc13783.c | 160 +++++++++
8 files changed, 959 insertions(+), 1 deletions(-)
create mode 100644 sound/soc/codecs/mc13783.c
create mode 100644 sound/soc/codecs/mc13783.h
create mode 100644 sound/soc/imx/phycore-mc13783.c
> And do you know if your initial mc13783 codec support coupled with
> mx31 had some limitations ? Our setup is quite straightforward, we have
> direct connection from the mx31 to the mc13783 on a single SSI.
Our board uses both SSI channels of the MC13783 which we then mux into
one channel in the DAM unit. I don't know how this affects you.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
1
0