All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] ASoC Support For Moorestown
@ 2011-05-06  5:45 Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver Lu Guanqun
                   ` (9 more replies)
  0 siblings, 10 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:45 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

This series of patches provides the ASoC implementation of moorestown audio.

This series adds a new codec called upd9976 and a new machine driver called
mrst_machine.  The platform driver is mostly re-used.

With this patchset, it can do:
 - playback via headphone
 - playback via internal speaker
 - capture via DMIC
 - capture via headset microphone
 - jack detection

v2:
 - change pr_err to dev_err
 - change DAPM widgets' name (adding correct suffix)
 - change to data based init of controls, widgets and route in machine driver
 - add Master Volume
 - change original "HP & Spker Mixer Volume" to "PCM Volume"
 - squash some patches into one, resulting in less number of patches
 - move jack handling from machine driver to codec driver
 - in codec probe, set the bias level to standby instead of off

Thanks for all the reviewers:
 - Mark Brown
 - Dimitris Papastamos
 - Takashi Iwai
 - Koul Vinod

Any more comments are welcome. :)

---

Lu Guanqun (8):
      ASoC: upd9976: Add Renesas uPD9976 codec driver
      ASoC: mrst_machine: add moorestown machine driver
      ASoC: upd9976: add DMIC support
      ASoC: upd9976: add Analog MIC support
      ASoC: upd9976: add jack detection function
      ASoC: mrst_machine: add capture functionality
      ASoC: mrst_machine: add jack detection support
      ASoC: mrst_machine: add initial config to machine driver

Wang Xingchao (2):
      ASoC: sst_platform: modify current cpu dai driver to suit the needs for moorestown platform
      ASoC: upd9976: add capture ability for dai driver


 sound/soc/codecs/Kconfig         |    4 
 sound/soc/codecs/Makefile        |    2 
 sound/soc/codecs/upd9976.c       |  697 ++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/upd9976.h       |   87 +++++
 sound/soc/mid-x86/Kconfig        |   12 +
 sound/soc/mid-x86/Makefile       |    2 
 sound/soc/mid-x86/mrst_machine.c |  228 ++++++++++++
 sound/soc/mid-x86/sst_platform.c |   13 -
 8 files changed, 1041 insertions(+), 4 deletions(-)
 create mode 100644 sound/soc/codecs/upd9976.c
 create mode 100644 sound/soc/codecs/upd9976.h
 create mode 100644 sound/soc/mid-x86/mrst_machine.c

-- 
guanqun

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

* [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06 10:17   ` Mark Brown
  2011-05-06  5:46 ` [PATCH v2 02/10] ASoC: sst_platform: modify current cpu dai driver to suit the needs for moorestown platform Lu Guanqun
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

uPD9976 is a complex codec, however this patch only provides basic playback
functionality for headphone. More functionality will be added bit by bit in the
following patches.

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
Signed-off-by: Wang Xingchao <xingchao.wang@intel.com>
---
 sound/soc/codecs/Kconfig   |    4 
 sound/soc/codecs/Makefile  |    2 
 sound/soc/codecs/upd9976.c |  407 ++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/upd9976.h |   83 +++++++++
 4 files changed, 496 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/codecs/upd9976.c
 create mode 100644 sound/soc/codecs/upd9976.h

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2a69718..b914bc6 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -52,6 +52,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_TWL6040 if TWL4030_CORE
 	select SND_SOC_UDA134X
 	select SND_SOC_UDA1380 if I2C
+	select SND_SOC_UPD9976 if INTEL_SCU_IPC
 	select SND_SOC_WL1273 if MFD_WL1273_CORE
 	select SND_SOC_WM1250_EV1 if I2C
 	select SND_SOC_WM2000 if I2C
@@ -244,6 +245,9 @@ config SND_SOC_UDA134X
 config SND_SOC_UDA1380
         tristate
 
+config SND_SOC_UPD9976
+	tristate
+
 config SND_SOC_WL1273
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4cb2f42..163c623 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -37,6 +37,7 @@ snd-soc-twl4030-objs := twl4030.o
 snd-soc-twl6040-objs := twl6040.o
 snd-soc-uda134x-objs := uda134x.o
 snd-soc-uda1380-objs := uda1380.o
+snd-soc-upd9976-objs := upd9976.o
 snd-soc-wl1273-objs := wl1273.o
 snd-soc-wm1250-ev1-objs := wm1250-ev1.o
 snd-soc-wm8350-objs := wm8350.o
@@ -128,6 +129,7 @@ obj-$(CONFIG_SND_SOC_TWL4030)	+= snd-soc-twl4030.o
 obj-$(CONFIG_SND_SOC_TWL6040)	+= snd-soc-twl6040.o
 obj-$(CONFIG_SND_SOC_UDA134X)	+= snd-soc-uda134x.o
 obj-$(CONFIG_SND_SOC_UDA1380)	+= snd-soc-uda1380.o
+obj-$(CONFIG_SND_SOC_UPD9976)	+= snd-soc-upd9976.o
 obj-$(CONFIG_SND_SOC_WL1273)	+= snd-soc-wl1273.o
 obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
 obj-$(CONFIG_SND_SOC_WM8350)	+= snd-soc-wm8350.o
diff --git a/sound/soc/codecs/upd9976.c b/sound/soc/codecs/upd9976.c
new file mode 100644
index 0000000..7642356
--- /dev/null
+++ b/sound/soc/codecs/upd9976.c
@@ -0,0 +1,407 @@
+/*
+ *  upd9976.c -  Renesas uPD9976 codec driver
+ *
+ *  Copyright (C) 2011 Intel Corporation
+ *
+ *  Maintainer:
+ *              Lu Guanqun <guanqun.lu@intel.com>
+ *              Wang Xingchao <xingchao.wang@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <asm/intel_scu_ipc.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 <sound/jack.h>
+#include "upd9976.h"
+
+static inline unsigned int upd9976_read(struct snd_soc_codec *codec,
+					unsigned int reg)
+{
+	u8 value = 0;
+	int ret;
+
+	ret = intel_scu_ipc_ioread8(reg, &value);
+	if (ret)
+		dev_err(codec->dev,
+			"upd9976 read of 0x%x failed, error: %d\n", reg, ret);
+	return value;
+}
+
+static inline int upd9976_write(struct snd_soc_codec *codec,
+				unsigned int reg, unsigned int value)
+{
+	int ret;
+
+	ret = intel_scu_ipc_iowrite8(reg, value);
+	if (ret)
+		dev_err(codec->dev,
+			"upd9976 write of 0x%x failed, error: %d\n", reg, ret);
+	return ret;
+}
+
+/*
+ * Mixing Volume: from -25 dB to 6 dB in 1 dB steps.
+ */
+static DECLARE_TLV_DB_SCALE(mixer_tlv, -2500, 100, 0);
+
+/*
+ * Audio DAC Volume: From -84 dB to 10.5 dB in 0.75 steps.
+ */
+static DECLARE_TLV_DB_SCALE(adac_tlv, -8400, 75, 0);
+static const struct snd_kcontrol_new upd9976_snd_controls[] = {
+	SOC_DOUBLE_R_TLV("Master Volume",
+			 UPD9976_AUDIOLVOL, UPD9976_AUDIORVOL,
+			 0, 0x7f, 1, adac_tlv),
+	SOC_DOUBLE_R_TLV("PCM Volume",
+			 UPD9976_HPSPRLVOL, UPD9976_HPSPRRVOL,
+			 0, 0x1f, 1, mixer_tlv),
+};
+
+static const struct snd_kcontrol_new upd9976_hp_spkr_mixer_left_controls[] = {
+	SOC_DAPM_SINGLE("Audio DAC Left Switch", UPD9976_HPLMIXSEL, 4, 1, 1),
+	SOC_DAPM_SINGLE("Audio DAC Right Switch", UPD9976_HPLMIXSEL, 3, 1, 1),
+};
+
+static const struct snd_kcontrol_new upd9976_hp_spkr_mixer_right_controls[] = {
+	SOC_DAPM_SINGLE("Audio DAC Left Switch", UPD9976_HPRMIXSEL, 4, 1, 1),
+	SOC_DAPM_SINGLE("Audio DAC Right Switch", UPD9976_HPRMIXSEL, 3, 1, 1),
+};
+
+static const struct snd_soc_dapm_widget upd9976_dapm_widgets[] = {
+	/* Input */
+	SND_SOC_DAPM_INPUT("LINEINL"),
+	SND_SOC_DAPM_INPUT("LINEINR"),
+	SND_SOC_DAPM_INPUT("MIC1"),
+	SND_SOC_DAPM_INPUT("MIC2"),
+	SND_SOC_DAPM_INPUT("DMICDAT"),
+	SND_SOC_DAPM_INPUT("HPINL"),
+	SND_SOC_DAPM_INPUT("HPINR"),
+
+	/* Output */
+	SND_SOC_DAPM_OUTPUT("PREOUTL"),
+	SND_SOC_DAPM_OUTPUT("PREOUTR"),
+	SND_SOC_DAPM_OUTPUT("EPOUTP"),
+	SND_SOC_DAPM_OUTPUT("EPOUTN"),
+	SND_SOC_DAPM_OUTPUT("LINEOUTL"),
+	SND_SOC_DAPM_OUTPUT("LINEOUTR"),
+	SND_SOC_DAPM_OUTPUT("HPOUTL"),
+	SND_SOC_DAPM_OUTPUT("HPOUTR"),
+
+	/* DAC */
+	SND_SOC_DAPM_DAC("ADAC", "Audio Playback", UPD9976_POWERCTRL1, 0, 0),
+	SND_SOC_DAPM_DAC("VDAC", "Voice Playback", UPD9976_POWERCTRL1, 6, 0),
+
+	/* ADC */
+	SND_SOC_DAPM_ADC("AADC", "Audio Capture", UPD9976_POWERCTRL1, 1, 0),
+	SND_SOC_DAPM_ADC("VADC", "Voice Capture", UPD9976_POWERCTRL1, 7, 0),
+
+	/* Mixer */
+	SND_SOC_DAPM_MIXER("HP Spkr Mixer Left", UPD9976_POWERCTRL2, 3, 0,
+			   upd9976_hp_spkr_mixer_left_controls,
+			   ARRAY_SIZE(upd9976_hp_spkr_mixer_left_controls)),
+	SND_SOC_DAPM_MIXER("HP Spkr Mixer Right", UPD9976_POWERCTRL2, 2, 0,
+			   upd9976_hp_spkr_mixer_right_controls,
+			   ARRAY_SIZE(upd9976_hp_spkr_mixer_right_controls)),
+
+	/* Microphose Bias */
+	SND_SOC_DAPM_MICBIAS("MIC1 Bias", UPD9976_MICCTRL, 6, 0),
+	SND_SOC_DAPM_MICBIAS("MIC2 Bias", UPD9976_MICCTRL, 4, 0),
+
+	/* PGA */
+	SND_SOC_DAPM_PGA("HP Playback Left PGA", UPD9976_DRVPOWERCTRL,
+			 2, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("HP Playback Right PGA", UPD9976_DRVPOWERCTRL,
+			 1, 0, NULL, 0),
+
+};
+
+static const struct snd_soc_dapm_route upd9976_dapm_routes[] = {
+	{"HP Spkr Mixer Left", "Audio DAC Left Switch", "ADAC"},
+	{"HP Spkr Mixer Left", "Audio DAC Right Switch", "ADAC"},
+
+	{"HP Spkr Mixer Right", "Audio DAC Left Switch", "ADAC"},
+	{"HP Spkr Mixer Right", "Audio DAC Right Switch", "ADAC"},
+
+	{"PREOUTL", NULL, "HP Spkr Mixer Left"},
+	{"PREOUTR", NULL, "HP Spkr Mixer Right"},
+
+	{"HP Playback Left PGA", NULL, "HPINL"},
+	{"HP Playback Right PGA", NULL, "HPINR"},
+
+	{"HPOUTL", NULL, "HP Playback Left PGA"},
+	{"HPOUTR", NULL, "HP Playback Right PGA"},
+
+};
+
+static int upd9976_audio_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	unsigned int value, mask;
+
+	/* soft mute on, fast 0.75dB/6fs */
+	value = 0;
+	if (mute)
+		value = 1;
+	mask = BIT(1) | BIT(0);
+	snd_soc_update_bits(codec, UPD9976_SOFTMUTE, mask, value);
+
+	/* mute headphone, internals speaker, internal earpiece mono */
+	value = 0;
+	if (mute)
+		value = BIT(2) | BIT(1) | BIT(0);
+	mask = BIT(2) | BIT(1) | BIT(0);
+	snd_soc_update_bits(codec, UPD9976_LMUTE, mask, value);
+
+	/* mute headphone, internal speaker */
+	value = 0;
+	if (mute)
+		value = BIT(2) | BIT(1);
+	mask = BIT(2) | BIT(1);
+	snd_soc_update_bits(codec, UPD9976_RMUTE, mask, value);
+
+	/* mute audio DAC */
+	value = 0;
+	if (mute)
+		value = BIT(7);
+	mask = BIT(7);
+	snd_soc_update_bits(codec, UPD9976_AUDIOLVOL, mask, value);
+	snd_soc_update_bits(codec, UPD9976_AUDIORVOL, mask, value);
+
+	return 0;
+}
+
+static int upd9976_audio_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	unsigned int mode, mask;
+
+	mask = BIT(5) | BIT(4);
+	mode = 0;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		mode |= BIT(4);
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		mode |= BIT(5);
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		mode |= BIT(5) | BIT(4);
+		break;
+	}
+
+	mask |= BIT(7) | BIT(3);
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+	case SND_SOC_DAIFMT_CBM_CFS:
+		mode |= BIT(7) | BIT(3);
+		break;
+	}
+
+	return snd_soc_update_bits(codec, UPD9976_AUDIOPORT1, mask, mode);
+}
+
+static int upd9976_audio_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params,
+				   struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	unsigned int rates[] = { 8000, 11025, 12000, 16000, 22050,
+				 24000, 32000, 0, 44100, 48000 };
+	unsigned int rate;
+	unsigned int tmp;
+	int i;
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		tmp = 0x00;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		tmp = 0x03;
+		break;
+	case SNDRV_PCM_FORMAT_S18_3LE:
+		tmp = 0x01;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		tmp = 0x02;
+		break;
+	default:
+		return -EINVAL;
+	}
+	snd_soc_update_bits(codec, UPD9976_AUDIOPORT1,
+			    BIT(2)|BIT(1)|BIT(0), tmp);
+
+	rate = params_rate(params);
+	if (!rate)
+		return -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(rates); i++) {
+		if (rates[i] == rate) {
+			tmp = i;
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(rates))
+		return -EINVAL;
+
+	snd_soc_update_bits(codec, UPD9976_AUDIOPORT2,
+			    BIT(3)|BIT(2)|BIT(1)|BIT(0), tmp);
+
+	return 0;
+}
+
+static int upd9976_audio_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	if (tristate)
+		snd_soc_update_bits(codec, UPD9976_AUDIOPORT1,
+				    BIT(4)|BIT(5), 0);
+	return 0;
+}
+
+static struct snd_soc_dai_ops upd9976_audio_dai_ops = {
+	.digital_mute	= upd9976_audio_digital_mute,
+	.set_fmt	= upd9976_audio_set_dai_fmt,
+	.set_tristate	= upd9976_audio_set_tristate,
+	.hw_params	= upd9976_audio_hw_params,
+};
+
+static struct snd_soc_dai_driver upd9976_dais[] = {
+{
+	.name = "upd9976-audio",
+	.playback = {
+		.stream_name = "Audio Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = (SNDRV_PCM_RATE_48000 |
+			  SNDRV_PCM_RATE_44100 |
+			  SNDRV_PCM_RATE_8000),
+		.formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
+			    SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
+			    SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
+	},
+	.ops = &upd9976_audio_dai_ops,
+},
+};
+
+static int upd9976_set_bias_level(struct snd_soc_codec *codec,
+				  enum snd_soc_bias_level level)
+{
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		break;
+
+	case SND_SOC_BIAS_PREPARE:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
+			snd_soc_update_bits(codec, UPD9976_VAUDIOCNT,
+					    0x27, 0x27);
+			snd_soc_update_bits(codec, UPD9976_VREFPLL,
+					    0x35, 0x35);
+		}
+		break;
+
+	case SND_SOC_BIAS_STANDBY:
+		snd_soc_write(codec, UPD9976_VAUDIOCNT, 0x25);
+		snd_soc_write(codec, UPD9976_VREFPLL, 0x10);
+		break;
+
+	case SND_SOC_BIAS_OFF:
+		snd_soc_write(codec, UPD9976_VREFPLL, 0);
+		snd_soc_write(codec, UPD9976_VAUDIOCNT, 0x24);
+		break;
+	}
+
+	codec->dapm.bias_level = level;
+	return 0;
+}
+
+static int upd9976_codec_probe(struct snd_soc_codec *codec)
+{
+	upd9976_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+	return 0;
+}
+
+static int upd9976_codec_remove(struct snd_soc_codec *codec)
+{
+	upd9976_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+	return 0;
+}
+
+static struct snd_soc_codec_driver upd9976_codec = {
+	.probe			= upd9976_codec_probe,
+	.remove			= upd9976_codec_remove,
+	.read			= upd9976_read,
+	.write			= upd9976_write,
+	.set_bias_level		= upd9976_set_bias_level,
+
+	.controls		= upd9976_snd_controls,
+	.num_controls		= ARRAY_SIZE(upd9976_snd_controls),
+	.dapm_widgets		= upd9976_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(upd9976_dapm_widgets),
+	.dapm_routes		= upd9976_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(upd9976_dapm_routes),
+};
+
+static int __devinit upd9976_device_probe(struct platform_device *pdev)
+{
+	return snd_soc_register_codec(&pdev->dev, &upd9976_codec,
+				      upd9976_dais, ARRAY_SIZE(upd9976_dais));
+}
+
+static int __devexit upd9976_device_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver upd9976_codec_driver = {
+	.driver	= {
+		.name	= "upd9976",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= upd9976_device_probe,
+	.remove	= __devexit_p(upd9976_device_remove),
+};
+
+static int __init upd9976_init(void)
+{
+	return platform_driver_register(&upd9976_codec_driver);
+}
+module_init(upd9976_init);
+
+static void __exit upd9976_exit(void)
+{
+	platform_driver_unregister(&upd9976_codec_driver);
+}
+module_exit(upd9976_exit);
+
+MODULE_DESCRIPTION("ASoC Renesas uPD9976 codec driver");
+MODULE_AUTHOR("Lu Guanqun <guanqun.lu@intel.com>");
+MODULE_AUTHOR("Wang Xingchao <xingchao.wang@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:upd9976");
diff --git a/sound/soc/codecs/upd9976.h b/sound/soc/codecs/upd9976.h
new file mode 100644
index 0000000..ab2ea15
--- /dev/null
+++ b/sound/soc/codecs/upd9976.h
@@ -0,0 +1,83 @@
+/*
+ *  upd9976.h -  Renesas uPD9976 codec driver
+ *
+ *  Copyright (C) 2011 Intel Corporation
+ *
+ *  Maintainer:
+ *              Lu Guanqun <guanqun.lu@intel.com>
+ *              Wang Xingchao <xingchao.wang@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#ifndef _UPD9976_H
+#define _UPD9976_H
+
+#define UPD9976_VAUDIOCNT       0x51
+
+#define UPD9976_VOICEPORT1	0x100
+#define UPD9976_VOICEPORT2	0x101
+#define UPD9976_AUDIOPORT1	0x102
+#define UPD9976_AUDIOPORT2	0x103
+#define UPD9976_ADCSAMPLERATE	0x104
+#define UPD9976_DMICCTRL1	0x105
+#define UPD9976_DMICCTRL2	0x106
+#define UPD9976_MICCTRL		0x107
+#define UPD9976_MICSELVOL	0x108
+#define UPD9976_LILSEL		0x109
+#define UPD9976_LIRSEL		0x10a
+#define UPD9976_VOICEVOL	0x10b
+#define UPD9976_AUDIOLVOL	0x10c
+#define UPD9976_AUDIORVOL	0x10d
+#define UPD9976_LMUTE		0x10e
+#define UPD9976_RMUTE		0x10f
+#define UPD9976_POWERCTRL1	0x110
+#define UPD9976_POWERCTRL2	0x111
+#define UPD9976_DRVPOWERCTRL	0x112
+#define UPD9976_VREFPLL		0x113
+#define UPD9976_PCMBUFCTRL	0x114
+#define UPD9976_SOFTMUTE	0x115
+#define UPD9976_DTMFPATH	0x116
+#define UPD9976_DTMFVOL		0x117
+#define UPD9976_DTMFFREQ	0x118
+#define UPD9976_DTMFHFREQ	0x119
+#define UPD9976_DTMFLFREQ	0x11a
+#define UPD9976_DTMFCTRL	0x11b
+#define UPD9976_DTMFASON	0x11c
+#define UPD9976_DTMFASOFF	0x11d
+#define UPD9976_DTMFASINUM	0x11e
+#define UPD9976_CLASSDVOL	0x11f
+#define UPD9976_VOICEDACAVOL	0x120
+#define UPD9976_AUDDACAVOL	0x121
+#define UPD9976_LOMUTEVOL	0x122
+#define UPD9976_HPSPRLVOL	0x123
+#define UPD9976_HPSPRRVOL	0x124
+#define UPD9976_MONOVOL		0x125
+#define UPD9976_LINEOUTMIXVOL	0x126
+#define UPD9976_EPMIXVOL	0x127
+#define UPD9976_LINEOUTLSEL	0x128
+#define UPD9976_LINEOUTRSEL	0x129
+#define UPD9976_EPMIXOUTSEL	0x12a
+#define UPD9976_HPLMIXSEL	0x12b
+#define UPD9976_HPRMIXSEL	0x12c
+#define UPD9976_LOANTIPOP	0x12d
+#define UPD9976_AUXDBNC		0x12f
+
+#define UPD9976_SAUXINT		0x132
+
+#endif

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

* [PATCH v2 02/10] ASoC: sst_platform: modify current cpu dai driver to suit the needs for moorestown platform
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 03/10] ASoC: mrst_machine: add moorestown machine driver Lu Guanqun
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

From: Wang Xingchao <xingchao.wang@intel.com>

Signed-off-by: Wang Xingchao <xingchao.wang@intel.com>
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
Acked-by: Koul Vinod <vinod.koul@intel.com>
---
 sound/soc/mid-x86/sst_platform.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index 139db15..afa5eab 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -68,16 +68,21 @@ struct snd_soc_dai_driver sst_platform_dai[] = {
 	.name = "Headset-cpu-dai",
 	.id = 0,
 	.playback = {
-		.channels_min = SST_STEREO,
+		.channels_min = SST_MONO,
 		.channels_max = SST_STEREO,
-		.rates = SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S24_LE,
+		.rates = (SNDRV_PCM_RATE_48000 |
+			  SNDRV_PCM_RATE_44100 |
+			  SNDRV_PCM_RATE_8000),
+		.formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
+			    SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
+			    SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
 	},
 	.capture = {
 		.channels_min = 1,
 		.channels_max = 5,
 		.rates = SNDRV_PCM_RATE_48000,
-		.formats = SNDRV_PCM_FMTBIT_S24_LE,
+		.formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
+			    SNDRV_PCM_FMTBIT_S24_LE),
 	},
 },
 {

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

* [PATCH v2 03/10] ASoC: mrst_machine: add moorestown machine driver
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 02/10] ASoC: sst_platform: modify current cpu dai driver to suit the needs for moorestown platform Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 04/10] ASoC: upd9976: add capture ability for dai driver Lu Guanqun
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

This machine driver glues upd9976 codec driver and sst_platform driver.

Playback via headphone and internal speaker is supported.  To note: This
internal speaker needs an extra GPIO to control its power. And these two output
devices can be enabled and disabled independently.

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
Signed-off-by: Wang Xingchao <xingchao.wang@intel.com>
---
 sound/soc/mid-x86/Kconfig        |   12 ++
 sound/soc/mid-x86/Makefile       |    2 
 sound/soc/mid-x86/mrst_machine.c |  194 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/mid-x86/mrst_machine.c

diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig
index 2935042..f76acba 100644
--- a/sound/soc/mid-x86/Kconfig
+++ b/sound/soc/mid-x86/Kconfig
@@ -10,5 +10,17 @@ config SND_MFLD_MACHINE
           Say Y if you have such a device
           If unsure select "N".
 
+config SND_MRST_MACHINE
+	tristate "SoC Machine Audio Driver for Intel Moorestown Platform"
+	depends on INTEL_SCU_IPC
+	depends on SND_INTEL_SST
+	select SND_SOC_UPD9976
+	select SND_SST_PLATFORM
+	help
+	  This adds support for ASoC machine driver for Intel(R) MID Moorestown platform.
+	  It is used as ALSA device in audio substream in Intel(R) MID devices.
+	  Say Y if you have such a device.
+	  If unsure, select 'N'.
+
 config SND_SST_PLATFORM
 	tristate
diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/mid-x86/Makefile
index 6398833..d0f2c29 100644
--- a/sound/soc/mid-x86/Makefile
+++ b/sound/soc/mid-x86/Makefile
@@ -1,5 +1,7 @@
 snd-soc-sst-platform-objs := sst_platform.o
 snd-soc-mfld-machine-objs := mfld_machine.o
+snd-soc-mrst-machine-objs := mrst_machine.o
 
 obj-$(CONFIG_SND_SST_PLATFORM) += snd-soc-sst-platform.o
 obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
+obj-$(CONFIG_SND_MRST_MACHINE) += snd-soc-mrst-machine.o
diff --git a/sound/soc/mid-x86/mrst_machine.c b/sound/soc/mid-x86/mrst_machine.c
new file mode 100644
index 0000000..10e4d40
--- /dev/null
+++ b/sound/soc/mid-x86/mrst_machine.c
@@ -0,0 +1,194 @@
+/*
+ *  mrst_machine.c - ASoC Machine driver for Intel Moorestown MID platform
+ *
+ *  Copyright (C) 2011 Intel Corporation
+ *
+ *  Maintainer:
+ *              Lu Guanqun <guanqun.lu@intel.com>
+ *              Wang Xingchao <xingchao.wang@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+static const struct snd_kcontrol_new mrst_snd_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Headphone"),
+	SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+/*
+ * GPIO pin to power on/off Internal Speaker
+ */
+static int mrst_gpio_amp;
+
+static int mrst_speaker_event(struct snd_soc_dapm_widget *widget,
+			      struct snd_kcontrol *control, int event)
+{
+	if (mrst_gpio_amp)
+		gpio_set_value_cansleep(mrst_gpio_amp,
+					SND_SOC_DAPM_EVENT_ON(event));
+
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget mrst_audio_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_SPK("Speaker", mrst_speaker_event),
+};
+
+static const struct snd_soc_dapm_route mrst_audio_map[] = {
+	{"HPINL", NULL, "PREOUTL"},
+	{"HPINR", NULL, "PREOUTR"},
+
+	{"Headphone", NULL, "HPOUTL"},
+	{"Headphone", NULL, "HPOUTR"},
+
+	{"Speaker", NULL, "PREOUTL"},
+	{"Speaker", NULL, "PREOUTR"},
+};
+
+static int mrst_audio_init(struct snd_soc_pcm_runtime *runtime)
+{
+	struct snd_soc_codec *codec = runtime->codec;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+	snd_soc_dapm_nc_pin(dapm, "LINEINL");
+	snd_soc_dapm_nc_pin(dapm, "LINEINR");
+	snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
+	snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
+
+	snd_soc_dapm_disable_pin(dapm, "Headphone");
+	snd_soc_dapm_enable_pin(dapm, "Speaker");
+
+	snd_soc_dapm_sync(dapm);
+
+	return 0;
+}
+
+static int mrst_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->codec_dai;
+	int ret;
+
+	ret = snd_soc_dai_set_fmt(codec_dai,
+				  SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM);
+
+	return ret;
+}
+
+static struct snd_soc_ops mrst_audio_ops = {
+	.hw_params = mrst_hw_params,
+};
+
+struct snd_soc_dai_link mrst_dailinks[] = {
+	{
+		.name = "Moorestown Audio",
+		.stream_name = "Audio",
+		.cpu_dai_name = "Headset-cpu-dai",
+		.codec_dai_name = "upd9976-audio",
+		.codec_name = "upd9976",
+		.platform_name = "sst-platform",
+		.init = mrst_audio_init,
+		.ops = &mrst_audio_ops,
+	},
+};
+
+static struct snd_soc_card snd_soc_card_mrst = {
+	.name = "moorestown_audio",
+
+	.dai_link = mrst_dailinks,
+	.num_links = ARRAY_SIZE(mrst_dailinks),
+
+	.controls = mrst_snd_controls,
+	.num_controls = ARRAY_SIZE(mrst_snd_controls),
+	.dapm_widgets = mrst_audio_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(mrst_audio_widgets),
+	.dapm_routes = mrst_audio_map,
+	.num_dapm_routes = ARRAY_SIZE(mrst_audio_map),
+};
+
+static int __devinit snd_mrst_audio_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	if (pdev->dev.platform_data) {
+		mrst_gpio_amp = *(int *)pdev->dev.platform_data;
+		if (gpio_request_one(mrst_gpio_amp,
+				     GPIOF_OUT_INIT_LOW, "amp power"))
+			mrst_gpio_amp = 0;
+	}
+
+	snd_soc_card_mrst.dev = &pdev->dev;
+	ret = snd_soc_register_card(&snd_soc_card_mrst);
+	if (ret)
+		goto fail_register_card;
+
+	return 0;
+
+fail_register_card:
+	if (mrst_gpio_amp)
+		gpio_free(mrst_gpio_amp);
+	return ret;
+}
+
+static int __devexit snd_mrst_audio_remove(struct platform_device *pdev)
+{
+	if (mrst_gpio_amp)
+		gpio_free(mrst_gpio_amp);
+	snd_soc_unregister_card(&snd_soc_card_mrst);
+	return 0;
+}
+
+static struct platform_driver snd_mrst_audio_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "pmic_audio",
+	},
+	.probe = snd_mrst_audio_probe,
+	.remove = __devexit_p(snd_mrst_audio_remove),
+};
+
+static int __init snd_mrst_driver_init(void)
+{
+	return platform_driver_register(&snd_mrst_audio_driver);
+}
+module_init(snd_mrst_driver_init);
+
+static void __exit snd_mrst_driver_exit(void)
+{
+	platform_driver_unregister(&snd_mrst_audio_driver);
+}
+module_exit(snd_mrst_driver_exit);
+
+MODULE_DESCRIPTION("ASoC Intel(R) MID Moorestown Machine Driver");
+MODULE_AUTHOR("Lu Guanqun <guanqun.lu@intel.com>");
+MODULE_AUTHOR("Wang Xingchao <xingchao.wang@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:mrst-audio");

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

* [PATCH v2 04/10] ASoC: upd9976: add capture ability for dai driver
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (2 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 03/10] ASoC: mrst_machine: add moorestown machine driver Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 05/10] ASoC: upd9976: add DMIC support Lu Guanqun
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

From: Wang Xingchao <xingchao.wang@intel.com>

Signed-off-by: Wang Xingchao <xingchao.wang@intel.com>
---
 sound/soc/codecs/upd9976.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/upd9976.c b/sound/soc/codecs/upd9976.c
index 7be10ae..5b8d047 100644
--- a/sound/soc/codecs/upd9976.c
+++ b/sound/soc/codecs/upd9976.c
@@ -303,6 +303,13 @@ static struct snd_soc_dai_driver upd9976_dais[] = {
 			    SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
 			    SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
 	},
+	.capture = {
+		.stream_name = "Audio Capture",
+		.channels_min = 1,
+		.channels_max = 1,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16),
+	},
 	.ops = &upd9976_audio_dai_ops,
 },
 };

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

* [PATCH v2 05/10] ASoC: upd9976: add DMIC support
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (3 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 04/10] ASoC: upd9976: add capture ability for dai driver Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06 11:07   ` Mark Brown
  2011-05-06  5:46 ` [PATCH v2 06/10] ASoC: upd9976: add Analog MIC support Lu Guanqun
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
---
 sound/soc/codecs/upd9976.c |   76 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/upd9976.c b/sound/soc/codecs/upd9976.c
index 5b8d047..a668b47 100644
--- a/sound/soc/codecs/upd9976.c
+++ b/sound/soc/codecs/upd9976.c
@@ -71,6 +71,12 @@ static DECLARE_TLV_DB_SCALE(mixer_tlv, -2500, 100, 0);
  * Audio DAC Volume: From -84 dB to 10.5 dB in 0.75 steps.
  */
 static DECLARE_TLV_DB_SCALE(adac_tlv, -8400, 75, 0);
+
+/*
+ * DMIC Volume: from -63 dB to 1 dB in 1 db steps.
+ */
+static DECLARE_TLV_DB_SCALE(dmic_tlv, -6300, 100, 1);
+
 static const struct snd_kcontrol_new upd9976_snd_controls[] = {
 	SOC_DOUBLE_R_TLV("Master Volume",
 			 UPD9976_AUDIOLVOL, UPD9976_AUDIORVOL,
@@ -78,6 +84,9 @@ static const struct snd_kcontrol_new upd9976_snd_controls[] = {
 	SOC_DOUBLE_R_TLV("PCM Volume",
 			 UPD9976_HPSPRLVOL, UPD9976_HPSPRRVOL,
 			 0, 0x1f, 1, mixer_tlv),
+	SOC_SINGLE("Internal Mic Switch", UPD9976_DMICCTRL1, 6, 1, 0),
+	SOC_SINGLE_TLV("Internal Mic Capture Volume",
+		       UPD9976_DMICCTRL1, 0, 0x3f, 1, dmic_tlv),
 };
 
 static const struct snd_kcontrol_new upd9976_hp_spkr_mixer_left_controls[] = {
@@ -90,6 +99,29 @@ static const struct snd_kcontrol_new upd9976_hp_spkr_mixer_right_controls[] = {
 	SOC_DAPM_SINGLE("Audio DAC Right Switch", UPD9976_HPRMIXSEL, 3, 1, 1),
 };
 
+/* PCM2 Left Mux */
+static const char *upd9976_pcm2_left_mux_texts[] = {"AADC Left", "DMIC"};
+static const struct soc_enum upd9976_pcm2_left_mux_enum =
+	SOC_ENUM_SINGLE(UPD9976_ADCSAMPLERATE, 5, 2,
+			upd9976_pcm2_left_mux_texts);
+static const struct snd_kcontrol_new upd9976_pcm2_left_mux_control =
+	SOC_DAPM_ENUM("PCM2 Left Mux", upd9976_pcm2_left_mux_enum);
+
+/* PCM2 Right Mux */
+static const char *upd9976_pcm2_right_mux_texts[] = {"AADC Right", "DMIC"};
+static const struct soc_enum upd9976_pcm2_right_mux_enum =
+	SOC_ENUM_SINGLE(UPD9976_ADCSAMPLERATE, 4, 2,
+			upd9976_pcm2_right_mux_texts);
+static const struct snd_kcontrol_new upd9976_pcm2_right_mux_control =
+	SOC_DAPM_ENUM("PCM2 Right Mux", upd9976_pcm2_right_mux_enum);
+
+/* PCM2 Mux */
+static const char *upd9976_pcm2_mux_texts[] = {"No Mix", "Mix"};
+static const struct soc_enum upd9976_pcm2_mux_enum =
+	SOC_ENUM_SINGLE(UPD9976_ADCSAMPLERATE, 3, 2, upd9976_pcm2_mux_texts);
+static const struct snd_kcontrol_new upd9976_pcm2_mux_control =
+	SOC_DAPM_ENUM("PCM2 Mux", upd9976_pcm2_mux_enum);
+
 static const struct snd_soc_dapm_widget upd9976_dapm_widgets[] = {
 	/* Input */
 	SND_SOC_DAPM_INPUT("LINEINL"),
@@ -130,12 +162,34 @@ static const struct snd_soc_dapm_widget upd9976_dapm_widgets[] = {
 	SND_SOC_DAPM_MICBIAS("MIC1 Bias", UPD9976_MICCTRL, 6, 0),
 	SND_SOC_DAPM_MICBIAS("MIC2 Bias", UPD9976_MICCTRL, 4, 0),
 
+	SND_SOC_DAPM_MIXER("PCM2 In Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("PCM2 In No Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	/* Mux */
+	SND_SOC_DAPM_MUX("PCM2 Left Mux", SND_SOC_NOPM, 0, 0,
+			 &upd9976_pcm2_left_mux_control),
+	SND_SOC_DAPM_MUX("PCM2 Right Mux", SND_SOC_NOPM, 0, 0,
+			 &upd9976_pcm2_right_mux_control),
+	SND_SOC_DAPM_MUX("PCM2 Mux", SND_SOC_NOPM, 0, 0,
+			 &upd9976_pcm2_mux_control),
+
 	/* PGA */
 	SND_SOC_DAPM_PGA("HP Playback Left PGA", UPD9976_DRVPOWERCTRL,
 			 2, 0, NULL, 0),
 	SND_SOC_DAPM_PGA("HP Playback Right PGA", UPD9976_DRVPOWERCTRL,
 			 1, 0, NULL, 0),
 
+	SND_SOC_DAPM_PGA("AADC Left PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("AADC Right PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_PGA("DMIC Gain PGA", UPD9976_DMICCTRL1, 7, 0, NULL, 0),
+
+	/* Audio Interface */
+	SND_SOC_DAPM_AIF_OUT("PCM2 Out", "Audio Capture", 0, SND_SOC_NOPM, 0,
+			     0),
+
+	/* Supply */
+	SND_SOC_DAPM_SUPPLY("DMIC Supply", UPD9976_POWERCTRL2, 1, 0, NULL, 0),
 };
 
 static const struct snd_soc_dapm_route upd9976_dapm_routes[] = {
@@ -154,6 +208,28 @@ static const struct snd_soc_dapm_route upd9976_dapm_routes[] = {
 	{"HPOUTL", NULL, "HP Playback Left PGA"},
 	{"HPOUTR", NULL, "HP Playback Right PGA"},
 
+	{"DMICDAT", NULL, "DMIC Supply"},
+	{"DMIC Gain PGA", NULL, "DMICDAT"},
+
+	{"AADC Left PGA", NULL, "AADC"},
+	{"AADC Right PGA", NULL, "AADC"},
+
+	{"PCM2 Left Mux", "DMIC", "DMIC Gain PGA"},
+	{"PCM2 Left Mux", "AADC Left", "AADC Left PGA"},
+
+	{"PCM2 Right Mux", "DMIC", "DMIC Gain PGA"},
+	{"PCM2 Right Mux", "AADC Right", "AADC Right PGA"},
+
+	{"PCM2 In Mixer", NULL, "PCM2 Left Mux"},
+	{"PCM2 In No Mixer", NULL, "PCM2 Left Mux"},
+
+	{"PCM2 In Mixer", NULL, "PCM2 Right Mux"},
+	{"PCM2 In No Mixer", NULL, "PCM2 Right Mux"},
+
+	{"PCM2 Mux", "Mix", "PCM2 In Mixer"},
+	{"PCM2 Mux", "No Mix", "PCM2 In No Mixer"},
+
+	{"PCM2 Out", NULL, "PCM2 Mux"},
 };
 
 static int upd9976_audio_digital_mute(struct snd_soc_dai *dai, int mute)

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

* [PATCH v2 06/10] ASoC: upd9976: add Analog MIC support
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (4 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 05/10] ASoC: upd9976: add DMIC support Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 07/10] ASoC: upd9976: add jack detection function Lu Guanqun
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
---
 sound/soc/codecs/upd9976.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/upd9976.c b/sound/soc/codecs/upd9976.c
index a668b47..cbcfbb2 100644
--- a/sound/soc/codecs/upd9976.c
+++ b/sound/soc/codecs/upd9976.c
@@ -77,6 +77,11 @@ static DECLARE_TLV_DB_SCALE(adac_tlv, -8400, 75, 0);
  */
 static DECLARE_TLV_DB_SCALE(dmic_tlv, -6300, 100, 1);
 
+/*
+ * Analog Volume: from -25 dB to 6 dB in 1 dB steps.
+ */
+static DECLARE_TLV_DB_SCALE(analog_tlv, -2500, 100, 0);
+
 static const struct snd_kcontrol_new upd9976_snd_controls[] = {
 	SOC_DOUBLE_R_TLV("Master Volume",
 			 UPD9976_AUDIOLVOL, UPD9976_AUDIORVOL,
@@ -87,6 +92,11 @@ static const struct snd_kcontrol_new upd9976_snd_controls[] = {
 	SOC_SINGLE("Internal Mic Switch", UPD9976_DMICCTRL1, 6, 1, 0),
 	SOC_SINGLE_TLV("Internal Mic Capture Volume",
 		       UPD9976_DMICCTRL1, 0, 0x3f, 1, dmic_tlv),
+	SOC_DOUBLE_R("Analog Mic Switch", UPD9976_LILSEL, UPD9976_LIRSEL,
+		     6, 1, 0),
+	SOC_DOUBLE_R_TLV("Analog Capture Volume",
+			 UPD9976_LILSEL, UPD9976_LILSEL,
+			 0, 0x1f, 1, analog_tlv),
 };
 
 static const struct snd_kcontrol_new upd9976_hp_spkr_mixer_left_controls[] = {
@@ -99,6 +109,13 @@ static const struct snd_kcontrol_new upd9976_hp_spkr_mixer_right_controls[] = {
 	SOC_DAPM_SINGLE("Audio DAC Right Switch", UPD9976_HPRMIXSEL, 3, 1, 1),
 };
 
+/* Analog Right Mux */
+static const char *upd9976_analog_mux_texts[] = {"MIC", "LineIn"};
+static const struct soc_enum upd9976_ar_mux_enum =
+	SOC_ENUM_SINGLE(UPD9976_LIRSEL, 7, 2, upd9976_analog_mux_texts);
+static const struct snd_kcontrol_new upd9976_ar_mux_control =
+	SOC_DAPM_ENUM("Route", upd9976_ar_mux_enum);
+
 /* PCM2 Left Mux */
 static const char *upd9976_pcm2_left_mux_texts[] = {"AADC Left", "DMIC"};
 static const struct soc_enum upd9976_pcm2_left_mux_enum =
@@ -166,6 +183,9 @@ static const struct snd_soc_dapm_widget upd9976_dapm_widgets[] = {
 	SND_SOC_DAPM_MIXER("PCM2 In No Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 
 	/* Mux */
+	SND_SOC_DAPM_MUX("Analog Right Mux", UPD9976_POWERCTRL1, 4, 0,
+			 &upd9976_ar_mux_control),
+
 	SND_SOC_DAPM_MUX("PCM2 Left Mux", SND_SOC_NOPM, 0, 0,
 			 &upd9976_pcm2_left_mux_control),
 	SND_SOC_DAPM_MUX("PCM2 Right Mux", SND_SOC_NOPM, 0, 0,
@@ -184,6 +204,8 @@ static const struct snd_soc_dapm_widget upd9976_dapm_widgets[] = {
 
 	SND_SOC_DAPM_PGA("DMIC Gain PGA", UPD9976_DMICCTRL1, 7, 0, NULL, 0),
 
+	SND_SOC_DAPM_PGA("MIC2 In PGA", UPD9976_POWERCTRL1, 2, 0, NULL, 0),
+
 	/* Audio Interface */
 	SND_SOC_DAPM_AIF_OUT("PCM2 Out", "Audio Capture", 0, SND_SOC_NOPM, 0,
 			     0),
@@ -208,6 +230,13 @@ static const struct snd_soc_dapm_route upd9976_dapm_routes[] = {
 	{"HPOUTL", NULL, "HP Playback Left PGA"},
 	{"HPOUTR", NULL, "HP Playback Right PGA"},
 
+	{"MIC2 In PGA", NULL, "MIC2"},
+
+	{"Analog Right Mux", "MIC", "MIC2 In PGA"},
+	{"Analog Right Mux", "LineIn", "LINEINR"},
+
+	{"AADC", NULL, "Analog Right Mux"},
+
 	{"DMICDAT", NULL, "DMIC Supply"},
 	{"DMIC Gain PGA", NULL, "DMICDAT"},
 

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

* [PATCH v2 07/10] ASoC: upd9976: add jack detection function
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (5 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 06/10] ASoC: upd9976: add Analog MIC support Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06 12:53   ` Mark Brown
  2011-05-06  5:46 ` [PATCH v2 08/10] ASoC: mrst_machine: add capture functionality Lu Guanqun
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

All the interrupt handling is done here in codec driver.

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
---
 sound/soc/codecs/upd9976.c |  182 ++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/upd9976.h |    4 +
 2 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/upd9976.c b/sound/soc/codecs/upd9976.c
index 4a790c5..c1b08f9 100644
--- a/sound/soc/codecs/upd9976.c
+++ b/sound/soc/codecs/upd9976.c
@@ -27,6 +27,8 @@
  */
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/list.h>
 #include <asm/intel_scu_ipc.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -37,6 +39,97 @@
 #include <sound/jack.h>
 #include "upd9976.h"
 
+struct upd9976_priv {
+	int irq;
+	struct resource *irq_mem;
+	void __iomem *int_base;
+	struct snd_soc_jack *jack;
+	int jack_init;
+	struct list_head pending_status;
+	spinlock_t lock;
+};
+
+struct upd9976_jack_node {
+	struct list_head list;
+	u8 interrupt_status;
+};
+
+static irqreturn_t upd9976_jack_intr_handler(int irq, void *dev)
+{
+	struct upd9976_priv *upd9976 = dev;
+	u8 interrupt_status;
+	struct upd9976_jack_node *node;
+	unsigned long flags;
+
+	memcpy_fromio(&interrupt_status,
+		      upd9976->int_base,
+		      sizeof(u8));
+
+	/* check if it's valid */
+	if (!(interrupt_status & 0xf))
+		return IRQ_NONE;
+
+	node = kzalloc(sizeof(*node), GFP_ATOMIC);
+	if (!node)
+		return IRQ_NONE;
+
+	INIT_LIST_HEAD(&node->list);
+	node->interrupt_status = interrupt_status;
+
+	spin_lock_irqsave(&upd9976->lock, flags);
+	list_add_tail(&node->list, &upd9976->pending_status);
+	spin_unlock_irqrestore(&upd9976->lock, flags);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t upd9976_jack_thread_handler(int irq, void *data)
+{
+	struct upd9976_priv *upd9976 = data;
+	struct snd_soc_jack *jack = upd9976->jack;
+	struct snd_soc_codec *codec = jack->codec;
+	struct upd9976_jack_node *node;
+	u8 interrupt_status;
+	unsigned long flags;
+	int status = 0;
+	unsigned int value = 0;
+	int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
+
+	spin_lock_irqsave(&upd9976->lock, flags);
+	if (list_empty(&upd9976->pending_status)) {
+		spin_unlock_irqrestore(&upd9976->lock, flags);
+		return IRQ_HANDLED;
+	}
+	node = list_first_entry(&upd9976->pending_status,
+				struct upd9976_jack_node,
+				list);
+	interrupt_status = node->interrupt_status;
+	list_del(&node->list);
+	kfree(node);
+	spin_unlock_irqrestore(&upd9976->lock, flags);
+
+	if (interrupt_status & 0x3)
+		value = snd_soc_read(codec, UPD9976_SAUXINT);
+
+	if (interrupt_status & 0x1 && value == 0x1)
+		status |= SND_JACK_HEADSET;
+
+	if (interrupt_status & 0x2 && value == 0x2)
+		status |= SND_JACK_HEADPHONE;
+
+	if (interrupt_status & 0x4)
+		status |= SND_JACK_HEADSET | SND_JACK_BTN_0;
+
+	if (interrupt_status & 0x8)
+		status |= SND_JACK_HEADSET | SND_JACK_BTN_1;
+
+	snd_soc_jack_report(jack, status, mask);
+	if (status & (SND_JACK_BTN_0 | SND_JACK_BTN_1))
+		snd_soc_jack_report(jack, SND_JACK_HEADSET, mask);
+
+	return IRQ_HANDLED;
+}
+
 static inline unsigned int upd9976_read(struct snd_soc_codec *codec,
 					unsigned int reg)
 {
@@ -62,6 +155,24 @@ static inline int upd9976_write(struct snd_soc_codec *codec,
 	return ret;
 }
 
+int upd9976_jack_detect(struct snd_soc_codec *codec,
+			struct snd_soc_jack *jack,
+			unsigned int debounce)
+{
+	struct upd9976_priv *upd9976 = snd_soc_codec_get_drvdata(codec);
+
+	if (!upd9976->jack_init)
+		return -ENODEV;
+
+	upd9976->jack = jack;
+
+	/* set debounce time */
+	snd_soc_write(codec, UPD9976_AUXDBNC, debounce);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(upd9976_jack_detect);
+
 /*
  * Mixing Volume: from -25 dB to 6 dB in 1 dB steps.
  */
@@ -452,13 +563,50 @@ static int upd9976_set_bias_level(struct snd_soc_codec *codec,
 
 static int upd9976_codec_probe(struct snd_soc_codec *codec)
 {
+	struct upd9976_priv *upd9976 = snd_soc_codec_get_drvdata(codec);
+
 	upd9976_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
+	/* disable jack detection first, will be enabled later */
+	snd_soc_update_bits(codec, UPD9976_MICCTRL, BIT(4), 0);
+
+	spin_lock_init(&upd9976->lock);
+	INIT_LIST_HEAD(&upd9976->pending_status);
+
+	upd9976->jack_init = 0;
+
+	if (upd9976->irq < 0 || !upd9976->irq_mem)
+		return 0;
+
+	upd9976->int_base = ioremap_nocache(upd9976->irq_mem->start,
+					    resource_size(upd9976->irq_mem));
+	if (!upd9976->int_base)
+		return 0;
+
+	if (request_threaded_irq(upd9976->irq,
+				 upd9976_jack_intr_handler,
+				 upd9976_jack_thread_handler,
+				 IRQF_SHARED,
+				 "jack detection",
+				 upd9976)) {
+		iounmap(upd9976->int_base);
+		return 0;
+	}
+
+	upd9976->jack_init = 1;
+
 	return 0;
 }
 
 static int upd9976_codec_remove(struct snd_soc_codec *codec)
 {
+	struct upd9976_priv *upd9976 = snd_soc_codec_get_drvdata(codec);
+
+	if (upd9976->jack_init) {
+		free_irq(upd9976->irq, upd9976);
+		iounmap(upd9976->int_base);
+	}
+
 	upd9976_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
 	return 0;
@@ -481,13 +629,43 @@ static struct snd_soc_codec_driver upd9976_codec = {
 
 static int __devinit upd9976_device_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_codec(&pdev->dev, &upd9976_codec,
-				      upd9976_dais, ARRAY_SIZE(upd9976_dais));
+	struct upd9976_priv *upd9976;
+	int err;
+
+	upd9976 = kzalloc(sizeof(*upd9976), GFP_KERNEL);
+	if (!upd9976) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	upd9976->irq = platform_get_irq(pdev, 0);
+	upd9976->irq_mem = platform_get_resource_byname(pdev,
+							IORESOURCE_MEM,
+							"IRQ_BASE");
+	platform_set_drvdata(pdev, upd9976);
+
+	err = snd_soc_register_codec(&pdev->dev, &upd9976_codec,
+				     upd9976_dais, ARRAY_SIZE(upd9976_dais));
+	if (err)
+		goto fail_register_codec;
+
+	return 0;
+
+fail_register_codec:
+	platform_set_drvdata(pdev, NULL);
+	kfree(upd9976);
+fail:
+	return err;
 }
 
 static int __devexit upd9976_device_remove(struct platform_device *pdev)
 {
+	struct upd9976_priv *upd9976 = platform_get_drvdata(pdev);
+
 	snd_soc_unregister_codec(&pdev->dev);
+	platform_set_drvdata(pdev, NULL);
+	kfree(upd9976);
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/upd9976.h b/sound/soc/codecs/upd9976.h
index ab2ea15..b1bb8d0 100644
--- a/sound/soc/codecs/upd9976.h
+++ b/sound/soc/codecs/upd9976.h
@@ -80,4 +80,8 @@
 
 #define UPD9976_SAUXINT		0x132
 
+int upd9976_jack_detect(struct snd_soc_codec *codec,
+			struct snd_soc_jack *jack,
+			unsigned int debounce);
+
 #endif

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

* [PATCH v2 08/10] ASoC: mrst_machine: add capture functionality
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (6 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 07/10] ASoC: upd9976: add jack detection function Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 09/10] ASoC: mrst_machine: add jack detection support Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 10/10] ASoC: mrst_machine: add initial config to machine driver Lu Guanqun
  9 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
---
 sound/soc/mid-x86/mrst_machine.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/sound/soc/mid-x86/mrst_machine.c b/sound/soc/mid-x86/mrst_machine.c
index 10e4d40..131deff 100644
--- a/sound/soc/mid-x86/mrst_machine.c
+++ b/sound/soc/mid-x86/mrst_machine.c
@@ -39,6 +39,9 @@
 static const struct snd_kcontrol_new mrst_snd_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Speaker"),
+
+	SOC_DAPM_PIN_SWITCH("Headset MIC"),
+	SOC_DAPM_PIN_SWITCH("Internal MIC"),
 };
 
 /*
@@ -59,6 +62,9 @@ static int mrst_speaker_event(struct snd_soc_dapm_widget *widget,
 static const struct snd_soc_dapm_widget mrst_audio_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_SPK("Speaker", mrst_speaker_event),
+
+	SND_SOC_DAPM_MIC("Headset MIC", NULL),
+	SND_SOC_DAPM_MIC("Internal MIC", NULL),
 };
 
 static const struct snd_soc_dapm_route mrst_audio_map[] = {
@@ -70,6 +76,9 @@ static const struct snd_soc_dapm_route mrst_audio_map[] = {
 
 	{"Speaker", NULL, "PREOUTL"},
 	{"Speaker", NULL, "PREOUTR"},
+
+	{"MIC2", NULL, "Headset MIC"},
+	{"DMICDAT", NULL, "Internal MIC"},
 };
 
 static int mrst_audio_init(struct snd_soc_pcm_runtime *runtime)
@@ -85,6 +94,9 @@ static int mrst_audio_init(struct snd_soc_pcm_runtime *runtime)
 	snd_soc_dapm_disable_pin(dapm, "Headphone");
 	snd_soc_dapm_enable_pin(dapm, "Speaker");
 
+	snd_soc_dapm_disable_pin(dapm, "Headset MIC");
+	snd_soc_dapm_enable_pin(dapm, "Internal MIC");
+
 	snd_soc_dapm_sync(dapm);
 
 	return 0;

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

* [PATCH v2 09/10] ASoC: mrst_machine: add jack detection support
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (7 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 08/10] ASoC: mrst_machine: add capture functionality Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06  5:46 ` [PATCH v2 10/10] ASoC: mrst_machine: add initial config to machine driver Lu Guanqun
  9 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

The jack processing logic only pulls the trigger, all the heavy work such as
interrupt handling is done in codec driver.

We need to enable MIC2 Bias to be able to get the jack interrupts.

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
---
 sound/soc/mid-x86/mrst_machine.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/sound/soc/mid-x86/mrst_machine.c b/sound/soc/mid-x86/mrst_machine.c
index 131deff..eb52a2b 100644
--- a/sound/soc/mid-x86/mrst_machine.c
+++ b/sound/soc/mid-x86/mrst_machine.c
@@ -35,6 +35,10 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/jack.h>
+#include <../codecs/upd9976.h>
+
+static struct snd_soc_jack mrst_jack;
 
 static const struct snd_kcontrol_new mrst_snd_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Headphone"),
@@ -85,6 +89,7 @@ static int mrst_audio_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_codec *codec = runtime->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	int ret;
 
 	snd_soc_dapm_nc_pin(dapm, "LINEINL");
 	snd_soc_dapm_nc_pin(dapm, "LINEINR");
@@ -99,6 +104,17 @@ static int mrst_audio_init(struct snd_soc_pcm_runtime *runtime)
 
 	snd_soc_dapm_sync(dapm);
 
+	ret = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
+			       (SND_JACK_HEADSET |
+				SND_JACK_BTN_0 |
+				SND_JACK_BTN_1),
+			       &mrst_jack);
+	if (ret)
+		return ret;
+
+	if (!upd9976_jack_detect(codec, &mrst_jack, 0xff))
+		snd_soc_dapm_force_enable_pin(dapm, "MIC2 Bias");
+
 	return 0;
 }
 

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

* [PATCH v2 10/10] ASoC: mrst_machine: add initial config to machine driver
  2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
                   ` (8 preceding siblings ...)
  2011-05-06  5:46 ` [PATCH v2 09/10] ASoC: mrst_machine: add jack detection support Lu Guanqun
@ 2011-05-06  5:46 ` Lu Guanqun
  2011-05-06 12:54   ` Mark Brown
  9 siblings, 1 reply; 18+ messages in thread
From: Lu Guanqun @ 2011-05-06  5:46 UTC (permalink / raw)
  To: ALSA, Lu Guanqun
  Cc: Takashi Iwai, Koul Vinod, Mark Brown, Liam Girdwood, Wang Xingchao

On Moorestown, DMIC's output is set to PCM2 mono.
And the Moorestown uses MIC2 pseudo-differential configuration.

Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
---
 sound/soc/mid-x86/mrst_machine.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/sound/soc/mid-x86/mrst_machine.c b/sound/soc/mid-x86/mrst_machine.c
index eb52a2b..806d18c 100644
--- a/sound/soc/mid-x86/mrst_machine.c
+++ b/sound/soc/mid-x86/mrst_machine.c
@@ -91,6 +91,12 @@ static int mrst_audio_init(struct snd_soc_pcm_runtime *runtime)
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int ret;
 
+	/* DMIC configuration: mono output to PCM2 */
+	snd_soc_update_bits(codec, UPD9976_MICCTRL, BIT(1)|BIT(0), 0x1);
+
+	/* Set MIC2 to pseudo-differential */
+	snd_soc_update_bits(codec, UPD9976_MICSELVOL, BIT(4), BIT(4));
+
 	snd_soc_dapm_nc_pin(dapm, "LINEINL");
 	snd_soc_dapm_nc_pin(dapm, "LINEINR");
 	snd_soc_dapm_nc_pin(dapm, "LINEOUTL");

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

* Re: [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver
  2011-05-06  5:46 ` [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver Lu Guanqun
@ 2011-05-06 10:17   ` Mark Brown
  2011-05-07 14:21     ` Lu Guanqun
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2011-05-06 10:17 UTC (permalink / raw)
  To: Lu Guanqun; +Cc: Takashi Iwai, Koul Vinod, ALSA, Liam Girdwood, Wang Xingchao

On Fri, May 06, 2011 at 01:46:03PM +0800, Lu Guanqun wrote:

> +static inline unsigned int upd9976_read(struct snd_soc_codec *codec,
> +					unsigned int reg)
> +{
> +	u8 value = 0;
> +	int ret;
> +
> +	ret = intel_scu_ipc_ioread8(reg, &value);
> +	if (ret)
> +		dev_err(codec->dev,
> +			"upd9976 read of 0x%x failed, error: %d\n", reg, ret);
> +	return value;
> +}

Please factor this stuff out.

> +/*
> + * Mixing Volume: from -25 dB to 6 dB in 1 dB steps.
> + */
> +static DECLARE_TLV_DB_SCALE(mixer_tlv, -2500, 100, 0);
> +
> +/*
> + * Audio DAC Volume: From -84 dB to 10.5 dB in 0.75 steps.
> + */
> +static DECLARE_TLV_DB_SCALE(adac_tlv, -8400, 75, 0);
> +static const struct snd_kcontrol_new upd9976_snd_controls[] = {

Use of blank lines here is really odd.

> +	SOC_DOUBLE_R_TLV("Master Volume",
> +			 UPD9976_AUDIOLVOL, UPD9976_AUDIORVOL,
> +			 0, 0x7f, 1, adac_tlv),
> +	SOC_DOUBLE_R_TLV("PCM Volume",
> +			 UPD9976_HPSPRLVOL, UPD9976_HPSPRRVOL,
> +			 0, 0x1f, 1, mixer_tlv),

PCM would usually be a digital audio stream but this is a control for a
mixer.

> +static struct snd_soc_dai_driver upd9976_dais[] = {
> +{
> +	.name = "upd9976-audio",

Previous issue with naming still applies.

> +	case SND_SOC_BIAS_PREPARE:
> +		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
> +			snd_soc_update_bits(codec, UPD9976_VAUDIOCNT,
> +					    0x27, 0x27);
> +			snd_soc_update_bits(codec, UPD9976_VREFPLL,
> +					    0x35, 0x35);
> +		}
> +		break;
> +
> +	case SND_SOC_BIAS_STANDBY:
> +		snd_soc_write(codec, UPD9976_VAUDIOCNT, 0x25);
> +		snd_soc_write(codec, UPD9976_VREFPLL, 0x10);
> +		break;
> +
> +	case SND_SOC_BIAS_OFF:
> +		snd_soc_write(codec, UPD9976_VREFPLL, 0);
> +		snd_soc_write(codec, UPD9976_VAUDIOCNT, 0x24);
> +		break;

This is all very magic and lots of what's going on (especially with
VAUDIOCNT) looks like it's actually trying to fiddle with bitmasks.

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

* Re: [PATCH v2 05/10] ASoC: upd9976: add DMIC support
  2011-05-06  5:46 ` [PATCH v2 05/10] ASoC: upd9976: add DMIC support Lu Guanqun
@ 2011-05-06 11:07   ` Mark Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2011-05-06 11:07 UTC (permalink / raw)
  To: Lu Guanqun; +Cc: Takashi Iwai, Koul Vinod, ALSA, Liam Girdwood, Wang Xingchao

On Fri, May 06, 2011 at 01:46:24PM +0800, Lu Guanqun wrote:
> Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>

As previously mentioned please merge these trivial feature patches into
the original driver unless there's some purpose in splitting them out.
In this case it looks like the split is the cause of one of the review
issues in the earlier post.

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

* Re: [PATCH v2 07/10] ASoC: upd9976: add jack detection function
  2011-05-06  5:46 ` [PATCH v2 07/10] ASoC: upd9976: add jack detection function Lu Guanqun
@ 2011-05-06 12:53   ` Mark Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2011-05-06 12:53 UTC (permalink / raw)
  To: Lu Guanqun; +Cc: Takashi Iwai, Koul Vinod, ALSA, Liam Girdwood, Wang Xingchao

On Fri, May 06, 2011 at 01:46:34PM +0800, Lu Guanqun wrote:

> +	if (interrupt_status & 0x1 && value == 0x1)
> +		status |= SND_JACK_HEADSET;
> +
> +	if (interrupt_status & 0x2 && value == 0x2)
> +		status |= SND_JACK_HEADPHONE;
> +
> +	if (interrupt_status & 0x4)
> +		status |= SND_JACK_HEADSET | SND_JACK_BTN_0;
> +
> +	if (interrupt_status & 0x8)
> +		status |= SND_JACK_HEADSET | SND_JACK_BTN_1;

It's very strange that you do a mix of checks with and without the == -
it doesn't matter either way but it'd be clearer to be consistent.

> +	if (upd9976->irq < 0 || !upd9976->irq_mem)
> +		return 0;

It'd seem better to have this condition the other way around so if you
need to add more conditional stuff things will be clearer.

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

* Re: [PATCH v2 10/10] ASoC: mrst_machine: add initial config to machine driver
  2011-05-06  5:46 ` [PATCH v2 10/10] ASoC: mrst_machine: add initial config to machine driver Lu Guanqun
@ 2011-05-06 12:54   ` Mark Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2011-05-06 12:54 UTC (permalink / raw)
  To: Lu Guanqun; +Cc: Takashi Iwai, Koul Vinod, ALSA, Liam Girdwood, Wang Xingchao

On Fri, May 06, 2011 at 01:46:49PM +0800, Lu Guanqun wrote:

> +	/* DMIC configuration: mono output to PCM2 */
> +	snd_soc_update_bits(codec, UPD9976_MICCTRL, BIT(1)|BIT(0), 0x1);
> +
> +	/* Set MIC2 to pseudo-differential */
> +	snd_soc_update_bits(codec, UPD9976_MICSELVOL, BIT(4), BIT(4));
> +

These look like regular routing controls to me...  If they do need to be
set with magic writes they should be platform data but things like
pseudo differential inputs are normally just represented as two single
ended inputs for which userspace just happens to choose a path that
looks differential.

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

* Re: [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver
  2011-05-06 10:17   ` Mark Brown
@ 2011-05-07 14:21     ` Lu Guanqun
  2011-05-07 14:27       ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Lu Guanqun @ 2011-05-07 14:21 UTC (permalink / raw)
  To: Mark Brown; +Cc: Takashi Iwai, Koul, Vinod, ALSA, Liam Girdwood, Wang, Xingchao

On Fri, May 06, 2011 at 06:17:27PM +0800, Mark Brown wrote:
> On Fri, May 06, 2011 at 01:46:03PM +0800, Lu Guanqun wrote:
> 
> > +static inline unsigned int upd9976_read(struct snd_soc_codec *codec,
> > +					unsigned int reg)
> > +{
> > +	u8 value = 0;
> > +	int ret;
> > +
> > +	ret = intel_scu_ipc_ioread8(reg, &value);
> > +	if (ret)
> > +		dev_err(codec->dev,
> > +			"upd9976 read of 0x%x failed, error: %d\n", reg, ret);
> > +	return value;
> > +}
> 
> Please factor this stuff out.

OK. Patch sent in another thread. Please give some comments whether it's
the right way to achieve this.

> 
> > +/*
> > + * Mixing Volume: from -25 dB to 6 dB in 1 dB steps.
> > + */
> > +static DECLARE_TLV_DB_SCALE(mixer_tlv, -2500, 100, 0);
> > +
> > +/*
> > + * Audio DAC Volume: From -84 dB to 10.5 dB in 0.75 steps.
> > + */
> > +static DECLARE_TLV_DB_SCALE(adac_tlv, -8400, 75, 0);
> > +static const struct snd_kcontrol_new upd9976_snd_controls[] = {
> 
> Use of blank lines here is really odd.

I don't see a blank line between upd9976_snd_controls and Master Volume.
Do you mean the blank line between the above comment and
DECLARE_TLV_DB_SCALE line?  I'll remove these blank lines.

> > +	SOC_DOUBLE_R_TLV("Master Volume",
> > +			 UPD9976_AUDIOLVOL, UPD9976_AUDIORVOL,
> > +			 0, 0x7f, 1, adac_tlv),
> > +	SOC_DOUBLE_R_TLV("PCM Volume",
> > +			 UPD9976_HPSPRLVOL, UPD9976_HPSPRRVOL,
> > +			 0, 0x1f, 1, mixer_tlv),
> 
> PCM would usually be a digital audio stream but this is a control for a
> mixer.

OK. I'll change it back to "Headphone Speaker Mixer Volume".

> 
> > +static struct snd_soc_dai_driver upd9976_dais[] = {
> > +{
> > +	.name = "upd9976-audio",
> 
> Previous issue with naming still applies.

Will change it to upd9976-hifi, thanks for your suggestion.

> 
> > +	case SND_SOC_BIAS_PREPARE:
> > +		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
> > +			snd_soc_update_bits(codec, UPD9976_VAUDIOCNT,
> > +					    0x27, 0x27);
> > +			snd_soc_update_bits(codec, UPD9976_VREFPLL,
> > +					    0x35, 0x35);
> > +		}
> > +		break;
> > +
> > +	case SND_SOC_BIAS_STANDBY:
> > +		snd_soc_write(codec, UPD9976_VAUDIOCNT, 0x25);
> > +		snd_soc_write(codec, UPD9976_VREFPLL, 0x10);
> > +		break;
> > +
> > +	case SND_SOC_BIAS_OFF:
> > +		snd_soc_write(codec, UPD9976_VREFPLL, 0);
> > +		snd_soc_write(codec, UPD9976_VAUDIOCNT, 0x24);
> > +		break;
> 
> This is all very magic and lots of what's going on (especially with
> VAUDIOCNT) looks like it's actually trying to fiddle with bitmasks.

I'll define some bitmasks so that these magic number will go away, and
others can grasp the idea what's going on...

Generally, it's used to disable/enable power save mode, power on/off
audio rail... etc.

On Fri, May 06, 2011 at 07:07:31PM +0800, Mark Brown wrote:
> On Fri, May 06, 2011 at 01:46:24PM +0800, Lu Guanqun wrote:
> > Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
> 
> As previously mentioned please merge these trivial feature patches into
> the original driver unless there's some purpose in splitting them out.
> In this case it looks like the split is the cause of one of the review
> issues in the earlier post.

No problem. I'll make them about three pathes, one for codec driver, one
for platform driver, one for machine driver.

On Fri, May 06, 2011 at 08:53:11PM +0800, Mark Brown wrote:
> On Fri, May 06, 2011 at 01:46:34PM +0800, Lu Guanqun wrote:
> 
> > +	if (interrupt_status & 0x1 && value == 0x1)
> > +		status |= SND_JACK_HEADSET;
> > +
> > +	if (interrupt_status & 0x2 && value == 0x2)
> > +		status |= SND_JACK_HEADPHONE;
> > +
> > +	if (interrupt_status & 0x4)
> > +		status |= SND_JACK_HEADSET | SND_JACK_BTN_0;
> > +
> > +	if (interrupt_status & 0x8)
> > +		status |= SND_JACK_HEADSET | SND_JACK_BTN_1;
> 
> It's very strange that you do a mix of checks with and without the == -
> it doesn't matter either way but it'd be clearer to be consistent.

OK. Let me make the code more clear.
how about this?

+       if (interrupt_status & 0x1) {
+               if (snd_soc_read(codec, UPD9976_SAUXINT) == 0x1)
+                       status |= SND_JACK_HEADSET;
+       }
+
+       if (interrupt_status & 0x2) {
+               if (snd_soc_read(codec, UPD9976_SAUXINT) == 0x2)
+                       status |= SND_JACK_HEADPHONE;
+       }
+
+       if (interrupt_status & 0x4)
+               status |= SND_JACK_HEADSET | SND_JACK_BTN_0;
+
+       if (interrupt_status & 0x8)
+               status |= SND_JACK_HEADSET | SND_JACK_BTN_1;


> 
> > +	if (upd9976->irq < 0 || !upd9976->irq_mem)
> > +		return 0;
> 
> It'd seem better to have this condition the other way around so if you
> need to add more conditional stuff things will be clearer.

changing it to `if (upd9976->ira >= 0 && !upd9976->irq_mem) is logically
ok, but it introduces more indentation for a large block of code...

On Fri, May 06, 2011 at 08:54:40PM +0800, Mark Brown wrote:
> On Fri, May 06, 2011 at 01:46:49PM +0800, Lu Guanqun wrote:
> 
> > +	/* DMIC configuration: mono output to PCM2 */
> > +	snd_soc_update_bits(codec, UPD9976_MICCTRL, BIT(1)|BIT(0), 0x1);
> > +
> > +	/* Set MIC2 to pseudo-differential */
> > +	snd_soc_update_bits(codec, UPD9976_MICSELVOL, BIT(4), BIT(4));
> > +
> 
> These look like regular routing controls to me...  If they do need to be
> set with magic writes they should be platform data but things like
> pseudo differential inputs are normally just represented as two single
> ended inputs for which userspace just happens to choose a path that
> looks differential.

The above DMIC output might fit routing control in some way, but I think
the MIC2 configuration is hardware specific, this is not related to
routing quite much. Let me check whether it's easy to be implemented as
a routing control or platform data...

-- 
guanqun

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

* Re: [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver
  2011-05-07 14:21     ` Lu Guanqun
@ 2011-05-07 14:27       ` Mark Brown
  2011-05-07 14:43         ` Lu Guanqun
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2011-05-07 14:27 UTC (permalink / raw)
  To: Lu Guanqun; +Cc: Takashi Iwai, Koul, Vinod, ALSA, Liam Girdwood, Wang, Xingchao

On Sat, May 07, 2011 at 10:21:12PM +0800, Lu Guanqun wrote:
> On Fri, May 06, 2011 at 06:17:27PM +0800, Mark Brown wrote:
> > On Fri, May 06, 2011 at 01:46:03PM +0800, Lu Guanqun wrote:

> > > +static DECLARE_TLV_DB_SCALE(adac_tlv, -8400, 75, 0);
> > > +static const struct snd_kcontrol_new upd9976_snd_controls[] = {

> > Use of blank lines here is really odd.

> I don't see a blank line between upd9976_snd_controls and Master Volume.

Yes, exactly.  There's randomly omitted vertical space which makes
things hard to read.

> Do you mean the blank line between the above comment and
> DECLARE_TLV_DB_SCALE line?  I'll remove these blank lines.

No, don't do that.

> OK. Let me make the code more clear.
> how about this?

That's fine.

> > > +	if (upd9976->irq < 0 || !upd9976->irq_mem)
> > > +		return 0;

> > It'd seem better to have this condition the other way around so if you
> > need to add more conditional stuff things will be clearer.

> changing it to `if (upd9976->ira >= 0 && !upd9976->irq_mem) is logically
> ok, but it introduces more indentation for a large block of code...

Put it in a function if that's an issue.

> > These look like regular routing controls to me...  If they do need to be
> > set with magic writes they should be platform data but things like
> > pseudo differential inputs are normally just represented as two single
> > ended inputs for which userspace just happens to choose a path that
> > looks differential.

> The above DMIC output might fit routing control in some way, but I think
> the MIC2 configuration is hardware specific, this is not related to
> routing quite much. Let me check whether it's easy to be implemented as
> a routing control or platform data...

Really, this is *very* common - a pseudo differential input is just two
single ended inputs that happen to be used to fake a differential input
on a given board.  It's likely that a board will use the same setup most
of the time (though sometimes it does change) but they should still not
be configuring this with magic register writes in the machine driver.

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

* Re: [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver
  2011-05-07 14:27       ` Mark Brown
@ 2011-05-07 14:43         ` Lu Guanqun
  0 siblings, 0 replies; 18+ messages in thread
From: Lu Guanqun @ 2011-05-07 14:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: Takashi Iwai, Koul, Vinod, ALSA, Liam Girdwood, Wang, Xingchao

On Sat, May 07, 2011 at 10:27:35PM +0800, Mark Brown wrote:
> > changing it to `if (upd9976->ira >= 0 && !upd9976->irq_mem) is logically
> > ok, but it introduces more indentation for a large block of code...
> 
> Put it in a function if that's an issue.

OK.

> 
> > > These look like regular routing controls to me...  If they do need to be
> > > set with magic writes they should be platform data but things like
> > > pseudo differential inputs are normally just represented as two single
> > > ended inputs for which userspace just happens to choose a path that
> > > looks differential.
> 
> > The above DMIC output might fit routing control in some way, but I think
> > the MIC2 configuration is hardware specific, this is not related to
> > routing quite much. Let me check whether it's easy to be implemented as
> > a routing control or platform data...
> 
> Really, this is *very* common - a pseudo differential input is just two
> single ended inputs that happen to be used to fake a differential input
> on a given board.  It's likely that a board will use the same setup most
> of the time (though sometimes it does change) but they should still not
> be configuring this with magic register writes in the machine driver.

As this should not be configured in machine driver, I'll make it a
control so that user is about to change it (this should only be set
once, and leave it there untouched).

-- 
guanqun

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

end of thread, other threads:[~2011-05-07 14:44 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-06  5:45 [PATCH v2 00/10] ASoC Support For Moorestown Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 01/10] ASoC: upd9976: Add Renesas uPD9976 codec driver Lu Guanqun
2011-05-06 10:17   ` Mark Brown
2011-05-07 14:21     ` Lu Guanqun
2011-05-07 14:27       ` Mark Brown
2011-05-07 14:43         ` Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 02/10] ASoC: sst_platform: modify current cpu dai driver to suit the needs for moorestown platform Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 03/10] ASoC: mrst_machine: add moorestown machine driver Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 04/10] ASoC: upd9976: add capture ability for dai driver Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 05/10] ASoC: upd9976: add DMIC support Lu Guanqun
2011-05-06 11:07   ` Mark Brown
2011-05-06  5:46 ` [PATCH v2 06/10] ASoC: upd9976: add Analog MIC support Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 07/10] ASoC: upd9976: add jack detection function Lu Guanqun
2011-05-06 12:53   ` Mark Brown
2011-05-06  5:46 ` [PATCH v2 08/10] ASoC: mrst_machine: add capture functionality Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 09/10] ASoC: mrst_machine: add jack detection support Lu Guanqun
2011-05-06  5:46 ` [PATCH v2 10/10] ASoC: mrst_machine: add initial config to machine driver Lu Guanqun
2011-05-06 12:54   ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.