[alsa-devel] ASoC updates for 2.6.31
The following changes since commit 8560b9321f9050968f393ce1ec67e47c1a0bd5cf: Takashi Iwai (1): Merge branch 'fix/asoc' into topic/asoc
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.31
Jinyoung Park (1): ASoC: Fix errors in WM8990
Jonathan Cameron (1): ASoC: IMote2 ASoC Support
Lopez Cruz, Misael (2): ASoC: TWL4030: Add VDL analog bypass ASoC: TWL4030: Add voice digital loopback: sidetone
Mark Brown (15): ASoC: Fix error message formatting in s3c64xx-i2s driver ASoC: Check for supported CPUs when building s3c-i2s-v2 ASoC: Make S3C64xx clock export function to return struct clk ASoC: Fix data format configuration for S3C64xx IISv2 and add 24 bit ASoC: Fix boot warnings from S3C IISv2 ASoC: Allow use of resource from the platform device for S3C IISv2 ASoC: Display the clock rate used as the basis for rate calculation ASoC: Display S3C IISv2 mode and MS errors by default ASoC: Staticise txctrl and rxctrl for S3C IISv2 ASoC: Use platform device resource for S3C64xx IISv2 ASoC: Use a shared define for AC97 CODEC data formats ASoC: Remove unused DAI format defines Merge commit 'takashi/topic/asoc' into for-2.6.31 Merge branch 'for-2.6.30' into for-2.6.31 ASoC: Remove redundant codec pointer from DAIs
Peter Ujfalusi (1): ASoC: TWL4030: Add VIBRA output
include/sound/soc-dai.h | 28 ++------- sound/soc/codecs/ac97.c | 4 +- sound/soc/codecs/ad1980.c | 4 +- sound/soc/codecs/twl4030.c | 121 +++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/wm8990.c | 40 +++++++------- sound/soc/codecs/wm9705.c | 4 +- sound/soc/codecs/wm9712.c | 6 +- sound/soc/codecs/wm9713.c | 6 +- sound/soc/pxa/Kconfig | 9 +++ sound/soc/pxa/Makefile | 2 + sound/soc/pxa/imote2.c | 114 ++++++++++++++++++++++++++++++++++++ sound/soc/s3c24xx/s3c-i2s-v2.c | 87 ++++++++++++++++++++++++---- sound/soc/s3c24xx/s3c64xx-i2s.c | 15 ++--- sound/soc/s3c24xx/s3c64xx-i2s.h | 4 +- 14 files changed, 362 insertions(+), 82 deletions(-) create mode 100644 sound/soc/pxa/imote2.c
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c64xx-i2s.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 1345fbd..7679f7b 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -215,7 +215,7 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); if (IS_ERR(i2s->iis_cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus"); + dev_err(&pdev->dev, "failed to get audio-bus\n"); ret = PTR_ERR(i2s->iis_cclk); goto err; }
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index ab680aa..3b9201c 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -37,6 +37,20 @@
#include "s3c-i2s-v2.h"
+#undef S3C_IIS_V2_SUPPORTED + +#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#define S3C_IIS_V2_SUPPORTED +#endif + +#ifdef CONFIG_PLAT_S3C64XX +#define S3C_IIS_V2_SUPPORTED +#endif + +#ifndef S3C_IIS_V2_SUPPORTED +#error Unsupported CPU model +#endif + #define S3C2412_I2S_DEBUG_CON 0
static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
This makes the interface usable with the s3c-iis-v2 rate calculator and consistent with S3C2412.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c64xx-i2s.c | 7 +++---- sound/soc/s3c24xx/s3c64xx-i2s.h | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 7679f7b..cb11f78 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -108,14 +108,13 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, return 0; }
- -unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai) +struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) { struct s3c_i2sv2_info *i2s = to_info(dai);
- return clk_get_rate(i2s->iis_cclk); + return i2s->iis_cclk; } -EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); +EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
static int s3c64xx_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h index 597822a..02148ce 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ b/sound/soc/s3c24xx/s3c64xx-i2s.h @@ -15,6 +15,8 @@ #ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H #define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
+struct clk; + #include "s3c-i2s-v2.h"
#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK @@ -26,6 +28,6 @@
extern struct snd_soc_dai s3c64xx_i2s_dai[];
-extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); +extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
The data format configuration for S3C64xx IISv2 is completely different to that for S3C24xx. Instead of a single bit configuration in bit 0 of IISMOD we have format selection in bits 13 and 14 and bit clock rate selection in bits 1 and 2. While we're here add support for 24 bit samples in S3C64xx.
At some point it may be desirable to expose the bit clock rate selection to users but given the limited configuration options that may not be required.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 22 +++++++++++++++++++++- sound/soc/s3c24xx/s3c64xx-i2s.c | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 3b9201c..54f4119 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -280,7 +280,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, */ #define IISMOD_MASTER_MASK (1 << 11) #define IISMOD_SLAVE (1 << 11) -#define IISMOD_MASTER (0x0) +#define IISMOD_MASTER (0 << 11) #endif
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -341,6 +341,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, iismod = readl(i2s->regs + S3C2412_IISMOD); pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C2412_IISMOD_8BIT; @@ -349,6 +350,25 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, iismod &= ~S3C2412_IISMOD_8BIT; break; } +#endif + +#ifdef CONFIG_PLAT_S3C64XX + iismod &= ~0x606; + /* Sample size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + /* 8 bit sample, 16fs BCLK */ + iismod |= 0x2004; + break; + case SNDRV_PCM_FORMAT_S16_LE: + /* 16 bit sample, 32fs BCLK */ + break; + case SNDRV_PCM_FORMAT_S24_LE: + /* 24 bit sample, 48fs BCLK */ + iismod |= 0x4002; + break; + } +#endif
writel(iismod, i2s->regs + S3C2412_IISMOD); pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index cb11f78..e0f4a16 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -146,7 +146,8 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev, SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
#define S3C64XX_I2S_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) + (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE)
static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { .set_sysclk = s3c64xx_i2s_set_sysclk,
On startup we try to make sure that the port is quiesced but if the port is already stopped then this will generate a warning about the RX/TX mode configuration. Configure the mode before doing the teardown to suppress these warnings.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 54f4119..34142c8 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -573,6 +573,7 @@ int s3c_i2sv2_probe(struct platform_device *pdev, unsigned long base) { struct device *dev = &pdev->dev; + unsigned int iismod;
i2s->dev = dev;
@@ -594,12 +595,16 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
clk_enable(i2s->iis_pclk);
+ /* Mark ourselves as in TXRX mode so we can run through our cleanup + * process without warnings. */ + iismod = readl(i2s->regs + S3C2412_IISMOD); + iismod |= S3C2412_IISMOD_MODE_TXRX; + writel(iismod, i2s->regs + S3C2412_IISMOD); s3c2412_snd_txctrl(i2s, 0); s3c2412_snd_rxctrl(i2s, 0);
return 0; } - EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
#ifdef CONFIG_PM
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 34142c8..cb85498 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -580,6 +580,24 @@ int s3c_i2sv2_probe(struct platform_device *pdev, /* record our i2s structure for later use in the callbacks */ dai->private_data = i2s;
+ if (!base) { + struct resource *res = platform_get_resource(pdev, + IORESOURCE_MEM, + 0); + if (!res) { + dev_err(dev, "Unable to get register resource\n"); + return -ENXIO; + } + + if (!request_mem_region(res->start, resource_size(res), + "s3c64xx-i2s-v4")) { + dev_err(dev, "Unable to request register region\n"); + return -EBUSY; + } + + base = res->start; + } + i2s->regs = ioremap(base, 0x100); if (i2s->regs == NULL) { dev_err(dev, "cannot ioremap registers\n");
Aids debugging.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index cb85498..ad690b2 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -523,6 +523,8 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, unsigned int best_rate = 0; unsigned int best_deviation = INT_MAX;
+ pr_debug("Input clock rate %ldHz\n", clkrate); + if (fstab == NULL) fstab = iis_fs_tab;
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index ad690b2..bc4e504 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -295,7 +295,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= IISMOD_MASTER; break; default: - pr_debug("unknwon master/slave format\n"); + pr_err("unknwon master/slave format\n"); return -EINVAL; }
@@ -312,7 +312,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= S3C2412_IISMOD_SDF_IIS; break; default: - pr_debug("Unknown data format\n"); + pr_err("Unknown data format\n"); return -EINVAL; }
They aren't used by anything external and aren't prototyped; if any users appear they can be exported again for them.
Also report what modes we have a problem with when we encounter invalid mode configurations.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c-i2s-v2.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index bc4e504..972c276 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -89,7 +89,7 @@ static inline void dbg_showcon(const char *fn, u32 con)
/* Turn on or off the transmission path. */ -void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) +static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) { void __iomem *regs = i2s->regs; u32 fic, con, mod; @@ -119,7 +119,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break;
default: - dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; }
writel(con, regs + S3C2412_IISCON); @@ -146,7 +148,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break;
default: - dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; }
writel(mod, regs + S3C2412_IISMOD); @@ -157,9 +161,8 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) dbg_showcon(__func__, con); pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } -EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl);
-void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) +static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) { void __iomem *regs = i2s->regs; u32 fic, con, mod; @@ -189,7 +192,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break;
default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); }
writel(mod, regs + S3C2412_IISMOD); @@ -213,7 +217,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break;
default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); }
writel(con, regs + S3C2412_IISCON); @@ -223,7 +228,6 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) fic = readl(regs + S3C2412_IISFIC); pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } -EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl);
/* * Wait for the LR signal to allow synchronisation to the L/R clock
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/s3c24xx/s3c64xx-i2s.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index e0f4a16..3c06c40 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -220,8 +220,7 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) goto err; }
- ret = s3c_i2sv2_probe(pdev, dai, i2s, - dai->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); + ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); if (ret) goto err_clk;
The AC97 wire format is completely fixed so CODECs don't have any choice about the formats they accept but controllers accept a variety of data formats and render them down onto the bus. Have a shared define so all the CODEC drivers will interoperate with any of our controller drivers.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- include/sound/soc-dai.h | 3 +++ sound/soc/codecs/ac97.c | 4 ++-- sound/soc/codecs/ad1980.c | 4 ++-- sound/soc/codecs/wm9705.c | 4 ++-- sound/soc/codecs/wm9712.c | 6 +++--- sound/soc/codecs/wm9713.c | 6 +++--- 6 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 22b729f..ea07b4b 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -96,6 +96,9 @@ struct snd_pcm_substream; #define SND_SOC_CLOCK_IN 0 #define SND_SOC_CLOCK_OUT 1
+#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + struct snd_soc_dai_ops; struct snd_soc_dai; struct snd_ac97_bus_ops; diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index b0d4af1..932299b 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -53,13 +53,13 @@ struct snd_soc_dai ac97_dai = { .channels_min = 1, .channels_max = 2, .rates = STD_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .capture = { .stream_name = "AC97 Capture", .channels_min = 1, .channels_max = 2, .rates = STD_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .ops = &ac97_dai_ops, }; EXPORT_SYMBOL_GPL(ac97_dai); diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index ddb3b08..d7440a9 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -137,13 +137,13 @@ struct snd_soc_dai ad1980_dai = { .channels_min = 2, .channels_max = 6, .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, }, + .formats = SND_SOC_STD_AC97_FMTS, }, .capture = { .stream_name = "Capture", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, }, + .formats = SND_SOC_STD_AC97_FMTS, }, }; EXPORT_SYMBOL_GPL(ad1980_dai);
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index c2d1a7a..fa88b46 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -282,14 +282,14 @@ struct snd_soc_dai wm9705_dai[] = { .channels_min = 1, .channels_max = 2, .rates = WM9705_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SND_SOC_STD_AC97_FMTS, }, .capture = { .stream_name = "HiFi Capture", .channels_min = 1, .channels_max = 2, .rates = WM9705_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SND_SOC_STD_AC97_FMTS, }, .ops = &wm9705_dai_ops, }, diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 765cf1e..550c903 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -534,13 +534,13 @@ struct snd_soc_dai wm9712_dai[] = { .channels_min = 1, .channels_max = 2, .rates = WM9712_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .capture = { .stream_name = "HiFi Capture", .channels_min = 1, .channels_max = 2, .rates = WM9712_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .ops = &wm9712_dai_ops_hifi, }, { @@ -550,7 +550,7 @@ struct snd_soc_dai wm9712_dai[] = { .channels_min = 1, .channels_max = 1, .rates = WM9712_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .ops = &wm9712_dai_ops_aux, } }; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index a6feb78..d1744e9 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1040,13 +1040,13 @@ struct snd_soc_dai wm9713_dai[] = { .channels_min = 1, .channels_max = 2, .rates = WM9713_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .capture = { .stream_name = "HiFi Capture", .channels_min = 1, .channels_max = 2, .rates = WM9713_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .ops = &wm9713_dai_ops_hifi, }, { @@ -1056,7 +1056,7 @@ struct snd_soc_dai wm9713_dai[] = { .channels_min = 1, .channels_max = 1, .rates = WM9713_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .formats = SND_SOC_STD_AC97_FMTS,}, .ops = &wm9713_dai_ops_aux, }, {
The defines for TDM and synchronous clocks are not used - they are mostly a legacy of the automatic clocking configuration. TDM will require configuration of the number of timeslots and which ones to use so can't be fit into the DAI format and synchronous mode is handled by symmetric_rates (and needs to be done by constraints rather than when the DAI format is being configured).
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- include/sound/soc-dai.h | 18 ------------------ 1 files changed, 0 insertions(+), 18 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index ea07b4b..a997c2c 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -45,24 +45,6 @@ struct snd_pcm_substream; #define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
/* - * DAI Left/Right Clocks. - * - * Specifies whether the DAI can support different samples for similtanious - * playback and capture. This usually requires a seperate physical frame - * clock for playback and capture. - */ -#define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */ -#define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */ - -/* - * TDM - * - * Time Division Multiplexing. Allows PCM data to be multplexed with other - * data on the DAI. - */ -#define SND_SOC_DAIFMT_TDM (1 << 6) - -/* * DAI hardware signal inversions. * * Specifies whether the DAI can also support inverted clocks for the specified
From: Jinyoung Park parkjy@mtekvision.com
The mis-typing exist in dapm controller definitions and dapm route definitions, so happen mis-matched error when snd_soc_dapm_add_routes().
Cc: stable@kernel.org Signed-off-by: Jinyoung Park parkjy@mtekvision.com Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/wm8990.c | 40 ++++++++++++++++++++-------------------- 1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c518c3e..40cd274 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -729,7 +729,7 @@ SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0, inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* AINLMUX */ -SND_SOC_DAPM_MUX_E("AILNMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0, +SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0, &wm8990_dapm_ainlmux_controls, inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -740,7 +740,7 @@ SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0, inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* AINRMUX */ -SND_SOC_DAPM_MUX_E("AIRNMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0, +SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0, &wm8990_dapm_ainrmux_controls, inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -848,40 +848,40 @@ static const struct snd_soc_dapm_route audio_map[] = { {"LIN12 PGA", "LIN2 Switch", "LIN2"}, /* LIN34 PGA */ {"LIN34 PGA", "LIN3 Switch", "LIN3"}, - {"LIN34 PGA", "LIN4 Switch", "LIN4"}, + {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"}, /* INMIXL */ {"INMIXL", "Record Left Volume", "LOMIX"}, {"INMIXL", "LIN2 Volume", "LIN2"}, {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"}, {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"}, - /* AILNMUX */ - {"AILNMUX", "INMIXL Mix", "INMIXL"}, - {"AILNMUX", "DIFFINL Mix", "LIN12PGA"}, - {"AILNMUX", "DIFFINL Mix", "LIN34PGA"}, - {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"}, - {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"}, + /* AINLMUX */ + {"AINLMUX", "INMIXL Mix", "INMIXL"}, + {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"}, + {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"}, + {"AINLMUX", "RXVOICE Mix", "LIN4/RXN"}, + {"AINLMUX", "RXVOICE Mix", "RIN4/RXP"}, /* ADC */ - {"Left ADC", NULL, "AILNMUX"}, + {"Left ADC", NULL, "AINLMUX"},
/* RIN12 PGA */ {"RIN12 PGA", "RIN1 Switch", "RIN1"}, {"RIN12 PGA", "RIN2 Switch", "RIN2"}, /* RIN34 PGA */ {"RIN34 PGA", "RIN3 Switch", "RIN3"}, - {"RIN34 PGA", "RIN4 Switch", "RIN4"}, + {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"}, /* INMIXL */ {"INMIXR", "Record Right Volume", "ROMIX"}, {"INMIXR", "RIN2 Volume", "RIN2"}, {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"}, {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"}, - /* AIRNMUX */ - {"AIRNMUX", "INMIXR Mix", "INMIXR"}, - {"AIRNMUX", "DIFFINR Mix", "RIN12PGA"}, - {"AIRNMUX", "DIFFINR Mix", "RIN34PGA"}, - {"AIRNMUX", "RXVOICE Mix", "RIN4/RXN"}, - {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"}, + /* AINRMUX */ + {"AINRMUX", "INMIXR Mix", "INMIXR"}, + {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"}, + {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"}, + {"AINRMUX", "RXVOICE Mix", "LIN4/RXN"}, + {"AINRMUX", "RXVOICE Mix", "RIN4/RXP"}, /* ADC */ - {"Right ADC", NULL, "AIRNMUX"}, + {"Right ADC", NULL, "AINRMUX"},
/* LOMIX */ {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"}, @@ -922,7 +922,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
/* OUT3MIX */ - {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXP"}, + {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"}, {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
/* OUT4MIX */ @@ -949,7 +949,7 @@ static const struct snd_soc_dapm_route audio_map[] = { /* Output Pins */ {"LON", NULL, "LONMIX"}, {"LOP", NULL, "LOPMIX"}, - {"OUT", NULL, "OUT3MIX"}, + {"OUT3", NULL, "OUT3MIX"}, {"LOUT", NULL, "LOUT PGA"}, {"SPKN", NULL, "SPKMIX"}, {"ROUT", NULL, "ROUT PGA"},
From: Lopez Cruz, Misael x0052729@ti.com
This patch adds voice downlink analog bypass switch. It follows the same approach as in other analog bypass switches. DAC switch is moved from 'DAC Voice' to 'Analog Voice Playback Mixer', that will also allow voice DAC to be powered in digital voice loopback (sidetone).
Signed-off-by: Misael Lopez Cruz x0052729@ti.com Acked-by: Peter Ujfalusi peter.ujfalusi@nokia.com Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/twl4030.c | 37 +++++++++++++++++++++++++++++++------ 1 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index efa1a80..efb371f 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -468,6 +468,10 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control = static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
+/* Analog bypass for Voice */ +static const struct snd_kcontrol_new twl4030_dapm_abypassv_control = + SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0); + /* Digital bypass gain, 0 mutes the bypass */ static const unsigned int twl4030_dapm_dbypass_tlv[] = { TLV_DB_RANGE_HEAD(2), @@ -585,7 +589,7 @@ static int bypass_event(struct snd_soc_dapm_widget *w, struct soc_mixer_control *m = (struct soc_mixer_control *)w->kcontrols->private_value; struct twl4030_priv *twl4030 = w->codec->private_data; - unsigned char reg; + unsigned char reg, misc;
reg = twl4030_read_reg_cache(w->codec, m->reg);
@@ -597,14 +601,28 @@ static int bypass_event(struct snd_soc_dapm_widget *w, else twl4030->bypass_state &= ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); + } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) { + /* Analog voice bypass */ + if (reg & (1 << m->shift)) + twl4030->bypass_state |= (1 << 4); + else + twl4030->bypass_state &= ~(1 << 4); } else { /* Digital bypass */ if (reg & (0x7 << m->shift)) - twl4030->bypass_state |= (1 << (m->shift ? 5 : 4)); + twl4030->bypass_state |= (1 << (m->shift ? 6 : 5)); else - twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4)); + twl4030->bypass_state &= ~(1 << (m->shift ? 6 : 5)); }
+ /* Enable master analog loopback mode if any analog switch is enabled*/ + misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1); + if (twl4030->bypass_state & 0x1F) + misc |= TWL4030_FMLOOP_EN; + else + misc &= ~TWL4030_FMLOOP_EN; + twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc); + if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { if (twl4030->bypass_state) twl4030_codec_mute(w->codec, 0); @@ -935,7 +953,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback", - TWL4030_REG_AVDAC_CTL, 4, 0), + SND_SOC_NOPM, 0, 0),
/* Analog PGAs */ SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, @@ -962,6 +980,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, &twl4030_dapm_abypassl2_control, bypass_event, SND_SOC_DAPM_POST_REG), + SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_abypassv_control, + bypass_event, SND_SOC_DAPM_POST_REG),
/* Digital bypasses */ SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, @@ -979,6 +1000,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { 2, 0, NULL, 0), SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0), + SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", TWL4030_REG_AVDAC_CTL, + 4, 0, NULL, 0),
/* Output MIXER controls */ /* Earpiece */ @@ -1067,13 +1090,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, {"Analog L2 Playback Mixer", NULL, "DAC Left2"}, {"Analog R2 Playback Mixer", NULL, "DAC Right2"}, + {"Analog Voice Playback Mixer", NULL, "DAC Voice"},
{"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"}, {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"}, {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, - - {"VDL_APGA", NULL, "DAC Voice"}, + {"VDL_APGA", NULL, "Analog Voice Playback Mixer"},
/* Internal playback routings */ /* Earpiece */ @@ -1169,11 +1192,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, + {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"},
{"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"}, + {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
/* Digital bypass routes */ {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
From: Lopez Cruz, Misael x0052729@ti.com
This patch add voice digital loopback (sidetone) to the twl4030 driver. It mixes voice uplink attenuated (by sidetone gain) with voice downlink when the codec is working in option2 (voice/audio mode).
Signed-off-by: Misael Lopez Cruz x0052729@ti.com Acked-by: Peter Ujfalusi peter.ujfalusi@nokia.com Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/twl4030.c | 27 +++++++++++++++++++++++++-- 1 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index efb371f..23bae74 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -491,6 +491,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control = TWL4030_REG_ATX2ARXPGA, 0, 7, 0, twl4030_dapm_dbypass_tlv);
+/* + * Voice Sidetone GAIN volume control: + * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB) + */ +static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1); + +/* Digital bypass voice: sidetone (VUL -> VDL)*/ +static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control = + SOC_DAPM_SINGLE_TLV("Volume", + TWL4030_REG_VSTPGA, 0, 0x29, 0, + twl4030_dapm_dbypassv_tlv); + static int micpath_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -607,12 +619,18 @@ static int bypass_event(struct snd_soc_dapm_widget *w, twl4030->bypass_state |= (1 << 4); else twl4030->bypass_state &= ~(1 << 4); + } else if (m->reg == TWL4030_REG_VSTPGA) { + /* Voice digital bypass */ + if (reg) + twl4030->bypass_state |= (1 << 5); + else + twl4030->bypass_state &= ~(1 << 5); } else { /* Digital bypass */ if (reg & (0x7 << m->shift)) - twl4030->bypass_state |= (1 << (m->shift ? 6 : 5)); + twl4030->bypass_state |= (1 << (m->shift ? 7 : 6)); else - twl4030->bypass_state &= ~(1 << (m->shift ? 6 : 5)); + twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6)); }
/* Enable master analog loopback mode if any analog switch is enabled*/ @@ -991,6 +1009,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, &twl4030_dapm_dbypassr_control, bypass_event, SND_SOC_DAPM_POST_REG), + SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_dbypassv_control, bypass_event, + SND_SOC_DAPM_POST_REG),
SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0), @@ -1203,9 +1224,11 @@ static const struct snd_soc_dapm_route intercon[] = { /* Digital bypass routes */ {"Right Digital Loopback", "Volume", "TX1 Capture Route"}, {"Left Digital Loopback", "Volume", "TX1 Capture Route"}, + {"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
{"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"}, {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"}, + {"Analog Voice Playback Mixer", NULL, "Voice Digital Loopback"},
};
From: Jonathan Cameron jic23@cam.ac.uk
This patch adds the ASoC side of the board support for the Crossbow IMB400 daughter board.
Thanks to Crossbow for considerable assistance.
Signed-off-by: Jonathan Cameron jic23@cam.ac.uk Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/pxa/Kconfig | 9 ++++ sound/soc/pxa/Makefile | 2 + sound/soc/pxa/imote2.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 sound/soc/pxa/imote2.c
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index ad8a10f..eb75a1c 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -134,3 +134,12 @@ config SND_PXA2XX_SOC_MIOA701 help Say Y if you want to add support for SoC audio on the MIO A701. + +config SND_PXA2XX_SOC_IMOTE2 + tristate "SoC Audio support for IMote 2" + depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 + select SND_PXA2XX_SOC_I2S + select SND_SOC_WM8940 + help + Say Y if you want to add support for SoC audio on the + IMote 2. diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index 4b90c3c..6e096b4 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o snd-soc-zylonite-objs := zylonite.o snd-soc-magician-objs := magician.o snd-soc-mioa701-objs := mioa701_wm9713.o +snd-soc-imote2-objs := imote2.o
obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o @@ -35,3 +36,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o +obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c new file mode 100644 index 0000000..405587a --- /dev/null +++ b/sound/soc/pxa/imote2.c @@ -0,0 +1,114 @@ + +#include <linux/module.h> +#include <sound/soc.h> + +#include <asm/mach-types.h> + +#include "../codecs/wm8940.h" +#include "pxa2xx-i2s.h" +#include "pxa2xx-pcm.h" + +static int imote2_asoc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + unsigned int clk = 0; + int ret; + + switch (params_rate(params)) { + case 8000: + case 16000: + case 48000: + case 96000: + clk = 12288000; + break; + case 11025: + case 22050: + case 44100: + clk = 11289600; + break; + } + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* CPU should be clock master */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set the I2S system clock as input (unused) */ + ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk, + SND_SOC_CLOCK_OUT); + + return ret; +} + +static struct snd_soc_ops imote2_asoc_ops = { + .hw_params = imote2_asoc_hw_params, +}; + +static struct snd_soc_dai_link imote2_dai = { + .name = "WM8940", + .stream_name = "WM8940", + .cpu_dai = &pxa_i2s_dai, + .codec_dai = &wm8940_dai, + .ops = &imote2_asoc_ops, +}; + +static struct snd_soc_card snd_soc_imote2 = { + .name = "Imote2", + .platform = &pxa2xx_soc_platform, + .dai_link = &imote2_dai, + .num_links = 1, +}; + +static struct snd_soc_device imote2_snd_devdata = { + .card = &snd_soc_imote2, + .codec_dev = &soc_codec_dev_wm8940, +}; + +static struct platform_device *imote2_snd_device; + +static int __init imote2_asoc_init(void) +{ + int ret; + + if (!machine_is_intelmote2()) + return -ENODEV; + imote2_snd_device = platform_device_alloc("soc-audio", -1); + if (!imote2_snd_device) + return -ENOMEM; + + platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata); + imote2_snd_devdata.dev = &imote2_snd_device->dev; + ret = platform_device_add(imote2_snd_device); + if (ret) + platform_device_put(imote2_snd_device); + + return ret; +} +module_init(imote2_asoc_init); + +static void __exit imote2_asoc_exit(void) +{ + platform_device_unregister(imote2_snd_device); +} +module_exit(imote2_asoc_exit); + +MODULE_AUTHOR("Jonathan Cameron"); +MODULE_DESCRIPTION("ALSA SoC Imote 2"); +MODULE_LICENSE("GPL");
From: Peter Ujfalusi peter.ujfalusi@nokia.com
This patch adds support for the VIBRA output on TWL4030 codec. The VIBRA output can be driven with audio data or with local vibrator driver. Add the needed DAPM elements and routes for the VIBRA output and controls for the VIBRA driver configuration.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@nokia.com Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- sound/soc/codecs/twl4030.c | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 23bae74..1a00e4b 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -396,6 +396,31 @@ static const struct soc_enum twl4030_handsfreer_enum = static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
+/* Vibra */ +/* Vibra audio path selection */ +static const char *twl4030_vibra_texts[] = + {"AudioL1", "AudioR1", "AudioL2", "AudioR2"}; + +static const struct soc_enum twl4030_vibra_enum = + SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2, + ARRAY_SIZE(twl4030_vibra_texts), + twl4030_vibra_texts); + +static const struct snd_kcontrol_new twl4030_dapm_vibra_control = +SOC_DAPM_ENUM("Route", twl4030_vibra_enum); + +/* Vibra path selection: local vibrator (PWM) or audio driven */ +static const char *twl4030_vibrapath_texts[] = + {"Local vibrator", "Audio"}; + +static const struct soc_enum twl4030_vibrapath_enum = + SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4, + ARRAY_SIZE(twl4030_vibrapath_texts), + twl4030_vibrapath_texts); + +static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control = +SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum); + /* Left analog microphone selection */ static const char *twl4030_analoglmic_texts[] = {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"}; @@ -867,6 +892,26 @@ static const struct soc_enum twl4030_rampdelay_enum = ARRAY_SIZE(twl4030_rampdelay_texts), twl4030_rampdelay_texts);
+/* Vibra H-bridge direction mode */ +static const char *twl4030_vibradirmode_texts[] = { + "Vibra H-bridge direction", "Audio data MSB", +}; + +static const struct soc_enum twl4030_vibradirmode_enum = + SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5, + ARRAY_SIZE(twl4030_vibradirmode_texts), + twl4030_vibradirmode_texts); + +/* Vibra H-bridge direction */ +static const char *twl4030_vibradir_texts[] = { + "Positive polarity", "Negative polarity", +}; + +static const struct soc_enum twl4030_vibradir_enum = + SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1, + ARRAY_SIZE(twl4030_vibradir_texts), + twl4030_vibradir_texts); + static const struct snd_kcontrol_new twl4030_snd_controls[] = { /* Common playback gain controls */ SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", @@ -933,6 +978,9 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { 0, 3, 5, 0, input_gain_tlv),
SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), + + SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), + SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum), };
static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { @@ -960,6 +1008,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("CARKITR"), SND_SOC_DAPM_OUTPUT("HFL"), SND_SOC_DAPM_OUTPUT("HFR"), + SND_SOC_DAPM_OUTPUT("VIBRA"),
/* DACs */ SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", @@ -1060,6 +1109,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0, &twl4030_dapm_handsfreer_control, handsfree_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + /* Vibra */ + SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, + &twl4030_dapm_vibra_control), + SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_vibrapath_control),
/* Introducing four virtual ADC, since TWL4030 have four channel for capture */ @@ -1161,6 +1215,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"}, {"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"}, {"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"}, + /* Vibra */ + {"Vibra Mux", "AudioL1", "DAC Left1"}, + {"Vibra Mux", "AudioR1", "DAC Right1"}, + {"Vibra Mux", "AudioL2", "DAC Left2"}, + {"Vibra Mux", "AudioR2", "DAC Right2"},
/* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, @@ -1174,6 +1233,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"CARKITR", NULL, "CarkitR Mixer"}, {"HFL", NULL, "HandsfreeL Mux"}, {"HFR", NULL, "HandsfreeR Mux"}, + {"Vibra Route", "Audio", "Vibra Mux"}, + {"VIBRA", NULL, "Vibra Route"},
/* Capture path */ {"Analog Left Capture Route", "Main mic", "MAINMIC"},
The DAI structure has two pointers to the codec, one in the body of the DAI and one in a union for a parent pointer. Drop the parent pointer version.
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- include/sound/soc-dai.h | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index a997c2c..496dc30 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -205,11 +205,8 @@ struct snd_soc_dai { /* DAI private data */ void *private_data;
- /* parent codec/platform */ - union { - struct snd_soc_codec *codec; - struct snd_soc_platform *platform; - }; + /* parent platform */ + struct snd_soc_platform *platform;
struct list_head list; };
At Tue, 5 May 2009 11:01:23 +0100, Mark Brown wrote:
The following changes since commit 8560b9321f9050968f393ce1ec67e47c1a0bd5cf: Takashi Iwai (1): Merge branch 'fix/asoc' into topic/asoc
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.31
Pulled this one, too. Thanks.
Takashi
Jinyoung Park (1): ASoC: Fix errors in WM8990
Jonathan Cameron (1): ASoC: IMote2 ASoC Support
Lopez Cruz, Misael (2): ASoC: TWL4030: Add VDL analog bypass ASoC: TWL4030: Add voice digital loopback: sidetone
Mark Brown (15): ASoC: Fix error message formatting in s3c64xx-i2s driver ASoC: Check for supported CPUs when building s3c-i2s-v2 ASoC: Make S3C64xx clock export function to return struct clk ASoC: Fix data format configuration for S3C64xx IISv2 and add 24 bit ASoC: Fix boot warnings from S3C IISv2 ASoC: Allow use of resource from the platform device for S3C IISv2 ASoC: Display the clock rate used as the basis for rate calculation ASoC: Display S3C IISv2 mode and MS errors by default ASoC: Staticise txctrl and rxctrl for S3C IISv2 ASoC: Use platform device resource for S3C64xx IISv2 ASoC: Use a shared define for AC97 CODEC data formats ASoC: Remove unused DAI format defines Merge commit 'takashi/topic/asoc' into for-2.6.31 Merge branch 'for-2.6.30' into for-2.6.31 ASoC: Remove redundant codec pointer from DAIs
Peter Ujfalusi (1): ASoC: TWL4030: Add VIBRA output
include/sound/soc-dai.h | 28 ++------- sound/soc/codecs/ac97.c | 4 +- sound/soc/codecs/ad1980.c | 4 +- sound/soc/codecs/twl4030.c | 121 +++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/wm8990.c | 40 +++++++------- sound/soc/codecs/wm9705.c | 4 +- sound/soc/codecs/wm9712.c | 6 +- sound/soc/codecs/wm9713.c | 6 +- sound/soc/pxa/Kconfig | 9 +++ sound/soc/pxa/Makefile | 2 + sound/soc/pxa/imote2.c | 114 ++++++++++++++++++++++++++++++++++++ sound/soc/s3c24xx/s3c-i2s-v2.c | 87 ++++++++++++++++++++++++---- sound/soc/s3c24xx/s3c64xx-i2s.c | 15 ++--- sound/soc/s3c24xx/s3c64xx-i2s.h | 4 +- 14 files changed, 362 insertions(+), 82 deletions(-) create mode 100644 sound/soc/pxa/imote2.c
participants (2)
-
Mark Brown
-
Takashi Iwai