Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* ASoC updates for 2.6.31
@ 2009-04-14 12:32 Mark Brown
  2009-04-14 12:32 ` [PATCH 01/14] ASoC: Add driver for s6000 I2S interface Mark Brown
                   ` (14 more replies)
  0 siblings, 15 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:32 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 34e51ce60a210094bd66cf0a75dd8512247618ca:
  Takashi Iwai (1):
        Merge branch 'for-2.6.30' of git://git.kernel.org/.../broonie/sound-2.6 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

Alexander Beregalov (1):
      ASoC: n810: replace BUG() with BUG_ON()

Daniel Glöckner (3):
      ASoC: Add driver for s6000 I2S interface
      ASoC: s6105 IP camera machine specific ASoC code
      ASoC: correct s6000 I2S clock polarity

Daniel Ribeiro (1):
      ASoC: pxa-ssp.c fix clock/frame invert

Mark Brown (11):
      ASoC: Display return code when failing to add a DAPM kcontrol
      ASoC: Provide core support for symmetric sample rates
      ASoC: Add WM8988 CODEC driver
      Merge branch 's6000' into for-2.6.31
      ASoC: WM9713 requires symmetric rates on the voice DAI
      ASoC: Factor out application of power for generic widgets
      ASoC: Support DAPM events for DACs and ADCs
      ASoC: Move the WM9713 voice DAC powerdown to a DAPM event
      ASoC: Add WM8960 CODEC driver
      Merge branch 'for-2.6.30' into for-2.6.31
      Merge branch 'for-2.6.30' into for-2.6.31

Peter Ujfalusi (1):
      ASoC: tlv320aic23: add DSP_A format support

 include/sound/soc-dai.h        |    1 +
 include/sound/soc-dapm.h       |   10 +
 include/sound/soc.h            |    6 +
 sound/soc/Kconfig              |    1 +
 sound/soc/Makefile             |    1 +
 sound/soc/codecs/Kconfig       |    8 +
 sound/soc/codecs/Makefile      |    4 +
 sound/soc/codecs/tlv320aic23.c |    2 +
 sound/soc/codecs/wm8960.c      |  969 +++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm8960.h      |  127 +++++
 sound/soc/codecs/wm8988.c      | 1097 ++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm8988.h      |   60 +++
 sound/soc/codecs/wm9713.c      |   40 +-
 sound/soc/omap/n810.c          |    7 +-
 sound/soc/pxa/pxa-ssp.c        |   11 +-
 sound/soc/s6000/Kconfig        |   19 +
 sound/soc/s6000/Makefile       |   11 +
 sound/soc/s6000/s6000-i2s.c    |  629 +++++++++++++++++++++++
 sound/soc/s6000/s6000-i2s.h    |   25 +
 sound/soc/s6000/s6000-pcm.c    |  497 ++++++++++++++++++
 sound/soc/s6000/s6000-pcm.h    |   35 ++
 sound/soc/s6000/s6105-ipcam.c  |  244 +++++++++
 sound/soc/soc-core.c           |   38 ++
 sound/soc/soc-dapm.c           |  131 +++---
 24 files changed, 3893 insertions(+), 80 deletions(-)
 create mode 100644 sound/soc/codecs/wm8960.c
 create mode 100644 sound/soc/codecs/wm8960.h
 create mode 100644 sound/soc/codecs/wm8988.c
 create mode 100644 sound/soc/codecs/wm8988.h
 create mode 100644 sound/soc/s6000/Kconfig
 create mode 100644 sound/soc/s6000/Makefile
 create mode 100644 sound/soc/s6000/s6000-i2s.c
 create mode 100644 sound/soc/s6000/s6000-i2s.h
 create mode 100644 sound/soc/s6000/s6000-pcm.c
 create mode 100644 sound/soc/s6000/s6000-pcm.h
 create mode 100644 sound/soc/s6000/s6105-ipcam.c

^ permalink raw reply	[flat|nested] 56+ messages in thread

* [PATCH 01/14] ASoC: Add driver for s6000 I2S interface
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
@ 2009-04-14 12:32 ` Mark Brown
  2009-04-14 12:33 ` [PATCH] mx31ads: Depend on all the WM8350 core dependencies for WM1133-EV1 board Mark Brown
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:32 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Daniel Glöckner

From: Daniel Glöckner <dg@emlix.com>

This patch adds a driver for the I2S interface found on Stretch s6000
family processors.

Signed-off-by: Daniel Glöckner <dg@emlix.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/Kconfig           |    1 +
 sound/soc/Makefile          |    1 +
 sound/soc/s6000/Kconfig     |   10 +
 sound/soc/s6000/Makefile    |    6 +
 sound/soc/s6000/s6000-i2s.c |  629 +++++++++++++++++++++++++++++++++++++++++++
 sound/soc/s6000/s6000-i2s.h |   25 ++
 sound/soc/s6000/s6000-pcm.c |  497 ++++++++++++++++++++++++++++++++++
 sound/soc/s6000/s6000-pcm.h |   35 +++
 8 files changed, 1204 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/s6000/Kconfig
 create mode 100644 sound/soc/s6000/Makefile
 create mode 100644 sound/soc/s6000/s6000-i2s.c
 create mode 100644 sound/soc/s6000/s6000-i2s.h
 create mode 100644 sound/soc/s6000/s6000-pcm.c
 create mode 100644 sound/soc/s6000/s6000-pcm.h

diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 3d2bb6f..3304f9d 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -32,6 +32,7 @@ source "sound/soc/fsl/Kconfig"
 source "sound/soc/omap/Kconfig"
 source "sound/soc/pxa/Kconfig"
 source "sound/soc/s3c24xx/Kconfig"
+source "sound/soc/s6000/Kconfig"
 source "sound/soc/sh/Kconfig"
 
 # Supported codecs
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 0237879..8943a14 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_SND_SOC)	+= fsl/
 obj-$(CONFIG_SND_SOC)	+= omap/
 obj-$(CONFIG_SND_SOC)	+= pxa/
 obj-$(CONFIG_SND_SOC)	+= s3c24xx/
+obj-$(CONFIG_SND_SOC)	+= s6000/
 obj-$(CONFIG_SND_SOC)	+= sh/
diff --git a/sound/soc/s6000/Kconfig b/sound/soc/s6000/Kconfig
new file mode 100644
index 0000000..4bfc8bc
--- /dev/null
+++ b/sound/soc/s6000/Kconfig
@@ -0,0 +1,10 @@
+config SND_S6000_SOC
+	tristate "SoC Audio for the Stretch s6000 family"
+	depends on XTENSA_VARIANT_S6000
+	help
+	  Say Y or M if you want to add support for codecs attached to
+	  s6000 family chips. You will also need to select the platform
+	  to support below.
+
+config SND_S6000_SOC_I2S
+	tristate
diff --git a/sound/soc/s6000/Makefile b/sound/soc/s6000/Makefile
new file mode 100644
index 0000000..df15f87
--- /dev/null
+++ b/sound/soc/s6000/Makefile
@@ -0,0 +1,6 @@
+# s6000 Platform Support
+snd-soc-s6000-objs := s6000-pcm.o
+snd-soc-s6000-i2s-objs := s6000-i2s.o
+
+obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o
+obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
new file mode 100644
index 0000000..dcc7904
--- /dev/null
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -0,0 +1,629 @@
+/*
+ * ALSA SoC I2S Audio Layer for the Stretch S6000 family
+ *
+ * Author:      Daniel Gloeckner, <dg@emlix.com>
+ * Copyright:   (C) 2009 emlix GmbH <info@emlix.com>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include "s6000-i2s.h"
+#include "s6000-pcm.h"
+
+struct s6000_i2s_dev {
+	dma_addr_t sifbase;
+	u8 __iomem *scbbase;
+	unsigned int wide;
+	unsigned int channel_in;
+	unsigned int channel_out;
+	unsigned int lines_in;
+	unsigned int lines_out;
+	struct s6000_pcm_dma_params dma_params;
+};
+
+#define S6_I2S_INTERRUPT_STATUS	0x00
+#define   S6_I2S_INT_OVERRUN	1
+#define   S6_I2S_INT_UNDERRUN	2
+#define   S6_I2S_INT_ALIGNMENT	4
+#define S6_I2S_INTERRUPT_ENABLE	0x04
+#define S6_I2S_INTERRUPT_RAW	0x08
+#define S6_I2S_INTERRUPT_CLEAR	0x0C
+#define S6_I2S_INTERRUPT_SET	0x10
+#define S6_I2S_MODE		0x20
+#define   S6_I2S_DUAL		0
+#define   S6_I2S_WIDE		1
+#define S6_I2S_TX_DEFAULT	0x24
+#define S6_I2S_DATA_CFG(c)	(0x40 + 0x10 * (c))
+#define   S6_I2S_IN		0
+#define   S6_I2S_OUT		1
+#define   S6_I2S_UNUSED		2
+#define S6_I2S_INTERFACE_CFG(c)	(0x44 + 0x10 * (c))
+#define   S6_I2S_DIV_MASK	0x001fff
+#define   S6_I2S_16BIT		0x000000
+#define   S6_I2S_20BIT		0x002000
+#define   S6_I2S_24BIT		0x004000
+#define   S6_I2S_32BIT		0x006000
+#define   S6_I2S_BITS_MASK	0x006000
+#define   S6_I2S_MEM_16BIT	0x000000
+#define   S6_I2S_MEM_32BIT	0x008000
+#define   S6_I2S_MEM_MASK	0x008000
+#define   S6_I2S_CHANNELS_SHIFT	16
+#define   S6_I2S_CHANNELS_MASK	0x030000
+#define   S6_I2S_SCK_IN		0x000000
+#define   S6_I2S_SCK_OUT	0x040000
+#define   S6_I2S_SCK_DIR	0x040000
+#define   S6_I2S_WS_IN		0x000000
+#define   S6_I2S_WS_OUT		0x080000
+#define   S6_I2S_WS_DIR		0x080000
+#define   S6_I2S_LEFT_FIRST	0x000000
+#define   S6_I2S_RIGHT_FIRST	0x100000
+#define   S6_I2S_FIRST		0x100000
+#define   S6_I2S_CUR_SCK	0x200000
+#define   S6_I2S_CUR_WS		0x400000
+#define S6_I2S_ENABLE(c)	(0x48 + 0x10 * (c))
+#define   S6_I2S_DISABLE_IF	0x02
+#define   S6_I2S_ENABLE_IF	0x03
+#define   S6_I2S_IS_BUSY	0x04
+#define   S6_I2S_DMA_ACTIVE	0x08
+#define   S6_I2S_IS_ENABLED	0x10
+
+#define S6_I2S_NUM_LINES	4
+
+#define S6_I2S_SIF_PORT0	0x0000000
+#define S6_I2S_SIF_PORT1	0x0000080 /* docs say 0x0000010 */
+
+static inline void s6_i2s_write_reg(struct s6000_i2s_dev *dev, int reg, u32 val)
+{
+	writel(val, dev->scbbase + reg);
+}
+
+static inline u32 s6_i2s_read_reg(struct s6000_i2s_dev *dev, int reg)
+{
+	return readl(dev->scbbase + reg);
+}
+
+static inline void s6_i2s_mod_reg(struct s6000_i2s_dev *dev, int reg,
+				  u32 mask, u32 val)
+{
+	val ^= s6_i2s_read_reg(dev, reg) & ~mask;
+	s6_i2s_write_reg(dev, reg, val);
+}
+
+static void s6000_i2s_start_channel(struct s6000_i2s_dev *dev, int channel)
+{
+	int i, j, cur, prev;
+
+	/*
+	 * Wait for WCLK to toggle 5 times before enabling the channel
+	 * s6000 Family Datasheet 3.6.4:
+	 *   "At least two cycles of WS must occur between commands
+	 *    to disable or enable the interface"
+	 */
+	j = 0;
+	prev = ~S6_I2S_CUR_WS;
+	for (i = 1000000; --i && j < 6; ) {
+		cur = s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(channel))
+		       & S6_I2S_CUR_WS;
+		if (prev != cur) {
+			prev = cur;
+			j++;
+		}
+	}
+	if (j < 6)
+		printk(KERN_WARNING "s6000-i2s: timeout waiting for WCLK\n");
+
+	s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_ENABLE_IF);
+}
+
+static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel)
+{
+	s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_DISABLE_IF);
+}
+
+static void s6000_i2s_start(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data;
+	int channel;
+
+	channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+			dev->channel_out : dev->channel_in;
+
+	s6000_i2s_start_channel(dev, channel);
+}
+
+static void s6000_i2s_stop(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data;
+	int channel;
+
+	channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+			dev->channel_out : dev->channel_in;
+
+	s6000_i2s_stop_channel(dev, channel);
+}
+
+static int s6000_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+			     int after)
+{
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ^ !after)
+			s6000_i2s_start(substream);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (!after)
+			s6000_i2s_stop(substream);
+	}
+	return 0;
+}
+
+static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev)
+{
+	unsigned int pending;
+	pending = s6_i2s_read_reg(dev, S6_I2S_INTERRUPT_RAW);
+	pending &= S6_I2S_INT_ALIGNMENT |
+		   S6_I2S_INT_UNDERRUN |
+		   S6_I2S_INT_OVERRUN;
+	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, pending);
+
+	return pending;
+}
+
+static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai)
+{
+	struct s6000_i2s_dev *dev = cpu_dai->private_data;
+	unsigned int errors;
+	unsigned int ret;
+
+	errors = s6000_i2s_int_sources(dev);
+	if (likely(!errors))
+		return 0;
+
+	ret = 0;
+	if (errors & S6_I2S_INT_ALIGNMENT)
+		printk(KERN_ERR "s6000-i2s: WCLK misaligned\n");
+	if (errors & S6_I2S_INT_UNDERRUN)
+		ret |= 1 << SNDRV_PCM_STREAM_PLAYBACK;
+	if (errors & S6_I2S_INT_OVERRUN)
+		ret |= 1 << SNDRV_PCM_STREAM_CAPTURE;
+	return ret;
+}
+
+static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev)
+{
+	int channel;
+	int n = 50;
+	for (channel = 0; channel < 2; channel++) {
+		while (--n >= 0) {
+			int v = s6_i2s_read_reg(dev, S6_I2S_ENABLE(channel));
+			if ((v & S6_I2S_IS_ENABLED)
+			    || !(v & (S6_I2S_DMA_ACTIVE | S6_I2S_IS_BUSY)))
+				break;
+			udelay(20);
+		}
+	}
+	if (n < 0)
+		printk(KERN_WARNING "s6000-i2s: timeout disabling interfaces");
+}
+
+static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+				   unsigned int fmt)
+{
+	struct s6000_i2s_dev *dev = cpu_dai->private_data;
+	u32 w;
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		w = S6_I2S_SCK_IN | S6_I2S_WS_IN;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFM:
+		w = S6_I2S_SCK_OUT | S6_I2S_WS_IN;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFS:
+		w = S6_I2S_SCK_IN | S6_I2S_WS_OUT;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		w = S6_I2S_SCK_OUT | S6_I2S_WS_OUT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_IB_IF:
+		w |= S6_I2S_LEFT_FIRST;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		w |= S6_I2S_RIGHT_FIRST;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(0),
+		       S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
+	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(1),
+		       S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
+
+	return 0;
+}
+
+static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
+{
+	struct s6000_i2s_dev *dev = dai->private_data;
+
+	if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2)
+		return -EINVAL;
+
+	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(div_id),
+		       S6_I2S_DIV_MASK, div / 2 - 1);
+	return 0;
+}
+
+static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai)
+{
+	struct s6000_i2s_dev *dev = dai->private_data;
+	int interf;
+	u32 w = 0;
+
+	if (dev->wide)
+		interf = 0;
+	else {
+		w |= (((params_channels(params) - 2) / 2)
+		      << S6_I2S_CHANNELS_SHIFT) & S6_I2S_CHANNELS_MASK;
+		interf = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+				? dev->channel_out : dev->channel_in;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		w |= S6_I2S_16BIT | S6_I2S_MEM_16BIT;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		w |= S6_I2S_32BIT | S6_I2S_MEM_32BIT;
+		break;
+	default:
+		printk(KERN_WARNING "s6000-i2s: unsupported PCM format %x\n",
+		       params_format(params));
+		return -EINVAL;
+	}
+
+	if (s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(interf))
+	     & S6_I2S_IS_ENABLED) {
+		printk(KERN_ERR "s6000-i2s: interface already enabled\n");
+		return -EBUSY;
+	}
+
+	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(interf),
+		       S6_I2S_CHANNELS_MASK|S6_I2S_MEM_MASK|S6_I2S_BITS_MASK,
+		       w);
+
+	return 0;
+}
+
+static int s6000_i2s_dai_probe(struct platform_device *pdev,
+			       struct snd_soc_dai *dai)
+{
+	struct s6000_i2s_dev *dev = dai->private_data;
+	struct s6000_snd_platform_data *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return -EINVAL;
+
+	dev->wide = pdata->wide;
+	dev->channel_in = pdata->channel_in;
+	dev->channel_out = pdata->channel_out;
+	dev->lines_in = pdata->lines_in;
+	dev->lines_out = pdata->lines_out;
+
+	s6_i2s_write_reg(dev, S6_I2S_MODE,
+			 dev->wide ? S6_I2S_WIDE : S6_I2S_DUAL);
+
+	if (dev->wide) {
+		int i;
+
+		if (dev->lines_in + dev->lines_out > S6_I2S_NUM_LINES)
+			return -EINVAL;
+
+		dev->channel_in = 0;
+		dev->channel_out = 1;
+		dai->capture.channels_min = 2 * dev->lines_in;
+		dai->capture.channels_max = dai->capture.channels_min;
+		dai->playback.channels_min = 2 * dev->lines_out;
+		dai->playback.channels_max = dai->playback.channels_min;
+
+		for (i = 0; i < dev->lines_out; i++)
+			s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT);
+
+		for (; i < S6_I2S_NUM_LINES - dev->lines_in; i++)
+			s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i),
+					 S6_I2S_UNUSED);
+
+		for (; i < S6_I2S_NUM_LINES; i++)
+			s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_IN);
+	} else {
+		unsigned int cfg[2] = {S6_I2S_UNUSED, S6_I2S_UNUSED};
+
+		if (dev->lines_in > 1 || dev->lines_out > 1)
+			return -EINVAL;
+
+		dai->capture.channels_min = 2 * dev->lines_in;
+		dai->capture.channels_max = 8 * dev->lines_in;
+		dai->playback.channels_min = 2 * dev->lines_out;
+		dai->playback.channels_max = 8 * dev->lines_out;
+
+		if (dev->lines_in)
+			cfg[dev->channel_in] = S6_I2S_IN;
+		if (dev->lines_out)
+			cfg[dev->channel_out] = S6_I2S_OUT;
+
+		s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(0), cfg[0]);
+		s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(1), cfg[1]);
+	}
+
+	if (dev->lines_out) {
+		if (dev->lines_in) {
+			if (!dev->dma_params.dma_out)
+				return -ENODEV;
+		} else {
+			dev->dma_params.dma_out = dev->dma_params.dma_in;
+			dev->dma_params.dma_in = 0;
+		}
+	}
+	dev->dma_params.sif_in = dev->sifbase + (dev->channel_in ?
+					S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0);
+	dev->dma_params.sif_out = dev->sifbase + (dev->channel_out ?
+					S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0);
+	dev->dma_params.same_rate = pdata->same_rate | pdata->wide;
+	return 0;
+}
+
+#define S6000_I2S_RATES	(SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
+			 SNDRV_PCM_RATE_8000_192000)
+#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops s6000_i2s_dai_ops = {
+	.set_fmt = s6000_i2s_set_dai_fmt,
+	.set_clkdiv = s6000_i2s_set_clkdiv,
+	.hw_params = s6000_i2s_hw_params,
+};
+
+struct snd_soc_dai s6000_i2s_dai = {
+	.name = "s6000-i2s",
+	.id = 0,
+	.probe = s6000_i2s_dai_probe,
+	.playback = {
+		.channels_min = 2,
+		.channels_max = 8,
+		.formats = S6000_I2S_FORMATS,
+		.rates = S6000_I2S_RATES,
+		.rate_min = 0,
+		.rate_max = 1562500,
+	},
+	.capture = {
+		.channels_min = 2,
+		.channels_max = 8,
+		.formats = S6000_I2S_FORMATS,
+		.rates = S6000_I2S_RATES,
+		.rate_min = 0,
+		.rate_max = 1562500,
+	},
+	.ops = &s6000_i2s_dai_ops,
+}
+EXPORT_SYMBOL_GPL(s6000_i2s_dai);
+
+static int __devinit s6000_i2s_probe(struct platform_device *pdev)
+{
+	struct s6000_i2s_dev *dev;
+	struct resource *scbmem, *sifmem, *region, *dma1, *dma2;
+	u8 __iomem *mmio;
+	int ret;
+
+	scbmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!scbmem) {
+		dev_err(&pdev->dev, "no mem resource?\n");
+		ret = -ENODEV;
+		goto err_release_none;
+	}
+
+	region = request_mem_region(scbmem->start,
+				    scbmem->end - scbmem->start + 1,
+				    pdev->name);
+	if (!region) {
+		dev_err(&pdev->dev, "I2S SCB region already claimed\n");
+		ret = -EBUSY;
+		goto err_release_none;
+	}
+
+	mmio = ioremap(scbmem->start, scbmem->end - scbmem->start + 1);
+	if (!mmio) {
+		dev_err(&pdev->dev, "can't ioremap SCB region\n");
+		ret = -ENOMEM;
+		goto err_release_scb;
+	}
+
+	sifmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!sifmem) {
+		dev_err(&pdev->dev, "no second mem resource?\n");
+		ret = -ENODEV;
+		goto err_release_map;
+	}
+
+	region = request_mem_region(sifmem->start,
+				    sifmem->end - sifmem->start + 1,
+				    pdev->name);
+	if (!region) {
+		dev_err(&pdev->dev, "I2S SIF region already claimed\n");
+		ret = -EBUSY;
+		goto err_release_map;
+	}
+
+	dma1 = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!dma1) {
+		dev_err(&pdev->dev, "no dma resource?\n");
+		ret = -ENODEV;
+		goto err_release_sif;
+	}
+
+	region = request_mem_region(dma1->start, dma1->end - dma1->start + 1,
+				    pdev->name);
+	if (!region) {
+		dev_err(&pdev->dev, "I2S DMA region already claimed\n");
+		ret = -EBUSY;
+		goto err_release_sif;
+	}
+
+	dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (dma2) {
+		region = request_mem_region(dma2->start,
+					    dma2->end - dma2->start + 1,
+					    pdev->name);
+		if (!region) {
+			dev_err(&pdev->dev,
+				"I2S DMA region already claimed\n");
+			ret = -EBUSY;
+			goto err_release_dma1;
+		}
+	}
+
+	dev = kzalloc(sizeof(struct s6000_i2s_dev), GFP_KERNEL);
+	if (!dev) {
+		ret = -ENOMEM;
+		goto err_release_dma2;
+	}
+
+	s6000_i2s_dai.dev = &pdev->dev;
+	s6000_i2s_dai.private_data = dev;
+	s6000_i2s_dai.dma_data = &dev->dma_params;
+
+	dev->sifbase = sifmem->start;
+	dev->scbbase = mmio;
+
+	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
+	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR,
+			 S6_I2S_INT_ALIGNMENT |
+			 S6_I2S_INT_UNDERRUN |
+			 S6_I2S_INT_OVERRUN);
+
+	s6000_i2s_stop_channel(dev, 0);
+	s6000_i2s_stop_channel(dev, 1);
+	s6000_i2s_wait_disabled(dev);
+
+	dev->dma_params.check_xrun = s6000_i2s_check_xrun;
+	dev->dma_params.trigger = s6000_i2s_trigger;
+	dev->dma_params.dma_in = dma1->start;
+	dev->dma_params.dma_out = dma2 ? dma2->start : 0;
+	dev->dma_params.irq = platform_get_irq(pdev, 0);
+	if (dev->dma_params.irq < 0) {
+		dev_err(&pdev->dev, "no irq resource?\n");
+		ret = -ENODEV;
+		goto err_release_dev;
+	}
+
+	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE,
+			 S6_I2S_INT_ALIGNMENT |
+			 S6_I2S_INT_UNDERRUN |
+			 S6_I2S_INT_OVERRUN);
+
+	ret = snd_soc_register_dai(&s6000_i2s_dai);
+	if (ret)
+		goto err_release_dev;
+
+	return 0;
+
+err_release_dev:
+	kfree(dev);
+err_release_dma2:
+	if (dma2)
+		release_mem_region(dma2->start, dma2->end - dma2->start + 1);
+err_release_dma1:
+	release_mem_region(dma1->start, dma1->end - dma1->start + 1);
+err_release_sif:
+	release_mem_region(sifmem->start, (sifmem->end - sifmem->start) + 1);
+err_release_map:
+	iounmap(mmio);
+err_release_scb:
+	release_mem_region(scbmem->start, (scbmem->end - scbmem->start) + 1);
+err_release_none:
+	return ret;
+}
+
+static void __devexit s6000_i2s_remove(struct platform_device *pdev)
+{
+	struct s6000_i2s_dev *dev = s6000_i2s_dai.private_data;
+	struct resource *region;
+	void __iomem *mmio = dev->scbbase;
+
+	snd_soc_unregister_dai(&s6000_i2s_dai);
+
+	s6000_i2s_stop_channel(dev, 0);
+	s6000_i2s_stop_channel(dev, 1);
+
+	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
+	s6000_i2s_dai.private_data = 0;
+	kfree(dev);
+
+	region = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	release_mem_region(region->start, region->end - region->start + 1);
+
+	region = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (region)
+		release_mem_region(region->start,
+				   region->end - region->start + 1);
+
+	region = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(region->start, (region->end - region->start) + 1);
+
+	iounmap(mmio);
+	region = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	release_mem_region(region->start, (region->end - region->start) + 1);
+}
+
+static struct platform_driver s6000_i2s_driver = {
+	.probe  = s6000_i2s_probe,
+	.remove = __devexit_p(s6000_i2s_remove),
+	.driver = {
+		.name   = "s6000-i2s",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init s6000_i2s_init(void)
+{
+	return platform_driver_register(&s6000_i2s_driver);
+}
+module_init(s6000_i2s_init);
+
+static void __exit s6000_i2s_exit(void)
+{
+	platform_driver_unregister(&s6000_i2s_driver);
+}
+module_exit(s6000_i2s_exit);
+
+MODULE_AUTHOR("Daniel Gloeckner");
+MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6000-i2s.h b/sound/soc/s6000/s6000-i2s.h
new file mode 100644
index 0000000..2375fdf
--- /dev/null
+++ b/sound/soc/s6000/s6000-i2s.h
@@ -0,0 +1,25 @@
+/*
+ * ALSA SoC I2S Audio Layer for the Stretch s6000 family
+ *
+ * Author:      Daniel Gloeckner, <dg@emlix.com>
+ * Copyright:   (C) 2009 emlix GmbH <info@emlix.com>
+ *
+ * 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 _S6000_I2S_H
+#define _S6000_I2S_H
+
+extern struct snd_soc_dai s6000_i2s_dai;
+
+struct s6000_snd_platform_data {
+	int lines_in;
+	int lines_out;
+	int channel_in;
+	int channel_out;
+	int wide;
+	int same_rate;
+};
+#endif
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
new file mode 100644
index 0000000..83b8028
--- /dev/null
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -0,0 +1,497 @@
+/*
+ * ALSA PCM interface for the Stetch s6000 family
+ *
+ * Author:      Daniel Gloeckner, <dg@emlix.com>
+ * Copyright:   (C) 2009 emlix GmbH <info@emlix.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <asm/dma.h>
+#include <variant/dmac.h>
+
+#include "s6000-pcm.h"
+
+#define S6_PCM_PREALLOCATE_SIZE (96 * 1024)
+#define S6_PCM_PREALLOCATE_MAX  (2048 * 1024)
+
+static struct snd_pcm_hardware s6000_pcm_hardware = {
+	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX),
+	.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE),
+	.rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
+		  SNDRV_PCM_RATE_8000_192000),
+	.rate_min = 0,
+	.rate_max = 1562500,
+	.channels_min = 2,
+	.channels_max = 8,
+	.buffer_bytes_max = 0x7ffffff0,
+	.period_bytes_min = 16,
+	.period_bytes_max = 0xfffff0,
+	.periods_min = 2,
+	.periods_max = 1024, /* no limit */
+	.fifo_size = 0,
+};
+
+struct s6000_runtime_data {
+	spinlock_t lock;
+	int period;		/* current DMA period */
+};
+
+static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct s6000_runtime_data *prtd = runtime->private_data;
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	int channel;
+	unsigned int period_size;
+	unsigned int dma_offset;
+	dma_addr_t dma_pos;
+	dma_addr_t src, dst;
+
+	period_size = snd_pcm_lib_period_bytes(substream);
+	dma_offset = prtd->period * period_size;
+	dma_pos = runtime->dma_addr + dma_offset;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		src = dma_pos;
+		dst = par->sif_out;
+		channel = par->dma_out;
+	} else {
+		src = par->sif_in;
+		dst = dma_pos;
+		channel = par->dma_in;
+	}
+
+	if (!s6dmac_channel_enabled(DMA_MASK_DMAC(channel),
+				    DMA_INDEX_CHNL(channel)))
+		return;
+
+	if (s6dmac_fifo_full(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel))) {
+		printk(KERN_ERR "s6000-pcm: fifo full\n");
+		return;
+	}
+
+	BUG_ON(period_size & 15);
+	s6dmac_put_fifo(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel),
+			src, dst, period_size);
+
+	prtd->period++;
+	if (unlikely(prtd->period >= runtime->periods))
+		prtd->period = 0;
+}
+
+static irqreturn_t s6000_pcm_irq(int irq, void *data)
+{
+	struct snd_pcm *pcm = data;
+	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
+	struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+	struct s6000_runtime_data *prtd;
+	unsigned int has_xrun;
+	int i, ret = IRQ_NONE;
+	u32 channel[2] = {
+		[SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out,
+		[SNDRV_PCM_STREAM_CAPTURE] = params->dma_in
+	};
+
+	has_xrun = params->check_xrun(runtime->dai->cpu_dai);
+
+	for (i = 0; i < ARRAY_SIZE(channel); ++i) {
+		struct snd_pcm_substream *substream = pcm->streams[i].substream;
+		unsigned int pending;
+
+		if (!channel[i])
+			continue;
+
+		if (unlikely(has_xrun & (1 << i)) &&
+		    substream->runtime &&
+		    snd_pcm_running(substream)) {
+			dev_dbg(pcm->dev, "xrun\n");
+			snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+			ret = IRQ_HANDLED;
+		}
+
+		pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]),
+					     DMA_INDEX_CHNL(channel[i]));
+
+		if (pending & 1) {
+			ret = IRQ_HANDLED;
+			if (likely(substream->runtime &&
+				   snd_pcm_running(substream))) {
+				snd_pcm_period_elapsed(substream);
+				dev_dbg(pcm->dev, "period elapsed %x %x\n",
+				       s6dmac_cur_src(DMA_MASK_DMAC(channel[i]),
+						   DMA_INDEX_CHNL(channel[i])),
+				       s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]),
+						   DMA_INDEX_CHNL(channel[i])));
+				prtd = substream->runtime->private_data;
+				spin_lock(&prtd->lock);
+				s6000_pcm_enqueue_dma(substream);
+				spin_unlock(&prtd->lock);
+			}
+		}
+
+		if (unlikely(pending & ~7)) {
+			if (pending & (1 << 3))
+				printk(KERN_WARNING
+				       "s6000-pcm: DMA %x Underflow\n",
+				       channel[i]);
+			if (pending & (1 << 4))
+				printk(KERN_WARNING
+				       "s6000-pcm: DMA %x Overflow\n",
+				       channel[i]);
+			if (pending & 0x1e0)
+				printk(KERN_WARNING
+				       "s6000-pcm: DMA %x Master Error "
+				       "(mask %x)\n",
+				       channel[i], pending >> 5);
+
+		}
+	}
+
+	return ret;
+}
+
+static int s6000_pcm_start(struct snd_pcm_substream *substream)
+{
+	struct s6000_runtime_data *prtd = substream->runtime->private_data;
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	unsigned long flags;
+	int srcinc;
+	u32 dma;
+
+	spin_lock_irqsave(&prtd->lock, flags);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		srcinc = 1;
+		dma = par->dma_out;
+	} else {
+		srcinc = 0;
+		dma = par->dma_in;
+	}
+	s6dmac_enable_chan(DMA_MASK_DMAC(dma), DMA_INDEX_CHNL(dma),
+			   1 /* priority 1 (0 is max) */,
+			   0 /* peripheral requests w/o xfer length mode */,
+			   srcinc /* source address increment */,
+			   srcinc^1 /* destination address increment */,
+			   0 /* chunksize 0 (skip impossible on this dma) */,
+			   0 /* source skip after chunk (impossible) */,
+			   0 /* destination skip after chunk (impossible) */,
+			   4 /* 16 byte burst size */,
+			   -1 /* don't conserve bandwidth */,
+			   0 /* low watermark irq descriptor theshold */,
+			   0 /* disable hardware timestamps */,
+			   1 /* enable channel */);
+
+	s6000_pcm_enqueue_dma(substream);
+	s6000_pcm_enqueue_dma(substream);
+
+	spin_unlock_irqrestore(&prtd->lock, flags);
+
+	return 0;
+}
+
+static int s6000_pcm_stop(struct snd_pcm_substream *substream)
+{
+	struct s6000_runtime_data *prtd = substream->runtime->private_data;
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	unsigned long flags;
+	u32 channel;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		channel = par->dma_out;
+	else
+		channel = par->dma_in;
+
+	s6dmac_set_terminal_count(DMA_MASK_DMAC(channel),
+				  DMA_INDEX_CHNL(channel), 0);
+
+	spin_lock_irqsave(&prtd->lock, flags);
+
+	s6dmac_disable_chan(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel));
+
+	spin_unlock_irqrestore(&prtd->lock, flags);
+
+	return 0;
+}
+
+static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	int ret;
+
+	ret = par->trigger(substream, cmd, 0);
+	if (ret < 0)
+		return ret;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		ret = s6000_pcm_start(substream);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		ret = s6000_pcm_stop(substream);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	if (ret < 0)
+		return ret;
+
+	return par->trigger(substream, cmd, 1);
+}
+
+static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct s6000_runtime_data *prtd = substream->runtime->private_data;
+
+	prtd->period = 0;
+
+	return 0;
+}
+
+static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct s6000_runtime_data *prtd = runtime->private_data;
+	unsigned long flags;
+	unsigned int offset;
+	dma_addr_t count;
+
+	spin_lock_irqsave(&prtd->lock, flags);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		count = s6dmac_cur_src(DMA_MASK_DMAC(par->dma_out),
+				       DMA_INDEX_CHNL(par->dma_out));
+	else
+		count = s6dmac_cur_dst(DMA_MASK_DMAC(par->dma_in),
+				       DMA_INDEX_CHNL(par->dma_in));
+
+	count -= runtime->dma_addr;
+
+	spin_unlock_irqrestore(&prtd->lock, flags);
+
+	offset = bytes_to_frames(runtime, count);
+	if (unlikely(offset >= runtime->buffer_size))
+		offset = 0;
+
+	return offset;
+}
+
+static int s6000_pcm_open(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct s6000_runtime_data *prtd;
+	int ret;
+
+	snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
+
+	ret = snd_pcm_hw_constraint_step(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);
+	if (ret < 0)
+		return ret;
+	ret = snd_pcm_hw_constraint_step(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
+	if (ret < 0)
+		return ret;
+	ret = snd_pcm_hw_constraint_integer(runtime,
+					    SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		return ret;
+
+	if (par->same_rate) {
+		int rate;
+		spin_lock(&par->lock); /* needed? */
+		rate = par->rate;
+		spin_unlock(&par->lock);
+		if (rate != -1) {
+			ret = snd_pcm_hw_constraint_minmax(runtime,
+							SNDRV_PCM_HW_PARAM_RATE,
+							rate, rate);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	prtd = kzalloc(sizeof(struct s6000_runtime_data), GFP_KERNEL);
+	if (prtd == NULL)
+		return -ENOMEM;
+
+	spin_lock_init(&prtd->lock);
+
+	runtime->private_data = prtd;
+
+	return 0;
+}
+
+static int s6000_pcm_close(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct s6000_runtime_data *prtd = runtime->private_data;
+
+	kfree(prtd);
+
+	return 0;
+}
+
+static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
+{
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+	int ret;
+	ret = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (ret < 0) {
+		printk(KERN_WARNING "s6000-pcm: allocation of memory failed\n");
+		return ret;
+	}
+
+	if (par->same_rate) {
+		spin_lock(&par->lock);
+		if (par->rate == -1 ||
+		    !(par->in_use & ~(1 << substream->stream))) {
+			par->rate = params_rate(hw_params);
+			par->in_use |= 1 << substream->stream;
+		} else if (params_rate(hw_params) != par->rate) {
+			snd_pcm_lib_free_pages(substream);
+			par->in_use &= ~(1 << substream->stream);
+			ret = -EBUSY;
+		}
+		spin_unlock(&par->lock);
+	}
+	return ret;
+}
+
+static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
+	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+
+	spin_lock(&par->lock);
+	par->in_use &= ~(1 << substream->stream);
+	if (!par->in_use)
+		par->rate = -1;
+	spin_unlock(&par->lock);
+
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static struct snd_pcm_ops s6000_pcm_ops = {
+	.open = 	s6000_pcm_open,
+	.close = 	s6000_pcm_close,
+	.ioctl = 	snd_pcm_lib_ioctl,
+	.hw_params = 	s6000_pcm_hw_params,
+	.hw_free = 	s6000_pcm_hw_free,
+	.trigger =	s6000_pcm_trigger,
+	.prepare = 	s6000_pcm_prepare,
+	.pointer = 	s6000_pcm_pointer,
+};
+
+static void s6000_pcm_free(struct snd_pcm *pcm)
+{
+	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
+	struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+
+	free_irq(params->irq, pcm);
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static u64 s6000_pcm_dmamask = DMA_32BIT_MASK;
+
+static int s6000_pcm_new(struct snd_card *card,
+			 struct snd_soc_dai *dai, struct snd_pcm *pcm)
+{
+	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
+	struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+	int res;
+
+	if (!card->dev->dma_mask)
+		card->dev->dma_mask = &s6000_pcm_dmamask;
+	if (!card->dev->coherent_dma_mask)
+		card->dev->coherent_dma_mask = DMA_32BIT_MASK;
+
+	if (params->dma_in) {
+		s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in),
+				    DMA_INDEX_CHNL(params->dma_in));
+		s6dmac_int_sources(DMA_MASK_DMAC(params->dma_in),
+				   DMA_INDEX_CHNL(params->dma_in));
+	}
+
+	if (params->dma_out) {
+		s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_out),
+				    DMA_INDEX_CHNL(params->dma_out));
+		s6dmac_int_sources(DMA_MASK_DMAC(params->dma_out),
+				   DMA_INDEX_CHNL(params->dma_out));
+	}
+
+	res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
+			  s6000_soc_platform.name, pcm);
+	if (res) {
+		printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
+		return res;
+	}
+
+	res = snd_pcm_lib_preallocate_pages_for_all(pcm,
+						    SNDRV_DMA_TYPE_DEV,
+						    card->dev,
+						    S6_PCM_PREALLOCATE_SIZE,
+						    S6_PCM_PREALLOCATE_MAX);
+	if (res)
+		printk(KERN_WARNING "s6000-pcm: preallocation failed\n");
+
+	spin_lock_init(&params->lock);
+	params->in_use = 0;
+	params->rate = -1;
+	return 0;
+}
+
+struct snd_soc_platform s6000_soc_platform = {
+	.name = 	"s6000-audio",
+	.pcm_ops = 	&s6000_pcm_ops,
+	.pcm_new = 	s6000_pcm_new,
+	.pcm_free = 	s6000_pcm_free,
+};
+EXPORT_SYMBOL_GPL(s6000_soc_platform);
+
+static int __init s6000_pcm_init(void)
+{
+	return snd_soc_register_platform(&s6000_soc_platform);
+}
+module_init(s6000_pcm_init);
+
+static void __exit s6000_pcm_exit(void)
+{
+	snd_soc_unregister_platform(&s6000_soc_platform);
+}
+module_exit(s6000_pcm_exit);
+
+MODULE_AUTHOR("Daniel Gloeckner");
+MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6000-pcm.h b/sound/soc/s6000/s6000-pcm.h
new file mode 100644
index 0000000..96f23f6
--- /dev/null
+++ b/sound/soc/s6000/s6000-pcm.h
@@ -0,0 +1,35 @@
+/*
+ * ALSA PCM interface for the Stretch s6000 family
+ *
+ * Author:      Daniel Gloeckner, <dg@emlix.com>
+ * Copyright:   (C) 2009 emlix GmbH <info@emlix.com>
+ *
+ * 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 _S6000_PCM_H
+#define _S6000_PCM_H
+
+struct snd_soc_dai;
+struct snd_pcm_substream;
+
+struct s6000_pcm_dma_params {
+	unsigned int (*check_xrun)(struct snd_soc_dai *cpu_dai);
+	int (*trigger)(struct snd_pcm_substream *substream, int cmd, int after);
+	dma_addr_t sif_in;
+	dma_addr_t sif_out;
+	u32 dma_in;
+	u32 dma_out;
+	int irq;
+	int same_rate;
+
+	spinlock_t lock;
+	int in_use;
+	int rate;
+};
+
+extern struct snd_soc_platform s6000_soc_platform;
+
+#endif
-- 
1.6.2.2

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH] mx31ads: Depend on all the WM8350 core dependencies for WM1133-EV1 board
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
  2009-04-14 12:32 ` [PATCH 01/14] ASoC: Add driver for s6000 I2S interface Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:34   ` Mark Brown
  2009-04-14 12:33 ` [PATCH 02/14] ASoC: s6105 IP camera machine specific ASoC code Mark Brown
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

Otherwise we'd need massive ifdefs in the code.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 arch/arm/mach-mx3/Kconfig |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index d623558..194b842 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -19,6 +19,8 @@ config MACH_MX31ADS
 config MACH_MX31ADS_WM1133_EV1
 	bool "Support Wolfson Microelectronics 1133-EV1 module"
 	depends on MACH_MX31ADS
+	depends on MFD_WM8350_I2C
+	depends on REGULATOR_WM8350
 	select MFD_WM8350_CONFIG_MODE_0
 	select MFD_WM8352_CONFIG_MODE_0
 	help
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 02/14] ASoC: s6105 IP camera machine specific ASoC code
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
  2009-04-14 12:32 ` [PATCH 01/14] ASoC: Add driver for s6000 I2S interface Mark Brown
  2009-04-14 12:33 ` [PATCH] mx31ads: Depend on all the WM8350 core dependencies for WM1133-EV1 board Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 03/14] ASoC: correct s6000 I2S clock polarity Mark Brown
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Daniel Glöckner

From: Daniel Glöckner <dg@emlix.com>

This patch adds machine specific code for the audio part of the Stretch
s6105 IP camera reference design.

The device uses the tlv320aic31(01) codec to generate the clock for
both I2S ports of the soc. While the master clock is generated by a
configurable PLL chip, the code assumes the factory default settings.

An additional kcontrol has been added to handle the special routing of
the board, connecting both HPLCOM and HPROUT to the same pin of the audio
jack. One of these should always be switched off.

Signed-off-by: Daniel Glöckner <dg@emlix.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/s6000/Kconfig       |    9 ++
 sound/soc/s6000/Makefile      |    5 +
 sound/soc/s6000/s6105-ipcam.c |  244 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 258 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/s6000/s6105-ipcam.c

diff --git a/sound/soc/s6000/Kconfig b/sound/soc/s6000/Kconfig
index 4bfc8bc..c74eb3d 100644
--- a/sound/soc/s6000/Kconfig
+++ b/sound/soc/s6000/Kconfig
@@ -8,3 +8,12 @@ config SND_S6000_SOC
 
 config SND_S6000_SOC_I2S
 	tristate
+
+config SND_S6000_SOC_S6IPCAM
+	tristate "SoC Audio support for Stretch 6105 IP Camera"
+	depends on SND_S6000_SOC && XTENSA_PLATFORM_S6105
+	select SND_S6000_SOC_I2S
+	select SND_SOC_TLV320AIC3X
+	help
+	  Say Y if you want to add support for SoC audio on the
+	  Stretch s6105 IP Camera Reference Design.
diff --git a/sound/soc/s6000/Makefile b/sound/soc/s6000/Makefile
index df15f87..7a61361 100644
--- a/sound/soc/s6000/Makefile
+++ b/sound/soc/s6000/Makefile
@@ -4,3 +4,8 @@ snd-soc-s6000-i2s-objs := s6000-i2s.o
 
 obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o
 obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o
+
+# s6105 Machine Support
+snd-soc-s6ipcam-objs := s6105-ipcam.o
+
+obj-$(CONFIG_SND_S6000_SOC_S6IPCAM) += snd-soc-s6ipcam.o
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
new file mode 100644
index 0000000..21c4f55
--- /dev/null
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -0,0 +1,244 @@
+/*
+ * ASoC driver for Stretch s6105 IP camera platform
+ *
+ * Author:      Daniel Gloeckner, <dg@emlix.com>
+ * Copyright:   (C) 2009 emlix GmbH <info@emlix.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <variant/dmac.h>
+
+#include "../codecs/tlv320aic3x.h"
+#include "s6000-pcm.h"
+#include "s6000-i2s.h"
+
+#define S6105_CAM_CODEC_CLOCK 12288000
+
+static int s6105_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;
+	int ret = 0;
+
+	/* set codec DAI configuration */
+	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+					     SND_SOC_DAIFMT_CBM_CFM);
+	if (ret < 0)
+		return ret;
+
+	/* set cpu DAI configuration */
+	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM |
+					   SND_SOC_DAIFMT_IB_IF);
+	if (ret < 0)
+		return ret;
+
+	/* set the codec system clock */
+	ret = snd_soc_dai_set_sysclk(codec_dai, 0, S6105_CAM_CODEC_CLOCK,
+					    SND_SOC_CLOCK_OUT);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct snd_soc_ops s6105_ops = {
+	.hw_params = s6105_hw_params,
+};
+
+/* s6105 machine dapm widgets */
+static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
+	SND_SOC_DAPM_LINE("Audio Out Differential", NULL),
+	SND_SOC_DAPM_LINE("Audio Out Stereo", NULL),
+	SND_SOC_DAPM_LINE("Audio In", NULL),
+};
+
+/* s6105 machine audio_mapnections to the codec pins */
+static const struct snd_soc_dapm_route audio_map[] = {
+	/* Audio Out connected to HPLOUT, HPLCOM, HPROUT */
+	{"Audio Out Differential", NULL, "HPLOUT"},
+	{"Audio Out Differential", NULL, "HPLCOM"},
+	{"Audio Out Stereo", NULL, "HPLOUT"},
+	{"Audio Out Stereo", NULL, "HPROUT"},
+
+	/* Audio In connected to LINE1L, LINE1R */
+	{"LINE1L", NULL, "Audio In"},
+	{"LINE1R", NULL, "Audio In"},
+};
+
+static int output_type_info(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item) {
+		uinfo->value.enumerated.item = 1;
+		strcpy(uinfo->value.enumerated.name, "HPLOUT/HPROUT");
+	} else {
+		strcpy(uinfo->value.enumerated.name, "HPLOUT/HPLCOM");
+	}
+	return 0;
+}
+
+static int output_type_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.enumerated.item[0] = kcontrol->private_value;
+	return 0;
+}
+
+static int output_type_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = kcontrol->private_data;
+	unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
+	char *differential = "Audio Out Differential";
+	char *stereo = "Audio Out Stereo";
+
+	if (kcontrol->private_value == val)
+		return 0;
+	kcontrol->private_value = val;
+	snd_soc_dapm_disable_pin(codec, val ? differential : stereo);
+	snd_soc_dapm_sync(codec);
+	snd_soc_dapm_enable_pin(codec, val ? stereo : differential);
+	snd_soc_dapm_sync(codec);
+
+	return 1;
+}
+
+static const struct snd_kcontrol_new audio_out_mux = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Master Output Mux",
+	.index = 0,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = output_type_info,
+	.get = output_type_get,
+	.put = output_type_put,
+	.private_value = 1 /* default to stereo */
+};
+
+/* Logic for a aic3x as connected on the s6105 ip camera ref design */
+static int s6105_aic3x_init(struct snd_soc_codec *codec)
+{
+	/* Add s6105 specific widgets */
+	snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
+				  ARRAY_SIZE(aic3x_dapm_widgets));
+
+	/* Set up s6105 specific audio path audio_map */
+	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+	/* not present */
+	snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
+	snd_soc_dapm_nc_pin(codec, "LINE2L");
+	snd_soc_dapm_nc_pin(codec, "LINE2R");
+
+	/* not connected */
+	snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */
+	snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */
+	snd_soc_dapm_nc_pin(codec, "LLOUT");
+	snd_soc_dapm_nc_pin(codec, "RLOUT");
+	snd_soc_dapm_nc_pin(codec, "HPRCOM");
+
+	/* always connected */
+	snd_soc_dapm_enable_pin(codec, "Audio In");
+
+	/* must correspond to audio_out_mux.private_value initializer */
+	snd_soc_dapm_disable_pin(codec, "Audio Out Differential");
+	snd_soc_dapm_sync(codec);
+	snd_soc_dapm_enable_pin(codec, "Audio Out Stereo");
+
+	snd_soc_dapm_sync(codec);
+
+	snd_ctl_add(codec->card, snd_ctl_new1(&audio_out_mux, codec));
+
+	return 0;
+}
+
+/* s6105 digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link s6105_dai = {
+	.name = "TLV320AIC31",
+	.stream_name = "AIC31",
+	.cpu_dai = &s6000_i2s_dai,
+	.codec_dai = &aic3x_dai,
+	.init = s6105_aic3x_init,
+	.ops = &s6105_ops,
+};
+
+/* s6105 audio machine driver */
+static struct snd_soc_card snd_soc_card_s6105 = {
+	.name = "Stretch IP Camera",
+	.platform = &s6000_soc_platform,
+	.dai_link = &s6105_dai,
+	.num_links = 1,
+};
+
+/* s6105 audio private data */
+static struct aic3x_setup_data s6105_aic3x_setup = {
+	.i2c_bus = 0,
+	.i2c_address = 0x18,
+};
+
+/* s6105 audio subsystem */
+static struct snd_soc_device s6105_snd_devdata = {
+	.card = &snd_soc_card_s6105,
+	.codec_dev = &soc_codec_dev_aic3x,
+	.codec_data = &s6105_aic3x_setup,
+};
+
+static struct s6000_snd_platform_data __initdata s6105_snd_data = {
+	.wide		= 0,
+	.channel_in	= 0,
+	.channel_out	= 1,
+	.lines_in	= 1,
+	.lines_out	= 1,
+	.same_rate	= 1,
+};
+
+static struct platform_device *s6105_snd_device;
+
+static int __init s6105_init(void)
+{
+	int ret;
+
+	s6105_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!s6105_snd_device)
+		return -ENOMEM;
+
+	platform_set_drvdata(s6105_snd_device, &s6105_snd_devdata);
+	s6105_snd_devdata.dev = &s6105_snd_device->dev;
+	platform_device_add_data(s6105_snd_device, &s6105_snd_data,
+				 sizeof(s6105_snd_data));
+
+	ret = platform_device_add(s6105_snd_device);
+	if (ret)
+		platform_device_put(s6105_snd_device);
+
+	return ret;
+}
+
+static void __exit s6105_exit(void)
+{
+	platform_device_unregister(s6105_snd_device);
+}
+
+module_init(s6105_init);
+module_exit(s6105_exit);
+
+MODULE_AUTHOR("Daniel Gloeckner");
+MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver");
+MODULE_LICENSE("GPL");
-- 
1.6.2.2

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 03/14] ASoC: correct s6000 I2S clock polarity
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (2 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 02/14] ASoC: s6105 IP camera machine specific ASoC code Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 04/14] ASoC: Display return code when failing to add a DAPM kcontrol Mark Brown
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Daniel Glöckner

From: Daniel Glöckner <dg@emlix.com>

According to the data sheet data is clocked out on the falling edge
and latched on the rising edge of the bit clock. While the left sample
is transmitted the word clock line is low.

Signed-off-by: Daniel Glöckner <dg@emlix.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/s6000/s6000-i2s.c   |    4 ++--
 sound/soc/s6000/s6105-ipcam.c |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index dcc7904..c5cda18 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -252,10 +252,10 @@ static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 	}
 
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-	case SND_SOC_DAIFMT_IB_IF:
+	case SND_SOC_DAIFMT_NB_NF:
 		w |= S6_I2S_LEFT_FIRST;
 		break;
-	case SND_SOC_DAIFMT_IB_NF:
+	case SND_SOC_DAIFMT_NB_IF:
 		w |= S6_I2S_RIGHT_FIRST;
 		break;
 	default:
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index 21c4f55..b5f95f9 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -43,7 +43,7 @@ static int s6105_hw_params(struct snd_pcm_substream *substream,
 
 	/* set cpu DAI configuration */
 	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM |
-					   SND_SOC_DAIFMT_IB_IF);
+					   SND_SOC_DAIFMT_NB_NF);
 	if (ret < 0)
 		return ret;
 
-- 
1.6.2.2

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 04/14] ASoC: Display return code when failing to add a DAPM kcontrol
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (3 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 03/14] ASoC: correct s6000 I2S clock polarity Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 05/14] ASoC: Provide core support for symmetric sample rates Mark Brown
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/soc-dapm.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 735903a..46485de 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -357,8 +357,9 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
 				path->long_name);
 			ret = snd_ctl_add(codec->card, path->kcontrol);
 			if (ret < 0) {
-				printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n",
-						path->long_name);
+				printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n",
+				       path->long_name,
+				       ret);
 				kfree(path->long_name);
 				path->long_name = NULL;
 				return ret;
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 05/14] ASoC: Provide core support for symmetric sample rates
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (4 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 04/14] ASoC: Display return code when failing to add a DAPM kcontrol Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-15  6:31   ` Peter Ujfalusi
  2009-04-14 12:33 ` [PATCH 06/14] ASoC: Add WM8988 CODEC driver Mark Brown
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

Many devices require symmetric configurations of capture and playback
data formats, often due to shared clocking but sometimes also due to
other shared playback and record configuration in the device. Start
providing core support for this by allowing the DAIs or the machine
to specify that the sample rates used should be kept symmetric.

A flag symmetric_rates is provided in the snd_soc_dai and
snd_soc_dai_link structures. If this is set in either of the DAIs or in
the machine then a constraint will be applied when a stream is already
open preventing any changes in sample rate.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 include/sound/soc-dai.h |    1 +
 include/sound/soc.h     |    6 ++++++
 sound/soc/soc-core.c    |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 1367647..22b729f 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -208,6 +208,7 @@ struct snd_soc_dai {
 	/* DAI capabilities */
 	struct snd_soc_pcm_stream capture;
 	struct snd_soc_pcm_stream playback;
+	unsigned int symmetric_rates:1;
 
 	/* DAI runtime info */
 	struct snd_pcm_runtime *runtime;
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a40bc6f..b1f2f88 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -417,6 +417,12 @@ struct snd_soc_dai_link  {
 	/* codec/machine specific init - e.g. add machine controls */
 	int (*init)(struct snd_soc_codec *codec);
 
+	/* Symmetry requirements */
+	unsigned int symmetric_rates:1;
+
+	/* Symmetry data - only valid if symmetry is being enforced */
+	unsigned int rate;
+
 	/* DAI pcm */
 	struct snd_pcm *pcm;
 };
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 99712f6..dd28009 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -113,6 +113,35 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
 }
 #endif
 
+static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_device *socdev = rtd->socdev;
+	struct snd_soc_card *card = socdev->card;
+	struct snd_soc_dai_link *machine = rtd->dai;
+	struct snd_soc_dai *cpu_dai = machine->cpu_dai;
+	struct snd_soc_dai *codec_dai = machine->codec_dai;
+	int ret;
+
+	if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates ||
+	    machine->symmetric_rates) {
+		dev_dbg(card->dev, "Symmetry forces %dHz rate\n", 
+			machine->rate);
+
+		ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+						   SNDRV_PCM_HW_PARAM_RATE,
+						   machine->rate,
+						   machine->rate);
+		if (ret < 0) {
+			dev_err(card->dev,
+				"Unable to apply rate symmetry constraint: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * Called by ALSA when a PCM substream is opened, the runtime->hw record is
  * then initialized and any private data can be allocated. This also calls
@@ -221,6 +250,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 		goto machine_err;
 	}
 
+	/* Symmetry only applies if we've already got an active stream. */
+	if (cpu_dai->active || codec_dai->active) {
+		ret = soc_pcm_apply_symmetry(substream);
+		if (ret != 0)
+			goto machine_err;
+	}
+
 	pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
 	pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
 	pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
@@ -521,6 +557,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 		}
 	}
 
+	machine->rate = params_rate(params);
+
 out:
 	mutex_unlock(&pcm_mutex);
 	return ret;
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 06/14] ASoC: Add WM8988 CODEC driver
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (5 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 05/14] ASoC: Provide core support for symmetric sample rates Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 07/14] ASoC: tlv320aic23: add DSP_A format support Mark Brown
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

The WM8988 is a low power, high quality stereo CODEC designed for
portable digital audio applications.

The device integrates complete interfaces to 2 stereo headphone or line
out ports. External component requirements are drastically reduced as no
separate headphone amplifiers are required. Advanced on-chip digital
signal processing performs graphic equaliser, 3-D sound enhancement and
automatic level control for the microphone or line input.

The WM8988 can operate as a master or a slave, with various master clock
frequencies including 12 or 24MHz for USB devices, or standard 256fs
rates like 12.288MHz and 24.576MHz. Different audio sample rates such as
96kHz, 48kHz, 44.1kHz are generated directly from the master clock
without the need for an external PLL.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/Kconfig  |    4 +
 sound/soc/codecs/Makefile |    2 +
 sound/soc/codecs/wm8988.c | 1097 +++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm8988.h |   60 +++
 4 files changed, 1163 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/codecs/wm8988.c
 create mode 100644 sound/soc/codecs/wm8988.h

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index b6c7f7a..ab36485 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_WM8900 if I2C
 	select SND_SOC_WM8903 if I2C
 	select SND_SOC_WM8971 if I2C
+	select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
 	select SND_SOC_WM8990 if I2C
 	select SND_SOC_WM9705 if SND_SOC_AC97_BUS
 	select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -141,6 +142,9 @@ config SND_SOC_WM8903
 config SND_SOC_WM8971
 	tristate
 
+config SND_SOC_WM8988
+	tristate
+
 config SND_SOC_WM8990
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 030d245..a72548d 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -24,6 +24,7 @@ snd-soc-wm8753-objs := wm8753.o
 snd-soc-wm8900-objs := wm8900.o
 snd-soc-wm8903-objs := wm8903.o
 snd-soc-wm8971-objs := wm8971.o
+snd-soc-wm8988-objs := wm8988.o
 snd-soc-wm8990-objs := wm8990.o
 snd-soc-wm9705-objs := wm9705.o
 snd-soc-wm9712-objs := wm9712.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_SND_SOC_WM8753)	+= snd-soc-wm8753.o
 obj-$(CONFIG_SND_SOC_WM8900)	+= snd-soc-wm8900.o
 obj-$(CONFIG_SND_SOC_WM8903)	+= snd-soc-wm8903.o
 obj-$(CONFIG_SND_SOC_WM8971)	+= snd-soc-wm8971.o
+obj-$(CONFIG_SND_SOC_WM8988)	+= snd-soc-wm8988.o
 obj-$(CONFIG_SND_SOC_WM8990)	+= snd-soc-wm8990.o
 obj-$(CONFIG_SND_SOC_WM8991)	+= snd-soc-wm8991.o
 obj-$(CONFIG_SND_SOC_WM9705)	+= snd-soc-wm9705.o
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
new file mode 100644
index 0000000..c05f718
--- /dev/null
+++ b/sound/soc/codecs/wm8988.c
@@ -0,0 +1,1097 @@
+/*
+ * wm8988.c -- WM8988 ALSA SoC audio driver
+ *
+ * Copyright 2009 Wolfson Microelectronics plc
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+
+#include "wm8988.h"
+
+/*
+ * wm8988 register cache
+ * We can't read the WM8988 register space when we
+ * are using 2 wire for device control, so we cache them instead.
+ */
+static const u16 wm8988_reg[] = {
+	0x0097, 0x0097, 0x0079, 0x0079,  /*  0 */
+	0x0000, 0x0008, 0x0000, 0x000a,  /*  4 */
+	0x0000, 0x0000, 0x00ff, 0x00ff,  /*  8 */
+	0x000f, 0x000f, 0x0000, 0x0000,  /* 12 */
+	0x0000, 0x007b, 0x0000, 0x0032,  /* 16 */
+	0x0000, 0x00c3, 0x00c3, 0x00c0,  /* 20 */
+	0x0000, 0x0000, 0x0000, 0x0000,  /* 24 */
+	0x0000, 0x0000, 0x0000, 0x0000,  /* 28 */
+	0x0000, 0x0000, 0x0050, 0x0050,  /* 32 */
+	0x0050, 0x0050, 0x0050, 0x0050,  /* 36 */
+	0x0079, 0x0079, 0x0079,          /* 40 */
+};
+
+/* codec private data */
+struct wm8988_priv {
+	unsigned int sysclk;
+	struct snd_soc_codec codec;
+	struct snd_pcm_hw_constraint_list *sysclk_constraints;
+	u16 reg_cache[WM8988_NUM_REG];
+};
+
+
+/*
+ * read wm8988 register cache
+ */
+static inline unsigned int wm8988_read_reg_cache(struct snd_soc_codec *codec,
+	unsigned int reg)
+{
+	u16 *cache = codec->reg_cache;
+	if (reg > WM8988_NUM_REG)
+		return -1;
+	return cache[reg];
+}
+
+/*
+ * write wm8988 register cache
+ */
+static inline void wm8988_write_reg_cache(struct snd_soc_codec *codec,
+	unsigned int reg, unsigned int value)
+{
+	u16 *cache = codec->reg_cache;
+	if (reg > WM8988_NUM_REG)
+		return;
+	cache[reg] = value;
+}
+
+static int wm8988_write(struct snd_soc_codec *codec, unsigned int reg,
+	unsigned int value)
+{
+	u8 data[2];
+
+	/* data is
+	 *   D15..D9 WM8753 register offset
+	 *   D8...D0 register data
+	 */
+	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+	data[1] = value & 0x00ff;
+
+	wm8988_write_reg_cache(codec, reg, value);
+	if (codec->hw_write(codec->control_data, data, 2) == 2)
+		return 0;
+	else
+		return -EIO;
+}
+
+#define wm8988_reset(c)	wm8988_write(c, WM8988_RESET, 0)
+
+/*
+ * WM8988 Controls
+ */
+
+static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"};
+static const struct soc_enum bass_boost =
+	SOC_ENUM_SINGLE(WM8988_BASS, 7, 2, bass_boost_txt);
+
+static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
+static const struct soc_enum bass_filter =
+	SOC_ENUM_SINGLE(WM8988_BASS, 6, 2, bass_filter_txt);
+
+static const char *treble_txt[] = {"8kHz", "4kHz"};
+static const struct soc_enum treble =
+	SOC_ENUM_SINGLE(WM8988_TREBLE, 6, 2, treble_txt);
+
+static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"};
+static const struct soc_enum stereo_3d_lc =
+	SOC_ENUM_SINGLE(WM8988_3D, 5, 2, stereo_3d_lc_txt);
+
+static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"};
+static const struct soc_enum stereo_3d_uc =
+	SOC_ENUM_SINGLE(WM8988_3D, 6, 2, stereo_3d_uc_txt);
+
+static const char *stereo_3d_func_txt[] = {"Capture", "Playback"};
+static const struct soc_enum stereo_3d_func =
+	SOC_ENUM_SINGLE(WM8988_3D, 7, 2, stereo_3d_func_txt);
+
+static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"};
+static const struct soc_enum alc_func =
+	SOC_ENUM_SINGLE(WM8988_ALC1, 7, 4, alc_func_txt);
+
+static const char *ng_type_txt[] = {"Constant PGA Gain",
+				    "Mute ADC Output"};
+static const struct soc_enum ng_type =
+	SOC_ENUM_SINGLE(WM8988_NGATE, 1, 2, ng_type_txt);
+
+static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"};
+static const struct soc_enum deemph =
+	SOC_ENUM_SINGLE(WM8988_ADCDAC, 1, 4, deemph_txt);
+
+static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert",
+				   "L + R Invert"};
+static const struct soc_enum adcpol =
+	SOC_ENUM_SINGLE(WM8988_ADCDAC, 5, 4, adcpol_txt);
+
+static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
+
+static const struct snd_kcontrol_new wm8988_snd_controls[] = {
+
+SOC_ENUM("Bass Boost", bass_boost),
+SOC_ENUM("Bass Filter", bass_filter),
+SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1),
+
+SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0),
+SOC_ENUM("Treble Cut-off", treble),
+
+SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0),
+SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0),
+SOC_ENUM("3D Lower Cut-off", stereo_3d_lc),
+SOC_ENUM("3D Upper Cut-off", stereo_3d_uc),
+SOC_ENUM("3D Mode", stereo_3d_func),
+
+SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0),
+SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0),
+SOC_ENUM("ALC Capture Function", alc_func),
+SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0),
+SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0),
+SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0),
+SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0),
+SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0),
+SOC_ENUM("ALC Capture NG Type", ng_type),
+SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0),
+
+SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0),
+
+SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC,
+		 0, 255, 0, adc_tlv),
+SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL,
+		 0, 63, 0, pga_tlv),
+SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1),
+
+SOC_ENUM("Playback De-emphasis", deemph),
+
+SOC_ENUM("Capture Polarity", adcpol),
+SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0),
+SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0),
+
+SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv),
+
+SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1,
+	       bypass_tlv),
+SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1,
+	       bypass_tlv),
+SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1,
+	       bypass_tlv),
+SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1,
+	       bypass_tlv),
+
+SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V,
+	     WM8988_ROUT1V, 7, 1, 0),
+SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V,
+		 0, 127, 0, out_tlv),
+
+SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V,
+	     WM8988_ROUT2V, 7, 1, 0),
+SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
+		 0, 127, 0, out_tlv),
+
+};
+
+/*
+ * DAPM Controls
+ */
+
+static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	u16 adctl2 = wm8988_read_reg_cache(codec, WM8988_ADCTL2);
+
+	/* Use the DAC to gate LRC if active, otherwise use ADC */
+	if (wm8988_read_reg_cache(codec, WM8988_PWR2) & 0x180)
+		adctl2 &= ~0x4;
+	else
+		adctl2 |= 0x4;
+
+	return wm8988_write(codec, WM8988_ADCTL2, adctl2);
+}
+
+static const char *wm8988_line_texts[] = {
+	"Line 1", "Line 2", "PGA", "Differential"};
+
+static const unsigned int wm8988_line_values[] = {
+	0, 1, 3, 4};
+
+static const struct soc_enum wm8988_lline_enum =
+	SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7,
+			      ARRAY_SIZE(wm8988_line_texts),
+			      wm8988_line_texts,
+			      wm8988_line_values);
+static const struct snd_kcontrol_new wm8988_left_line_controls =
+	SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum);
+
+static const struct soc_enum wm8988_rline_enum =
+	SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7,
+			      ARRAY_SIZE(wm8988_line_texts),
+			      wm8988_line_texts,
+			      wm8988_line_values);
+static const struct snd_kcontrol_new wm8988_right_line_controls =
+	SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum);
+
+/* Left Mixer */
+static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {
+	SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0),
+	SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0),
+	SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0),
+	SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0),
+};
+
+/* Right Mixer */
+static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = {
+	SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0),
+	SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0),
+	SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0),
+	SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0),
+};
+
+static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"};
+static const unsigned int wm8988_pga_val[] = { 0, 1, 3 };
+
+/* Left PGA Mux */
+static const struct soc_enum wm8988_lpga_enum =
+	SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3,
+			      ARRAY_SIZE(wm8988_pga_sel),
+			      wm8988_pga_sel,
+			      wm8988_pga_val);
+static const struct snd_kcontrol_new wm8988_left_pga_controls =
+	SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum);
+
+/* Right PGA Mux */
+static const struct soc_enum wm8988_rpga_enum =
+	SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3,
+			      ARRAY_SIZE(wm8988_pga_sel),
+			      wm8988_pga_sel,
+			      wm8988_pga_val);
+static const struct snd_kcontrol_new wm8988_right_pga_controls =
+	SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum);
+
+/* Differential Mux */
+static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"};
+static const struct soc_enum diffmux =
+	SOC_ENUM_SINGLE(WM8988_ADCIN, 8, 2, wm8988_diff_sel);
+static const struct snd_kcontrol_new wm8988_diffmux_controls =
+	SOC_DAPM_ENUM("Route", diffmux);
+
+/* Mono ADC Mux */
+static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)",
+	"Mono (Right)", "Digital Mono"};
+static const struct soc_enum monomux =
+	SOC_ENUM_SINGLE(WM8988_ADCIN, 6, 4, wm8988_mono_mux);
+static const struct snd_kcontrol_new wm8988_monomux_controls =
+	SOC_DAPM_ENUM("Route", monomux);
+
+static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
+	SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0),
+
+	SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
+		&wm8988_diffmux_controls),
+	SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
+		&wm8988_monomux_controls),
+	SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
+		&wm8988_monomux_controls),
+
+	SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0,
+		&wm8988_left_pga_controls),
+	SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0,
+		&wm8988_right_pga_controls),
+
+	SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
+		&wm8988_left_line_controls),
+	SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
+		&wm8988_right_line_controls),
+
+	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0),
+	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0),
+
+	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),
+	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),
+
+	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
+		&wm8988_left_mixer_controls[0],
+		ARRAY_SIZE(wm8988_left_mixer_controls)),
+	SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
+		&wm8988_right_mixer_controls[0],
+		ARRAY_SIZE(wm8988_right_mixer_controls)),
+
+	SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0),
+
+	SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control),
+
+	SND_SOC_DAPM_OUTPUT("LOUT1"),
+	SND_SOC_DAPM_OUTPUT("ROUT1"),
+	SND_SOC_DAPM_OUTPUT("LOUT2"),
+	SND_SOC_DAPM_OUTPUT("ROUT2"),
+	SND_SOC_DAPM_OUTPUT("VREF"),
+
+	SND_SOC_DAPM_INPUT("LINPUT1"),
+	SND_SOC_DAPM_INPUT("LINPUT2"),
+	SND_SOC_DAPM_INPUT("RINPUT1"),
+	SND_SOC_DAPM_INPUT("RINPUT2"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+
+	{ "Left Line Mux", "Line 1", "LINPUT1" },
+	{ "Left Line Mux", "Line 2", "LINPUT2" },
+	{ "Left Line Mux", "PGA", "Left PGA Mux" },
+	{ "Left Line Mux", "Differential", "Differential Mux" },
+
+	{ "Right Line Mux", "Line 1", "RINPUT1" },
+	{ "Right Line Mux", "Line 2", "RINPUT2" },
+	{ "Right Line Mux", "PGA", "Right PGA Mux" },
+	{ "Right Line Mux", "Differential", "Differential Mux" },
+
+	{ "Left PGA Mux", "Line 1", "LINPUT1" },
+	{ "Left PGA Mux", "Line 2", "LINPUT2" },
+	{ "Left PGA Mux", "Differential", "Differential Mux" },
+
+	{ "Right PGA Mux", "Line 1", "RINPUT1" },
+	{ "Right PGA Mux", "Line 2", "RINPUT2" },
+	{ "Right PGA Mux", "Differential", "Differential Mux" },
+
+	{ "Differential Mux", "Line 1", "LINPUT1" },
+	{ "Differential Mux", "Line 1", "RINPUT1" },
+	{ "Differential Mux", "Line 2", "LINPUT2" },
+	{ "Differential Mux", "Line 2", "RINPUT2" },
+
+	{ "Left ADC Mux", "Stereo", "Left PGA Mux" },
+	{ "Left ADC Mux", "Mono (Left)", "Left PGA Mux" },
+	{ "Left ADC Mux", "Digital Mono", "Left PGA Mux" },
+
+	{ "Right ADC Mux", "Stereo", "Right PGA Mux" },
+	{ "Right ADC Mux", "Mono (Right)", "Right PGA Mux" },
+	{ "Right ADC Mux", "Digital Mono", "Right PGA Mux" },
+
+	{ "Left ADC", NULL, "Left ADC Mux" },
+	{ "Right ADC", NULL, "Right ADC Mux" },
+
+	{ "Left Line Mux", "Line 1", "LINPUT1" },
+	{ "Left Line Mux", "Line 2", "LINPUT2" },
+	{ "Left Line Mux", "PGA", "Left PGA Mux" },
+	{ "Left Line Mux", "Differential", "Differential Mux" },
+
+	{ "Right Line Mux", "Line 1", "RINPUT1" },
+	{ "Right Line Mux", "Line 2", "RINPUT2" },
+	{ "Right Line Mux", "PGA", "Right PGA Mux" },
+	{ "Right Line Mux", "Differential", "Differential Mux" },
+
+	{ "Left Mixer", "Playback Switch", "Left DAC" },
+	{ "Left Mixer", "Left Bypass Switch", "Left Line Mux" },
+	{ "Left Mixer", "Right Playback Switch", "Right DAC" },
+	{ "Left Mixer", "Right Bypass Switch", "Right Line Mux" },
+
+	{ "Right Mixer", "Left Playback Switch", "Left DAC" },
+	{ "Right Mixer", "Left Bypass Switch", "Left Line Mux" },
+	{ "Right Mixer", "Playback Switch", "Right DAC" },
+	{ "Right Mixer", "Right Bypass Switch", "Right Line Mux" },
+
+	{ "Left Out 1", NULL, "Left Mixer" },
+	{ "LOUT1", NULL, "Left Out 1" },
+	{ "Right Out 1", NULL, "Right Mixer" },
+	{ "ROUT1", NULL, "Right Out 1" },
+
+	{ "Left Out 2", NULL, "Left Mixer" },
+	{ "LOUT2", NULL, "Left Out 2" },
+	{ "Right Out 2", NULL, "Right Mixer" },
+	{ "ROUT2", NULL, "Right Out 2" },
+};
+
+struct _coeff_div {
+	u32 mclk;
+	u32 rate;
+	u16 fs;
+	u8 sr:5;
+	u8 usb:1;
+};
+
+/* codec hifi mclk clock divider coefficients */
+static const struct _coeff_div coeff_div[] = {
+	/* 8k */
+	{12288000, 8000, 1536, 0x6, 0x0},
+	{11289600, 8000, 1408, 0x16, 0x0},
+	{18432000, 8000, 2304, 0x7, 0x0},
+	{16934400, 8000, 2112, 0x17, 0x0},
+	{12000000, 8000, 1500, 0x6, 0x1},
+
+	/* 11.025k */
+	{11289600, 11025, 1024, 0x18, 0x0},
+	{16934400, 11025, 1536, 0x19, 0x0},
+	{12000000, 11025, 1088, 0x19, 0x1},
+
+	/* 16k */
+	{12288000, 16000, 768, 0xa, 0x0},
+	{18432000, 16000, 1152, 0xb, 0x0},
+	{12000000, 16000, 750, 0xa, 0x1},
+
+	/* 22.05k */
+	{11289600, 22050, 512, 0x1a, 0x0},
+	{16934400, 22050, 768, 0x1b, 0x0},
+	{12000000, 22050, 544, 0x1b, 0x1},
+
+	/* 32k */
+	{12288000, 32000, 384, 0xc, 0x0},
+	{18432000, 32000, 576, 0xd, 0x0},
+	{12000000, 32000, 375, 0xa, 0x1},
+
+	/* 44.1k */
+	{11289600, 44100, 256, 0x10, 0x0},
+	{16934400, 44100, 384, 0x11, 0x0},
+	{12000000, 44100, 272, 0x11, 0x1},
+
+	/* 48k */
+	{12288000, 48000, 256, 0x0, 0x0},
+	{18432000, 48000, 384, 0x1, 0x0},
+	{12000000, 48000, 250, 0x0, 0x1},
+
+	/* 88.2k */
+	{11289600, 88200, 128, 0x1e, 0x0},
+	{16934400, 88200, 192, 0x1f, 0x0},
+	{12000000, 88200, 136, 0x1f, 0x1},
+
+	/* 96k */
+	{12288000, 96000, 128, 0xe, 0x0},
+	{18432000, 96000, 192, 0xf, 0x0},
+	{12000000, 96000, 125, 0xe, 0x1},
+};
+
+static inline int get_coeff(int mclk, int rate)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+		if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
+			return i;
+	}
+
+	return -EINVAL;
+}
+
+/* The set of rates we can generate from the above for each SYSCLK */
+
+static unsigned int rates_12288[] = {
+	8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12288 = {
+	.count	= ARRAY_SIZE(rates_12288),
+	.list	= rates_12288,
+};
+
+static unsigned int rates_112896[] = {
+	8000, 11025, 22050, 44100,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_112896 = {
+	.count	= ARRAY_SIZE(rates_112896),
+	.list	= rates_112896,
+};
+
+static unsigned int rates_12[] = {
+	8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
+	48000, 88235, 96000,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_12 = {
+	.count	= ARRAY_SIZE(rates_12),
+	.list	= rates_12,
+};
+
+/*
+ * Note that this should be called from init rather than from hw_params.
+ */
+static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+		int clk_id, unsigned int freq, int dir)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct wm8988_priv *wm8988 = codec->private_data;
+
+	switch (freq) {
+	case 11289600:
+	case 18432000:
+	case 22579200:
+	case 36864000:
+		wm8988->sysclk_constraints = &constraints_112896;
+		wm8988->sysclk = freq;
+		return 0;
+
+	case 12288000:
+	case 16934400:
+	case 24576000:
+	case 33868800:
+		wm8988->sysclk_constraints = &constraints_12288;
+		wm8988->sysclk = freq;
+		return 0;
+
+	case 12000000:
+	case 24000000:
+		wm8988->sysclk_constraints = &constraints_12;
+		wm8988->sysclk = freq;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
+		unsigned int fmt)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	u16 iface = 0;
+
+	/* set master/slave audio interface */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		iface = 0x0040;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* interface format */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		iface |= 0x0002;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		iface |= 0x0001;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		iface |= 0x0003;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		iface |= 0x0013;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* clock inversion */
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		iface |= 0x0090;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		iface |= 0x0080;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		iface |= 0x0010;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	wm8988_write(codec, WM8988_IFACE, iface);
+	return 0;
+}
+
+static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
+			      struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct wm8988_priv *wm8988 = codec->private_data;
+
+	/* The set of sample rates that can be supported depends on the
+	 * MCLK supplied to the CODEC - enforce this.
+	 */
+	if (!wm8988->sysclk) {
+		dev_err(codec->dev,
+			"No MCLK configured, call set_sysclk() on init\n");
+		return -EINVAL;
+	}
+
+	snd_pcm_hw_constraint_list(substream->runtime, 0,
+				   SNDRV_PCM_HW_PARAM_RATE,
+				   wm8988->sysclk_constraints);
+
+	return 0;
+}
+
+static int wm8988_pcm_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_device *socdev = rtd->socdev;
+	struct snd_soc_codec *codec = socdev->card->codec;
+	struct wm8988_priv *wm8988 = codec->private_data;
+	u16 iface = wm8988_read_reg_cache(codec, WM8988_IFACE) & 0x1f3;
+	u16 srate = wm8988_read_reg_cache(codec, WM8988_SRATE) & 0x180;
+	int coeff;
+
+	coeff = get_coeff(wm8988->sysclk, params_rate(params));
+	if (coeff < 0) {
+		coeff = get_coeff(wm8988->sysclk / 2, params_rate(params));
+		srate |= 0x40;
+	}
+	if (coeff < 0) {
+		dev_err(codec->dev,
+			"Unable to configure sample rate %dHz with %dHz MCLK\n",
+			params_rate(params), wm8988->sysclk);
+		return coeff;
+	}
+
+	/* bit size */
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		iface |= 0x0004;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		iface |= 0x0008;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		iface |= 0x000c;
+		break;
+	}
+
+	/* set iface & srate */
+	wm8988_write(codec, WM8988_IFACE, iface);
+	if (coeff >= 0)
+		wm8988_write(codec, WM8988_SRATE, srate |
+			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
+
+	return 0;
+}
+
+static int wm8988_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	u16 mute_reg = wm8988_read_reg_cache(codec, WM8988_ADCDAC) & 0xfff7;
+
+	if (mute)
+		wm8988_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
+	else
+		wm8988_write(codec, WM8988_ADCDAC, mute_reg);
+	return 0;
+}
+
+static int wm8988_set_bias_level(struct snd_soc_codec *codec,
+				 enum snd_soc_bias_level level)
+{
+	u16 pwr_reg = wm8988_read_reg_cache(codec, WM8988_PWR1) & ~0x1c1;
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		break;
+
+	case SND_SOC_BIAS_PREPARE:
+		/* VREF, VMID=2x50k, digital enabled */
+		wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
+		break;
+
+	case SND_SOC_BIAS_STANDBY:
+		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+			/* VREF, VMID=2x5k */
+			wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
+
+			/* Charge caps */
+			msleep(100);
+		}
+
+		/* VREF, VMID=2*500k, digital stopped */
+		wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x0141);
+		break;
+
+	case SND_SOC_BIAS_OFF:
+		wm8988_write(codec, WM8988_PWR1, 0x0000);
+		break;
+	}
+	codec->bias_level = level;
+	return 0;
+}
+
+#define WM8988_RATES SNDRV_PCM_RATE_8000_96000
+
+#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+	SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops wm8988_ops = {
+	.startup = wm8988_pcm_startup,
+	.hw_params = wm8988_pcm_hw_params,
+	.set_fmt = wm8988_set_dai_fmt,
+	.set_sysclk = wm8988_set_dai_sysclk,
+	.digital_mute = wm8988_mute,
+};
+
+struct snd_soc_dai wm8988_dai = {
+	.name = "WM8988",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = WM8988_RATES,
+		.formats = WM8988_FORMATS,
+	},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = WM8988_RATES,
+		.formats = WM8988_FORMATS,
+	 },
+	.ops = &wm8988_ops,
+	.symmetric_rates = 1,
+};
+EXPORT_SYMBOL_GPL(wm8988_dai);
+
+static int wm8988_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec = socdev->card->codec;
+
+	wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	return 0;
+}
+
+static int wm8988_resume(struct platform_device *pdev)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec = socdev->card->codec;
+	int i;
+	u8 data[2];
+	u16 *cache = codec->reg_cache;
+
+	/* Sync reg_cache with the hardware */
+	for (i = 0; i < WM8988_NUM_REG; i++) {
+		if (i == WM8988_RESET)
+			continue;
+		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
+		data[1] = cache[i] & 0x00ff;
+		codec->hw_write(codec->control_data, data, 2);
+	}
+
+	wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+	return 0;
+}
+
+static struct snd_soc_codec *wm8988_codec;
+
+static int wm8988_probe(struct platform_device *pdev)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec;
+	int ret = 0;
+
+	if (wm8988_codec == NULL) {
+		dev_err(&pdev->dev, "Codec device not registered\n");
+		return -ENODEV;
+	}
+
+	socdev->card->codec = wm8988_codec;
+	codec = wm8988_codec;
+
+	/* register pcms */
+	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+	if (ret < 0) {
+		dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+		goto pcm_err;
+	}
+
+	snd_soc_add_controls(codec, wm8988_snd_controls,
+				ARRAY_SIZE(wm8988_snd_controls));
+	snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
+				  ARRAY_SIZE(wm8988_dapm_widgets));
+	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+	snd_soc_dapm_new_widgets(codec);
+
+	ret = snd_soc_init_card(socdev);
+	if (ret < 0) {
+		dev_err(codec->dev, "failed to register card: %d\n", ret);
+		goto card_err;
+	}
+
+	return ret;
+
+card_err:
+	snd_soc_free_pcms(socdev);
+	snd_soc_dapm_free(socdev);
+pcm_err:
+	return ret;
+}
+
+static int wm8988_remove(struct platform_device *pdev)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+	snd_soc_free_pcms(socdev);
+	snd_soc_dapm_free(socdev);
+
+	return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8988 = {
+	.probe = 	wm8988_probe,
+	.remove = 	wm8988_remove,
+	.suspend = 	wm8988_suspend,
+	.resume =	wm8988_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
+
+static int wm8988_register(struct wm8988_priv *wm8988)
+{
+	struct snd_soc_codec *codec = &wm8988->codec;
+	int ret;
+	u16 reg;
+
+	if (wm8988_codec) {
+		dev_err(codec->dev, "Another WM8988 is registered\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	mutex_init(&codec->mutex);
+	INIT_LIST_HEAD(&codec->dapm_widgets);
+	INIT_LIST_HEAD(&codec->dapm_paths);
+
+	codec->private_data = wm8988;
+	codec->name = "WM8988";
+	codec->owner = THIS_MODULE;
+	codec->read = wm8988_read_reg_cache;
+	codec->write = wm8988_write;
+	codec->dai = &wm8988_dai;
+	codec->num_dai = 1;
+	codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
+	codec->reg_cache = &wm8988->reg_cache;
+	codec->bias_level = SND_SOC_BIAS_OFF;
+	codec->set_bias_level = wm8988_set_bias_level;
+
+	memcpy(codec->reg_cache, wm8988_reg,
+	       sizeof(wm8988_reg));
+
+	ret = wm8988_reset(codec);
+	if (ret < 0) {
+		dev_err(codec->dev, "Failed to issue reset\n");
+		return ret;
+	}
+
+	/* set the update bits (we always update left then right) */
+	reg = wm8988_read_reg_cache(codec, WM8988_RADC);
+	wm8988_write(codec, WM8988_RADC, reg | 0x100);
+	reg = wm8988_read_reg_cache(codec, WM8988_RDAC);
+	wm8988_write(codec, WM8988_RDAC, reg | 0x0100);
+	reg = wm8988_read_reg_cache(codec, WM8988_ROUT1V);
+	wm8988_write(codec, WM8988_ROUT1V, reg | 0x0100);
+	reg = wm8988_read_reg_cache(codec, WM8988_ROUT2V);
+	wm8988_write(codec, WM8988_ROUT2V, reg | 0x0100);
+	reg = wm8988_read_reg_cache(codec, WM8988_RINVOL);
+	wm8988_write(codec, WM8988_RINVOL, reg | 0x0100);
+
+	wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY);
+
+	wm8988_dai.dev = codec->dev;
+
+	wm8988_codec = codec;
+
+	ret = snd_soc_register_codec(codec);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_register_dai(&wm8988_dai);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+		snd_soc_unregister_codec(codec);
+		return ret;
+	}
+
+	return 0;
+
+err:
+	kfree(wm8988);
+	return ret;
+}
+
+static void wm8988_unregister(struct wm8988_priv *wm8988)
+{
+	wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF);
+	snd_soc_unregister_dai(&wm8988_dai);
+	snd_soc_unregister_codec(&wm8988->codec);
+	kfree(wm8988);
+	wm8988_codec = NULL;
+}
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int wm8988_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct wm8988_priv *wm8988;
+	struct snd_soc_codec *codec;
+
+	wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
+	if (wm8988 == NULL)
+		return -ENOMEM;
+
+	codec = &wm8988->codec;
+	codec->hw_write = (hw_write_t)i2c_master_send;
+
+	i2c_set_clientdata(i2c, wm8988);
+	codec->control_data = i2c;
+
+	codec->dev = &i2c->dev;
+
+	return wm8988_register(wm8988);
+}
+
+static int wm8988_i2c_remove(struct i2c_client *client)
+{
+	struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
+	wm8988_unregister(wm8988);
+	return 0;
+}
+
+static const struct i2c_device_id wm8988_i2c_id[] = {
+	{ "wm8988", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
+
+static struct i2c_driver wm8988_i2c_driver = {
+	.driver = {
+		.name = "WM8988",
+		.owner = THIS_MODULE,
+	},
+	.probe = wm8988_i2c_probe,
+	.remove = wm8988_i2c_remove,
+	.id_table = wm8988_i2c_id,
+};
+#endif
+
+#if defined(CONFIG_SPI_MASTER)
+static int wm8988_spi_write(struct spi_device *spi, const char *data, int len)
+{
+	struct spi_transfer t;
+	struct spi_message m;
+	u8 msg[2];
+
+	if (len <= 0)
+		return 0;
+
+	msg[0] = data[0];
+	msg[1] = data[1];
+
+	spi_message_init(&m);
+	memset(&t, 0, (sizeof t));
+
+	t.tx_buf = &msg[0];
+	t.len = len;
+
+	spi_message_add_tail(&t, &m);
+	spi_sync(spi, &m);
+
+	return len;
+}
+
+static int __devinit wm8988_spi_probe(struct spi_device *spi)
+{
+	struct wm8988_priv *wm8988;
+	struct snd_soc_codec *codec;
+
+	wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
+	if (wm8988 == NULL)
+		return -ENOMEM;
+
+	codec = &wm8988->codec;
+	codec->hw_write = (hw_write_t)wm8988_spi_write;
+	codec->control_data = spi;
+	codec->dev = &spi->dev;
+
+	spi->dev.driver_data = wm8988;
+
+	return wm8988_register(wm8988);
+}
+
+static int __devexit wm8988_spi_remove(struct spi_device *spi)
+{
+	struct wm8988_priv *wm8988 = spi->dev.driver_data;
+
+	wm8988_unregister(wm8988);
+
+	return 0;
+}
+
+static struct spi_driver wm8988_spi_driver = {
+	.driver = {
+		.name	= "wm8988",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm8988_spi_probe,
+	.remove		= __devexit_p(wm8988_spi_remove),
+};
+#endif
+
+static int __init wm8988_modinit(void)
+{
+	int ret;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	ret = i2c_add_driver(&wm8988_i2c_driver);
+	if (ret != 0)
+		pr_err("WM8988: Unable to register I2C driver: %d\n", ret);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+	ret = spi_register_driver(&wm8988_spi_driver);
+	if (ret != 0)
+		pr_err("WM8988: Unable to register SPI driver: %d\n", ret);
+#endif
+	return ret;
+}
+module_init(wm8988_modinit);
+
+static void __exit wm8988_exit(void)
+{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	i2c_del_driver(&wm8988_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+	spi_unregister_driver(&wm8988_spi_driver);
+#endif
+}
+module_exit(wm8988_exit);
+
+
+MODULE_DESCRIPTION("ASoC WM8988 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8988.h b/sound/soc/codecs/wm8988.h
new file mode 100644
index 0000000..4552d37
--- /dev/null
+++ b/sound/soc/codecs/wm8988.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@openedhand.com>
+ *
+ * Based on WM8753.h
+ *
+ * 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 _WM8988_H
+#define _WM8988_H
+
+/* WM8988 register space */
+
+#define WM8988_LINVOL    0x00
+#define WM8988_RINVOL    0x01
+#define WM8988_LOUT1V    0x02
+#define WM8988_ROUT1V    0x03
+#define WM8988_ADCDAC    0x05
+#define WM8988_IFACE     0x07
+#define WM8988_SRATE     0x08
+#define WM8988_LDAC      0x0a
+#define WM8988_RDAC      0x0b
+#define WM8988_BASS      0x0c
+#define WM8988_TREBLE    0x0d
+#define WM8988_RESET     0x0f
+#define WM8988_3D        0x10
+#define WM8988_ALC1      0x11
+#define WM8988_ALC2      0x12
+#define WM8988_ALC3      0x13
+#define WM8988_NGATE     0x14
+#define WM8988_LADC      0x15
+#define WM8988_RADC      0x16
+#define WM8988_ADCTL1    0x17
+#define WM8988_ADCTL2    0x18
+#define WM8988_PWR1      0x19
+#define WM8988_PWR2      0x1a
+#define WM8988_ADCTL3    0x1b
+#define WM8988_ADCIN     0x1f
+#define WM8988_LADCIN    0x20
+#define WM8988_RADCIN    0x21
+#define WM8988_LOUTM1    0x22
+#define WM8988_LOUTM2    0x23
+#define WM8988_ROUTM1    0x24
+#define WM8988_ROUTM2    0x25
+#define WM8988_LOUT2V    0x28
+#define WM8988_ROUT2V    0x29
+#define WM8988_LPPB      0x43
+#define WM8988_NUM_REG   0x44
+
+#define WM8988_SYSCLK	0
+
+extern struct snd_soc_dai wm8988_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8988;
+
+#endif
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 07/14] ASoC: tlv320aic23: add DSP_A format support
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (6 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 06/14] ASoC: Add WM8988 CODEC driver Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 08/14] ASoC: n810: replace BUG() with BUG_ON() Mark Brown
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Peter Ujfalusi

From: Peter Ujfalusi <peter.ujfalusi@nokia.com>

Add DSP_A interface format support by setting the LRP bit in
DSP mode.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/tlv320aic23.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index c3f4afb..21f69df 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -523,6 +523,8 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	case SND_SOC_DAIFMT_I2S:
 		iface_reg |= TLV320AIC23_FOR_I2S;
 		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		iface_reg |= TLV320AIC23_LRP_ON;
 	case SND_SOC_DAIFMT_DSP_B:
 		iface_reg |= TLV320AIC23_FOR_DSP;
 		break;
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 08/14] ASoC: n810: replace BUG() with BUG_ON()
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (7 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 07/14] ASoC: tlv320aic23: add DSP_A format support Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 09/14] ASoC: WM9713 requires symmetric rates on the voice DAI Mark Brown
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Alexander Beregalov

From: Alexander Beregalov <a.beregalov@gmail.com>

Signed-off-by: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/omap/n810.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index a6d1178..e54e1c2 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -383,10 +383,9 @@ static int __init n810_soc_init(void)
 	clk_set_parent(sys_clkout2_src, func96m_clk);
 	clk_set_rate(sys_clkout2, 12000000);
 
-	if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0)
-		BUG();
-	if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0)
-		BUG();
+	BUG_ON((gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) ||
+	       (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0));
+
 	gpio_direction_output(N810_HEADSET_AMP_GPIO, 0);
 	gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0);
 
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 09/14] ASoC: WM9713 requires symmetric rates on the voice DAI
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (8 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 08/14] ASoC: n810: replace BUG() with BUG_ON() Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 10/14] ASoC: Factor out application of power for generic widgets Mark Brown
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm9713.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 523bad0..aa94cc6 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1069,6 +1069,7 @@ struct snd_soc_dai wm9713_dai[] = {
 		.rates = WM9713_PCM_RATES,
 		.formats = WM9713_PCM_FORMATS,},
 	.ops = &wm9713_dai_ops_voice,
+	.symmetric_rates = 1,
 	},
 };
 EXPORT_SYMBOL_GPL(wm9713_dai);
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 10/14] ASoC: Factor out application of power for generic widgets
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (9 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 09/14] ASoC: WM9713 requires symmetric rates on the voice DAI Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 11/14] ASoC: Support DAPM events for DACs and ADCs Mark Brown
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

This is simple code motion, intended to support future refactoring of
the DAPM algorithms and (more immediately) the additon of events for
DACs and ADCs.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/soc-dapm.c |  110 +++++++++++++++++++++++++++-----------------------
 1 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 46485de..713d125 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -522,6 +522,65 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(dapm_reg_event);
 
+/* Standard power change method, used to apply power changes to most
+ * widgets.
+ */
+static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
+{
+	int ret;
+
+	/* call any power change event handlers */
+	if (w->event)
+		pr_debug("power %s event for %s flags %x\n",
+			 w->power ? "on" : "off",
+			 w->name, w->event_flags);
+
+	/* power up pre event */
+	if (w->power && w->event &&
+	    (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
+		ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* power down pre event */
+	if (!w->power && w->event &&
+	    (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
+		ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Lower PGA volume to reduce pops */
+	if (w->id == snd_soc_dapm_pga && !w->power)
+		dapm_set_pga(w, w->power);
+
+	dapm_update_bits(w);
+
+	/* Raise PGA volume to reduce pops */
+	if (w->id == snd_soc_dapm_pga && w->power)
+		dapm_set_pga(w, w->power);
+
+	/* power up post event */
+	if (w->power && w->event &&
+	    (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
+		ret = w->event(w,
+			       NULL, SND_SOC_DAPM_POST_PMU);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* power down post event */
+	if (!w->power && w->event &&
+	    (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
+		ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 /*
  * Scan a single DAPM widget for a complete audio path and update the
  * power status appropriately.
@@ -601,56 +660,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
 	if (!power_change)
 		return 0;
 
-	/* call any power change event handlers */
-	if (w->event)
-		pr_debug("power %s event for %s flags %x\n",
-			 w->power ? "on" : "off",
-			 w->name, w->event_flags);
-
-	/* power up pre event */
-	if (power && w->event &&
-	    (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
-		ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
-		if (ret < 0)
-			return ret;
-	}
-
-	/* power down pre event */
-	if (!power && w->event &&
-	    (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
-		ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
-		if (ret < 0)
-			return ret;
-	}
-
-	/* Lower PGA volume to reduce pops */
-	if (w->id == snd_soc_dapm_pga && !power)
-		dapm_set_pga(w, power);
-
-	dapm_update_bits(w);
-
-	/* Raise PGA volume to reduce pops */
-	if (w->id == snd_soc_dapm_pga && power)
-		dapm_set_pga(w, power);
-
-	/* power up post event */
-	if (power && w->event &&
-	    (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
-		ret = w->event(w,
-			       NULL, SND_SOC_DAPM_POST_PMU);
-		if (ret < 0)
-			return ret;
-	}
-
-	/* power down post event */
-	if (!power && w->event &&
-	    (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
-		ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
-		if (ret < 0)
-			return ret;
-	}
-
-	return 0;
+	return dapm_generic_apply_power(w);
 }
 
 /*
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 11/14] ASoC: Support DAPM events for DACs and ADCs
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (10 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 10/14] ASoC: Factor out application of power for generic widgets Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 12/14] ASoC: Move the WM9713 voice DAC powerdown to a DAPM event Mark Brown
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 include/sound/soc-dapm.h |   10 ++++++++++
 sound/soc/soc-dapm.c     |   16 ++++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index a7def6a..fcc929d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -140,9 +140,19 @@
 #define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
 {	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
 	.shift = wshift, .invert = winvert}
+#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
+			   wevent, wflags)				\
+{	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
+	.shift = wshift, .invert = winvert, \
+	.event = wevent, .event_flags = wflags}
 #define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
 {	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
 	.shift = wshift, .invert = winvert}
+#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
+			   wevent, wflags)				\
+{	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
+	.shift = wshift, .invert = winvert, \
+	.event = wevent, .event_flags = wflags}
 
 /* generic register modifier widget */
 #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 713d125..a6d7337 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -598,18 +598,22 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
 	if (w->id == snd_soc_dapm_adc && w->active) {
 		in = is_connected_input_ep(w);
 		dapm_clear_walk(w->codec);
-		w->power = (in != 0) ? 1 : 0;
-		dapm_update_bits(w);
-		return 0;
+		power = (in != 0) ? 1 : 0;
+		if (power == w->power)
+			return 0;
+		w->power = power;
+		return dapm_generic_apply_power(w);
 	}
 
 	/* active DAC */
 	if (w->id == snd_soc_dapm_dac && w->active) {
 		out = is_connected_output_ep(w);
 		dapm_clear_walk(w->codec);
-		w->power = (out != 0) ? 1 : 0;
-		dapm_update_bits(w);
-		return 0;
+		power = (out != 0) ? 1 : 0;
+		if (power == w->power)
+			return 0;
+		w->power = power;
+		return dapm_generic_apply_power(w);
 	}
 
 	/* pre and post event widgets */
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 12/14] ASoC: Move the WM9713 voice DAC powerdown to a DAPM event
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (11 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 11/14] ASoC: Support DAPM events for DACs and ADCs Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 13/14] ASoC: pxa-ssp.c fix clock/frame invert Mark Brown
  2009-04-14 12:33 ` [PATCH 14/14] ASoC: Add WM8960 CODEC driver Mark Brown
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

This ensures that we sync with the DAPM powerdown sequencing properly
and don't need to bounce the power on the voice DAC so often.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm9713.c |   39 ++++++++++++++++++++++-----------------
 1 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index aa94cc6..a6feb78 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -189,6 +189,26 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
 SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
 };
 
+static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	u16 status, rate;
+
+	BUG_ON(event != SND_SOC_DAPM_PRE_PMD);
+
+	/* Gracefully shut down the voice interface. */
+	status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000;
+	rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
+	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
+	schedule_timeout_interruptible(msecs_to_jiffies(1));
+	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
+	ac97_write(codec, AC97_EXTENDED_MID, status);
+
+	return 0;
+}
+
+
 /* We have to create a fake left and right HP mixers because
  * the codec only has a single control that is shared by both channels.
  * This makes it impossible to determine the audio path using the current
@@ -400,7 +420,8 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
+SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1,
+		   wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
 SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
 SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
@@ -936,21 +957,6 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
-				 struct snd_soc_dai *dai)
-{
-	struct snd_soc_codec *codec = dai->codec;
-	u16 status, rate;
-
-	/* Gracefully shut down the voice interface. */
-	status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
-	rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
-	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
-	schedule_timeout_interruptible(msecs_to_jiffies(1));
-	ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
-	ac97_write(codec, AC97_EXTENDED_MID, status);
-}
-
 static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *dai)
 {
@@ -1019,7 +1025,6 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
 
 static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
 	.hw_params	= wm9713_pcm_hw_params,
-	.shutdown	= wm9713_voiceshutdown,
 	.set_clkdiv	= wm9713_set_dai_clkdiv,
 	.set_pll	= wm9713_set_dai_pll,
 	.set_fmt	= wm9713_set_dai_fmt,
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 13/14] ASoC: pxa-ssp.c fix clock/frame invert
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (12 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 12/14] ASoC: Move the WM9713 voice DAC powerdown to a DAPM event Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  2009-04-14 12:33 ` [PATCH 14/14] ASoC: Add WM8960 CODEC driver Mark Brown
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown, Daniel Ribeiro

From: Daniel Ribeiro <drwyrm@gmail.com>

SCMODE(0): Data Driven (Falling), Data Sampled (Rising), Idle State (Low)
SCMODE(1): Data Driven (Rising), Data Sampled (Falling), Idle State (Low)
SCMODE(2): Data Driven (Rising), Data Sampled (Falling), Idle State (High)
SCMODE(3): Data Driven (Falling), Data Sampled (Rising), Idle State (High)

SCMODE(3) does not invert the clock polarity compared to the default SCMODE(0).

This patch also adds all possible NF/IF, NB/IB combinations to the DSP_A and
DSP_B modes.

Signed-off-by: Daniel Ribeiro <drwyrm@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/pxa/pxa-ssp.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index c7c1996..176af7f 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -568,7 +568,10 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		case SND_SOC_DAIFMT_NB_IF:
 			break;
 		case SND_SOC_DAIFMT_IB_IF:
-			sspsp |= SSPSP_SCMODE(3);
+			sspsp |= SSPSP_SCMODE(2);
+			break;
+		case SND_SOC_DAIFMT_IB_NF:
+			sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
 			break;
 		default:
 			return -EINVAL;
@@ -585,7 +588,13 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		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;
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [PATCH 14/14] ASoC: Add WM8960 CODEC driver
  2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
                   ` (13 preceding siblings ...)
  2009-04-14 12:33 ` [PATCH 13/14] ASoC: pxa-ssp.c fix clock/frame invert Mark Brown
@ 2009-04-14 12:33 ` Mark Brown
  14 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Mark Brown

The WM8960 is a low power, high quality stereo codec designed for
portable digital audio applications.

Stereo class D speaker drivers provide 1W per channel into 8W loads.
Guaranteed low leakage, excellent PSRR and pop/click suppression
mechanisms enable direct battery connection for the speaker supply.

The device also integrates a complete microphone interface and a stereo
headphone driver. External component requirements are drastically
reduced as no separate microphone, speaker or headphone amplifiers are
required. Advanced on-chip digital signal processing performs automatic
level control for the microphone or line input.

Stereo 24-bit sigma-delta ADCs and DACs are used with low power
over-sampling digital interpolation and decimation filters and a
flexible digital audio interface.

The master clock can be input directly or generated internally by an
onboard PLL, supporting most commonly-used clocking schemes.

This driver was originally written by Liam Girdwood, with substantial
subsequent additions and updates for feature completeness and changes in
the ASoC framework from me.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/Kconfig  |    4 +
 sound/soc/codecs/Makefile |    2 +
 sound/soc/codecs/wm8960.c |  969 +++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm8960.h |  127 ++++++
 4 files changed, 1102 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/codecs/wm8960.c
 create mode 100644 sound/soc/codecs/wm8960.h

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index ab36485..121d63f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -35,6 +35,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
 	select SND_SOC_WM8900 if I2C
 	select SND_SOC_WM8903 if I2C
+	select SND_SOC_WM8960 if I2C
 	select SND_SOC_WM8971 if I2C
 	select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
 	select SND_SOC_WM8990 if I2C
@@ -139,6 +140,9 @@ config SND_SOC_WM8900
 config SND_SOC_WM8903
 	tristate
 
+config SND_SOC_WM8960
+	tristate
+
 config SND_SOC_WM8971
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index a72548d..d8e15a4 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -23,6 +23,7 @@ snd-soc-wm8750-objs := wm8750.o
 snd-soc-wm8753-objs := wm8753.o
 snd-soc-wm8900-objs := wm8900.o
 snd-soc-wm8903-objs := wm8903.o
+snd-soc-wm8960-objs := wm8960.o
 snd-soc-wm8971-objs := wm8971.o
 snd-soc-wm8988-objs := wm8988.o
 snd-soc-wm8990-objs := wm8990.o
@@ -56,6 +57,7 @@ obj-$(CONFIG_SND_SOC_WM8753)	+= snd-soc-wm8753.o
 obj-$(CONFIG_SND_SOC_WM8900)	+= snd-soc-wm8900.o
 obj-$(CONFIG_SND_SOC_WM8903)	+= snd-soc-wm8903.o
 obj-$(CONFIG_SND_SOC_WM8971)	+= snd-soc-wm8971.o
+obj-$(CONFIG_SND_SOC_WM8960)	+= snd-soc-wm8960.o
 obj-$(CONFIG_SND_SOC_WM8988)	+= snd-soc-wm8988.o
 obj-$(CONFIG_SND_SOC_WM8990)	+= snd-soc-wm8990.o
 obj-$(CONFIG_SND_SOC_WM8991)	+= snd-soc-wm8991.o
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
new file mode 100644
index 0000000..e224d8a
--- /dev/null
+++ b/sound/soc/codecs/wm8960.c
@@ -0,0 +1,969 @@
+/*
+ * wm8960.c  --  WM8960 ALSA SoC Audio driver
+ *
+ * Author: Liam Girdwood
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8960.h"
+
+#define AUDIO_NAME "wm8960"
+
+struct snd_soc_codec_device soc_codec_dev_wm8960;
+
+/* R25 - Power 1 */
+#define WM8960_VREF      0x40
+
+/* R28 - Anti-pop 1 */
+#define WM8960_POBCTRL   0x80
+#define WM8960_BUFDCOPEN 0x10
+#define WM8960_BUFIOEN   0x08
+#define WM8960_SOFT_ST   0x04
+#define WM8960_HPSTBY    0x01
+
+/* R29 - Anti-pop 2 */
+#define WM8960_DISOP     0x40
+
+/*
+ * wm8960 register cache
+ * We can't read the WM8960 register space when we are
+ * using 2 wire for device control, so we cache them instead.
+ */
+static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
+	0x0097, 0x0097, 0x0000, 0x0000,
+	0x0000, 0x0008, 0x0000, 0x000a,
+	0x01c0, 0x0000, 0x00ff, 0x00ff,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x007b, 0x0100, 0x0032,
+	0x0000, 0x00c3, 0x00c3, 0x01c0,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0100, 0x0100, 0x0050, 0x0050,
+	0x0050, 0x0050, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0040, 0x0000,
+	0x0000, 0x0050, 0x0050, 0x0000,
+	0x0002, 0x0037, 0x004d, 0x0080,
+	0x0008, 0x0031, 0x0026, 0x00e9,
+};
+
+struct wm8960_priv {
+	u16 reg_cache[WM8960_CACHEREGNUM];
+	struct snd_soc_codec codec;
+};
+
+/*
+ * read wm8960 register cache
+ */
+static inline unsigned int wm8960_read_reg_cache(struct snd_soc_codec *codec,
+	unsigned int reg)
+{
+	u16 *cache = codec->reg_cache;
+	if (reg == WM8960_RESET)
+		return 0;
+	if (reg >= WM8960_CACHEREGNUM)
+		return -1;
+	return cache[reg];
+}
+
+/*
+ * write wm8960 register cache
+ */
+static inline void wm8960_write_reg_cache(struct snd_soc_codec *codec,
+	u16 reg, unsigned int value)
+{
+	u16 *cache = codec->reg_cache;
+	if (reg >= WM8960_CACHEREGNUM)
+		return;
+	cache[reg] = value;
+}
+
+static inline unsigned int wm8960_read(struct snd_soc_codec *codec,
+	unsigned int reg)
+{
+	return wm8960_read_reg_cache(codec, reg);
+}
+
+/*
+ * write to the WM8960 register space
+ */
+static int wm8960_write(struct snd_soc_codec *codec, unsigned int reg,
+	unsigned int value)
+{
+	u8 data[2];
+
+	/* data is
+	 *   D15..D9 WM8960 register offset
+	 *   D8...D0 register data
+	 */
+	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+	data[1] = value & 0x00ff;
+
+	wm8960_write_reg_cache(codec, reg, value);
+	if (codec->hw_write(codec->control_data, data, 2) == 2)
+		return 0;
+	else
+		return -EIO;
+}
+
+#define wm8960_reset(c)	wm8960_write(c, WM8960_RESET, 0)
+
+/* enumerated controls */
+static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
+static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
+	"Right Inverted", "Stereo Inversion"};
+static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
+static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"};
+static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
+static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
+
+static const struct soc_enum wm8960_enum[] = {
+	SOC_ENUM_SINGLE(WM8960_DACCTL1, 1, 4, wm8960_deemph),
+	SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
+	SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
+	SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
+	SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff),
+	SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc),
+	SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
+};
+
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
+static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
+
+static const struct snd_kcontrol_new wm8960_snd_controls[] = {
+SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
+		 0, 63, 0, adc_tlv),
+SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
+	6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
+	7, 1, 0),
+
+SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
+		 0, 255, 0, dac_tlv),
+
+SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1,
+		 0, 127, 0, out_tlv),
+SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1,
+	7, 1, 0),
+
+SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2,
+		 0, 127, 0, out_tlv),
+SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2,
+	7, 1, 0),
+SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
+SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
+
+SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
+SOC_ENUM("ADC Polarity", wm8960_enum[1]),
+SOC_ENUM("Playback De-emphasis", wm8960_enum[0]),
+SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
+
+SOC_ENUM("DAC Polarity", wm8960_enum[2]),
+
+SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[3]),
+SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[4]),
+SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
+SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
+
+SOC_ENUM("ALC Function", wm8960_enum[5]),
+SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
+SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
+SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
+SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
+SOC_ENUM("ALC Mode", wm8960_enum[6]),
+SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
+SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
+
+SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0),
+SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0),
+
+SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH,
+	0, 127, 0),
+
+SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume",
+	       WM8960_BYPASS1, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume",
+	       WM8960_LOUTMIX, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume",
+	       WM8960_BYPASS2, 4, 7, 1, bypass_tlv),
+SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume",
+	       WM8960_ROUTMIX, 4, 7, 1, bypass_tlv),
+};
+
+static const struct snd_kcontrol_new wm8960_lin_boost[] = {
+SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0),
+SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0),
+SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_lin[] = {
+SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_rin_boost[] = {
+SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0),
+SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0),
+SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_rin[] = {
+SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_loutput_mixer[] = {
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0),
+SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0),
+SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_routput_mixer[] = {
+SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0),
+SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0),
+SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8960_mono_out[] = {
+SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0),
+SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = {
+SND_SOC_DAPM_INPUT("LINPUT1"),
+SND_SOC_DAPM_INPUT("RINPUT1"),
+SND_SOC_DAPM_INPUT("LINPUT2"),
+SND_SOC_DAPM_INPUT("RINPUT2"),
+SND_SOC_DAPM_INPUT("LINPUT3"),
+SND_SOC_DAPM_INPUT("RINPUT3"),
+
+SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0),
+
+SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
+		   wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
+SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0,
+		   wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)),
+
+SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
+		   wm8960_lin, ARRAY_SIZE(wm8960_lin)),
+SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
+		   wm8960_rin, ARRAY_SIZE(wm8960_rin)),
+
+SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0),
+
+SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
+
+SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0,
+	&wm8960_loutput_mixer[0],
+	ARRAY_SIZE(wm8960_loutput_mixer)),
+SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
+	&wm8960_routput_mixer[0],
+	ARRAY_SIZE(wm8960_routput_mixer)),
+
+SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
+	&wm8960_mono_out[0],
+	ARRAY_SIZE(wm8960_mono_out)),
+
+SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0),
+
+SND_SOC_DAPM_OUTPUT("SPK_LP"),
+SND_SOC_DAPM_OUTPUT("SPK_LN"),
+SND_SOC_DAPM_OUTPUT("HP_L"),
+SND_SOC_DAPM_OUTPUT("HP_R"),
+SND_SOC_DAPM_OUTPUT("SPK_RP"),
+SND_SOC_DAPM_OUTPUT("SPK_RN"),
+SND_SOC_DAPM_OUTPUT("OUT3"),
+};
+
+static const struct snd_soc_dapm_route audio_paths[] = {
+	{ "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
+	{ "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
+	{ "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" },
+
+	{ "Left Input Mixer", "Boost Switch", "Left Boost Mixer", },
+	{ "Left Input Mixer", NULL, "LINPUT1", },  /* Really Boost Switch */
+	{ "Left Input Mixer", NULL, "LINPUT2" },
+	{ "Left Input Mixer", NULL, "LINPUT3" },
+
+	{ "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" },
+	{ "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" },
+	{ "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" },
+
+	{ "Right Input Mixer", "Boost Switch", "Right Boost Mixer", },
+	{ "Right Input Mixer", NULL, "RINPUT1", },  /* Really Boost Switch */
+	{ "Right Input Mixer", NULL, "RINPUT2" },
+	{ "Right Input Mixer", NULL, "LINPUT3" },
+
+	{ "Left ADC", NULL, "Left Input Mixer" },
+	{ "Right ADC", NULL, "Right Input Mixer" },
+
+	{ "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" },
+	{ "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} ,
+	{ "Left Output Mixer", "PCM Playback Switch", "Left DAC" },
+
+	{ "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" },
+	{ "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } ,
+	{ "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
+
+	{ "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
+	{ "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
+
+	{ "LOUT1 PGA", NULL, "Left Output Mixer" },
+	{ "ROUT1 PGA", NULL, "Right Output Mixer" },
+
+	{ "HP_L", NULL, "LOUT1 PGA" },
+	{ "HP_R", NULL, "ROUT1 PGA" },
+
+	{ "Left Speaker PGA", NULL, "Left Output Mixer" },
+	{ "Right Speaker PGA", NULL, "Right Output Mixer" },
+
+	{ "Left Speaker Output", NULL, "Left Speaker PGA" },
+	{ "Right Speaker Output", NULL, "Right Speaker PGA" },
+
+	{ "SPK_LN", NULL, "Left Speaker Output" },
+	{ "SPK_LP", NULL, "Left Speaker Output" },
+	{ "SPK_RN", NULL, "Right Speaker Output" },
+	{ "SPK_RP", NULL, "Right Speaker Output" },
+
+	{ "OUT3", NULL, "Mono Output Mixer", }
+};
+
+static int wm8960_add_widgets(struct snd_soc_codec *codec)
+{
+	snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
+				  ARRAY_SIZE(wm8960_dapm_widgets));
+
+	snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
+
+	snd_soc_dapm_new_widgets(codec);
+	return 0;
+}
+
+static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
+		unsigned int fmt)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	u16 iface = 0;
+
+	/* set master/slave audio interface */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		iface |= 0x0040;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* interface format */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		iface |= 0x0002;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		iface |= 0x0001;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		iface |= 0x0003;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		iface |= 0x0013;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* clock inversion */
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		iface |= 0x0090;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		iface |= 0x0080;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		iface |= 0x0010;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set iface */
+	wm8960_write(codec, WM8960_IFACE1, iface);
+	return 0;
+}
+
+static int wm8960_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_device *socdev = rtd->socdev;
+	struct snd_soc_codec *codec = socdev->card->codec;
+	u16 iface = wm8960_read(codec, WM8960_IFACE1) & 0xfff3;
+
+	/* bit size */
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		iface |= 0x0004;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		iface |= 0x0008;
+		break;
+	}
+
+	/* set iface */
+	wm8960_write(codec, WM8960_IFACE1, iface);
+	return 0;
+}
+
+static int wm8960_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	u16 mute_reg = wm8960_read(codec, WM8960_DACCTL1) & 0xfff7;
+
+	if (mute)
+		wm8960_write(codec, WM8960_DACCTL1, mute_reg | 0x8);
+	else
+		wm8960_write(codec, WM8960_DACCTL1, mute_reg);
+	return 0;
+}
+
+static int wm8960_set_bias_level(struct snd_soc_codec *codec,
+				 enum snd_soc_bias_level level)
+{
+	struct wm8960_data *pdata = codec->dev->platform_data;
+	u16 reg;
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		break;
+
+	case SND_SOC_BIAS_PREPARE:
+		/* Set VMID to 2x50k */
+		reg = wm8960_read(codec, WM8960_POWER1);
+		reg &= ~0x180;
+		reg |= 0x80;
+		wm8960_write(codec, WM8960_POWER1, reg);
+		break;
+
+	case SND_SOC_BIAS_STANDBY:
+		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+			/* Enable anti-pop features */
+			wm8960_write(codec, WM8960_APOP1,
+				     WM8960_POBCTRL | WM8960_SOFT_ST |
+				     WM8960_BUFDCOPEN | WM8960_BUFIOEN);
+
+			/* Discharge HP output */
+			reg = WM8960_DISOP;
+			if (pdata)
+				reg |= pdata->dres << 4;
+			wm8960_write(codec, WM8960_APOP2, reg);
+
+			msleep(400);
+
+			wm8960_write(codec, WM8960_APOP2, 0);
+
+			/* Enable & ramp VMID at 2x50k */
+			reg = wm8960_read(codec, WM8960_POWER1);
+			reg |= 0x80;
+			wm8960_write(codec, WM8960_POWER1, reg);
+			msleep(100);
+
+			/* Enable VREF */
+			wm8960_write(codec, WM8960_POWER1, reg | WM8960_VREF);
+
+			/* Disable anti-pop features */
+			wm8960_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
+		}
+
+		/* Set VMID to 2x250k */
+		reg = wm8960_read(codec, WM8960_POWER1);
+		reg &= ~0x180;
+		reg |= 0x100;
+		wm8960_write(codec, WM8960_POWER1, reg);
+		break;
+
+	case SND_SOC_BIAS_OFF:
+		/* Enable anti-pop features */
+		wm8960_write(codec, WM8960_APOP1,
+			     WM8960_POBCTRL | WM8960_SOFT_ST |
+			     WM8960_BUFDCOPEN | WM8960_BUFIOEN);
+
+		/* Disable VMID and VREF, let them discharge */
+		wm8960_write(codec, WM8960_POWER1, 0);
+		msleep(600);
+
+		wm8960_write(codec, WM8960_APOP1, 0);
+		break;
+	}
+
+	codec->bias_level = level;
+
+	return 0;
+}
+
+/* PLL divisors */
+struct _pll_div {
+	u32 pre_div:1;
+	u32 n:4;
+	u32 k:24;
+};
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 24) * 10)
+
+static int pll_factors(unsigned int source, unsigned int target,
+		       struct _pll_div *pll_div)
+{
+	unsigned long long Kpart;
+	unsigned int K, Ndiv, Nmod;
+
+	pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target);
+
+	/* Scale up target to PLL operating frequency */
+	target *= 4;
+
+	Ndiv = target / source;
+	if (Ndiv < 6) {
+		source >>= 1;
+		pll_div->pre_div = 1;
+		Ndiv = target / source;
+	} else
+		pll_div->pre_div = 0;
+
+	if ((Ndiv < 6) || (Ndiv > 12)) {
+		pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv);
+		return -EINVAL;
+	}
+
+	pll_div->n = Ndiv;
+	Nmod = target % source;
+	Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+	do_div(Kpart, source);
+
+	K = Kpart & 0xFFFFFFFF;
+
+	/* Check if we need to round */
+	if ((K % 10) >= 5)
+		K += 5;
+
+	/* Move down to proper range now rounding is done */
+	K /= 10;
+
+	pll_div->k = K;
+
+	pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n",
+		 pll_div->n, pll_div->k, pll_div->pre_div);
+
+	return 0;
+}
+
+static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai,
+		int pll_id, unsigned int freq_in, unsigned int freq_out)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	u16 reg;
+	static struct _pll_div pll_div;
+	int ret;
+
+	if (freq_in && freq_out) {
+		ret = pll_factors(freq_in, freq_out, &pll_div);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* Disable the PLL: even if we are changing the frequency the
+	 * PLL needs to be disabled while we do so. */
+	wm8960_write(codec, WM8960_CLOCK1,
+		     wm8960_read(codec, WM8960_CLOCK1) & ~1);
+	wm8960_write(codec, WM8960_POWER2,
+		     wm8960_read(codec, WM8960_POWER2) & ~1);
+
+	if (!freq_in || !freq_out)
+		return 0;
+
+	reg = wm8960_read(codec, WM8960_PLL1) & ~0x3f;
+	reg |= pll_div.pre_div << 4;
+	reg |= pll_div.n;
+
+	if (pll_div.k) {
+		reg |= 0x20;
+
+		wm8960_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
+		wm8960_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
+		wm8960_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
+	}
+	wm8960_write(codec, WM8960_PLL1, reg);
+
+	/* Turn it on */
+	wm8960_write(codec, WM8960_POWER2,
+		     wm8960_read(codec, WM8960_POWER2) | 1);
+	msleep(250);
+	wm8960_write(codec, WM8960_CLOCK1,
+		     wm8960_read(codec, WM8960_CLOCK1) | 1);
+
+	return 0;
+}
+
+static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
+		int div_id, int div)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	u16 reg;
+
+	switch (div_id) {
+	case WM8960_SYSCLKSEL:
+		reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1fe;
+		wm8960_write(codec, WM8960_CLOCK1, reg | div);
+		break;
+	case WM8960_SYSCLKDIV:
+		reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1f9;
+		wm8960_write(codec, WM8960_CLOCK1, reg | div);
+		break;
+	case WM8960_DACDIV:
+		reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1c7;
+		wm8960_write(codec, WM8960_CLOCK1, reg | div);
+		break;
+	case WM8960_OPCLKDIV:
+		reg = wm8960_read(codec, WM8960_PLL1) & 0x03f;
+		wm8960_write(codec, WM8960_PLL1, reg | div);
+		break;
+	case WM8960_DCLKDIV:
+		reg = wm8960_read(codec, WM8960_CLOCK2) & 0x03f;
+		wm8960_write(codec, WM8960_CLOCK2, reg | div);
+		break;
+	case WM8960_TOCLKSEL:
+		reg = wm8960_read(codec, WM8960_ADDCTL1) & 0x1fd;
+		wm8960_write(codec, WM8960_ADDCTL1, reg | div);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
+
+#define WM8960_FORMATS \
+	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+	SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops wm8960_dai_ops = {
+	.hw_params = wm8960_hw_params,
+	.digital_mute = wm8960_mute,
+	.set_fmt = wm8960_set_dai_fmt,
+	.set_clkdiv = wm8960_set_dai_clkdiv,
+	.set_pll = wm8960_set_dai_pll,
+};
+
+struct snd_soc_dai wm8960_dai = {
+	.name = "WM8960",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = WM8960_RATES,
+		.formats = WM8960_FORMATS,},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = WM8960_RATES,
+		.formats = WM8960_FORMATS,},
+	.ops = &wm8960_dai_ops,
+	.symmetric_rates = 1,
+};
+EXPORT_SYMBOL_GPL(wm8960_dai);
+
+static int wm8960_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec = socdev->card->codec;
+
+	wm8960_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	return 0;
+}
+
+static int wm8960_resume(struct platform_device *pdev)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec = socdev->card->codec;
+	int i;
+	u8 data[2];
+	u16 *cache = codec->reg_cache;
+
+	/* Sync reg_cache with the hardware */
+	for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
+		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
+		data[1] = cache[i] & 0x00ff;
+		codec->hw_write(codec->control_data, data, 2);
+	}
+
+	wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	wm8960_set_bias_level(codec, codec->suspend_bias_level);
+	return 0;
+}
+
+static struct snd_soc_codec *wm8960_codec;
+
+static int wm8960_probe(struct platform_device *pdev)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec;
+	int ret = 0;
+
+	if (wm8960_codec == NULL) {
+		dev_err(&pdev->dev, "Codec device not registered\n");
+		return -ENODEV;
+	}
+
+	socdev->card->codec = wm8960_codec;
+	codec = wm8960_codec;
+
+	/* register pcms */
+	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+	if (ret < 0) {
+		dev_err(codec->dev, "failed to create pcms: %d\n", ret);
+		goto pcm_err;
+	}
+
+	snd_soc_add_controls(codec, wm8960_snd_controls,
+			     ARRAY_SIZE(wm8960_snd_controls));
+	wm8960_add_widgets(codec);
+	ret = snd_soc_init_card(socdev);
+	if (ret < 0) {
+		dev_err(codec->dev, "failed to register card: %d\n", ret);
+		goto card_err;
+	}
+
+	return ret;
+
+card_err:
+	snd_soc_free_pcms(socdev);
+	snd_soc_dapm_free(socdev);
+pcm_err:
+	return ret;
+}
+
+/* power down chip */
+static int wm8960_remove(struct platform_device *pdev)
+{
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+	snd_soc_free_pcms(socdev);
+	snd_soc_dapm_free(socdev);
+
+	return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8960 = {
+	.probe = 	wm8960_probe,
+	.remove = 	wm8960_remove,
+	.suspend = 	wm8960_suspend,
+	.resume =	wm8960_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
+
+static int wm8960_register(struct wm8960_priv *wm8960)
+{
+	struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
+	struct snd_soc_codec *codec = &wm8960->codec;
+	int ret;
+	u16 reg;
+
+	if (wm8960_codec) {
+		dev_err(codec->dev, "Another WM8960 is registered\n");
+		return -EINVAL;
+	}
+
+	if (!pdata) {
+		dev_warn(codec->dev, "No platform data supplied\n");
+	} else {
+		if (pdata->dres > WM8960_DRES_MAX) {
+			dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
+			pdata->dres = 0;
+		}
+	}
+
+	mutex_init(&codec->mutex);
+	INIT_LIST_HEAD(&codec->dapm_widgets);
+	INIT_LIST_HEAD(&codec->dapm_paths);
+
+	codec->private_data = wm8960;
+	codec->name = "WM8960";
+	codec->owner = THIS_MODULE;
+	codec->read = wm8960_read_reg_cache;
+	codec->write = wm8960_write;
+	codec->bias_level = SND_SOC_BIAS_OFF;
+	codec->set_bias_level = wm8960_set_bias_level;
+	codec->dai = &wm8960_dai;
+	codec->num_dai = 1;
+	codec->reg_cache_size = WM8960_CACHEREGNUM;
+	codec->reg_cache = &wm8960->reg_cache;
+
+	memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
+
+	ret = wm8960_reset(codec);
+	if (ret < 0) {
+		dev_err(codec->dev, "Failed to issue reset\n");
+		return ret;
+	}
+
+	wm8960_dai.dev = codec->dev;
+
+	wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+	/* Latch the update bits */
+	reg = wm8960_read(codec, WM8960_LINVOL);
+	wm8960_write(codec, WM8960_LINVOL, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_RINVOL);
+	wm8960_write(codec, WM8960_RINVOL, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_LADC);
+	wm8960_write(codec, WM8960_LADC, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_RADC);
+	wm8960_write(codec, WM8960_RADC, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_LDAC);
+	wm8960_write(codec, WM8960_LDAC, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_RDAC);
+	wm8960_write(codec, WM8960_RDAC, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_LOUT1);
+	wm8960_write(codec, WM8960_LOUT1, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_ROUT1);
+	wm8960_write(codec, WM8960_ROUT1, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_LOUT2);
+	wm8960_write(codec, WM8960_LOUT2, reg | 0x100);
+	reg = wm8960_read(codec, WM8960_ROUT2);
+	wm8960_write(codec, WM8960_ROUT2, reg | 0x100);
+
+	wm8960_codec = codec;
+
+	ret = snd_soc_register_codec(codec);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_register_dai(&wm8960_dai);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
+		snd_soc_unregister_codec(codec);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void wm8960_unregister(struct wm8960_priv *wm8960)
+{
+	wm8960_set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF);
+	snd_soc_unregister_dai(&wm8960_dai);
+	snd_soc_unregister_codec(&wm8960->codec);
+	kfree(wm8960);
+	wm8960_codec = NULL;
+}
+
+static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
+				      const struct i2c_device_id *id)
+{
+	struct wm8960_priv *wm8960;
+	struct snd_soc_codec *codec;
+
+	wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
+	if (wm8960 == NULL)
+		return -ENOMEM;
+
+	codec = &wm8960->codec;
+	codec->hw_write = (hw_write_t)i2c_master_send;
+
+	i2c_set_clientdata(i2c, wm8960);
+	codec->control_data = i2c;
+
+	codec->dev = &i2c->dev;
+
+	return wm8960_register(wm8960);
+}
+
+static __devexit int wm8960_i2c_remove(struct i2c_client *client)
+{
+	struct wm8960_priv *wm8960 = i2c_get_clientdata(client);
+	wm8960_unregister(wm8960);
+	return 0;
+}
+
+static const struct i2c_device_id wm8960_i2c_id[] = {
+	{ "wm8960", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
+
+static struct i2c_driver wm8960_i2c_driver = {
+	.driver = {
+		.name = "WM8960 I2C Codec",
+		.owner = THIS_MODULE,
+	},
+	.probe =    wm8960_i2c_probe,
+	.remove =   __devexit_p(wm8960_i2c_remove),
+	.id_table = wm8960_i2c_id,
+};
+
+static int __init wm8960_modinit(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&wm8960_i2c_driver);
+	if (ret != 0) {
+		printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
+		       ret);
+	}
+
+	return ret;
+}
+module_init(wm8960_modinit);
+
+static void __exit wm8960_exit(void)
+{
+	i2c_del_driver(&wm8960_i2c_driver);
+}
+module_exit(wm8960_exit);
+
+
+MODULE_DESCRIPTION("ASoC WM8960 driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
new file mode 100644
index 0000000..c9af56c
--- /dev/null
+++ b/sound/soc/codecs/wm8960.h
@@ -0,0 +1,127 @@
+/*
+ * wm8960.h  --  WM8960 Soc Audio driver
+ *
+ * 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 _WM8960_H
+#define _WM8960_H
+
+/* WM8960 register space */
+
+
+#define WM8960_CACHEREGNUM 	56
+
+#define WM8960_LINVOL		0x0
+#define WM8960_RINVOL		0x1
+#define WM8960_LOUT1		0x2
+#define WM8960_ROUT1		0x3
+#define WM8960_CLOCK1		0x4
+#define WM8960_DACCTL1		0x5
+#define WM8960_DACCTL2		0x6
+#define WM8960_IFACE1		0x7
+#define WM8960_CLOCK2		0x8
+#define WM8960_IFACE2		0x9
+#define WM8960_LDAC		0xa
+#define WM8960_RDAC		0xb
+
+#define WM8960_RESET		0xf
+#define WM8960_3D		0x10
+#define WM8960_ALC1		0x11
+#define WM8960_ALC2		0x12
+#define WM8960_ALC3		0x13
+#define WM8960_NOISEG		0x14
+#define WM8960_LADC		0x15
+#define WM8960_RADC		0x16
+#define WM8960_ADDCTL1		0x17
+#define WM8960_ADDCTL2		0x18
+#define WM8960_POWER1		0x19
+#define WM8960_POWER2		0x1a
+#define WM8960_ADDCTL3		0x1b
+#define WM8960_APOP1		0x1c
+#define WM8960_APOP2		0x1d
+
+#define WM8960_LINPATH		0x20
+#define WM8960_RINPATH		0x21
+#define WM8960_LOUTMIX		0x22
+
+#define WM8960_ROUTMIX		0x25
+#define WM8960_MONOMIX1		0x26
+#define WM8960_MONOMIX2		0x27
+#define WM8960_LOUT2		0x28
+#define WM8960_ROUT2		0x29
+#define WM8960_MONO		0x2a
+#define WM8960_INBMIX1		0x2b
+#define WM8960_INBMIX2		0x2c
+#define WM8960_BYPASS1		0x2d
+#define WM8960_BYPASS2		0x2e
+#define WM8960_POWER3		0x2f
+#define WM8960_ADDCTL4		0x30
+#define WM8960_CLASSD1		0x31
+
+#define WM8960_CLASSD3		0x33
+#define WM8960_PLL1		0x34
+#define WM8960_PLL2		0x35
+#define WM8960_PLL3		0x36
+#define WM8960_PLL4		0x37
+
+
+/*
+ * WM8960 Clock dividers
+ */
+#define WM8960_SYSCLKDIV 		0
+#define WM8960_DACDIV			1
+#define WM8960_OPCLKDIV			2
+#define WM8960_DCLKDIV			3
+#define WM8960_TOCLKSEL			4
+#define WM8960_SYSCLKSEL		5
+
+#define WM8960_SYSCLK_DIV_1		(0 << 1)
+#define WM8960_SYSCLK_DIV_2		(2 << 1)
+
+#define WM8960_SYSCLK_MCLK		(0 << 0)
+#define WM8960_SYSCLK_PLL		(1 << 0)
+
+#define WM8960_DAC_DIV_1		(0 << 3)
+#define WM8960_DAC_DIV_1_5		(1 << 3)
+#define WM8960_DAC_DIV_2		(2 << 3)
+#define WM8960_DAC_DIV_3		(3 << 3)
+#define WM8960_DAC_DIV_4		(4 << 3)
+#define WM8960_DAC_DIV_5_5		(5 << 3)
+#define WM8960_DAC_DIV_6		(6 << 3)
+
+#define WM8960_DCLK_DIV_1_5		(0 << 6)
+#define WM8960_DCLK_DIV_2		(1 << 6)
+#define WM8960_DCLK_DIV_3		(2 << 6)
+#define WM8960_DCLK_DIV_4		(3 << 6)
+#define WM8960_DCLK_DIV_6		(4 << 6)
+#define WM8960_DCLK_DIV_8		(5 << 6)
+#define WM8960_DCLK_DIV_12		(6 << 6)
+#define WM8960_DCLK_DIV_16		(7 << 6)
+
+#define WM8960_TOCLK_F19		(0 << 1)
+#define WM8960_TOCLK_F21		(1 << 1)
+
+#define WM8960_OPCLK_DIV_1		(0 << 0)
+#define WM8960_OPCLK_DIV_2		(1 << 0)
+#define WM8960_OPCLK_DIV_3		(2 << 0)
+#define WM8960_OPCLK_DIV_4		(3 << 0)
+#define WM8960_OPCLK_DIV_5_5		(4 << 0)
+#define WM8960_OPCLK_DIV_6		(5 << 0)
+
+extern struct snd_soc_dai wm8960_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8960;
+
+#define WM8960_DRES_400R 0
+#define WM8960_DRES_200R 1
+#define WM8960_DRES_600R 2
+#define WM8960_DRES_150R 3
+#define WM8960_DRES_MAX  3
+
+struct wm8960_data {
+	int dres;
+};
+
+#endif
-- 
1.6.2.2

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [PATCH] mx31ads: Depend on all the WM8350 core dependencies for WM1133-EV1 board
  2009-04-14 12:33 ` [PATCH] mx31ads: Depend on all the WM8350 core dependencies for WM1133-EV1 board Mark Brown
@ 2009-04-14 12:34   ` Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-14 12:34 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

On Tue, Apr 14, 2009 at 01:33:00PM +0100, Mark Brown wrote:
> Otherwise we'd need massive ifdefs in the code.

Sorry, forgot to delete this before sending - it's not in the branch I
requested that you pull.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 05/14] ASoC: Provide core support for symmetric sample rates
  2009-04-14 12:33 ` [PATCH 05/14] ASoC: Provide core support for symmetric sample rates Mark Brown
@ 2009-04-15  6:31   ` Peter Ujfalusi
  2009-04-15  8:29     ` Mark Brown
  0 siblings, 1 reply; 56+ messages in thread
From: Peter Ujfalusi @ 2009-04-15  6:31 UTC (permalink / raw)
  To: alsa-devel; +Cc: Takashi Iwai, ext Mark Brown

On Tuesday 14 April 2009 15:33:04 ext Mark Brown wrote:
> Many devices require symmetric configurations of capture and playback
> data formats, often due to shared clocking but sometimes also due to
> other shared playback and record configuration in the device. Start
> providing core support for this by allowing the DAIs or the machine
> to specify that the sample rates used should be kept symmetric.
>
> A flag symmetric_rates is provided in the snd_soc_dai and
> snd_soc_dai_link structures. If this is set in either of the DAIs or in
> the machine then a constraint will be applied when a stream is already
> open preventing any changes in sample rate.
>
> +
> +		ret = snd_pcm_hw_constraint_minmax(substream->runtime,
> +						   SNDRV_PCM_HW_PARAM_RATE,
> +						   machine->rate,
> +						   machine->rate);

Would it make sense to add also the channel count and probably sample_bits as 
constraint as well here?
I think the symmetric means that you should not be able to change any of the 
parameters.

-- 
Péter

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [PATCH 05/14] ASoC: Provide core support for symmetric sample rates
  2009-04-15  6:31   ` Peter Ujfalusi
@ 2009-04-15  8:29     ` Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-15  8:29 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: Takashi Iwai, alsa-devel

On Wed, Apr 15, 2009 at 09:31:46AM +0300, Peter Ujfalusi wrote:
> On Tuesday 14 April 2009 15:33:04 ext Mark Brown wrote:

> > Many devices require symmetric configurations of capture and playback
> > data formats, often due to shared clocking but sometimes also due to

> Would it make sense to add also the channel count and probably sample_bits as 
> constraint as well here?
> I think the symmetric means that you should not be able to change any of the 
> parameters.

Yes, we should have something for those but they are a bit more complex:
normally with bit clock the restriction is actually that you need to
have at least as many clocks as the format needs but can have more.
This means that rather than an absolute symmetry requirement you end up
setting a reduced maximum for both directions.

The two limits play into each other with DSP mode too: you can have
twice as many channels in the same number of bit clocks if you halve the
sameple size.  For I2S style modes the channel count doesn't tend to be
restricted since you always have the clocks for two channels even if
you're only looking at one.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-04-16 13:50 Mark Brown
  2009-04-16 14:06 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-04-16 13:50 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 6967963d6d5cac40a091d075326f0e3ccb95c58a:
  Mark Brown (1):
        Merge branch 'for-2.6.30' into for-2.6.31

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

Ben Dooks (4):
      ASoC: Fix jive_wm8750.c build problems
      ASoC: s3c-i2s-v2.c fix for s3c_i2sv2_iis_calc_rate
      ASoC: Fix s3c-i2s-v2.c snd_soc_dai changes
      ASoC: Fix include build error in s3c2412-i2s.c

Daniel Mack (1):
      ASoC: pxa-ssp: allow setting of dai format 0

Jarkko Nikula (2):
      ASoC: OMAP: Fix DSP_B format in OMAP McBSP DAI driver
      ASoC: OMAP: Fix FS polarity in OSK5912 machine driver

Mark Brown (4):
      ASoC: Check we have DAI ops when calling via accessor functions
      ASoC: Volume controls are never of boolean type
      ASoC: Request shared rates for WM8903
      Merge branch 'for-2.6.30' into for-2.6.31

Peter Ujfalusi (2):
      ASoC: OMAP: Use single-phase for DSP mode
      ASoC: OMAP: Add DSP_A mode support for mcbsp

 sound/soc/codecs/wm8903.c       |    1 +
 sound/soc/omap/omap-mcbsp.c     |   45 ++++++++++++++++++++++++++------------
 sound/soc/omap/osk5912.c        |    4 +-
 sound/soc/pxa/pxa-ssp.c         |    1 +
 sound/soc/s3c24xx/jive_wm8750.c |   12 +++++-----
 sound/soc/s3c24xx/s3c-i2s-v2.c  |   18 ++++++++-------
 sound/soc/s3c24xx/s3c2412-i2s.c |    2 +-
 sound/soc/soc-core.c            |   20 ++++++++--------
 8 files changed, 62 insertions(+), 41 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-04-16 13:50 ASoC updates for 2.6.31 Mark Brown
@ 2009-04-16 14:06 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-04-16 14:06 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Thu, 16 Apr 2009 14:50:27 +0100,
Mark Brown wrote:
> 
> The following changes since commit 6967963d6d5cac40a091d075326f0e3ccb95c58a:
>   Mark Brown (1):
>         Merge branch 'for-2.6.30' into for-2.6.31
> 
> 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 to topic/asoc branch now.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-04-20 11:58 Mark Brown
  2009-04-20 12:05 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-04-20 11:58 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 8d98f2246d7c622198ae0b8ca66f1c82b8a25377:
  Mark Brown (1):
        Merge branch 'for-2.6.30' into for-2.6.31

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

Jarkko Nikula (1):
      ASoC: OMAP: Update contact addresses

Joonyoung Shim (1):
      ASoC: TWL4030: Add support Voice DAI

Mark Brown (1):
      Merge branch 'for-2.6.30' into for-2.6.31

Peter Ujfalusi (1):
      ASoC: TWL4030: Fix for the constraint handling

Philipp Zabel (1):
      ASoC: pxa-ssp: Don't use SSCR0_SerClkDiv and SSCR0_SCR

 sound/soc/codecs/twl4030.c    |  258 +++++++++++++++++++++++++++++++++++++----
 sound/soc/codecs/twl4030.h    |   18 +++-
 sound/soc/omap/n810.c         |    4 +-
 sound/soc/omap/omap-mcbsp.c   |    5 +-
 sound/soc/omap/omap-mcbsp.h   |    3 +-
 sound/soc/omap/omap-pcm.c     |    5 +-
 sound/soc/omap/omap-pcm.h     |    3 +-
 sound/soc/omap/omap2evm.c     |    2 +-
 sound/soc/omap/omap3beagle.c  |    2 +-
 sound/soc/omap/omap3pandora.c |    4 +-
 sound/soc/omap/overo.c        |    2 +-
 sound/soc/omap/sdp3430.c      |    2 +-
 sound/soc/pxa/pxa-ssp.c       |   36 +++++--
 13 files changed, 297 insertions(+), 47 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-04-20 11:58 Mark Brown
@ 2009-04-20 12:05 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-04-20 12:05 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Mon, 20 Apr 2009 12:58:08 +0100,
Mark Brown wrote:
> 
> The following changes since commit 8d98f2246d7c622198ae0b8ca66f1c82b8a25377:
>   Mark Brown (1):
>         Merge branch 'for-2.6.30' into for-2.6.31
> 
> 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 now.  Thanks.

Takashi

> Jarkko Nikula (1):
>       ASoC: OMAP: Update contact addresses
> 
> Joonyoung Shim (1):
>       ASoC: TWL4030: Add support Voice DAI
> 
> Mark Brown (1):
>       Merge branch 'for-2.6.30' into for-2.6.31
> 
> Peter Ujfalusi (1):
>       ASoC: TWL4030: Fix for the constraint handling
> 
> Philipp Zabel (1):
>       ASoC: pxa-ssp: Don't use SSCR0_SerClkDiv and SSCR0_SCR
> 
>  sound/soc/codecs/twl4030.c    |  258 +++++++++++++++++++++++++++++++++++++----
>  sound/soc/codecs/twl4030.h    |   18 +++-
>  sound/soc/omap/n810.c         |    4 +-
>  sound/soc/omap/omap-mcbsp.c   |    5 +-
>  sound/soc/omap/omap-mcbsp.h   |    3 +-
>  sound/soc/omap/omap-pcm.c     |    5 +-
>  sound/soc/omap/omap-pcm.h     |    3 +-
>  sound/soc/omap/omap2evm.c     |    2 +-
>  sound/soc/omap/omap3beagle.c  |    2 +-
>  sound/soc/omap/omap3pandora.c |    4 +-
>  sound/soc/omap/overo.c        |    2 +-
>  sound/soc/omap/sdp3430.c      |    2 +-
>  sound/soc/pxa/pxa-ssp.c       |   36 +++++--
>  13 files changed, 297 insertions(+), 47 deletions(-)
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-04-23 19:54 Mark Brown
  2009-04-24  6:10 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-04-23 19:54 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 9b5b0c01598f9782690b09ce6c49f4ba116dde44:
  Mark Brown (1):
        Merge branch 'for-2.6.30' into for-2.6.31

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

Eric Miao (2):
      ASoC: simplify the SSP DMA parameters settings by run-time generation
      ASoC: change stereo/mono to 32-bit/16-bit for pxa-ssp

Joonyoung Shim (2):
      ASoC: OMAP: Add checking to detect bufferless pcms
      ASoC: TWL4030: Add VDL path support

Mark Brown (16):
      ASoC: Factor out generic widget power checks
      ASoC: Factor out DAPM power checks for DACs and ADCs
      ASoC: Make the DAPM power check an operation on the widget
      ASoC: Fix offset of freqmode in WM8580 PLL configuration
      ASoC: Fix WM8580 volume update handling for large register changes
      ASoC: Add power supply widget to DAPM
      ASoC: Use DAPM supply widget for WM8903 charge pump
      ASoC: Support CLK_DSP in WM8903
      ASoC: Optimise configuration of WM8903 DC servo
      ASoC: Actively manage the DC servo for WM8903
      ASoC: Remove redundant rate constraint for WM8903
      ASoC: Implement WM8903 digital sidetone support
      Merge commit 'takashi/fix/asoc' into for-2.6.30
      Merge branch 'for-2.6.30' into for-2.6.31
      ASoC: s3c-i2s-v2 needs to declare a license for modular builds
      Merge branch 'for-2.6.30' into for-2.6.31

Peter Ujfalusi (2):
      ASoC: OMAP: Add 4 channel support to mcbsp
      ASoC: TWL4030: Add 4 channel TDM support

Russell King - ARM Linux (1):
      ASoC: Fix warning in wm9705

Takashi Iwai (1):
      ASoC: remove non-existing referece to CONFIG_SND_SOC_CODEC_WM8991

 Documentation/sound/alsa/soc/dapm.txt |    1 +
 include/sound/soc-dapm.h              |    9 +-
 sound/soc/codecs/Makefile             |    1 -
 sound/soc/codecs/twl4030.c            |  308 +++++++++++++++++++--------------
 sound/soc/codecs/twl4030.h            |   11 ++
 sound/soc/codecs/wm8580.c             |   16 +-
 sound/soc/codecs/wm8903.c             |  118 ++++++++-----
 sound/soc/codecs/wm9705.c             |    2 +-
 sound/soc/omap/omap-mcbsp.c           |    5 +-
 sound/soc/omap/omap-pcm.c             |    9 +-
 sound/soc/pxa/pxa-ssp.c               |  203 +++++-----------------
 sound/soc/s3c24xx/s3c-i2s-v2.c        |    3 +-
 sound/soc/soc-dapm.c                  |  139 +++++++++++-----
 13 files changed, 438 insertions(+), 387 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-04-23 19:54 Mark Brown
@ 2009-04-24  6:10 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-04-24  6:10 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Thu, 23 Apr 2009 20:54:20 +0100,
Mark Brown wrote:
> 
> The following changes since commit 9b5b0c01598f9782690b09ce6c49f4ba116dde44:
>   Mark Brown (1):
>         Merge branch 'for-2.6.30' into for-2.6.31
> 
> 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 now to topic/asoc branch.  Thanks.

Takashi

> 
> Eric Miao (2):
>       ASoC: simplify the SSP DMA parameters settings by run-time generation
>       ASoC: change stereo/mono to 32-bit/16-bit for pxa-ssp
> 
> Joonyoung Shim (2):
>       ASoC: OMAP: Add checking to detect bufferless pcms
>       ASoC: TWL4030: Add VDL path support
> 
> Mark Brown (16):
>       ASoC: Factor out generic widget power checks
>       ASoC: Factor out DAPM power checks for DACs and ADCs
>       ASoC: Make the DAPM power check an operation on the widget
>       ASoC: Fix offset of freqmode in WM8580 PLL configuration
>       ASoC: Fix WM8580 volume update handling for large register changes
>       ASoC: Add power supply widget to DAPM
>       ASoC: Use DAPM supply widget for WM8903 charge pump
>       ASoC: Support CLK_DSP in WM8903
>       ASoC: Optimise configuration of WM8903 DC servo
>       ASoC: Actively manage the DC servo for WM8903
>       ASoC: Remove redundant rate constraint for WM8903
>       ASoC: Implement WM8903 digital sidetone support
>       Merge commit 'takashi/fix/asoc' into for-2.6.30
>       Merge branch 'for-2.6.30' into for-2.6.31
>       ASoC: s3c-i2s-v2 needs to declare a license for modular builds
>       Merge branch 'for-2.6.30' into for-2.6.31
> 
> Peter Ujfalusi (2):
>       ASoC: OMAP: Add 4 channel support to mcbsp
>       ASoC: TWL4030: Add 4 channel TDM support
> 
> Russell King - ARM Linux (1):
>       ASoC: Fix warning in wm9705
> 
> Takashi Iwai (1):
>       ASoC: remove non-existing referece to CONFIG_SND_SOC_CODEC_WM8991
> 
>  Documentation/sound/alsa/soc/dapm.txt |    1 +
>  include/sound/soc-dapm.h              |    9 +-
>  sound/soc/codecs/Makefile             |    1 -
>  sound/soc/codecs/twl4030.c            |  308 +++++++++++++++++++--------------
>  sound/soc/codecs/twl4030.h            |   11 ++
>  sound/soc/codecs/wm8580.c             |   16 +-
>  sound/soc/codecs/wm8903.c             |  118 ++++++++-----
>  sound/soc/codecs/wm9705.c             |    2 +-
>  sound/soc/omap/omap-mcbsp.c           |    5 +-
>  sound/soc/omap/omap-pcm.c             |    9 +-
>  sound/soc/pxa/pxa-ssp.c               |  203 +++++-----------------
>  sound/soc/s3c24xx/s3c-i2s-v2.c        |    3 +-
>  sound/soc/soc-dapm.c                  |  139 +++++++++++-----
>  13 files changed, 438 insertions(+), 387 deletions(-)
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-04-28 15:22 Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-04-28 15:22 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 8a1f936acdfd53cb0a981f3f80483863dcd84fa9:
  Peter Ujfalusi (1):
        ASoC: TWL4030: Add 4 channel TDM support

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

Daniel Mack (3):
      ASoC: add SOC_DOUBLE_EXT macro
      ASoC: cs4270: fix Master Capture Switch polarity
      ASoC: cs4270: add Master Playback Switch

Jon Smirl (3):
      ASoC: Set the MPC5200 i2s driver to BROKEN status.
      ASoC: Basic split of mpc5200 DMA code out from mpc5200_psc_i2s
      ASoC: Rename the PSC functions to DMA

Jonathan Cameron (1):
      ASoC WM8940 Driver

Joonyoung Shim (1):
      ASoC: TWL4030: Fix gain control for earpiece amplifier

Mark Brown (10):
      ASoC: Fix S3C64xx IIS device registration and support both ports
      ASoC: S3C2412: Failing to get the I2S clock is an error
      ASoC: Enforce symmetric rates for S3C64xx I2S interface
      ASoC: Include WM8350 register definitions in CODEC header
      ASoC: s3c-i2s-v2 diagnostic improvements
      ASoC: Use our registration function for S3C64xx
      ASoC: Fix logic in WM8350 master clocking check
      Merge branch 'for-2.6.30' into for-2.6.31
      ASoC: Staticise TLV values in WM8940
      Merge branch 'for-2.6.30' into for-2.6.31

Peter Ujfalusi (1):
      ASoC: Beagle: Add support for 4 channel

 include/sound/soc.h             |    8 +
 sound/soc/codecs/Kconfig        |    4 +
 sound/soc/codecs/Makefile       |    2 +
 sound/soc/codecs/cs4270.c       |   44 ++-
 sound/soc/codecs/twl4030.c      |    8 +-
 sound/soc/codecs/wm8350.c       |    2 +-
 sound/soc/codecs/wm8350.h       |    1 +
 sound/soc/codecs/wm8940.c       |  955 +++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm8940.h       |  104 +++++
 sound/soc/fsl/Kconfig           |    6 +-
 sound/soc/fsl/Makefile          |    2 +
 sound/soc/fsl/mpc5200_dma.c     |  457 +++++++++++++++++++
 sound/soc/fsl/mpc5200_dma.h     |   81 ++++
 sound/soc/fsl/mpc5200_psc_i2s.c |  644 ++++-----------------------
 sound/soc/omap/omap3beagle.c    |   26 +-
 sound/soc/s3c24xx/s3c2412-i2s.c |    2 +-
 sound/soc/s3c24xx/s3c64xx-i2s.c |  148 ++++--
 sound/soc/s3c24xx/s3c64xx-i2s.h |    2 +-
 18 files changed, 1867 insertions(+), 629 deletions(-)
 create mode 100644 sound/soc/codecs/wm8940.c
 create mode 100644 sound/soc/codecs/wm8940.h
 create mode 100644 sound/soc/fsl/mpc5200_dma.c
 create mode 100644 sound/soc/fsl/mpc5200_dma.h

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-05 10:01 Mark Brown
  2009-05-05 10:45 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-05 10:01 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

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

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-05 10:01 Mark Brown
@ 2009-05-05 10:45 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-05 10:45 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

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
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-08 12:57 Mark Brown
  2009-05-08 14:37 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-08 12:57 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit bbd993077d788589a86a718ba7a7895ba5e71a17:
  Mark Brown (1):
        ASoC: Remove redundant codec pointer from DAIs

are available in the git repository at:

  ssh://master.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.31

(git:// doesn't seem to be updating so...).

Daniel Mack (2):
      ASoC: cs4270: introduce CS4270_I2C_INCR
      ASoC: cs4270: add power management support

Mark Brown (2):
      ASoC: Add headers to match patterns in MAINTAINERS
      ASoC: Fix file patterns for PXA sound drivers

Peter Ujfalusi (1):
      ASoC: TWL4030: Fix typo in twl4030_codec_mute function

 MAINTAINERS                |    4 ++-
 sound/soc/codecs/cs4270.c  |   61 ++++++++++++++++++++++++++++++++++++++++++-
 sound/soc/codecs/twl4030.c |    2 +-
 3 files changed, 63 insertions(+), 4 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-08 12:57 Mark Brown
@ 2009-05-08 14:37 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-08 14:37 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Fri, 8 May 2009 13:57:11 +0100,
Mark Brown wrote:
> 
> The following changes since commit bbd993077d788589a86a718ba7a7895ba5e71a17:
>   Mark Brown (1):
>         ASoC: Remove redundant codec pointer from DAIs
> 
> are available in the git repository at:
> 
>   ssh://master.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.31
> 
> (git:// doesn't seem to be updating so...).

It appears now.  Thanks, pulled now.


Takashi

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-12 10:25 Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-05-12 10:25 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit bec4c99e8637b5b8bd4b0513eacb51da25885e3b:
  Mark Brown (1):
        ASoC: Fix file patterns for PXA sound drivers

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

Joonyoung Shim (1):
      ASoC: TWL4030: change DAPM for analog microphone selection

Mark Brown (3):
      ASoC: Fix up CODEC DAI formats for big endian CPUs
      ASoC: Enforce symmetric rates for PXA2xx I2S
      Merge branch 'for-2.6.30' into for-2.6.31

Mike Rapoport (3):
      ASoC: soc-core: fix crash when removing not instantiated card
      pxa2xx-ac97: fix reset gpio mode setting
      ASoC: em-x270: make the driver support also eXeda and CM-X300 machines

Roel Kluin (1):
      ASoC: remove driver_data direct access of struct device

Sergey Lapin (1):
      ASoC: AFEB9260 driver

 sound/arm/pxa2xx-ac97-lib.c        |    2 +-
 sound/soc/atmel/Kconfig            |    8 ++
 sound/soc/atmel/Makefile           |    1 +
 sound/soc/atmel/snd-soc-afeb9260.c |  203 ++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/twl4030.c         |   52 ++++------
 sound/soc/codecs/wm8400.c          |    4 +-
 sound/soc/codecs/wm8731.c          |    4 +-
 sound/soc/codecs/wm8753.c          |    4 +-
 sound/soc/pxa/Kconfig              |    4 +-
 sound/soc/pxa/em-x270.c            |    9 +-
 sound/soc/pxa/pxa2xx-i2s.c         |    1 +
 sound/soc/soc-core.c               |   43 ++++++++
 12 files changed, 289 insertions(+), 46 deletions(-)
 create mode 100644 sound/soc/atmel/snd-soc-afeb9260.c

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
  2009-05-15  8:23 ASoC updates for 2.6.30 Mark Brown
@ 2009-05-15  8:26 ` Mark Brown
  2009-05-15  8:34   ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-15  8:26 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit dd4a416442a2fb4bd761163277d37ab6ce75ee4e:
  Takashi Iwai (1):
        Merge branch 'for-2.6.31' of git://git.kernel.org/.../broonie/sound-2.6 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

Anuj Aggarwal (1):
      ASoC: Added OMAP3 EVM support in ASoC.

David Brownell (3):
      ASoC: davinci-pcm buildfixes
      ASoC: DaVinci I2S updates
      ASoC: DaVinci EVM board support buildfixes

Jon Smirl (1):
      ASoC: Add SNDRV_PCM_FMTBIT_S32_BE as a valid AC97 format

Karl Beldan (5):
      ASoC: pxa2xx-i2s: Proper initialization
      ASoC: pxa2xx-i2s: Proper hw initialization
      ASoC: pxa2xx-i2s: Handle SACR1_DRPL and SACR1_DREC separately
      ASoC: pxa2xx-i2s: Fix inappropriate release of i2s clock
      ASoC: pxa2xx-i2s: Fix suspend/resume

Marek Vasut (1):
      ASoC: Support AC97 link off by default on WM9712

Mark Brown (3):
      ASoC: Point at kernel.org git
      Merge branch 'pxa2xx-i2s' into for-2.6.31
      Merge branch 'for-2.6.30' into for-2.6.31

 MAINTAINERS                              |    2 +-
 arch/arm/mach-davinci/include/mach/asp.h |   25 +++++
 include/sound/soc-dai.h                  |    3 +-
 sound/soc/codecs/wm9712.c                |    2 +
 sound/soc/davinci/Kconfig                |    7 +-
 sound/soc/davinci/davinci-evm.c          |   63 +++++++++++--
 sound/soc/davinci/davinci-i2s.c          |   26 +++++-
 sound/soc/davinci/davinci-pcm.c          |   71 +++++++++------
 sound/soc/omap/Kconfig                   |    8 ++
 sound/soc/omap/Makefile                  |    2 +
 sound/soc/omap/omap3evm.c                |  147 ++++++++++++++++++++++++++++++
 sound/soc/pxa/pxa2xx-i2s.c               |   38 +++++---
 12 files changed, 330 insertions(+), 64 deletions(-)
 create mode 100644 arch/arm/mach-davinci/include/mach/asp.h
 create mode 100644 sound/soc/omap/omap3evm.c

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-15  8:26 ` ASoC updates for 2.6.31 Mark Brown
@ 2009-05-15  8:34   ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-15  8:34 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Fri, 15 May 2009 09:26:31 +0100,
Mark Brown wrote:
> 
> The following changes since commit dd4a416442a2fb4bd761163277d37ab6ce75ee4e:
>   Takashi Iwai (1):
>         Merge branch 'for-2.6.31' of git://git.kernel.org/.../broonie/sound-2.6 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 now.  Thanks.


Takashi


> Anuj Aggarwal (1):
>       ASoC: Added OMAP3 EVM support in ASoC.
> 
> David Brownell (3):
>       ASoC: davinci-pcm buildfixes
>       ASoC: DaVinci I2S updates
>       ASoC: DaVinci EVM board support buildfixes
> 
> Jon Smirl (1):
>       ASoC: Add SNDRV_PCM_FMTBIT_S32_BE as a valid AC97 format
> 
> Karl Beldan (5):
>       ASoC: pxa2xx-i2s: Proper initialization
>       ASoC: pxa2xx-i2s: Proper hw initialization
>       ASoC: pxa2xx-i2s: Handle SACR1_DRPL and SACR1_DREC separately
>       ASoC: pxa2xx-i2s: Fix inappropriate release of i2s clock
>       ASoC: pxa2xx-i2s: Fix suspend/resume
> 
> Marek Vasut (1):
>       ASoC: Support AC97 link off by default on WM9712
> 
> Mark Brown (3):
>       ASoC: Point at kernel.org git
>       Merge branch 'pxa2xx-i2s' into for-2.6.31
>       Merge branch 'for-2.6.30' into for-2.6.31
> 
>  MAINTAINERS                              |    2 +-
>  arch/arm/mach-davinci/include/mach/asp.h |   25 +++++
>  include/sound/soc-dai.h                  |    3 +-
>  sound/soc/codecs/wm9712.c                |    2 +
>  sound/soc/davinci/Kconfig                |    7 +-
>  sound/soc/davinci/davinci-evm.c          |   63 +++++++++++--
>  sound/soc/davinci/davinci-i2s.c          |   26 +++++-
>  sound/soc/davinci/davinci-pcm.c          |   71 +++++++++------
>  sound/soc/omap/Kconfig                   |    8 ++
>  sound/soc/omap/Makefile                  |    2 +
>  sound/soc/omap/omap3evm.c                |  147 ++++++++++++++++++++++++++++++
>  sound/soc/pxa/pxa2xx-i2s.c               |   38 +++++---
>  12 files changed, 330 insertions(+), 64 deletions(-)
>  create mode 100644 arch/arm/mach-davinci/include/mach/asp.h
>  create mode 100644 sound/soc/omap/omap3evm.c
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-18 15:04 Mark Brown
  2009-05-18 15:16 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-18 15:04 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 5b740ea975c4ce3da12ac21b56f9e43354ca4327:
  Julia Lawall (1):
        sound: use dev_set_drvdata

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

Mark Brown (4):
      ASoC: Split DAPM power checks from sequencing of power changes
      ASoC: Make DAPM sysfs entries non-optional
      ASoC: Integrate bias management with DAPM power management
      ASoC: Add debug trace for bias level transitions

Misael Lopez Cruz (1):
      ASoC: TWL4030: Enable/disable voice digital filters

 include/sound/soc-dapm.h   |    5 +-
 include/sound/soc.h        |    3 +
 sound/soc/codecs/twl4030.c |   37 +++++++++
 sound/soc/codecs/twl4030.h |    2 +-
 sound/soc/soc-core.c       |   61 +++------------
 sound/soc/soc-dapm.c       |  187 ++++++++++++++++++++++++++++++--------------
 6 files changed, 183 insertions(+), 112 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-18 15:04 Mark Brown
@ 2009-05-18 15:16 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-18 15:16 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Mon, 18 May 2009 16:04:53 +0100,
Mark Brown wrote:
> 
> The following changes since commit 5b740ea975c4ce3da12ac21b56f9e43354ca4327:
>   Julia Lawall (1):
>         sound: use dev_set_drvdata
> 
> 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

Thanks, pulled now.


Takashi

> Mark Brown (4):
>       ASoC: Split DAPM power checks from sequencing of power changes
>       ASoC: Make DAPM sysfs entries non-optional
>       ASoC: Integrate bias management with DAPM power management
>       ASoC: Add debug trace for bias level transitions
> 
> Misael Lopez Cruz (1):
>       ASoC: TWL4030: Enable/disable voice digital filters
> 
>  include/sound/soc-dapm.h   |    5 +-
>  include/sound/soc.h        |    3 +
>  sound/soc/codecs/twl4030.c |   37 +++++++++
>  sound/soc/codecs/twl4030.h |    2 +-
>  sound/soc/soc-core.c       |   61 +++------------
>  sound/soc/soc-dapm.c       |  187 ++++++++++++++++++++++++++++++--------------
>  6 files changed, 183 insertions(+), 112 deletions(-)
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-19 19:27 Mark Brown
  2009-05-19 19:39 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-19 19:27 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit f83fba8baab9e95fff0fe2be0e1e32a1650bdd7f:
  Mark Brown (1):
        ASoC: Add debug trace for bias level transitions

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

Atsushi Nemoto (1):
      ASoC: Add TXx9 AC link controller driver (v3)

Lopez Cruz, Misael (2):
      ASoC: TWL4030: Add control for selecting codec operation mode
      ASoC: SDP3430: Connect twl4030 voice DAI to McBSP3

Peter Ujfalusi (1):
      ASoC: TWL4030: Fix Analog capture path for AUXR

 sound/soc/Kconfig                 |    1 +
 sound/soc/Makefile                |    1 +
 sound/soc/codecs/twl4030.c        |   49 ++++-
 sound/soc/omap/sdp3430.c          |   87 +++++++-
 sound/soc/txx9/Kconfig            |   29 +++
 sound/soc/txx9/Makefile           |   11 +
 sound/soc/txx9/txx9aclc-ac97.c    |  255 ++++++++++++++++++++++
 sound/soc/txx9/txx9aclc-generic.c |   98 +++++++++
 sound/soc/txx9/txx9aclc.c         |  430 +++++++++++++++++++++++++++++++++++++
 sound/soc/txx9/txx9aclc.h         |   83 +++++++
 10 files changed, 1033 insertions(+), 11 deletions(-)
 create mode 100644 sound/soc/txx9/Kconfig
 create mode 100644 sound/soc/txx9/Makefile
 create mode 100644 sound/soc/txx9/txx9aclc-ac97.c
 create mode 100644 sound/soc/txx9/txx9aclc-generic.c
 create mode 100644 sound/soc/txx9/txx9aclc.c
 create mode 100644 sound/soc/txx9/txx9aclc.h

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-19 19:27 Mark Brown
@ 2009-05-19 19:39 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-19 19:39 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Tue, 19 May 2009 20:27:32 +0100,
Mark Brown wrote:
> 
> The following changes since commit f83fba8baab9e95fff0fe2be0e1e32a1650bdd7f:
>   Mark Brown (1):
>         ASoC: Add debug trace for bias level transitions
> 
> 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 now.  Thanks!


Takashi


> Atsushi Nemoto (1):
>       ASoC: Add TXx9 AC link controller driver (v3)
> 
> Lopez Cruz, Misael (2):
>       ASoC: TWL4030: Add control for selecting codec operation mode
>       ASoC: SDP3430: Connect twl4030 voice DAI to McBSP3
> 
> Peter Ujfalusi (1):
>       ASoC: TWL4030: Fix Analog capture path for AUXR
> 
>  sound/soc/Kconfig                 |    1 +
>  sound/soc/Makefile                |    1 +
>  sound/soc/codecs/twl4030.c        |   49 ++++-
>  sound/soc/omap/sdp3430.c          |   87 +++++++-
>  sound/soc/txx9/Kconfig            |   29 +++
>  sound/soc/txx9/Makefile           |   11 +
>  sound/soc/txx9/txx9aclc-ac97.c    |  255 ++++++++++++++++++++++
>  sound/soc/txx9/txx9aclc-generic.c |   98 +++++++++
>  sound/soc/txx9/txx9aclc.c         |  430 +++++++++++++++++++++++++++++++++++++
>  sound/soc/txx9/txx9aclc.h         |   83 +++++++
>  10 files changed, 1033 insertions(+), 11 deletions(-)
>  create mode 100644 sound/soc/txx9/Kconfig
>  create mode 100644 sound/soc/txx9/Makefile
>  create mode 100644 sound/soc/txx9/txx9aclc-ac97.c
>  create mode 100644 sound/soc/txx9/txx9aclc-generic.c
>  create mode 100644 sound/soc/txx9/txx9aclc.c
>  create mode 100644 sound/soc/txx9/txx9aclc.h
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-22 20:21 Mark Brown
  2009-05-22 20:34 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-22 20:21 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit e24805dd85283ac0912b9c400768a4d171b400ff:
  Atsushi Nemoto (1):
        ASoC: Add TXx9 AC link controller driver (v3)

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

Mark Brown (2):
      ASoC: Make snd_soc_read() and snd_soc_write() functions
      ASoC: WM9081 mono DAC with integrated 2.6W class AB/D amplifier driver

Peter Ujfalusi (5):
      ASoC: TWL4030: Change DAPM routings and controls for DACs and PGAs
      ASoC: TWL4030: Move the Headset pop-attenuation code to PGA event
      ASoC: TWL4030: Add support for platform dependent configuration
      ASoC: SDP4030: Use the twl4030_setup_data for headset pop-removal
      ASoC: TWL4030: Differentiate the playback streams

 include/sound/soc.h        |   17 +-
 include/sound/wm9081.h     |   25 +
 sound/soc/codecs/Kconfig   |    4 +
 sound/soc/codecs/Makefile  |    2 +
 sound/soc/codecs/twl4030.c |  285 ++++++---
 sound/soc/codecs/twl4030.h |    5 +
 sound/soc/codecs/wm9081.c  | 1532 ++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm9081.h  |  787 +++++++++++++++++++++++
 sound/soc/omap/sdp3430.c   |    7 +
 9 files changed, 2559 insertions(+), 105 deletions(-)
 create mode 100644 include/sound/wm9081.h
 create mode 100644 sound/soc/codecs/wm9081.c
 create mode 100644 sound/soc/codecs/wm9081.h

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-22 20:21 Mark Brown
@ 2009-05-22 20:34 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-22 20:34 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Fri, 22 May 2009 21:21:24 +0100,
Mark Brown wrote:
> 
> The following changes since commit e24805dd85283ac0912b9c400768a4d171b400ff:
>   Atsushi Nemoto (1):
>         ASoC: Add TXx9 AC link controller driver (v3)
> 
> 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

Thanks, pulled now.


Takashi

> Mark Brown (2):
>       ASoC: Make snd_soc_read() and snd_soc_write() functions
>       ASoC: WM9081 mono DAC with integrated 2.6W class AB/D amplifier driver
> 
> Peter Ujfalusi (5):
>       ASoC: TWL4030: Change DAPM routings and controls for DACs and PGAs
>       ASoC: TWL4030: Move the Headset pop-attenuation code to PGA event
>       ASoC: TWL4030: Add support for platform dependent configuration
>       ASoC: SDP4030: Use the twl4030_setup_data for headset pop-removal
>       ASoC: TWL4030: Differentiate the playback streams
> 
>  include/sound/soc.h        |   17 +-
>  include/sound/wm9081.h     |   25 +
>  sound/soc/codecs/Kconfig   |    4 +
>  sound/soc/codecs/Makefile  |    2 +
>  sound/soc/codecs/twl4030.c |  285 ++++++---
>  sound/soc/codecs/twl4030.h |    5 +
>  sound/soc/codecs/wm9081.c  | 1532 ++++++++++++++++++++++++++++++++++++++++++++
>  sound/soc/codecs/wm9081.h  |  787 +++++++++++++++++++++++
>  sound/soc/omap/sdp3430.c   |    7 +
>  9 files changed, 2559 insertions(+), 105 deletions(-)
>  create mode 100644 include/sound/wm9081.h
>  create mode 100644 sound/soc/codecs/wm9081.c
>  create mode 100644 sound/soc/codecs/wm9081.h
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-25 12:07 Mark Brown
  2009-05-25 12:29 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-25 12:07 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 86ed3669f068b514ab85ffd548456a342b3fb8d3:
  Mark Brown (1):
        ASoC: WM9081 mono DAC with integrated 2.6W class AB/D amplifier driver

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

Jon Smirl (4):
      ASoC: Codec for STAC9766 used on the Efika
      ASoC: Basic split of mpc5200 DMA code out of mpc5200_psc_i2s
      ASoC: Rename the PSC functions to DMA
      ASoC: Add a few more mpc5200 PSC defines

Mark Brown (2):
      ASoC: Fix WM9081 PowerPC compiler issues
      ASoC: Fix minor issues in STAC9766 driver

Peter Ujfalusi (3):
      ASoC: TWL4030: Handsfree pop removal redesign
      ASoC: TWL4030: Add shadow register
      ASoC: TWL4030: HandsfreeL/R mute DAPM switch

 arch/powerpc/include/asm/mpc52xx_psc.h |   11 +
 sound/soc/codecs/Kconfig               |    4 +
 sound/soc/codecs/Makefile              |    2 +
 sound/soc/codecs/stac9766.c            |  463 +++++++++++++++++++++++
 sound/soc/codecs/stac9766.h            |   21 +
 sound/soc/codecs/twl4030.c             |   99 ++++-
 sound/soc/codecs/twl4030.h             |    7 +-
 sound/soc/codecs/wm9081.c              |    6 +-
 sound/soc/fsl/Kconfig                  |    4 +
 sound/soc/fsl/Makefile                 |    2 +
 sound/soc/fsl/mpc5200_dma.c            |  458 ++++++++++++++++++++++
 sound/soc/fsl/mpc5200_dma.h            |   81 ++++
 sound/soc/fsl/mpc5200_psc_i2s.c        |  645 ++++----------------------------
 13 files changed, 1217 insertions(+), 586 deletions(-)
 create mode 100644 sound/soc/codecs/stac9766.c
 create mode 100644 sound/soc/codecs/stac9766.h
 create mode 100644 sound/soc/fsl/mpc5200_dma.c
 create mode 100644 sound/soc/fsl/mpc5200_dma.h

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-25 12:07 Mark Brown
@ 2009-05-25 12:29 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-25 12:29 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Mon, 25 May 2009 13:07:57 +0100,
Mark Brown wrote:
> 
> The following changes since commit 86ed3669f068b514ab85ffd548456a342b3fb8d3:
>   Mark Brown (1):
>         ASoC: WM9081 mono DAC with integrated 2.6W class AB/D amplifier driver
> 
> 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 now.  Thanks.


Takashi

> Jon Smirl (4):
>       ASoC: Codec for STAC9766 used on the Efika
>       ASoC: Basic split of mpc5200 DMA code out of mpc5200_psc_i2s
>       ASoC: Rename the PSC functions to DMA
>       ASoC: Add a few more mpc5200 PSC defines
> 
> Mark Brown (2):
>       ASoC: Fix WM9081 PowerPC compiler issues
>       ASoC: Fix minor issues in STAC9766 driver
> 
> Peter Ujfalusi (3):
>       ASoC: TWL4030: Handsfree pop removal redesign
>       ASoC: TWL4030: Add shadow register
>       ASoC: TWL4030: HandsfreeL/R mute DAPM switch
> 
>  arch/powerpc/include/asm/mpc52xx_psc.h |   11 +
>  sound/soc/codecs/Kconfig               |    4 +
>  sound/soc/codecs/Makefile              |    2 +
>  sound/soc/codecs/stac9766.c            |  463 +++++++++++++++++++++++
>  sound/soc/codecs/stac9766.h            |   21 +
>  sound/soc/codecs/twl4030.c             |   99 ++++-
>  sound/soc/codecs/twl4030.h             |    7 +-
>  sound/soc/codecs/wm9081.c              |    6 +-
>  sound/soc/fsl/Kconfig                  |    4 +
>  sound/soc/fsl/Makefile                 |    2 +
>  sound/soc/fsl/mpc5200_dma.c            |  458 ++++++++++++++++++++++
>  sound/soc/fsl/mpc5200_dma.h            |   81 ++++
>  sound/soc/fsl/mpc5200_psc_i2s.c        |  645 ++++----------------------------
>  13 files changed, 1217 insertions(+), 586 deletions(-)
>  create mode 100644 sound/soc/codecs/stac9766.c
>  create mode 100644 sound/soc/codecs/stac9766.h
>  create mode 100644 sound/soc/fsl/mpc5200_dma.c
>  create mode 100644 sound/soc/fsl/mpc5200_dma.h
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-27 10:48 Mark Brown
  2009-05-27 13:58 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-27 10:48 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 0f89bdcac61536c5cb2a095a514657019573afb4:
  Peter Ujfalusi (1):
        ASoC: TWL4030: HandsfreeL/R mute DAPM switch

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

Jon Smirl (4):
      ASoC: Main rewite of the mpc5200 audio DMA code
      ASoC: AC97 driver for mpc5200
      ASoC: Support for AC97 on Phytec pmc030 base board.
      ASoC: Fabric bindings for STAC9766 on the Efika

Mark Brown (2):
      ASoC: Mark MPC5200 AC97 as BROKEN until PowerPC merge issues are resolved
      ASoC: Switch FSL SSI DAI over to symmetric_rates

 sound/soc/fsl/Kconfig               |   28 +++-
 sound/soc/fsl/Makefile              |    5 +
 sound/soc/fsl/efika-audio-fabric.c  |   90 +++++++
 sound/soc/fsl/fsl_ssi.c             |    9 +-
 sound/soc/fsl/mpc5200_dma.c         |  442 ++++++++++++++++++++++-------------
 sound/soc/fsl/mpc5200_dma.h         |   33 ++--
 sound/soc/fsl/mpc5200_psc_ac97.c    |  331 ++++++++++++++++++++++++++
 sound/soc/fsl/mpc5200_psc_ac97.h    |   15 ++
 sound/soc/fsl/mpc5200_psc_i2s.c     |  247 ++++----------------
 sound/soc/fsl/mpc5200_psc_i2s.h     |   12 +
 sound/soc/fsl/pcm030-audio-fabric.c |   90 +++++++
 11 files changed, 905 insertions(+), 397 deletions(-)
 create mode 100644 sound/soc/fsl/efika-audio-fabric.c
 create mode 100644 sound/soc/fsl/mpc5200_psc_ac97.c
 create mode 100644 sound/soc/fsl/mpc5200_psc_ac97.h
 create mode 100644 sound/soc/fsl/mpc5200_psc_i2s.h
 create mode 100644 sound/soc/fsl/pcm030-audio-fabric.c

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-27 10:48 Mark Brown
@ 2009-05-27 13:58 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-27 13:58 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Wed, 27 May 2009 11:48:49 +0100,
Mark Brown wrote:
> 
> The following changes since commit 0f89bdcac61536c5cb2a095a514657019573afb4:
>   Peter Ujfalusi (1):
>         ASoC: TWL4030: HandsfreeL/R mute DAPM switch
> 
> 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

Thanks, pulled now.


Takashi

> 
> Jon Smirl (4):
>       ASoC: Main rewite of the mpc5200 audio DMA code
>       ASoC: AC97 driver for mpc5200
>       ASoC: Support for AC97 on Phytec pmc030 base board.
>       ASoC: Fabric bindings for STAC9766 on the Efika
> 
> Mark Brown (2):
>       ASoC: Mark MPC5200 AC97 as BROKEN until PowerPC merge issues are resolved
>       ASoC: Switch FSL SSI DAI over to symmetric_rates
> 
>  sound/soc/fsl/Kconfig               |   28 +++-
>  sound/soc/fsl/Makefile              |    5 +
>  sound/soc/fsl/efika-audio-fabric.c  |   90 +++++++
>  sound/soc/fsl/fsl_ssi.c             |    9 +-
>  sound/soc/fsl/mpc5200_dma.c         |  442 ++++++++++++++++++++++-------------
>  sound/soc/fsl/mpc5200_dma.h         |   33 ++--
>  sound/soc/fsl/mpc5200_psc_ac97.c    |  331 ++++++++++++++++++++++++++
>  sound/soc/fsl/mpc5200_psc_ac97.h    |   15 ++
>  sound/soc/fsl/mpc5200_psc_i2s.c     |  247 ++++----------------
>  sound/soc/fsl/mpc5200_psc_i2s.h     |   12 +
>  sound/soc/fsl/pcm030-audio-fabric.c |   90 +++++++
>  11 files changed, 905 insertions(+), 397 deletions(-)
>  create mode 100644 sound/soc/fsl/efika-audio-fabric.c
>  create mode 100644 sound/soc/fsl/mpc5200_psc_ac97.c
>  create mode 100644 sound/soc/fsl/mpc5200_psc_ac97.h
>  create mode 100644 sound/soc/fsl/mpc5200_psc_i2s.h
>  create mode 100644 sound/soc/fsl/pcm030-audio-fabric.c
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-05-28 18:04 Mark Brown
  2009-05-28 18:12 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-05-28 18:04 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 08d15f034e94251606479d7ca9070994c2e2fcf0:
  Mark Brown (1):
        ASoC: Switch FSL SSI DAI over to symmetric_rates

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

Chaithrika U S (1):
      ASoC: Add dummy S/PDIF codec support

Jon Smirl (1):
      ASoC: Modify mpc5200 AC97 driver to use V9 of spin_event_timeout()

Mark Brown (1):
      ASoC: Initialise dev for the dummy S/PDIF DAI

Roel Kluin (1):
      ASoC: correct print specifiers for unsigneds

 sound/soc/atmel/playpaq_wm8510.c     |    2 +-
 sound/soc/codecs/Kconfig             |    4 ++
 sound/soc/codecs/Makefile            |    2 +
 sound/soc/codecs/spdif_transciever.c |   71 ++++++++++++++++++++++++++++++++++
 sound/soc/codecs/spdif_transciever.h |   17 ++++++++
 sound/soc/codecs/tlv320aic23.c       |    4 +-
 sound/soc/codecs/uda134x.c           |    4 +-
 sound/soc/codecs/wm8350.c            |    2 +-
 sound/soc/codecs/wm8400.c            |    4 +-
 sound/soc/codecs/wm8510.c            |    2 +-
 sound/soc/codecs/wm8580.c            |    4 +-
 sound/soc/codecs/wm8753.c            |    2 +-
 sound/soc/codecs/wm8900.c            |    6 +-
 sound/soc/codecs/wm8990.c            |    2 +-
 sound/soc/codecs/wm9713.c            |    2 +-
 sound/soc/fsl/mpc5200_psc_ac97.c     |   30 +++++++--------
 sound/soc/pxa/pxa-ssp.c              |    4 +-
 sound/soc/s3c24xx/s3c-i2s-v2.c       |    4 +-
 sound/soc/sh/ssi.c                   |    2 +-
 19 files changed, 130 insertions(+), 38 deletions(-)
 create mode 100644 sound/soc/codecs/spdif_transciever.c
 create mode 100644 sound/soc/codecs/spdif_transciever.h

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-05-28 18:04 Mark Brown
@ 2009-05-28 18:12 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-05-28 18:12 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Thu, 28 May 2009 19:04:30 +0100,
Mark Brown wrote:
> 
> The following changes since commit 08d15f034e94251606479d7ca9070994c2e2fcf0:
>   Mark Brown (1):
>         ASoC: Switch FSL SSI DAI over to symmetric_rates
> 
> 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

Thanks, pulled now.


Takashi

> Chaithrika U S (1):
>       ASoC: Add dummy S/PDIF codec support
> 
> Jon Smirl (1):
>       ASoC: Modify mpc5200 AC97 driver to use V9 of spin_event_timeout()
> 
> Mark Brown (1):
>       ASoC: Initialise dev for the dummy S/PDIF DAI
> 
> Roel Kluin (1):
>       ASoC: correct print specifiers for unsigneds
> 
>  sound/soc/atmel/playpaq_wm8510.c     |    2 +-
>  sound/soc/codecs/Kconfig             |    4 ++
>  sound/soc/codecs/Makefile            |    2 +
>  sound/soc/codecs/spdif_transciever.c |   71 ++++++++++++++++++++++++++++++++++
>  sound/soc/codecs/spdif_transciever.h |   17 ++++++++
>  sound/soc/codecs/tlv320aic23.c       |    4 +-
>  sound/soc/codecs/uda134x.c           |    4 +-
>  sound/soc/codecs/wm8350.c            |    2 +-
>  sound/soc/codecs/wm8400.c            |    4 +-
>  sound/soc/codecs/wm8510.c            |    2 +-
>  sound/soc/codecs/wm8580.c            |    4 +-
>  sound/soc/codecs/wm8753.c            |    2 +-
>  sound/soc/codecs/wm8900.c            |    6 +-
>  sound/soc/codecs/wm8990.c            |    2 +-
>  sound/soc/codecs/wm9713.c            |    2 +-
>  sound/soc/fsl/mpc5200_psc_ac97.c     |   30 +++++++--------
>  sound/soc/pxa/pxa-ssp.c              |    4 +-
>  sound/soc/s3c24xx/s3c-i2s-v2.c       |    4 +-
>  sound/soc/sh/ssi.c                   |    2 +-
>  19 files changed, 130 insertions(+), 38 deletions(-)
>  create mode 100644 sound/soc/codecs/spdif_transciever.c
>  create mode 100644 sound/soc/codecs/spdif_transciever.h
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-06-03 10:51 Mark Brown
  2009-06-03 11:02 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-06-03 10:51 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 203350c1a8e23adf17fd9a96d8bfc7adf63c1ff6:
  Mark Brown (1):
        ASoC: Initialise dev for the dummy S/PDIF DAI

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

Cliff Cai (3):
      ASoC: SSM2602: remove unsupported sample rates
      ASoC: Blackfin: set the transfer size according the ac97_frame size
      ASoC: SSM2602: assign last substream to the master when shutting down

Peter Ujfalusi (2):
      ASoC: TWL4030: Use reg_cache in twl4030_init_chip
      ASoC: TWL4030: Check the interface format for 4 channel mode

Sonic Zhang (1):
      ASoC: Blackfin: document how anomaly 05000250 is handled

 sound/soc/blackfin/bf5xx-ac97.c  |    9 +++++++++
 sound/soc/blackfin/bf5xx-sport.c |    4 ++--
 sound/soc/codecs/ssm2602.c       |   33 +++++++++++++++++++--------------
 sound/soc/codecs/twl4030.c       |   16 +++++++++++-----
 4 files changed, 41 insertions(+), 21 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-06-03 10:51 Mark Brown
@ 2009-06-03 11:02 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-06-03 11:02 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Wed, 3 Jun 2009 11:51:50 +0100,
Mark Brown wrote:
> 
> The following changes since commit 203350c1a8e23adf17fd9a96d8bfc7adf63c1ff6:
>   Mark Brown (1):
>         ASoC: Initialise dev for the dummy S/PDIF DAI
> 
> 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

Thanks, pulled now.


Takashi

> Cliff Cai (3):
>       ASoC: SSM2602: remove unsupported sample rates
>       ASoC: Blackfin: set the transfer size according the ac97_frame size
>       ASoC: SSM2602: assign last substream to the master when shutting down
> 
> Peter Ujfalusi (2):
>       ASoC: TWL4030: Use reg_cache in twl4030_init_chip
>       ASoC: TWL4030: Check the interface format for 4 channel mode
> 
> Sonic Zhang (1):
>       ASoC: Blackfin: document how anomaly 05000250 is handled
> 
>  sound/soc/blackfin/bf5xx-ac97.c  |    9 +++++++++
>  sound/soc/blackfin/bf5xx-sport.c |    4 ++--
>  sound/soc/codecs/ssm2602.c       |   33 +++++++++++++++++++--------------
>  sound/soc/codecs/twl4030.c       |   16 +++++++++++-----
>  4 files changed, 41 insertions(+), 21 deletions(-)
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-06-21 13:15 Mark Brown
  2009-06-22  6:20 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-06-21 13:15 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit ef39412622b6e8f09c383de9565b07e93553fc27:
  Takashi Iwai (1):
        ASoC: Kill BUS_ID_SIZE

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

Barry Song (1):
      ASoC: Blackfin: update the bf5xx_i2s_resume parameters

Cliff Cai (1):
      ASoC: Blackfin: keep better track of SPORT configuration state

 sound/soc/blackfin/bf5xx-i2s.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-06-21 13:15 Mark Brown
@ 2009-06-22  6:20 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-06-22  6:20 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Sun, 21 Jun 2009 14:15:31 +0100,
Mark Brown wrote:
> 
> The following changes since commit ef39412622b6e8f09c383de9565b07e93553fc27:
>   Takashi Iwai (1):
>         ASoC: Kill BUS_ID_SIZE
> 
> 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 now.  Thanks.


Takashi

> Barry Song (1):
>       ASoC: Blackfin: update the bf5xx_i2s_resume parameters
> 
> Cliff Cai (1):
>       ASoC: Blackfin: keep better track of SPORT configuration state
> 
>  sound/soc/blackfin/bf5xx-i2s.c |   10 +++++++---
>  1 files changed, 7 insertions(+), 3 deletions(-)
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
@ 2009-06-25 13:09 Mark Brown
  2009-06-25 13:35 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-06-25 13:09 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 28d0325ce6e0a52f53d8af687e6427fee59004d3:
  Linus Torvalds (1):
        Linux 2.6.31-rc1

are available in the git repository at:

  ssh://master.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.31

Peter Ujfalusi (1):
      MAINTAINERS: Add entry for twl4030 series soc codec driver

 MAINTAINERS |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-06-25 13:09 Mark Brown
@ 2009-06-25 13:35 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-06-25 13:35 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Thu, 25 Jun 2009 14:09:39 +0100,
Mark Brown wrote:
> 
> The following changes since commit 28d0325ce6e0a52f53d8af687e6427fee59004d3:
>   Linus Torvalds (1):
>         Linux 2.6.31-rc1
> 
> are available in the git repository at:
> 
>   ssh://master.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git for-2.6.31

Thanks.  This gave me a merge error (because other entries have been
added to MAINTAINERS) so I corrected manually.

So, I based my 2.6.32 asoc branch on this to avoid the doubly merge
corrections, and I pulled your 2.6.32 branch there, too.

Now everything should be settled doen, you can forward gracefully by
just pulling from my branches :)


Takashi

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-07-01 20:45 Mark Brown
  2009-07-02  8:55 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-07-01 20:45 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 10121a12e2380fb34b6e646a8e367add06d036c3:
  Takashi Iwai (1):
        Merge branch 'for-2.6.31' of git://git.kernel.org/.../broonie/sound-2.6 into fix/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

Grant Likely (2):
      ASoC: Fix typo in MPC5200 PSC AC97 driver Kconfig
      ASoC: remove BROKEN from Efika and pcm030 fabric drivers

Janusz Krzysztofik (1):
      ASoC: OMAP: fix OMAP1510 broken PCM pointer callback

Mark Brown (1):
      ASoC: Only disable pxa2xx-i2s clocks if we enabled them

 sound/soc/fsl/Kconfig      |    6 +++---
 sound/soc/omap/omap-pcm.c  |   11 +++++++----
 sound/soc/pxa/pxa2xx-i2s.c |    7 ++++++-
 3 files changed, 16 insertions(+), 8 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-07-01 20:45 Mark Brown
@ 2009-07-02  8:55 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-07-02  8:55 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Wed, 1 Jul 2009 21:45:05 +0100,
Mark Brown wrote:
> 
> The following changes since commit 10121a12e2380fb34b6e646a8e367add06d036c3:
>   Takashi Iwai (1):
>         Merge branch 'for-2.6.31' of git://git.kernel.org/.../broonie/sound-2.6 into fix/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 now.  Thanks.


Takashi

> Grant Likely (2):
>       ASoC: Fix typo in MPC5200 PSC AC97 driver Kconfig
>       ASoC: remove BROKEN from Efika and pcm030 fabric drivers
> 
> Janusz Krzysztofik (1):
>       ASoC: OMAP: fix OMAP1510 broken PCM pointer callback
> 
> Mark Brown (1):
>       ASoC: Only disable pxa2xx-i2s clocks if we enabled them
> 
>  sound/soc/fsl/Kconfig      |    6 +++---
>  sound/soc/omap/omap-pcm.c  |   11 +++++++----
>  sound/soc/pxa/pxa2xx-i2s.c |    7 ++++++-
>  3 files changed, 16 insertions(+), 8 deletions(-)
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-07-06 20:49 Mark Brown
  2009-07-07  5:56 ` Takashi Iwai
  0 siblings, 1 reply; 56+ messages in thread
From: Mark Brown @ 2009-07-06 20:49 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit da9ff1f796e81976935407251815838bef9868d4:
  Mark Brown (1):
        ASoC: Only disable pxa2xx-i2s clocks if we enabled them

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

Grant Likely (2):
      ASoC: Fix mpc5200-psc-ac97 to ensure the data ready bit is cleared
      ASoC: add locking to mpc5200-psc-ac97 driver

Lars-Peter Clausen (1):
      ASoC: Fix wm8753 register cache size and initialization

Mark Brown (1):
      ASoC: Fix register cache initialisation for WM8753

 sound/soc/codecs/wm8753.c        |    6 +++---
 sound/soc/fsl/mpc5200_dma.c      |    1 +
 sound/soc/fsl/mpc5200_dma.h      |    1 +
 sound/soc/fsl/mpc5200_psc_ac97.c |   17 ++++++++++++++++-
 4 files changed, 21 insertions(+), 4 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: ASoC updates for 2.6.31
  2009-07-06 20:49 Mark Brown
@ 2009-07-07  5:56 ` Takashi Iwai
  0 siblings, 0 replies; 56+ messages in thread
From: Takashi Iwai @ 2009-07-07  5:56 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel

At Mon, 6 Jul 2009 21:49:01 +0100,
Mark Brown wrote:
> 
> The following changes since commit da9ff1f796e81976935407251815838bef9868d4:
>   Mark Brown (1):
>         ASoC: Only disable pxa2xx-i2s clocks if we enabled them
> 
> 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 both branches now.  Thanks.


Takashi

> Grant Likely (2):
>       ASoC: Fix mpc5200-psc-ac97 to ensure the data ready bit is cleared
>       ASoC: add locking to mpc5200-psc-ac97 driver
> 
> Lars-Peter Clausen (1):
>       ASoC: Fix wm8753 register cache size and initialization
> 
> Mark Brown (1):
>       ASoC: Fix register cache initialisation for WM8753
> 
>  sound/soc/codecs/wm8753.c        |    6 +++---
>  sound/soc/fsl/mpc5200_dma.c      |    1 +
>  sound/soc/fsl/mpc5200_dma.h      |    1 +
>  sound/soc/fsl/mpc5200_psc_ac97.c |   17 ++++++++++++++++-
>  4 files changed, 21 insertions(+), 4 deletions(-)
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* ASoC updates for 2.6.31
@ 2009-07-10 19:25 Mark Brown
  0 siblings, 0 replies; 56+ messages in thread
From: Mark Brown @ 2009-07-10 19:25 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

The following changes since commit 637a935aaba2f05e2178c9d1b714d7a2c36c8b44:
  Lars-Peter Clausen (1):
        ASoC: Fix wm8753 register cache size and initialization

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

Daniel Mack (1):
      ASoC: Fix NULL pointer dereference in __pxa2xx_pcm_hw_free

 sound/arm/pxa2xx-pcm-lib.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2009-07-10 19:25 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-14 12:32 ASoC updates for 2.6.31 Mark Brown
2009-04-14 12:32 ` [PATCH 01/14] ASoC: Add driver for s6000 I2S interface Mark Brown
2009-04-14 12:33 ` [PATCH] mx31ads: Depend on all the WM8350 core dependencies for WM1133-EV1 board Mark Brown
2009-04-14 12:34   ` Mark Brown
2009-04-14 12:33 ` [PATCH 02/14] ASoC: s6105 IP camera machine specific ASoC code Mark Brown
2009-04-14 12:33 ` [PATCH 03/14] ASoC: correct s6000 I2S clock polarity Mark Brown
2009-04-14 12:33 ` [PATCH 04/14] ASoC: Display return code when failing to add a DAPM kcontrol Mark Brown
2009-04-14 12:33 ` [PATCH 05/14] ASoC: Provide core support for symmetric sample rates Mark Brown
2009-04-15  6:31   ` Peter Ujfalusi
2009-04-15  8:29     ` Mark Brown
2009-04-14 12:33 ` [PATCH 06/14] ASoC: Add WM8988 CODEC driver Mark Brown
2009-04-14 12:33 ` [PATCH 07/14] ASoC: tlv320aic23: add DSP_A format support Mark Brown
2009-04-14 12:33 ` [PATCH 08/14] ASoC: n810: replace BUG() with BUG_ON() Mark Brown
2009-04-14 12:33 ` [PATCH 09/14] ASoC: WM9713 requires symmetric rates on the voice DAI Mark Brown
2009-04-14 12:33 ` [PATCH 10/14] ASoC: Factor out application of power for generic widgets Mark Brown
2009-04-14 12:33 ` [PATCH 11/14] ASoC: Support DAPM events for DACs and ADCs Mark Brown
2009-04-14 12:33 ` [PATCH 12/14] ASoC: Move the WM9713 voice DAC powerdown to a DAPM event Mark Brown
2009-04-14 12:33 ` [PATCH 13/14] ASoC: pxa-ssp.c fix clock/frame invert Mark Brown
2009-04-14 12:33 ` [PATCH 14/14] ASoC: Add WM8960 CODEC driver Mark Brown
  -- strict thread matches above, loose matches on Subject: below --
2009-04-16 13:50 ASoC updates for 2.6.31 Mark Brown
2009-04-16 14:06 ` Takashi Iwai
2009-04-20 11:58 Mark Brown
2009-04-20 12:05 ` Takashi Iwai
2009-04-23 19:54 Mark Brown
2009-04-24  6:10 ` Takashi Iwai
2009-04-28 15:22 Mark Brown
2009-05-05 10:01 Mark Brown
2009-05-05 10:45 ` Takashi Iwai
2009-05-08 12:57 Mark Brown
2009-05-08 14:37 ` Takashi Iwai
2009-05-12 10:25 Mark Brown
2009-05-15  8:23 ASoC updates for 2.6.30 Mark Brown
2009-05-15  8:26 ` ASoC updates for 2.6.31 Mark Brown
2009-05-15  8:34   ` Takashi Iwai
2009-05-18 15:04 Mark Brown
2009-05-18 15:16 ` Takashi Iwai
2009-05-19 19:27 Mark Brown
2009-05-19 19:39 ` Takashi Iwai
2009-05-22 20:21 Mark Brown
2009-05-22 20:34 ` Takashi Iwai
2009-05-25 12:07 Mark Brown
2009-05-25 12:29 ` Takashi Iwai
2009-05-27 10:48 Mark Brown
2009-05-27 13:58 ` Takashi Iwai
2009-05-28 18:04 Mark Brown
2009-05-28 18:12 ` Takashi Iwai
2009-06-03 10:51 Mark Brown
2009-06-03 11:02 ` Takashi Iwai
2009-06-21 13:15 Mark Brown
2009-06-22  6:20 ` Takashi Iwai
2009-06-25 13:09 Mark Brown
2009-06-25 13:35 ` Takashi Iwai
2009-07-01 20:45 Mark Brown
2009-07-02  8:55 ` Takashi Iwai
2009-07-06 20:49 Mark Brown
2009-07-07  5:56 ` Takashi Iwai
2009-07-10 19:25 Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox