Skip to contentSkip to conversation

Convert wm8xxx codec drivers to use snd_soc_cache_sync

PATCH Superseded Axel Lin 3 participants 20 messages Oct 6, 2011

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Axel Lin

author
#0 lore raw

cover Convert wm8xxx codec drivers to use snd_soc_cache_sync

This serial converts the wm8xxx codec drivers to use snd_soc_cache_sync. I don't have these hardware, but I assume Mark has all these hardware. These patches are UNTESTED. I'd appreciate if someone can test them. (Current code is broken anyway, thus we need convert to use new API. )

Axel Lin (10):
ASoC: wm8510: Convert to snd_soc_cache_sync
ASoC: wm8711: Convert to snd_soc_cache_sync
ASoC: wm8731: Convert to snd_soc_cache_sync
ASoC: wm8750: Convert to snd_soc_cache_sync
ASoC: wm8776: Convert to snd_soc_cache_sync
ASoC: wm8940: Convert to snd_soc_cache_sync
ASoC: wm8960: Convert to snd_soc_cache_sync
ASoC: wm8971: Convert to snd_soc_cache_sync
ASoC: wm8974: Convert to snd_soc_cache_sync
ASoC: wm8988: Convert to snd_soc_cache_sync

 sound/soc/codecs/wm8510.c |   30 ++++++++++++++++++----------
 sound/soc/codecs/wm8711.c |   19 +++++++----------
 sound/soc/codecs/wm8731.c |   29 ++++++++++++++++-----------
 sound/soc/codecs/wm8750.c |   32 +++++++++++++++++-------------
 sound/soc/codecs/wm8776.c |   33 ++++++++++++++++++-------------
 sound/soc/codecs/wm8940.c |   46 +++++++++++++++++++++-----------------------
 sound/soc/codecs/wm8960.c |   37 +++++++++++++++++++++++++----------
 sound/soc/codecs/wm8971.c |   32 +++++++++++++++++++-----------
 sound/soc/codecs/wm8974.c |   29 +++++++++++++++++----------
 sound/soc/codecs/wm8988.c |   32 +++++++++++++++++-------------
 10 files changed, 185 insertions(+), 134 deletions(-)
Signature · 1 line
1.7.4.1
author
#1 lore raw

PATCH 1/10 ASoC: wm8510: Convert to snd_soc_cache_sync

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8510.c |   30 +++++++++++++++++++-----------
 1 files changed, 19 insertions(+), 11 deletions(-)
sound/soc/codecs/wm8510.c +19 -11
index 55a4c83..8e2fe22 100644
@@ -55,6 +55,17 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
 #define WM8510_POWER1_BIASEN  0x08
 #define WM8510_POWER1_BUFIOEN 0x10
 
+static int wm8510_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8510_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define wm8510_reset(c)	snd_soc_write(c, WM8510_RESET, 0)
 
 /* codec private data */
@@ -467,6 +478,7 @@ 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)
 {
+	int ret;
 	u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
 
 	switch (level) {
@@ -480,6 +492,12 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
 		power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
 
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+
 			/* Initial cap charge at VMID 5k */
 			snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
 			mdelay(100);
@@ -541,18 +559,7 @@ static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8510_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8510_reg); i++) {
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
 	wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
@@ -597,6 +604,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
 	.reg_cache_size = ARRAY_SIZE(wm8510_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default =wm8510_reg,
+	.volatile_register = wm8510_volatile_register,
 };
 
 static const struct of_device_id wm8510_of_match[] = {
Signature · 1 line
1.7.4.1
#2 lore raw

Re: [PATCH 01/10] ASoC: wm8510: Convert to snd_soc_cache_sync

sound/soc/codecs/wm8510.c static const u16 wm8510_reg[WM8510_CACHEREGNUM] = { · line 68

Quoted 11 lines · Axel Lin
sound/soc/codecs/wm8510.c +11 -0
+static int wm8510_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8510_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+

This is wrong in quite a few of the patches - all the 7, 9 CODECs are write only, there's no readback support at all (in general if the driver isn't actully verifying a device ID or otherwise doing a physical read then it probably doesn't support readback).

author
#3 lore raw

PATCH 2/10 ASoC: wm8711: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8711.c |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)
sound/soc/codecs/wm8711.c +8 -11
index 47c7fd5..b489edf 100644
@@ -291,6 +291,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int wm8711_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
 
 	switch (level) {
@@ -300,6 +301,13 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+		}
 		snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
 		break;
 	case SND_SOC_BIAS_OFF:
@@ -346,18 +354,7 @@ static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8711_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
 	wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
Signature · 1 line
1.7.4.1
author
#4 lore raw

PATCH 3/10 ASoC: wm8731: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8731.c |   29 +++++++++++++++++------------
 1 files changed, 17 insertions(+), 12 deletions(-)
sound/soc/codecs/wm8731.c +17 -12
index f76b6fc..78cbcf8 100644
@@ -63,6 +63,17 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
 	0x0000, 0x0000
 };
 
+static int wm8731_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8731_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define wm8731_reset(c)	snd_soc_write(c, WM8731_RESET, 0)
 
 static const char *wm8731_input_select[] = {"Line In", "Mic"};
@@ -427,9 +438,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
 	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-	int i, ret;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
+	int ret;
 	u16 reg;
 
 	switch (level) {
@@ -444,15 +453,10 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 			if (ret != 0)
 				return ret;
 
-			/* Sync reg_cache with the hardware */
-			for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
-				if (cache[i] == wm8731_reg[i])
-					continue;
-
-				data[0] = (i << 1) | ((cache[i] >> 8)
-						      & 0x0001);
-				data[1] = cache[i] & 0x00ff;
-				codec->hw_write(codec->control_data, data, 2);
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
 			}
 		}
 
@@ -606,6 +610,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
 	.num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
 	.dapm_routes = wm8731_intercon,
 	.num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
+	.volatile_register = wm8731_volatile_register,
 };
 
 static const struct of_device_id wm8731_of_match[] = {
Signature · 1 line
1.7.4.1
author
#5 lore raw

PATCH 4/10 ASoC: wm8750: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8750.c |   32 ++++++++++++++++++--------------
 1 files changed, 18 insertions(+), 14 deletions(-)
sound/soc/codecs/wm8750.c +18 -14
index 862c520..7e5af9f 100644
@@ -55,6 +55,17 @@ struct wm8750_priv {
 	enum snd_soc_control_type control_type;
 };
 
+static int wm8750_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8750_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define wm8750_reset(c)	snd_soc_write(c, WM8750_RESET, 0)
 
 /*
@@ -605,6 +616,7 @@ static int wm8750_mute(struct snd_soc_dai *dai, int mute)
 static int wm8750_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
 
 	switch (level) {
@@ -616,6 +628,11 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
 			/* Set VMID to 5k */
 			snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
 
@@ -673,21 +690,7 @@ static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8750_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8750_reg); i++) {
-		if (i == WM8750_RESET)
-			continue;
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
-
 	wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
@@ -742,6 +745,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
 	.reg_cache_size = ARRAY_SIZE(wm8750_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8750_reg,
+	.volatile_register = wm8750_volatile_register,
 };
 
 static const struct of_device_id wm8750_of_match[] = {
Signature · 1 line
1.7.4.1
author
#6 lore raw

PATCH 5/10 ASoC: wm8776: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8776.c |   33 +++++++++++++++++++--------------
 1 files changed, 19 insertions(+), 14 deletions(-)
sound/soc/codecs/wm8776.c +19 -14
index 00d8846..4f24446 100644
@@ -37,6 +37,17 @@ struct wm8776_priv {
 	int sysclk[2];
 };
 
+static int wm8776_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8776_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
 	0x79, 0x79, 0x79, 0xff, 0xff,  /* 4 */
 	0xff, 0x00, 0x90, 0x00, 0x00,  /* 9 */
@@ -301,6 +312,8 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
 static int wm8776_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	int ret;
+
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -308,6 +321,11 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
 			/* Disable the global powerdown; DAPM does the rest */
 			snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
 		}
@@ -379,21 +397,7 @@ static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8776_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
-		if (cache[i] == wm8776_reg[i])
-			continue;
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
-
 	wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 #else
@@ -451,6 +455,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
 	.reg_cache_size = ARRAY_SIZE(wm8776_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8776_reg,
+	.volatile_register = wm8776_volatile_register,
 };
 
 static const struct of_device_id wm8776_of_match[] = {
Signature · 1 line
1.7.4.1
author
#7 lore raw

PATCH 6/10 ASoC: wm8940: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8940.c |   46 +++++++++++++++++++++-----------------------
 1 files changed, 22 insertions(+), 24 deletions(-)
sound/soc/codecs/wm8940.c +22 -24
index 7e0f54c..a4abfdf 100644
@@ -45,6 +45,17 @@ struct wm8940_priv {
 	enum snd_soc_control_type control_type;
 };
 
+static int wm8940_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8940_SOFTRESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static u16 wm8940_reg_defaults[] = {
 	0x8940, /* Soft Reset */
 	0x0000, /* Power 1 */
@@ -459,6 +470,14 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
 		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
 		break;
 	case SND_SOC_BIAS_STANDBY:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+		}
+
 		/* ensure bufioen and biasen */
 		pwr_reg |= (1 << 2) | (1 << 3);
 		/* set vmid to 300k for standby */
@@ -659,30 +678,8 @@ static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8940_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	int ret;
-	u8 data[3];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware
-	 * Could use auto incremented writes to speed this up
-	 */
-	for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) {
-		data[0] = i;
-		data[1] = (cache[i] & 0xFF00) >> 8;
-		data[2] = cache[i] & 0x00FF;
-		ret = codec->hw_write(codec->control_data, data, 3);
-		if (ret < 0)
-			goto error_ret;
-		else if (ret != 3) {
-			ret = -EIO;
-			goto error_ret;
-		}
-	}
-	ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-error_ret:
-	return ret;
+	wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	return 0;
 }
 
 static int wm8940_probe(struct snd_soc_codec *codec)
@@ -742,6 +739,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
 	.reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8940_reg_defaults,
+	.volatile_register = wm8940_volatile_register,
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Signature · 1 line
1.7.4.1
#8 lore raw

Re: [PATCH 06/10] ASoC: wm8940: Convert to snd_soc_cache_sync

Quoted 1 line · Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

Looks sane, but I'm not that familiar with the cache side of things, so you'll want an ack from someone who is. One comment inline.

Quoted 14 lines
---
 sound/soc/codecs/wm8940.c |   46 +++++++++++++++++++++-----------------------
 1 files changed, 22 insertions(+), 24 deletions(-)
sound/soc/codecs/wm8940.c +0 -0
index 7e0f54c..a4abfdf 100644
@@ -45,6 +45,17 @@ struct wm8940_priv {
 	enum snd_soc_control_type control_type;
 };
 

sound/soc/codecs/wm8940.c struct wm8940_priv { · line 57

Quoted 10 lines
sound/soc/codecs/wm8940.c +10 -0
+static int wm8940_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8940_SOFTRESET:
+		return 1;
+	default:
+		return 0;
+	}
+}

I guess this makes sense from point of view of keeping things inline with more complex drivers. Otherwise I'd expect to see something like:

{
	return !!(reg == WM894_SOFTRESET);
}
Quoted 60 lines
sound/soc/codecs/wm8940.c +12 -24
+
 static u16 wm8940_reg_defaults[] = {
 	0x8940, /* Soft Reset */
 	0x0000, /* Power 1 */
@@ -459,6 +470,14 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
 		ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
 		break;
 	case SND_SOC_BIAS_STANDBY:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+		}
+
 		/* ensure bufioen and biasen */
 		pwr_reg |= (1 << 2) | (1 << 3);
 		/* set vmid to 300k for standby */
@@ -659,30 +678,8 @@ static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8940_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	int ret;
-	u8 data[3];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware
-	 * Could use auto incremented writes to speed this up
-	 */
-	for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) {
-		data[0] = i;
-		data[1] = (cache[i] & 0xFF00) >> 8;
-		data[2] = cache[i] & 0x00FF;
-		ret = codec->hw_write(codec->control_data, data, 3);
-		if (ret < 0)
-			goto error_ret;
-		else if (ret != 3) {
-			ret = -EIO;
-			goto error_ret;
-		}
-	}
-	ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-error_ret:
-	return ret;
+	wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	return 0;
 }
 
 static int wm8940_probe(struct snd_soc_codec *codec)
@@ -742,6 +739,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
 	.reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8940_reg_defaults,
+	.volatile_register = wm8940_volatile_register,
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
author
#9 lore raw

Re: [PATCH 06/10] ASoC: wm8940: Convert to snd_soc_cache_sync

Quoted 7 lines
Quoted 7 lines
sound/soc/codecs/wm8940.c +7 -0
+static int wm8940_volatile_register(struct snd_soc_codec *codec,
+                                 unsigned int reg)
+{
+     switch (reg) {
+     case WM8940_SOFTRESET:
+             return 1;
+     default:
Quoted 8 lines
Quoted 3 lines

+             return 0;
+     }
+}

I guess this makes sense from point of view of keeping things inline with more complex drivers.  Otherwise I'd expect to see something like:
{
       return !!(reg == WM894_SOFTRESET);
}

Either is ok to me.
But current syntax makes it easier to add more registers to be volatile if necessary.

So I'll let Mark decide if I need to send a v2 for changing this.

Regards,
Axel

#10 lore raw

Re: [PATCH 06/10] ASoC: wm8940: Convert to snd_soc_cache_sync

In reply to Jonathan Cameron
Quoted 15 lines · Jonathan Cameron

sound/soc/codecs/wm8940.c struct wm8940_priv { · line 57

Quoted 10 lines · Axel Lin
sound/soc/codecs/wm8940.c +10 -0
+static int wm8940_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8940_SOFTRESET:
+		return 1;
+	default:
+		return 0;
+	}
+}

I guess this makes sense from point of view of keeping things inline with more complex drivers. Otherwise I'd expect to see something like:

Quoted 3 lines
{
	return !!(reg == WM894_SOFTRESET);
}

On the other hand we actually want people to be able to read the code (though the !! there which is the major complication isn't actually doing anything...).

#11 lore raw

Re: [PATCH 06/10] ASoC: wm8940: Convert to snd_soc_cache_sync

Quoted 20 lines · Mark Brown
Quoted 15 lines · Jonathan Cameron

sound/soc/codecs/wm8940.c struct wm8940_priv { · line 57

Quoted 10 lines · Axel Lin
sound/soc/codecs/wm8940.c +10 -0
+static int wm8940_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8940_SOFTRESET:
+		return 1;
+	default:
+		return 0;
+	}
+}

I guess this makes sense from point of view of keeping things inline with more complex drivers. Otherwise I'd expect to see something like:

Quoted 3 lines
{
	return !!(reg == WM894_SOFTRESET);
}
Quoted 3 lines

On the other hand we actually want people to be able to read the code (though the !! there which is the major complication isn't actually doing anything...).

Fair point.

author
#12 lore raw

PATCH 7/10 ASoC: wm8960: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8960.c |   37 ++++++++++++++++++++++++++-----------
 1 files changed, 26 insertions(+), 11 deletions(-)
sound/soc/codecs/wm8960.c +26 -11
index 831c20f..ef5c2d8 100644
@@ -81,6 +81,17 @@ struct wm8960_priv {
 	int playback_fs;
 };
 
+static int wm8960_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8960_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define wm8960_reset(c)	snd_soc_write(c, WM8960_RESET, 0)
 
 /* enumerated controls */
@@ -558,6 +569,7 @@ static int wm8960_mute(struct snd_soc_dai *dai, int mute)
 static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 				      enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 reg;
 
 	switch (level) {
@@ -574,6 +586,12 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+
 			/* Enable anti-pop features */
 			snd_soc_write(codec, WM8960_APOP1,
 				      WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -620,7 +638,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 					 enum snd_soc_bias_level level)
 {
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int reg;
+	int reg, ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -629,6 +647,12 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		switch (codec->dapm.bias_level) {
 		case SND_SOC_BIAS_STANDBY:
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+
 			/* Enable anti pop mode */
 			snd_soc_update_bits(codec, WM8960_APOP1,
 					    WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -901,16 +925,6 @@ static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
 static int wm8960_resume(struct snd_soc_codec *codec)
 {
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
 
 	wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	return 0;
@@ -998,6 +1012,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
 	.reg_cache_size = ARRAY_SIZE(wm8960_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8960_reg,
+	.volatile_register = wm8960_volatile_register,
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Signature · 1 line
1.7.4.1
author
#13 lore raw

PATCH v2 7/10 ASoC: wm8960: Convert to snd_soc_cache_sync

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
v2: Just found in v1 I put snd_soc_cache_sync() at wrong place in wm8960_set_bias_level_capless().

 sound/soc/codecs/wm8960.c |   38 +++++++++++++++++++++++++++-----------
 1 files changed, 27 insertions(+), 11 deletions(-)
sound/soc/codecs/wm8960.c +27 -11
index 831c20f..e8262a0 100644
@@ -81,6 +81,17 @@ struct wm8960_priv {
 	int playback_fs;
 };
 
+static int wm8960_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8960_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define wm8960_reset(c)	snd_soc_write(c, WM8960_RESET, 0)
 
 /* enumerated controls */
@@ -558,6 +569,7 @@ static int wm8960_mute(struct snd_soc_dai *dai, int mute)
 static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 				      enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 reg;
 
 	switch (level) {
@@ -574,6 +586,12 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+
 			/* Enable anti-pop features */
 			snd_soc_write(codec, WM8960_APOP1,
 				      WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -620,7 +638,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 					 enum snd_soc_bias_level level)
 {
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int reg;
+	int reg, ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -697,6 +715,13 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
 					    WM8960_BUFDCOPEN);
 			break;
 
+		case SND_SOC_BIAS_OFF:
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+			break;
 		default:
 			break;
 		}
@@ -901,16 +926,6 @@ static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
 static int wm8960_resume(struct snd_soc_codec *codec)
 {
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
 
 	wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	return 0;
@@ -998,6 +1013,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
 	.reg_cache_size = ARRAY_SIZE(wm8960_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8960_reg,
+	.volatile_register = wm8960_volatile_register,
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Signature · 1 line
1.7.4.1
author
#14 lore raw

PATCH 8/10 ASoC: wm8971: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8971.c |   32 ++++++++++++++++++++------------
 1 files changed, 20 insertions(+), 12 deletions(-)
sound/soc/codecs/wm8971.c +20 -12
index 08ea6f8..b50927f 100644
@@ -58,6 +58,17 @@ static const u16 wm8971_reg[] = {
 	0x0079, 0x0079, 0x0079,          /* 40 */
 };
 
+static int wm8971_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8971_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define wm8971_reset(c)	snd_soc_write(c, WM8971_RESET, 0)
 
 /* WM8971 Controls */
@@ -536,6 +547,7 @@ static int wm8971_mute(struct snd_soc_dai *dai, int mute)
 static int wm8971_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
 
 	switch (level) {
@@ -546,6 +558,13 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_PREPARE:
 		break;
 	case SND_SOC_BIAS_STANDBY:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+		}
 		/* mute dac and set vmid to 500k, enable VREF */
 		snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
 		break;
@@ -605,20 +624,8 @@ static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8971_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
 	u16 reg;
 
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
-		if (i == WM8971_RESET)
-			continue;
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
-
 	wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
 	/* charge wm8971 caps */
@@ -696,6 +703,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
 	.reg_cache_size = ARRAY_SIZE(wm8971_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8971_reg,
+	.volatile_register = wm8971_volatile_register,
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Signature · 1 line
1.7.4.1
author
#15 lore raw

PATCH 9/10 ASoC: wm8974: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8974.c |   29 ++++++++++++++++++-----------
 1 files changed, 18 insertions(+), 11 deletions(-)
sound/soc/codecs/wm8974.c +18 -11
index ca646a8..e25f0ad 100644
@@ -46,6 +46,17 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
 	0x0000,
 };
 
+static int wm8974_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8974_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 #define WM8974_POWER1_BIASEN  0x08
 #define WM8974_POWER1_BUFIOEN 0x04
 
@@ -517,6 +528,7 @@ static int wm8974_mute(struct snd_soc_dai *dai, int mute)
 static int wm8974_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 power1 = snd_soc_read(codec, WM8974_POWER1) & ~0x3;
 
 	switch (level) {
@@ -530,6 +542,11 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
 		power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
 
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
 			/* Initial cap charge at VMID 5k */
 			snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
 			mdelay(100);
@@ -589,18 +606,7 @@ static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8974_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8974_reg); i++) {
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
 	wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
@@ -644,6 +650,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
 	.reg_cache_size = ARRAY_SIZE(wm8974_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8974_reg,
+	.volatile_register = wm8974_volatile_register,
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
Signature · 1 line
1.7.4.1
author
#16 lore raw

PATCH 10/10 ASoC: wm8988: Convert to snd_soc_cache_sync

In reply to Axel Lin

Convert to snd_soc_cache_sync for sync reg_cache with the hardware.

---
 sound/soc/codecs/wm8988.c |   32 ++++++++++++++++++--------------
 1 files changed, 18 insertions(+), 14 deletions(-)
sound/soc/codecs/wm8988.c +18 -14
index 1c6f8bf..ed453e5 100644
@@ -55,6 +55,16 @@ struct wm8988_priv {
 	struct snd_pcm_hw_constraint_list *sysclk_constraints;
 };
 
+static int wm8988_volatile_register(struct snd_soc_codec *codec,
+				    unsigned int reg)
+{
+	switch (reg) {
+	case WM8988_RESET:
+		return 1;
+	default:
+		return 0;
+	}
+}
 
 #define wm8988_reset(c)	snd_soc_write(c, WM8988_RESET, 0)
 
@@ -663,6 +673,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
 static int wm8988_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	int ret;
 	u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
 
 	switch (level) {
@@ -676,6 +687,12 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			ret = snd_soc_cache_sync(codec);
+			if (ret < 0) {
+				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+				return ret;
+			}
+
 			/* VREF, VMID=2x5k */
 			snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
 
@@ -736,21 +753,7 @@ static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm8988_resume(struct snd_soc_codec *codec)
 {
-	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 0; i < WM8988_NUM_REG; i++) {
-		if (i == WM8988_RESET)
-			continue;
-		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
-	}
-
 	wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
@@ -805,6 +808,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
 	.reg_cache_size = ARRAY_SIZE(wm8988_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8988_reg,
+	.volatile_register = wm8988_volatile_register,
 };
 
 #if defined(CONFIG_SPI_MASTER)
Signature · 1 line
1.7.4.1
author
#17 lore raw
In reply to Axel Lin

Sorry. I just found we need to set codec->cache_sync = 1 in SND_SOC_BIAS_OFF. Otherwise, snd_soc_cache_sync won't sync work.

Will send a v2 soon.

Axel

於 四,2011-10-06 於 14:10 +0800,Axel Lin 提到:

Quoted 17 lines

This serial converts the wm8xxx codec drivers to use snd_soc_cache_sync. I don't have these hardware, but I assume Mark has all these hardware. These patches are UNTESTED. I'd appreciate if someone can test them. (Current code is broken anyway, thus we need convert to use new API. )

Axel Lin (10):
ASoC: wm8510: Convert to snd_soc_cache_sync
ASoC: wm8711: Convert to snd_soc_cache_sync
ASoC: wm8731: Convert to snd_soc_cache_sync
ASoC: wm8750: Convert to snd_soc_cache_sync
ASoC: wm8776: Convert to snd_soc_cache_sync
ASoC: wm8940: Convert to snd_soc_cache_sync
ASoC: wm8960: Convert to snd_soc_cache_sync
ASoC: wm8971: Convert to snd_soc_cache_sync
ASoC: wm8974: Convert to snd_soc_cache_sync
ASoC: wm8988: Convert to snd_soc_cache_sync

Quoted 12 lines
 sound/soc/codecs/wm8510.c |   30 ++++++++++++++++++----------
 sound/soc/codecs/wm8711.c |   19 +++++++----------
 sound/soc/codecs/wm8731.c |   29 ++++++++++++++++-----------
 sound/soc/codecs/wm8750.c |   32 +++++++++++++++++-------------
 sound/soc/codecs/wm8776.c |   33 ++++++++++++++++++-------------
 sound/soc/codecs/wm8940.c |   46 +++++++++++++++++++++-----------------------
 sound/soc/codecs/wm8960.c |   37 +++++++++++++++++++++++++----------
 sound/soc/codecs/wm8971.c |   32 +++++++++++++++++++-----------
 sound/soc/codecs/wm8974.c |   29 +++++++++++++++++----------
 sound/soc/codecs/wm8988.c |   32 +++++++++++++++++-------------
 10 files changed, 185 insertions(+), 134 deletions(-)

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

author
#18 lore raw

於 四,2011-10-06 於 14:52 +0800,Axel Lin 提到:

Quoted 4 lines

Sorry. I just found we need to set codec->cache_sync = 1 in SND_SOC_BIAS_OFF. Otherwise, snd_soc_cache_sync won't sync work.

Will send a v2 soon.

I take it back. sorry again.
After commit 7be4ba24 "ASoC: Mark cache as dirty when suspending", The soc-core will set codec->cache_sync flag now.

Regards,
Axel

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#19 lore raw
In reply to Axel Lin
Quoted 4 lines · Axel Lin

This serial converts the wm8xxx codec drivers to use snd_soc_cache_sync. I don't have these hardware, but I assume Mark has all these hardware. These patches are UNTESTED. I'd appreciate if someone can test them. (Current code is broken anyway, thus we need convert to use new API. )

Axel, when submitting patches please don't fish e-mail addresses out of the code - use the git logs to find out who's working on the driver. This seems to be a fairly big source of bouncing e-mails in your CC lists.

Quoted 30 lines

Axel Lin (10):
ASoC: wm8510: Convert to snd_soc_cache_sync
ASoC: wm8711: Convert to snd_soc_cache_sync
ASoC: wm8731: Convert to snd_soc_cache_sync
ASoC: wm8750: Convert to snd_soc_cache_sync
ASoC: wm8776: Convert to snd_soc_cache_sync
ASoC: wm8940: Convert to snd_soc_cache_sync
ASoC: wm8960: Convert to snd_soc_cache_sync
ASoC: wm8971: Convert to snd_soc_cache_sync
ASoC: wm8974: Convert to snd_soc_cache_sync
ASoC: wm8988: Convert to snd_soc_cache_sync

 sound/soc/codecs/wm8510.c |   30 ++++++++++++++++++----------
 sound/soc/codecs/wm8711.c |   19 +++++++----------
 sound/soc/codecs/wm8731.c |   29 ++++++++++++++++-----------
 sound/soc/codecs/wm8750.c |   32 +++++++++++++++++-------------
 sound/soc/codecs/wm8776.c |   33 ++++++++++++++++++-------------
 sound/soc/codecs/wm8940.c |   46 +++++++++++++++++++++-----------------------
 sound/soc/codecs/wm8960.c |   37 +++++++++++++++++++++++++----------
 sound/soc/codecs/wm8971.c |   32 +++++++++++++++++++-----------
 sound/soc/codecs/wm8974.c |   29 +++++++++++++++++----------
 sound/soc/codecs/wm8988.c |   32 +++++++++++++++++-------------
 10 files changed, 185 insertions(+), 134 deletions(-)
Signature · 1 line
1.7.4.1