Skip to contentSkip to conversation

ASoC updates

PATCH In review Mark Brown 2 participants 10 messages Oct 8, 2008

Subsystems (5)
lore
Share & tools
lore

Mark Brown

author
#0 lore raw

cover ASoC updates

The following changes since commit 691ac84a77b1aebb7e09b4924b4b9c07a0f4f66a:
Takashi Iwai (1):
Merge branch 'asoc-fixes' into topic/asoc

are available in the git repository at:

git://opensource.wolfsonmicro.com/linux-2.6-asoc for-tiwai

This is all 2.6.28ish material.

Arun KS (1):
ASoC: Add custom SOC_SINGLE_TLV for tlv320aic23 codec

Jarkko Nikula (2):
ASoC: tlv320aic3x: Use uniform tlv320aic naming
ASoC: Remove unused AUDIO_NAME define from codec drivers

Mark Brown (4):
ASoC: Add WM8753 SPI support
ASoC: Add WM8510 SPI support
ASoC: Implement WM8510 bias level control
ASoC: Make WM8510 microphone input a DAPM mixer

Richard Zhao (1):
ALSA: ASoC: add new param mux to dapm_mux_update_power

 sound/soc/codecs/ak4535.c      |    1 -
 sound/soc/codecs/ssm2602.c     |    1 -
 sound/soc/codecs/tlv320aic23.c |   54 ++++++++++++++++++--
 sound/soc/codecs/tlv320aic3x.c |    5 +-
 sound/soc/codecs/uda1380.c     |    1 -
 sound/soc/codecs/wm8510.c      |  109 ++++++++++++++++++++++++++++++++++-----
 sound/soc/codecs/wm8510.h      |    1 +
 sound/soc/codecs/wm8580.c      |    1 -
 sound/soc/codecs/wm8731.c      |    1 -
 sound/soc/codecs/wm8750.c      |    1 -
 sound/soc/codecs/wm8753.c      |   72 +++++++++++++++++++++++++-
 sound/soc/codecs/wm8753.h      |    1 +
 sound/soc/codecs/wm8971.c      |    1 -
 sound/soc/codecs/wm8990.c      |    1 -
 sound/soc/soc-dapm.c           |    8 ++--
 15 files changed, 221 insertions(+), 37 deletions(-)
author
#1 lore raw

PATCH 1/8 ASoC: Add custom SOC_SINGLE_TLV for tlv320aic23 codec

From: Arun KS <[email protected]>

Replaces SOC_ENUM with custom SOC_SINGLE_TLV for Sidetone volume

---
 sound/soc/codecs/tlv320aic23.c |   53 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 49 insertions(+), 4 deletions(-)
sound/soc/codecs/tlv320aic23.c +49 -4
index c2d35e9..bb7cfb8 100644
@@ -113,7 +113,6 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
 
 static const char *rec_src_text[] = { "Line", "Mic" };
 static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const char *sidetone_text[] = {"-6db", "-9db", "-12db", "-18db", "0db"};
 
 static const struct soc_enum rec_src_enum =
 	SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
@@ -125,11 +124,56 @@ static const struct soc_enum tlv320aic23_rec_src =
 	SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
 static const struct soc_enum tlv320aic23_deemph =
 	SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
-static const struct soc_enum tlv320aic23_sidetone =
-	SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 6, 5, sidetone_text);
 
 static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
 static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
+static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
+
+static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	u16 val, reg;
+
+	val = (ucontrol->value.integer.value[0] & 0x07);
+
+	/* linear conversion to userspace
+	* 000	=	-6db
+	* 001	=	-9db
+	* 010	=	-12db
+	* 011	=	-18db (Min)
+	* 100	=	0db (Max)
+	*/
+	val = (val >= 4) ? 4  : (3 - val);
+
+	reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0);
+	tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
+
+	return 0;
+}
+
+static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	u16 val;
+
+	val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0);
+	val = val >> 6;
+	val = (val >= 4) ? 4  : (3 -  val);
+	ucontrol->value.integer.value[0] = val;
+	return 0;
+
+}
+
+#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
+	.put = snd_soc_tlv320aic23_put_volsw, \
+	.private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
 
 static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
 	SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
@@ -141,7 +185,8 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
 			 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
 	SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
 	SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
-	SOC_ENUM("Sidetone Gain", tlv320aic23_sidetone),
+	SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG,
+				  6, 4, 0, sidetone_vol_tlv),
 	SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
 };
 
Signature · 1 line
1.5.6.5
author
#2 lore raw

PATCH 2/8 ASoC: Add WM8753 SPI support

Implement SPI support for WM8753, cut'n'pasting from the support for WM8731 contributed by Cliff Cai and Alan Horstmann since the wire format is the same for both codecs.

---
 sound/soc/codecs/wm8753.c |   71 +++++++++++++++++++++++++++++++++++++++++++-
 sound/soc/codecs/wm8753.h |    1 +
 2 files changed, 70 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8753.c +69 -2
index 8c4df44..83ba419 100644
@@ -40,6 +40,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/spi/spi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -1719,6 +1720,63 @@ err_driver:
 }
 #endif
 
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8753_spi_probe(struct spi_device *spi)
+{
+	struct snd_soc_device *socdev = wm8753_socdev;
+	struct snd_soc_codec *codec = socdev->codec;
+	int ret;
+
+	codec->control_data = spi;
+
+	ret = wm8753_init(socdev);
+	if (ret < 0)
+		dev_err(&spi->dev, "failed to initialise WM8753\n");
+
+	return ret;
+}
+
+static int __devexit wm8753_spi_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+static struct spi_driver wm8753_spi_driver = {
+	.driver = {
+		.name	= "wm8753",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm8753_spi_probe,
+	.remove		= __devexit_p(wm8753_spi_remove),
+};
+
+static int wm8753_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;
+}
+#endif
+
+
 static int wm8753_probe(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1753,8 +1811,14 @@ static int wm8753_probe(struct platform_device *pdev)
 		codec->hw_write = (hw_write_t)i2c_master_send;
 		ret = wm8753_add_i2c_device(pdev, setup);
 	}
-#else
-		/* Add other interfaces here */
+#endif
+#if defined(CONFIG_SPI_MASTER)
+	if (setup->spi) {
+		codec->hw_write = (hw_write_t)wm8753_spi_write;
+		ret = spi_register_driver(&wm8753_spi_driver);
+		if (ret != 0)
+			printk(KERN_ERR "can't add spi driver");
+	}
 #endif
 
 	if (ret != 0) {
@@ -1798,6 +1862,9 @@ static int wm8753_remove(struct platform_device *pdev)
 	i2c_unregister_device(codec->control_data);
 	i2c_del_driver(&wm8753_i2c_driver);
 #endif
+#if defined(CONFIG_SPI_MASTER)
+	spi_unregister_driver(&wm8753_spi_driver);
+#endif
 	kfree(codec->private_data);
 	kfree(codec);
 
sound/soc/codecs/wm8753.h +1 -0
index 7defde0..6678379 100644
@@ -79,6 +79,7 @@
 #define WM8753_ADCTL2		0x3f
 
 struct wm8753_setup_data {
+	int spi;
 	int i2c_bus;
 	unsigned short i2c_address;
 };
Signature · 1 line
1.5.6.5
author
#3 lore raw

PATCH 3/8 ASoC: Add WM8510 SPI support

Implement SPI support for WM8510, cut'n'pasting from the support for WM8731 contributed by Cliff Cai and Alan Horstmann since the wire format is the same for both codecs.

---
 sound/soc/codecs/wm8510.c |   70 +++++++++++++++++++++++++++++++++++++++++++-
 sound/soc/codecs/wm8510.h |    1 +
 2 files changed, 69 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8510.c +68 -2
index 9a37c8d..16768a5 100644
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/spi/spi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -747,6 +748,62 @@ err_driver:
 }
 #endif
 
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8510_spi_probe(struct spi_device *spi)
+{
+	struct snd_soc_device *socdev = wm8510_socdev;
+	struct snd_soc_codec *codec = socdev->codec;
+	int ret;
+
+	codec->control_data = spi;
+
+	ret = wm8510_init(socdev);
+	if (ret < 0)
+		dev_err(&spi->dev, "failed to initialise WM8510\n");
+
+	return ret;
+}
+
+static int __devexit wm8510_spi_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+static struct spi_driver wm8510_spi_driver = {
+	.driver = {
+		.name	= "wm8510",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm8510_spi_probe,
+	.remove		= __devexit_p(wm8510_spi_remove),
+};
+
+static int wm8510_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;
+}
+#endif /* CONFIG_SPI_MASTER */
+
 static int wm8510_probe(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -772,8 +829,14 @@ static int wm8510_probe(struct platform_device *pdev)
 		codec->hw_write = (hw_write_t)i2c_master_send;
 		ret = wm8510_add_i2c_device(pdev, setup);
 	}
-#else
-	/* Add other interfaces here */
+#endif
+#if defined(CONFIG_SPI_MASTER)
+	if (setup->spi) {
+		codec->hw_write = (hw_write_t)wm8510_spi_write;
+		ret = spi_register_driver(&wm8510_spi_driver);
+		if (ret != 0)
+			printk(KERN_ERR "can't add spi driver");
+	}
 #endif
 
 	if (ret != 0)
@@ -796,6 +859,9 @@ static int wm8510_remove(struct platform_device *pdev)
 	i2c_unregister_device(codec->control_data);
 	i2c_del_driver(&wm8510_i2c_driver);
 #endif
+#if defined(CONFIG_SPI_MASTER)
+	spi_unregister_driver(&wm8510_spi_driver);
+#endif
 	kfree(codec);
 
 	return 0;
sound/soc/codecs/wm8510.h +1 -0
index c536839..bdefcf5 100644
@@ -94,6 +94,7 @@
 #define WM8510_MCLKDIV_12	(7 << 5)
 
 struct wm8510_setup_data {
+	int spi;
 	int i2c_bus;
 	unsigned short i2c_address;
 };
Signature · 1 line
1.5.6.5
author
#4 lore raw

PATCH 4/8 ALSA: ASoC: add new param mux to dapm_mux_update_power

From: Richard Zhao <[email protected]>

Function dapm_mux_update_power needs enum index mux and register mask value val as parameters, but it only has a parameter val, and uses it as both val and mux. snd_soc_test_bits(widget->codec, e->reg, mask, val) val is register mask here, e->texts[val] but val should be enum index mux here.

This patch adds a new param mux to fix it.

---
 sound/soc/soc-dapm.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
sound/soc/soc-dapm.c +4 -4
index 05ffba2..83fa9c4 100644
@@ -693,7 +693,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
 /* test and update the power status of a mux widget */
 static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
 				 struct snd_kcontrol *kcontrol, int mask,
-				 int val, struct soc_enum* e)
+				 int mux, int val, struct soc_enum *e)
 {
 	struct snd_soc_dapm_path *path;
 	int found = 0;
@@ -709,12 +709,12 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
 		if (path->kcontrol != kcontrol)
 			continue;
 
-		if (!path->name || ! e->texts[val])
+		if (!path->name || !e->texts[mux])
 			continue;
 
 		found = 1;
 		/* we now need to match the string in the enum to the path */
-		if (!(strcmp(path->name, e->texts[val])))
+		if (!(strcmp(path->name, e->texts[mux])))
 			path->connect = 1; /* new connection */
 		else
 			path->connect = 0; /* old connection must be powered down */
@@ -1291,7 +1291,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&widget->codec->mutex);
 	widget->value = val;
-	dapm_mux_update_power(widget, kcontrol, mask, mux, e);
+	dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
 	if (widget->event) {
 		if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
 			ret = widget->event(widget,
Signature · 1 line
1.5.6.5
author
#5 lore raw

PATCH 5/8 ASoC: tlv320aic3x: Use uniform tlv320aic naming

From: Jarkko Nikula <[email protected]>

---
 sound/soc/codecs/tlv320aic3x.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/tlv320aic3x.c +2 -2
index 566a427..57fc5af 100644
@@ -991,7 +991,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
 			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
 
 struct snd_soc_dai aic3x_dai = {
-	.name = "aic3x",
+	.name = "tlv320aic3x",
 	.playback = {
 		.stream_name = "Playback",
 		.channels_min = 1,
@@ -1055,7 +1055,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
 	struct aic3x_setup_data *setup = socdev->codec_data;
 	int reg, ret = 0;
 
-	codec->name = "aic3x";
+	codec->name = "tlv320aic3x";
 	codec->owner = THIS_MODULE;
 	codec->read = aic3x_read_reg_cache;
 	codec->write = aic3x_write;
Signature · 1 line
1.5.6.5
author
#6 lore raw

PATCH 6/8 ASoC: Remove unused AUDIO_NAME define from codec drivers

From: Jarkko Nikula <[email protected]>

---
 sound/soc/codecs/ak4535.c      |    1 -
 sound/soc/codecs/ssm2602.c     |    1 -
 sound/soc/codecs/tlv320aic23.c |    1 -
 sound/soc/codecs/tlv320aic3x.c |    1 -
 sound/soc/codecs/uda1380.c     |    1 -
 sound/soc/codecs/wm8510.c      |    1 -
 sound/soc/codecs/wm8580.c      |    1 -
 sound/soc/codecs/wm8731.c      |    1 -
 sound/soc/codecs/wm8750.c      |    1 -
 sound/soc/codecs/wm8753.c      |    1 -
 sound/soc/codecs/wm8971.c      |    1 -
 sound/soc/codecs/wm8990.c      |    1 -
 12 files changed, 0 insertions(+), 12 deletions(-)
sound/soc/codecs/ak4535.c +0 -1
index 088cf99..2a89b58 100644
@@ -28,7 +28,6 @@
 
 #include "ak4535.h"
 
-#define AUDIO_NAME "ak4535"
 #define AK4535_VERSION "0.3"
 
 struct snd_soc_codec_device soc_codec_dev_ak4535;
sound/soc/codecs/ssm2602.c +0 -1
index 940ce1c..44ef0da 100644
@@ -42,7 +42,6 @@
 
 #include "ssm2602.h"
 
-#define AUDIO_NAME "ssm2602"
 #define SSM2602_VERSION "0.1"
 
 struct snd_soc_codec_device soc_codec_dev_ssm2602;
sound/soc/codecs/tlv320aic23.c +0 -1
index bb7cfb8..bac7815 100644
@@ -35,7 +35,6 @@
 
 #include "tlv320aic23.h"
 
-#define AUDIO_NAME "tlv320aic23"
 #define AIC23_VERSION "0.1"
 
 struct tlv320aic23_srate_reg_info {
sound/soc/codecs/tlv320aic3x.c +0 -1
index 57fc5af..05336ed 100644
@@ -48,7 +48,6 @@
 
 #include "tlv320aic3x.h"
 
-#define AUDIO_NAME "aic3x"
 #define AIC3X_VERSION "0.2"
 
 /* codec private data */
sound/soc/codecs/uda1380.c +0 -1
index d206d7f..a69ee72 100644
@@ -36,7 +36,6 @@
 #include "uda1380.h"
 
 #define UDA1380_VERSION "0.6"
-#define AUDIO_NAME "uda1380"
 
 /*
  * uda1380 register cache
sound/soc/codecs/wm8510.c +0 -1
index 16768a5..142c49b 100644
@@ -28,7 +28,6 @@
 
 #include "wm8510.h"
 
-#define AUDIO_NAME "wm8510"
 #define WM8510_VERSION "0.6"
 
 struct snd_soc_codec_device soc_codec_dev_wm8510;
sound/soc/codecs/wm8580.c +0 -1
index df1ffbe..056787f 100644
@@ -36,7 +36,6 @@
 
 #include "wm8580.h"
 
-#define AUDIO_NAME "wm8580"
 #define WM8580_VERSION "0.1"
 
 struct pll_state {
sound/soc/codecs/wm8731.c +0 -1
index 7b64d9a..7f8a7e3 100644
@@ -29,7 +29,6 @@
 
 #include "wm8731.h"
 
-#define AUDIO_NAME "wm8731"
 #define WM8731_VERSION "0.13"
 
 struct snd_soc_codec_device soc_codec_dev_wm8731;
sound/soc/codecs/wm8750.c +0 -1
index 4892e39..9b7296e 100644
@@ -29,7 +29,6 @@
 
 #include "wm8750.h"
 
-#define AUDIO_NAME "WM8750"
 #define WM8750_VERSION "0.12"
 
 /* codec private data */
sound/soc/codecs/wm8753.c +0 -1
index 83ba419..63dbc56 100644
@@ -52,7 +52,6 @@
 
 #include "wm8753.h"
 
-#define AUDIO_NAME "wm8753"
 #define WM8753_VERSION "0.16"
 
 static int caps_charge = 2000;
sound/soc/codecs/wm8971.c +0 -1
index 974a4cd..f41a578 100644
@@ -29,7 +29,6 @@
 
 #include "wm8971.h"
 
-#define AUDIO_NAME "wm8971"
 #define WM8971_VERSION "0.9"
 
 #define	WM8971_REG_COUNT		43
sound/soc/codecs/wm8990.c +0 -1
index 63410d7..572d22b 100644
@@ -30,7 +30,6 @@
 
 #include "wm8990.h"
 
-#define AUDIO_NAME "wm8990"
 #define WM8990_VERSION "0.2"
 
 /* codec private data */
Signature · 1 line
1.5.6.5
author
#7 lore raw

PATCH 7/8 ASoC: Implement WM8510 bias level control

The WM8510 bias level configuration blindly overwrites the power management registers, interfering with the operation of DAPM. Only adjust the specific bits required, implementing use of the VMID resistor string configuration control as we go.

---
 sound/soc/codecs/wm8510.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)
sound/soc/codecs/wm8510.c +24 -8
index 142c49b..94cab49 100644
@@ -55,6 +55,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
 	0x0001,
 };
 
+#define WM8510_POWER1_BIASEN  0x08
+#define WM8510_POWER1_BUFIOEN 0x10
+
 /*
  * read wm8510 register cache
  */
@@ -526,23 +529,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
 static int wm8510_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
-		wm8510_write(codec, WM8510_POWER1, 0x1ff);
-		wm8510_write(codec, WM8510_POWER2, 0x1ff);
-		wm8510_write(codec, WM8510_POWER3, 0x1ff);
-		break;
 	case SND_SOC_BIAS_PREPARE:
+		power1 |= 0x1;  /* VMID 50k */
+		wm8510_write(codec, WM8510_POWER1, power1);
+		break;
+
 	case SND_SOC_BIAS_STANDBY:
+		power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
+
+		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+			/* Initial cap charge at VMID 5k */
+			wm8510_write(codec, WM8510_POWER1, power1 | 0x3);
+			mdelay(100);
+		}
+
+		power1 |= 0x2;  /* VMID 500k */
+		wm8510_write(codec, WM8510_POWER1, power1);
 		break;
+
 	case SND_SOC_BIAS_OFF:
-		/* everything off, dac mute, inactive */
-		wm8510_write(codec, WM8510_POWER1, 0x0);
-		wm8510_write(codec, WM8510_POWER2, 0x0);
-		wm8510_write(codec, WM8510_POWER3, 0x0);
+		wm8510_write(codec, WM8510_POWER1, 0);
+		wm8510_write(codec, WM8510_POWER2, 0);
+		wm8510_write(codec, WM8510_POWER3, 0);
 		break;
 	}
+
 	codec->bias_level = level;
 	return 0;
 }
@@ -640,6 +655,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
 	}
 
 	/* power on device */
+	codec->bias_level = SND_SOC_BIAS_OFF;
 	wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	wm8510_add_controls(codec);
 	wm8510_add_widgets(codec);
Signature · 1 line
1.5.6.5
author
#8 lore raw

PATCH 8/8 ASoC: Make WM8510 microphone input a DAPM mixer

The WM8510 microphone input PGA was represented as a DAPM PGA but in DAPM terms the functionality is that of a mixer since it takes three switchable inputs and produces one output. Representing it as an input was causing its controls to be misinterpreted as gain controls and would cause some required DAPM updates to be missed.

---
 sound/soc/codecs/wm8510.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm8510.c +3 -3
index 94cab49..ea524c4 100644
@@ -227,9 +227,9 @@ SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
 SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
 SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
 
-SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0,
-		 &wm8510_micpga_controls[0],
-		 ARRAY_SIZE(wm8510_micpga_controls)),
+SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0,
+		   &wm8510_micpga_controls[0],
+		   ARRAY_SIZE(wm8510_micpga_controls)),
 SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
 	&wm8510_boost_controls[0],
 	ARRAY_SIZE(wm8510_boost_controls)),
Signature · 1 line
1.5.6.5
#9 lore raw
In reply to Mark Brown

At Wed, 8 Oct 2008 10:36:11 +0100,

Quoted 10 lines · Mark Brown

The following changes since commit 691ac84a77b1aebb7e09b4924b4b9c07a0f4f66a:
Takashi Iwai (1):
Merge branch 'asoc-fixes' into topic/asoc

are available in the git repository at:

git://opensource.wolfsonmicro.com/linux-2.6-asoc for-tiwai

This is all 2.6.28ish material.

Thanks. All looks good. Pulled in and pushed out.

Takashi