[alsa-devel] [PATCH 00/14] ASoC: AC'97 driver cleanups
Hi,
This series does a few AC'97 driver cleanups in preparation of the conversion of the drivers to regmap. Most of the patches are quite trivial.
The last two patches remove the virtual registers from the wm9712 and wm9713 drivers, which is a requirement for regmap conversion.
The last patch is the only one in this series that is a bit more complex. Currently the drivers have a open-coded implementation of shared controls which is replaced by the patch with the generic one from the ASoC core. Unfortunately this changes the controls that are exposed by the driver, instead of having a "Left HP Mixer ..." and a "Right HP Mixer ..." control for each mixer input there will only be a single "HP Mixer" control. This may or may not be considered breaking the userspace interface. If it is we need to take a different approach at removing the virtual register form the driver.
- Lars
Lars-Peter Clausen (14): ASoC: ad1980: Remove unused header ASoC: ad1980: Cleanup printk usage ASoC: ad1980: Use table based control setup ASoC: stac9766: Cleanup printk usage ASoC: stac9766: Use table based control setup ASoC: wm9705: Cleanup printk usage ASoC: wm9705: Use table based control setup ASoC: wm9712: Cleanup printk usage ASoC: wm9712: Use table based control setup ASoC: wm9713: Cleanup printk usage ASoC: wm9713: Use table based control setup ASoC: wm9713: Move driver state struct allocation to driver probe ASoC: wm9713: Use virtual control instead of virtual register ASoC: wm9712/wm9713: Use shared controls
sound/soc/blackfin/bf5xx-ad1980.c | 2 - sound/soc/codecs/ad1980.c | 23 ++---- sound/soc/codecs/ad1980.h | 26 ------ sound/soc/codecs/stac9766.c | 9 +- sound/soc/codecs/wm9705.c | 14 ++-- sound/soc/codecs/wm9712.c | 136 +++++++----------------------- sound/soc/codecs/wm9713.c | 170 +++++++++++--------------------------- 7 files changed, 98 insertions(+), 282 deletions(-) delete mode 100644 sound/soc/codecs/ad1980.h
The constants defined in the ad1980 header are not used. So remove the file.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/blackfin/bf5xx-ad1980.c | 2 -- sound/soc/codecs/ad1980.c | 2 -- sound/soc/codecs/ad1980.h | 26 -------------------------- 3 files changed, 30 deletions(-) delete mode 100644 sound/soc/codecs/ad1980.h
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c index 3450e8f..0fa81a5 100644 --- a/sound/soc/blackfin/bf5xx-ad1980.c +++ b/sound/soc/blackfin/bf5xx-ad1980.c @@ -46,8 +46,6 @@ #include <linux/gpio.h> #include <asm/portmux.h>
-#include "../codecs/ad1980.h" - #include "bf5xx-ac97.h"
static struct snd_soc_card bf5xx_board; diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 304d300..cc28dba 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -30,8 +30,6 @@ #include <sound/initval.h> #include <sound/soc.h>
-#include "ad1980.h" - /* * AD1980 register cache */ diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h deleted file mode 100644 index eb0af44..0000000 --- a/sound/soc/codecs/ad1980.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ad1980.h -- ad1980 Soc Audio driver - * - * WARNING: - * - * Because Analog Devices Inc. discontinued the ad1980 sound chip since - * Sep. 2009, this ad1980 driver is not maintained, tested and supported - * by ADI now. - */ - -#ifndef _AD1980_H -#define _AD1980_H -/* Bit definition of Power-Down Control/Status Register */ -#define ADC 0x0001 -#define DAC 0x0002 -#define ANL 0x0004 -#define REF 0x0008 -#define PR0 0x0100 -#define PR1 0x0200 -#define PR2 0x0400 -#define PR3 0x0800 -#define PR4 0x1000 -#define PR5 0x2000 -#define PR6 0x4000 - -#endif
Use dev_err()/dev_warn() instead of printk(KERN_ERR/KERN_WARNING. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Also remove the info message that is printed when the driver is probed, this is just noise in bootlog.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/ad1980.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index cc28dba..5f076c2 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -209,7 +209,8 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) return 0; } while (retry_cnt++ < 10);
- printk(KERN_ERR "AD1980 AC97 reset failed\n"); + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); + return -EIO; }
@@ -219,19 +220,15 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) u16 vendor_id2; u16 ext_status;
- printk(KERN_INFO "AD1980 SoC Audio Codec\n"); - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) { - printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); + dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; }
ret = ad1980_reset(codec, 0); - if (ret < 0) { - printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); + if (ret < 0) goto reset_err; - }
/* Read out vendor ID to make sure it is ad1980 */ if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) { @@ -246,9 +243,8 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) ret = -ENODEV; goto reset_err; } else { - printk(KERN_WARNING "ad1980: " - "Found AD1981 - only 2/2 IN/OUT Channels " - "supported\n"); + dev_warn(codec->dev, + "Found AD1981 - only 2/2 IN/OUT Channels supported\n"); } }
On Thu, Oct 30, 2014 at 09:00:59PM +0100, Lars-Peter Clausen wrote:
Use dev_err()/dev_warn() instead of printk(KERN_ERR/KERN_WARNING. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Applied, thanks.
Makes the code a bit cleaner.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/ad1980.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 5f076c2..9ed4e12 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -259,9 +259,6 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
- snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls, - ARRAY_SIZE(ad1980_snd_ac97_controls)); - return 0;
reset_err: @@ -285,6 +282,8 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { .write = ac97_write, .read = ac97_read,
+ .controls = ad1980_snd_ac97_controls, + .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), .dapm_widgets = ad1980_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), .dapm_routes = ad1980_dapm_routes,
Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/stac9766.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 9878534..e88d9ac 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -262,7 +262,7 @@ static int stac9766_codec_resume(struct snd_soc_codec *codec) /* give the codec an AC97 warm reset to start the link */ reset: if (reset > 5) { - printk(KERN_ERR "stac9766 failed to resume"); + dev_err(codec->dev, "Failed to resume\n"); return -EIO; } codec->ac97->bus->ops->warm_reset(codec->ac97); @@ -338,7 +338,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) stac9766_reset(codec, 0); ret = stac9766_reset(codec, 1); if (ret < 0) { - printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n"); + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); goto codec_err; }
Makes the code a bit cleaner.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/stac9766.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index e88d9ac..6c62d29 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -342,9 +342,6 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) goto codec_err; }
- snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls, - ARRAY_SIZE(stac9766_snd_ac97_controls)); - return 0;
codec_err: @@ -359,6 +356,8 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec) }
static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { + .controls = stac9766_snd_ac97_controls, + .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), .write = stac9766_ac97_write, .read = stac9766_ac97_read, .set_bias_level = stac9766_set_bias_level,
Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9705.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index c0b7f45..355b28d 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -300,6 +300,8 @@ static int wm9705_reset(struct snd_soc_codec *codec) return 0; /* Success */ }
+ dev_err(codec->dev, "Failed to reset: AC97 link error\n"); + return -EIO; }
@@ -317,10 +319,8 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec) u16 *cache = codec->reg_cache;
ret = wm9705_reset(codec); - if (ret < 0) { - printk(KERN_ERR "could not reset AC97 codec\n"); + if (ret < 0) return ret; - }
for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); @@ -339,7 +339,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) { - printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); + dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; }
Makes the code a bit cleaner.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9705.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 355b28d..1650195 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -347,9 +347,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) if (ret) goto reset_err;
- snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls, - ARRAY_SIZE(wm9705_snd_ac97_controls)); - return 0;
reset_err: @@ -374,6 +371,9 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9705_reg, + + .controls = wm9705_snd_ac97_controls, + .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), .dapm_widgets = wm9705_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), .dapm_routes = wm9705_audio_map,
Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Also avoid printing two error messages when the reset fails.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9712.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index c5eb746..c389e56 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -595,7 +595,7 @@ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) return 0;
err: - printk(KERN_ERR "WM9712 AC97 reset failed\n"); + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); return -EIO; }
@@ -611,10 +611,8 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec) u16 *cache = codec->reg_cache;
ret = wm9712_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "could not reset AC97 codec\n"); + if (ret < 0) return ret; - }
wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -637,15 +635,13 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) { - printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); + dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; }
ret = wm9712_reset(codec, 0); - if (ret < 0) { - printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n"); + if (ret < 0) goto reset_err; - }
/* set alc mux to none */ ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
On Thu, Oct 30, 2014 at 09:01:05PM +0100, Lars-Peter Clausen wrote:
Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Applied, thanks.
Makes the code a bit cleaner.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9712.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index c389e56..f3aab6e 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -647,8 +647,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls, - ARRAY_SIZE(wm9712_snd_ac97_controls));
return 0;
@@ -675,6 +673,9 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9712_reg, + + .controls = wm9712_snd_ac97_controls, + .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), .dapm_widgets = wm9712_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), .dapm_routes = wm9712_audio_map,
Use dev_err()/dev_warn() instead of printk(KERN_ERR/KERN_WARNING. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9713.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index bddee30..38e17d4 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -689,7 +689,8 @@ struct _pll_div { * to allow rounding later */ #define FIXED_PLL_SIZE ((1 << 22) * 10)
-static void pll_factors(struct _pll_div *pll_div, unsigned int source) +static void pll_factors(struct snd_soc_codec *codec, + struct _pll_div *pll_div, unsigned int source) { u64 Kpart; unsigned int K, Ndiv, Nmod, target; @@ -724,7 +725,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source)
Ndiv = target / source; if ((Ndiv < 5) || (Ndiv > 12)) - printk(KERN_WARNING + dev_warn(codec->dev, "WM9713 PLL N value %u out of recommended range!\n", Ndiv);
@@ -768,7 +769,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, return 0; }
- pll_factors(&pll_div, freq_in); + pll_factors(codec, &pll_div, freq_in);
if (pll_div.k == 0) { reg = (pll_div.n << 12) | (pll_div.lf << 11) | @@ -1104,8 +1105,11 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm) soc_ac97_ops->reset(codec->ac97); if (soc_ac97_ops->warm_reset) soc_ac97_ops->warm_reset(codec->ac97); - if (ac97_read(codec, 0) != wm9713_reg[0]) + if (ac97_read(codec, 0) != wm9713_reg[0]) { + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); return -EIO; + } + return 0; } EXPORT_SYMBOL_GPL(wm9713_reset); @@ -1163,10 +1167,8 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec) u16 *cache = codec->reg_cache;
ret = wm9713_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "could not reset AC97 codec\n"); + if (ret < 0) return ret; - }
wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1205,10 +1207,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) * a warm reset followed by an optional cold reset for codec */ wm9713_reset(codec, 0); ret = wm9713_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n"); + if (ret < 0) goto reset_err; - }
wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
Makes the code a bit cleaner.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9713.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 38e17d4..ba8c276 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1216,9 +1216,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) reg = ac97_read(codec, AC97_CD) & 0x7fff; ac97_write(codec, AC97_CD, reg);
- snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls, - ARRAY_SIZE(wm9713_snd_ac97_controls)); - return 0;
reset_err: @@ -1248,6 +1245,9 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9713_reg, + + .controls = wm9713_snd_ac97_controls, + .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), .dapm_widgets = wm9713_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), .dapm_routes = wm9713_audio_map,
Resources for the device should be allocated in the device driver probe callback, rather than in the ASoC CODEC probe callback.
E.g. one advantage is that we can use device managed allocations.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9713.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index ba8c276..2704783 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1191,17 +1191,11 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
static int wm9713_soc_probe(struct snd_soc_codec *codec) { - struct wm9713_priv *wm9713; int ret = 0, reg;
- wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL); - if (wm9713 == NULL) - return -ENOMEM; - snd_soc_codec_set_drvdata(codec, wm9713); - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) - goto codec_err; + return ret;
/* do a cold reset for the controller and then try * a warm reset followed by an optional cold reset for codec */ @@ -1220,16 +1214,12 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
reset_err: snd_soc_free_ac97_codec(codec); -codec_err: - kfree(wm9713); return ret; }
static int wm9713_soc_remove(struct snd_soc_codec *codec) { - struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); snd_soc_free_ac97_codec(codec); - kfree(wm9713); return 0; }
@@ -1256,6 +1246,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
static int wm9713_probe(struct platform_device *pdev) { + struct wm9713_priv *wm9713; + + wm9713 = devm_kzalloc(&pdev->dev, sizeof(*wm9713), GFP_KERNEL); + if (wm9713 == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, wm9713); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai)); }
The wm9713 currently implements the virtual control for the Mic B Source MUX using a virtual register. Replace this by using SOC_ENUM_SINGLE_VIRT().
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9713.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 2704783..ac13fc8 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -59,13 +59,12 @@ static const u16 wm9713_reg[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0001, 0x0000, 0x574d, 0x4c13, - 0x0000, 0x0000, 0x0000 + 0x0000, 0x0000 };
/* virtual HP mixers regs */ #define HPL_MIXER 0x80 #define HPR_MIXER 0x82 -#define MICB_MUX 0x82
static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; @@ -110,7 +109,7 @@ SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 10, 8, wm9713_dac_inv), /* dac invert 2 15 */ SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_bass), /* bass control 16 */ SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), /* noise gate type 17 */ SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18 */ -SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */ +SOC_ENUM_SINGLE_VIRT(2, wm9713_micb_select), /* mic selection 19 */ };
static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
The wm9712/wm9713 has separate mixers for the left and the right channel, but the inputs to the mixers are enabled/disabled by the same control. Currently this is implemented by the driver by registering two virtual controls for each physical control, one for the left mixer and one for the right mixer.
This patch converts the driver to use the shared control feature of the ASoC core which allows to use the same control for multiple mixers. This allows the removal of the virtual controls and their virtual registers.
Note: This changes the exposed controls, instead of having one "Left HP Mixer ..." and one "Right HP Mixer ..." control for each input there will only be a single "HP Mixer ..." control.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de --- sound/soc/codecs/wm9712.c | 119 ++++++++++----------------------------------- sound/soc/codecs/wm9713.c | 121 +++++++++------------------------------------- 2 files changed, 49 insertions(+), 191 deletions(-)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index f3aab6e..4ef44bf 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -48,13 +48,8 @@ static const u16 wm9712_reg[] = { 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */ 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */ 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */ - 0x0000, 0x0000 /* virtual hp mixers */ };
-/* virtual HP mixers regs */ -#define HPL_MIXER 0x80 -#define HPR_MIXER 0x82 - static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"}; static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"}; static const char *wm9712_out3_src[] = {"Left", "VREF", "Left + Right", @@ -157,75 +152,14 @@ SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv), SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv), };
-/* We have to create a fake left and right HP mixers because - * the codec only has a single control that is shared by both channels. - * This makes it impossible to determine the audio path. - */ -static int mixer_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - u16 l, r, beep, line, phone, mic, pcm, aux; - - l = ac97_read(w->codec, HPL_MIXER); - r = ac97_read(w->codec, HPR_MIXER); - beep = ac97_read(w->codec, AC97_PC_BEEP); - mic = ac97_read(w->codec, AC97_VIDEO); - phone = ac97_read(w->codec, AC97_PHONE); - line = ac97_read(w->codec, AC97_LINE); - pcm = ac97_read(w->codec, AC97_PCM); - aux = ac97_read(w->codec, AC97_CD); - - if (l & 0x1 || r & 0x1) - ac97_write(w->codec, AC97_VIDEO, mic & 0x7fff); - else - ac97_write(w->codec, AC97_VIDEO, mic | 0x8000); - - if (l & 0x2 || r & 0x2) - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff); - else - ac97_write(w->codec, AC97_PCM, pcm | 0x8000); - - if (l & 0x4 || r & 0x4) - ac97_write(w->codec, AC97_LINE, line & 0x7fff); - else - ac97_write(w->codec, AC97_LINE, line | 0x8000); - - if (l & 0x8 || r & 0x8) - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff); - else - ac97_write(w->codec, AC97_PHONE, phone | 0x8000); - - if (l & 0x10 || r & 0x10) - ac97_write(w->codec, AC97_CD, aux & 0x7fff); - else - ac97_write(w->codec, AC97_CD, aux | 0x8000); - - if (l & 0x20 || r & 0x20) - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff); - else - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000); - - return 0; -} - -/* Left Headphone Mixers */ -static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPL_MIXER, 5, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 4, 1, 0), - SOC_DAPM_SINGLE("Phone Bypass Switch", HPL_MIXER, 3, 1, 0), - SOC_DAPM_SINGLE("Line Bypass Switch", HPL_MIXER, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 1, 1, 0), - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPL_MIXER, 0, 1, 0), -}; - -/* Right Headphone Mixers */ -static const struct snd_kcontrol_new wm9712_hpr_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPR_MIXER, 5, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 4, 1, 0), - SOC_DAPM_SINGLE("Phone Bypass Switch", HPR_MIXER, 3, 1, 0), - SOC_DAPM_SINGLE("Line Bypass Switch", HPR_MIXER, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 1, 1, 0), - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPR_MIXER, 0, 1, 0), +/* Headphone Mixers */ +static const struct snd_kcontrol_new wm9712_hp_mixer_controls[] = { + SOC_DAPM_SINGLE("HP Mixer PCBeep Bypass Switch", AC97_PC_BEEP, 15, 1, 1), + SOC_DAPM_SINGLE("HP Mixer Aux Playback Switch", AC97_CD, 15, 1, 1), + SOC_DAPM_SINGLE("HP Mixer Phone Bypass Switch", AC97_PHONE, 15, 1, 1), + SOC_DAPM_SINGLE("HP Mixer Line Bypass Switch", AC97_LINE, 15, 1, 1), + SOC_DAPM_SINGLE("HP Mixer PCM Playback Switch", AC97_PCM, 15, 1, 1), + SOC_DAPM_SINGLE("HP Mixer Mic Sidetone Switch", AC97_VIDEO, 15, 1, 1), };
/* Speaker Mixer */ @@ -299,12 +233,10 @@ SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, &wm9712_diff_sel_controls), SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT_PAGING, 9, 1, - &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_INT_PAGING, 8, 1, - &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), +SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_INT_PAGING, 9, 1, + wm9712_hp_mixer_controls, ARRAY_SIZE(wm9712_hp_mixer_controls)), +SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_INT_PAGING, 8, 1, + wm9712_hp_mixer_controls, ARRAY_SIZE(wm9712_hp_mixer_controls)), SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAGING, 6, 1, &wm9712_phone_mixer_controls[0], ARRAY_SIZE(wm9712_phone_mixer_controls)), SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_PAGING, 7, 1, @@ -344,21 +276,21 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { {"AC97 Mixer", NULL, "Right DAC"},
/* Left HP mixer */ - {"Left HP Mixer", "PCBeep Bypass Switch", "PCBEEP"}, - {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Left HP Mixer", "Phone Bypass Switch", "Phone PGA"}, - {"Left HP Mixer", "Line Bypass Switch", "Line PGA"}, - {"Left HP Mixer", "PCM Playback Switch", "Left DAC"}, - {"Left HP Mixer", "Mic Sidetone Switch", "Mic PGA"}, + {"Left HP Mixer", "HP Mixer PCBeep Bypass Switch", "PCBEEP"}, + {"Left HP Mixer", "HP Mixer Aux Playback Switch", "Aux DAC"}, + {"Left HP Mixer", "HP Mixer Phone Bypass Switch", "Phone PGA"}, + {"Left HP Mixer", "HP Mixer Line Bypass Switch", "Line PGA"}, + {"Left HP Mixer", "HP Mixer PCM Playback Switch", "Left DAC"}, + {"Left HP Mixer", "HP Mixer Mic Sidetone Switch", "Mic PGA"}, {"Left HP Mixer", NULL, "ALC Sidetone Mux"},
/* Right HP mixer */ - {"Right HP Mixer", "PCBeep Bypass Switch", "PCBEEP"}, - {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Right HP Mixer", "Phone Bypass Switch", "Phone PGA"}, - {"Right HP Mixer", "Line Bypass Switch", "Line PGA"}, - {"Right HP Mixer", "PCM Playback Switch", "Right DAC"}, - {"Right HP Mixer", "Mic Sidetone Switch", "Mic PGA"}, + {"Right HP Mixer", "HP Mixer PCBeep Bypass Switch", "PCBEEP"}, + {"Right HP Mixer", "HP Mixer Aux Playback Switch", "Aux DAC"}, + {"Right HP Mixer", "HP Mixer Phone Bypass Switch", "Phone PGA"}, + {"Right HP Mixer", "HP Mixer Line Bypass Switch", "Line PGA"}, + {"Right HP Mixer", "HP Mixer PCM Playback Switch", "Right DAC"}, + {"Right HP Mixer", "HP Mixer Mic Sidetone Switch", "Mic PGA"}, {"Right HP Mixer", NULL, "ALC Sidetone Mux"},
/* speaker mixer */ @@ -471,8 +403,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, { u16 *cache = codec->reg_cache;
- if (reg < 0x7c) - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(codec->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9712_reg))) cache[reg] = val; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index ac13fc8..cb2bf6c 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -59,13 +59,8 @@ static const u16 wm9713_reg[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0001, 0x0000, 0x574d, 0x4c13, - 0x0000, 0x0000 };
-/* virtual HP mixers regs */ -#define HPL_MIXER 0x80 -#define HPR_MIXER 0x82 - static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; static const char *wm9713_rec_src[] = @@ -233,80 +228,14 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, return 0; }
- -/* We have to create a fake left and right HP mixers because - * the codec only has a single control that is shared by both channels. - * This makes it impossible to determine the audio path using the current - * register map, thus we add a new (virtual) register to help determine the - * audio route within the device. - */ -static int mixer_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - u16 l, r, beep, tone, phone, rec, pcm, aux; - - l = ac97_read(w->codec, HPL_MIXER); - r = ac97_read(w->codec, HPR_MIXER); - beep = ac97_read(w->codec, AC97_PC_BEEP); - tone = ac97_read(w->codec, AC97_MASTER_TONE); - phone = ac97_read(w->codec, AC97_PHONE); - rec = ac97_read(w->codec, AC97_REC_SEL); - pcm = ac97_read(w->codec, AC97_PCM); - aux = ac97_read(w->codec, AC97_AUX); - - if (event & SND_SOC_DAPM_PRE_REG) - return 0; - if ((l & 0x1) || (r & 0x1)) - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff); - else - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000); - - if ((l & 0x2) || (r & 0x2)) - ac97_write(w->codec, AC97_MASTER_TONE, tone & 0x7fff); - else - ac97_write(w->codec, AC97_MASTER_TONE, tone | 0x8000); - - if ((l & 0x4) || (r & 0x4)) - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff); - else - ac97_write(w->codec, AC97_PHONE, phone | 0x8000); - - if ((l & 0x8) || (r & 0x8)) - ac97_write(w->codec, AC97_REC_SEL, rec & 0x7fff); - else - ac97_write(w->codec, AC97_REC_SEL, rec | 0x8000); - - if ((l & 0x10) || (r & 0x10)) - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff); - else - ac97_write(w->codec, AC97_PCM, pcm | 0x8000); - - if ((l & 0x20) || (r & 0x20)) - ac97_write(w->codec, AC97_AUX, aux & 0x7fff); - else - ac97_write(w->codec, AC97_AUX, aux | 0x8000); - - return 0; -} - -/* Left Headphone Mixers */ -static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = { -SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0), -SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0), -SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0), -SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("MonoIn Playback Switch", HPL_MIXER, 1, 1, 0), -SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0), -}; - -/* Right Headphone Mixers */ -static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = { -SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0), -SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0), -SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0), -SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("MonoIn Playback Switch", HPR_MIXER, 1, 1, 0), -SOC_DAPM_SINGLE("Bypass Playback Switch", HPR_MIXER, 0, 1, 0), +/* Headphone Mixers */ +static const struct snd_kcontrol_new wm9713_hp_mixer_controls[] = { +SOC_DAPM_SINGLE("HP Mixer Beep Playback Switch", AC97_AUX, 15, 1, 1), +SOC_DAPM_SINGLE("HP Mixer Voice Playback Switch", AC97_PCM, 15, 1, 1), +SOC_DAPM_SINGLE("HP Mixer Aux Playback Switch", AC97_REC_SEL, 15, 1, 1), +SOC_DAPM_SINGLE("HP Mixer PCM Playback Switch", AC97_PHONE, 15, 1, 1), +SOC_DAPM_SINGLE("HP Mixer MonoIn Playback Switch", AC97_MASTER_TONE, 15, 1, 1), +SOC_DAPM_SINGLE("HP Mixer Bypass Playback Switch", AC97_PC_BEEP, 15, 1, 1), };
/* headphone capture mux */ @@ -428,12 +357,10 @@ SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0, &wm9713_mic_sel_mux_controls), SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0, &wm9713_micb_sel_mux_controls), -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_EXTENDED_MID, 3, 1, - &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_EXTENDED_MID, 2, 1, - &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), +SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_EXTENDED_MID, 3, 1, + wm9713_hp_mixer_controls, ARRAY_SIZE(wm9713_hp_mixer_controls)), +SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_EXTENDED_MID, 2, 1, + wm9713_hp_mixer_controls, ARRAY_SIZE(wm9713_hp_mixer_controls)), SND_SOC_DAPM_MIXER("Mono Mixer", AC97_EXTENDED_MID, 0, 1, &wm9713_mono_mixer_controls[0], ARRAY_SIZE(wm9713_mono_mixer_controls)), SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_EXTENDED_MID, 1, 1, @@ -488,21 +415,21 @@ SND_SOC_DAPM_VMID("VMID"),
static const struct snd_soc_dapm_route wm9713_audio_map[] = { /* left HP mixer */ - {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"}, - {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, - {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"}, - {"Left HP Mixer", "PCM Playback Switch", "Left DAC"}, - {"Left HP Mixer", "MonoIn Playback Switch", "Mono In"}, + {"Left HP Mixer", "HP Mixer Beep Playback Switch", "PCBEEP"}, + {"Left HP Mixer", "HP Mixer Voice Playback Switch", "Voice DAC"}, + {"Left HP Mixer", "HP Mixer Aux Playback Switch", "Aux DAC"}, + {"Left HP Mixer", "HP Mixer Bypass Playback Switch", "Left Line In"}, + {"Left HP Mixer", "HP Mixer PCM Playback Switch", "Left DAC"}, + {"Left HP Mixer", "HP Mixer MonoIn Playback Switch", "Mono In"}, {"Left HP Mixer", NULL, "Capture Headphone Mux"},
/* right HP mixer */ - {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"}, - {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"}, - {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"}, - {"Right HP Mixer", "PCM Playback Switch", "Right DAC"}, - {"Right HP Mixer", "MonoIn Playback Switch", "Mono In"}, + {"Right HP Mixer", "HP Mixer Beep Playback Switch", "PCBEEP"}, + {"Right HP Mixer", "HP Mixer Voice Playback Switch", "Voice DAC"}, + {"Right HP Mixer", "HP Mixer Aux Playback Switch", "Aux DAC"}, + {"Right HP Mixer", "HP Mixer Bypass Playback Switch", "Right Line In"}, + {"Right HP Mixer", "HP Mixer PCM Playback Switch", "Right DAC"}, + {"Right HP Mixer", "HP Mixer MonoIn Playback Switch", "Mono In"}, {"Right HP Mixer", NULL, "Capture Headphone Mux"},
/* virtual mixer - mixes left & right channels for spk and mono */
On Thu, Oct 30, 2014 at 09:01:11PM +0100, Lars-Peter Clausen wrote:
Note: This changes the exposed controls, instead of having one "Left HP Mixer ..." and one "Right HP Mixer ..." control for each input there will only be a single "HP Mixer ..." control.
This change would be a win except for the above - these devices were very widely deployed in fairly popular devices like the Sharp Zaurus devices so there's quite a bit of deployed distro config in things like Angstrom which would get broken if we updated, and some user community remaining too. On balance I'd say that the cleanup to use the new feature isn't worth the disruption it'd cause to userspace.
On 10/31/2014 06:40 PM, Mark Brown wrote:
On Thu, Oct 30, 2014 at 09:01:11PM +0100, Lars-Peter Clausen wrote:
Note: This changes the exposed controls, instead of having one "Left HP Mixer ..." and one "Right HP Mixer ..." control for each input there will only be a single "HP Mixer ..." control.
This change would be a win except for the above - these devices were very widely deployed in fairly popular devices like the Sharp Zaurus devices so there's quite a bit of deployed distro config in things like Angstrom which would get broken if we updated, and some user community remaining too. On balance I'd say that the cleanup to use the new feature isn't worth the disruption it'd cause to userspace.
It was worth a try ;) We can still clean this up using custom put/get handlers instead of virtual registers.
On Thu, Oct 30, 2014 at 09:00:57PM +0100, Lars-Peter Clausen wrote:
Hi,
This series does a few AC'97 driver cleanups in preparation of the conversion of the drivers to regmap. Most of the patches are quite trivial.
The last two patches remove the virtual registers from the wm9712 and wm9713 drivers, which is a requirement for regmap conversion.
The last patch is the only one in this series that is a bit more complex. Currently the drivers have a open-coded implementation of shared controls which is replaced by the patch with the generic one from the ASoC core. Unfortunately this changes the controls that are exposed by the driver, instead of having a "Left HP Mixer ..." and a "Right HP Mixer ..." control for each mixer input there will only be a single "HP Mixer" control. This may or may not be considered breaking the userspace interface. If it is we need to take a different approach at removing the virtual register form the driver.
- Lars
Lars-Peter Clausen (14): ASoC: ad1980: Remove unused header ASoC: ad1980: Cleanup printk usage ASoC: ad1980: Use table based control setup ASoC: stac9766: Cleanup printk usage ASoC: stac9766: Use table based control setup ASoC: wm9705: Cleanup printk usage ASoC: wm9705: Use table based control setup ASoC: wm9712: Cleanup printk usage ASoC: wm9712: Use table based control setup ASoC: wm9713: Cleanup printk usage ASoC: wm9713: Use table based control setup ASoC: wm9713: Move driver state struct allocation to driver probe ASoC: wm9713: Use virtual control instead of virtual register ASoC: wm9712/wm9713: Use shared controls
Acked-by: Charles Keepax ckeepax@opensource.wolfsonmicro.com
For the Wolfson parts.
Thanks, Charles
participants (3)
-
Charles Keepax
-
Lars-Peter Clausen
-
Mark Brown