From b4f4f2eba4e8f717ccd1bb2a35c602ad00dcdfe0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 30 Sep 2016 19:27:29 +0200 Subject: [PATCH 1/6] ASoC: wm9712: Convert to regmap Currently the wm9712 driver still uses custom snd_soc_codec_driver IO callbacks. This has been deprecated for a while, so convert the wm9712 driver to use regmap for its IO. Signed-off-by: Lars-Peter Clausen Tested-by: Marek Vasut Acked-by: Marek Vasut Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 1 + sound/soc/codecs/wm9712.c | 143 +++++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 65 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index c67667bb970f..f472254a575d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1057,6 +1057,7 @@ config SND_SOC_WM9705 config SND_SOC_WM9712 tristate + select REGMAP_AC97 config SND_SOC_WM9713 tristate diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 557709eac698..d2d0d2bb4412 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -32,31 +33,66 @@ struct wm9712_priv { struct mutex lock; }; -static unsigned int ac97_read(struct snd_soc_codec *codec, - unsigned int reg); -static int ac97_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val); +static const struct reg_default wm9712_reg_defaults[] = { + { 0x02, 0x8000 }, + { 0x04, 0x8000 }, + { 0x06, 0x8000 }, + { 0x08, 0x0f0f }, + { 0x0a, 0xaaa0 }, + { 0x0c, 0xc008 }, + { 0x0e, 0x6808 }, + { 0x10, 0xe808 }, + { 0x12, 0xaaa0 }, + { 0x14, 0xad00 }, + { 0x16, 0x8000 }, + { 0x18, 0xe808 }, + { 0x1a, 0x3000 }, + { 0x1c, 0x8000 }, + { 0x20, 0x0000 }, + { 0x22, 0x0000 }, + { 0x26, 0x000f }, + { 0x28, 0x0605 }, + { 0x2a, 0x0410 }, + { 0x2c, 0xbb80 }, + { 0x2e, 0xbb80 }, + { 0x32, 0xbb80 }, + { 0x34, 0x2000 }, + { 0x4c, 0xf83e }, + { 0x4e, 0xffff }, + { 0x50, 0x0000 }, + { 0x52, 0x0000 }, + { 0x56, 0xf83e }, + { 0x58, 0x0008 }, + { 0x5c, 0x0000 }, + { 0x60, 0xb032 }, + { 0x62, 0x3e00 }, + { 0x64, 0x0000 }, + { 0x76, 0x0006 }, + { 0x78, 0x0001 }, + { 0x7a, 0x0000 }, +}; -/* - * WM9712 register cache - */ -static const u16 wm9712_reg[] = { - 0x6174, 0x8000, 0x8000, 0x8000, /* 6 */ - 0x0f0f, 0xaaa0, 0xc008, 0x6808, /* e */ - 0xe808, 0xaaa0, 0xad00, 0x8000, /* 16 */ - 0xe808, 0x3000, 0x8000, 0x0000, /* 1e */ - 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */ - 0x0405, 0x0410, 0xbb80, 0xbb80, /* 2e */ - 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */ - 0x0000, 0x2000, 0x0000, 0x0000, /* 3e */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 46 */ - 0x0000, 0x0000, 0xf83e, 0xffff, /* 4e */ - 0x0000, 0x0000, 0x0000, 0xf83e, /* 56 */ - 0x0008, 0x0000, 0x0000, 0x0000, /* 5e */ - 0xb032, 0x3e00, 0x0000, 0x0000, /* 66 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */ - 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */ - 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */ +static bool wm9712_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case AC97_REC_GAIN: + return true; + default: + return regmap_ac97_default_volatile(dev, reg); + } +} + +static const struct regmap_config wm9712_regmap_config = { + .reg_bits = 16, + .reg_stride = 2, + .val_bits = 16, + .max_register = 0x7e, + .cache_type = REGCACHE_RBTREE, + + .volatile_reg = wm9712_volatile_reg, + + .reg_defaults = wm9712_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm9712_reg_defaults), }; #define HPL_MIXER 0x0 @@ -488,35 +524,13 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { - struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); - u16 *cache = codec->reg_cache; - - if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || - reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || - reg == AC97_REC_GAIN) - return soc_ac97_ops->read(wm9712->ac97, reg); - else { - reg = reg >> 1; - - if (reg >= (ARRAY_SIZE(wm9712_reg))) - return -EIO; - - return cache[reg]; - } + return snd_soc_read(codec, reg); } static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { - struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); - u16 *cache = codec->reg_cache; - - soc_ac97_ops->write(wm9712->ac97, reg, val); - reg = reg >> 1; - if (reg < (ARRAY_SIZE(wm9712_reg))) - cache[reg] = val; - - return 0; + return snd_soc_write(codec, reg, val); } static int ac97_prepare(struct snd_pcm_substream *substream, @@ -619,8 +633,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec, static int wm9712_soc_resume(struct snd_soc_codec *codec) { struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); - int i, ret; - u16 *cache = codec->reg_cache; + int ret; ret = snd_ac97_reset(wm9712->ac97, true, WM9712_VENDOR_ID, WM9712_VENDOR_ID_MASK); @@ -629,15 +642,8 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec) snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); - if (ret == 0) { - /* Sync reg_cache with the hardware after cold reset */ - for (i = 2; i < ARRAY_SIZE(wm9712_reg) << 1; i += 2) { - if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || - (i > 0x58 && i != 0x5c)) - continue; - soc_ac97_ops->write(wm9712->ac97, i, cache[i>>1]); - } - } + if (ret == 0) + regcache_sync(codec->component.regmap); return ret; } @@ -645,6 +651,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec) static int wm9712_soc_probe(struct snd_soc_codec *codec) { struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); + struct regmap *regmap; int ret; wm9712->ac97 = snd_soc_new_ac97_codec(codec, WM9712_VENDOR_ID, @@ -655,16 +662,28 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) return ret; } + regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto err_free_ac97_codec; + } + + snd_soc_codec_init_regmap(codec, regmap); + /* set alc mux to none */ ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); return 0; +err_free_ac97_codec: + snd_soc_free_ac97_codec(wm9712->ac97); + return ret; } static int wm9712_soc_remove(struct snd_soc_codec *codec) { struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); + snd_soc_codec_exit_regmap(codec); snd_soc_free_ac97_codec(wm9712->ac97); return 0; } @@ -673,14 +692,8 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = { .probe = wm9712_soc_probe, .remove = wm9712_soc_remove, .resume = wm9712_soc_resume, - .read = ac97_read, - .write = ac97_write, .set_bias_level = wm9712_set_bias_level, .suspend_bias_off = true, - .reg_cache_size = ARRAY_SIZE(wm9712_reg), - .reg_word_size = sizeof(u16), - .reg_cache_step = 2, - .reg_cache_default = wm9712_reg, .component_driver = { .controls = wm9712_snd_ac97_controls, From 7e845e76e656967366be04646d80d815e8704914 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 30 Sep 2016 19:27:30 +0200 Subject: [PATCH 2/6] ASoC: wm9712: Remove ac97_read/ac97_write wrappers Since the regmap conversion ac97_read/ac97_write are just simple wrappers around snd_soc_read/snd_soc_write. Use those instead directly and remove the wrappers. Also use snd_soc_update_bits() were appropriate. Signed-off-by: Lars-Peter Clausen Tested-by: Marek Vasut Acked-by: Marek Vasut Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index d2d0d2bb4412..20b2e8216336 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -521,53 +521,36 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { {"ROUT2", NULL, "Speaker PGA"}, }; -static unsigned int ac97_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return snd_soc_read(codec, reg); -} - -static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - return snd_soc_write(codec, reg, val); -} - static int ac97_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; int reg; - u16 vra; struct snd_pcm_runtime *runtime = substream->runtime; - vra = ac97_read(codec, AC97_EXTENDED_STATUS); - ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); + snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg = AC97_PCM_FRONT_DAC_RATE; else reg = AC97_PCM_LR_ADC_RATE; - return ac97_write(codec, reg, runtime->rate); + return snd_soc_write(codec, reg, runtime->rate); } static int ac97_aux_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - u16 vra, xsle; struct snd_pcm_runtime *runtime = substream->runtime; - vra = ac97_read(codec, AC97_EXTENDED_STATUS); - ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); - xsle = ac97_read(codec, AC97_PCI_SID); - ac97_write(codec, AC97_PCI_SID, xsle | 0x8000); + snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1); + snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000); if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; - return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); + return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); } #define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ @@ -619,12 +602,12 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - ac97_write(codec, AC97_POWERDOWN, 0x0000); + snd_soc_write(codec, AC97_POWERDOWN, 0x0000); break; case SND_SOC_BIAS_OFF: /* disable everything including AC link */ - ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); - ac97_write(codec, AC97_POWERDOWN, 0xffff); + snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); + snd_soc_write(codec, AC97_POWERDOWN, 0xffff); break; } return 0; @@ -671,7 +654,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) snd_soc_codec_init_regmap(codec, regmap); /* set alc mux to none */ - ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); + snd_soc_update_bits(codec, AC97_VIDEO, 0x3000, 0x3000); return 0; err_free_ac97_codec: From 0d895e14dff0af1838ca79a82f2c0cee7b8bf7ef Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 15 Oct 2016 19:32:52 +0200 Subject: [PATCH 3/6] ASoC: wm9712: Remove unused DAI ID defines The DAI ID defines are back from the time when DAIs were referenced by a numerical ID. These days a string is used for matching instead and the defines are unused. The last user of these defines was removed in commit f0fba2ad1b6b ("ASoC: multi-component - ASoC Multi-Component Support"). So remove the defines as well. This also means the wm9712.h file no longer has any content and can be removed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 1 - sound/soc/codecs/wm9712.h | 11 ----------- sound/soc/pxa/e800_wm9712.c | 1 - sound/soc/pxa/em-x270.c | 1 - sound/soc/pxa/palm27x.c | 1 - sound/soc/pxa/tosa.c | 1 - 6 files changed, 16 deletions(-) delete mode 100644 sound/soc/codecs/wm9712.h diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 20b2e8216336..5ed484eb47b2 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -22,7 +22,6 @@ #include #include #include -#include "wm9712.h" #define WM9712_VENDOR_ID 0x574d4c12 #define WM9712_VENDOR_ID_MASK 0xffffffff diff --git a/sound/soc/codecs/wm9712.h b/sound/soc/codecs/wm9712.h deleted file mode 100644 index fb69c3aa4ed0..000000000000 --- a/sound/soc/codecs/wm9712.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * wm9712.h -- WM9712 Soc Audio driver - */ - -#ifndef _WM9712_H -#define _WM9712_H - -#define WM9712_DAI_AC97_HIFI 0 -#define WM9712_DAI_AC97_AUX 1 - -#endif diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 41bf71466a7b..07b9c6e17df9 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -21,7 +21,6 @@ #include #include -#include "../codecs/wm9712.h" #include "pxa2xx-ac97.h" static int e800_spk_amp_event(struct snd_soc_dapm_widget *w, diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index 64743a05aeae..966163d1c813 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -30,7 +30,6 @@ #include #include -#include "../codecs/wm9712.h" #include "pxa2xx-ac97.h" static struct snd_soc_dai_link em_x270_dai[] = { diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index bcc81e920a67..387492d46b6c 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -27,7 +27,6 @@ #include #include -#include "../codecs/wm9712.h" #include "pxa2xx-ac97.h" static struct snd_soc_jack hs_jack; diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index c508f024ecfb..daed981f02dd 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -31,7 +31,6 @@ #include #include -#include "../codecs/wm9712.h" #include "pxa2xx-ac97.h" #define TOSA_HP 0 From 50d12367811a26dd8d5f7090d5578c3edecb795d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 15 Oct 2016 19:32:53 +0200 Subject: [PATCH 4/6] ASoC: wm9713: Remove unused DAI ID defines The DAI ID defines are back from the time when DAIs were referenced by a numerical ID. These days a string is used for matching instead and the defines are unused. The last user of these defines was removed in commit f0fba2ad1b6b ("ASoC: multi-component - ASoC Multi-Component Support"). So remove the defines as well. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h index 53df11b1f727..7ecffc563016 100644 --- a/sound/soc/codecs/wm9713.h +++ b/sound/soc/codecs/wm9713.h @@ -41,8 +41,4 @@ #define WM9713_PCMBCLK_DIV_8 (3 << 9) #define WM9713_PCMBCLK_DIV_16 (4 << 9) -#define WM9713_DAI_AC97_HIFI 0 -#define WM9713_DAI_AC97_AUX 1 -#define WM9713_DAI_PCM_VOICE 2 - #endif From de7975c2a42de889e2b3fd2f7d46f899ad8ccd45 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 8 Dec 2016 16:44:14 +0800 Subject: [PATCH 5/6] ASoC: zte: spdif and i2s drivers are not zx296702 specific ZTE ZX SPDIF and I2S drivers can work on not only ZX296702 but also other ZTE ZX family SoCs like ZX296718, which is an arm64 platform. Let's make a few renaming and tweak the Kconfig a bit to get the drivers available for other ZTE ZX platforms. Signed-off-by: Shawn Guo Reviewed-by: Jun Nie Signed-off-by: Mark Brown --- sound/soc/zte/Kconfig | 16 ++++++++-------- sound/soc/zte/Makefile | 4 ++-- sound/soc/zte/{zx296702-i2s.c => zx-i2s.c} | 0 sound/soc/zte/{zx296702-spdif.c => zx-spdif.c} | 0 4 files changed, 10 insertions(+), 10 deletions(-) rename sound/soc/zte/{zx296702-i2s.c => zx-i2s.c} (100%) rename sound/soc/zte/{zx296702-spdif.c => zx-spdif.c} (100%) diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig index c47eb25e441f..6d8a90d36315 100644 --- a/sound/soc/zte/Kconfig +++ b/sound/soc/zte/Kconfig @@ -1,17 +1,17 @@ -config ZX296702_SPDIF - tristate "ZX296702 spdif" - depends on SOC_ZX296702 || COMPILE_TEST +config ZX_SPDIF + tristate "ZTE ZX SPDIF Driver Support" + depends on ARCH_ZX || COMPILE_TEST depends on COMMON_CLK select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the - zx296702 spdif interface + ZTE ZX SPDIF interface -config ZX296702_I2S - tristate "ZX296702 i2s" - depends on SOC_ZX296702 || COMPILE_TEST +config ZX_I2S + tristate "ZTE ZX I2S Driver Support" + depends on ARCH_ZX || COMPILE_TEST depends on COMMON_CLK select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the - zx296702 i2s interface + ZTE ZX I2S interface diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile index 254ed2c8c1a0..77768f5fd10c 100644 --- a/sound/soc/zte/Makefile +++ b/sound/soc/zte/Makefile @@ -1,2 +1,2 @@ -obj-$(CONFIG_ZX296702_SPDIF) += zx296702-spdif.o -obj-$(CONFIG_ZX296702_I2S) += zx296702-i2s.o +obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o +obj-$(CONFIG_ZX_I2S) += zx-i2s.o diff --git a/sound/soc/zte/zx296702-i2s.c b/sound/soc/zte/zx-i2s.c similarity index 100% rename from sound/soc/zte/zx296702-i2s.c rename to sound/soc/zte/zx-i2s.c diff --git a/sound/soc/zte/zx296702-spdif.c b/sound/soc/zte/zx-spdif.c similarity index 100% rename from sound/soc/zte/zx296702-spdif.c rename to sound/soc/zte/zx-spdif.c From 44b1c9a6e7a2692e761e35ada2ffe84b20c2a377 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 8 Dec 2016 16:44:15 +0800 Subject: [PATCH 6/6] ASoC: zte: spdif: correct ZX_SPDIF_CLK_RAT define The macro ZX_SPDIF_CLK_RAT should be 2 instead of 4. With this fix, we can get correct audio output on HDMI through SPDIF interface. Signed-off-by: Shawn Guo Acked-by: Jun Nie Signed-off-by: Mark Brown --- sound/soc/zte/zx-spdif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/zte/zx-spdif.c b/sound/soc/zte/zx-spdif.c index 26265ce4caca..9fa6463ce5d7 100644 --- a/sound/soc/zte/zx-spdif.c +++ b/sound/soc/zte/zx-spdif.c @@ -71,7 +71,7 @@ #define ZX_VALID_RIGHT_TRACK (2 << 0) #define ZX_VALID_TRACK_MASK (3 << 0) -#define ZX_SPDIF_CLK_RAT (4 * 32) +#define ZX_SPDIF_CLK_RAT (2 * 32) struct zx_spdif_info { struct snd_dmaengine_dai_dma_data dma_data;