diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-03-05 15:07:33 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-03-05 15:07:33 +0100 |
commit | 650d6e25cde82fda425995ba77ed4b0ad3be5b8d (patch) | |
tree | 44ed9829a0b1797d4eea907aa1ed68273f7e3692 /sound/soc/codecs | |
parent | 6b21ed851624a03f11ea9ed3f229f56419e03686 (diff) | |
parent | ad20ff920c1fd217578e2c637dd50c1878a21c06 (diff) | |
download | linux-stable-650d6e25cde82fda425995ba77ed4b0ad3be5b8d.tar.gz linux-stable-650d6e25cde82fda425995ba77ed4b0ad3be5b8d.tar.bz2 linux-stable-650d6e25cde82fda425995ba77ed4b0ad3be5b8d.zip |
Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into topic/asoc
This has been a very active release for ASoC, as well as the usual raft
of bugfixes and driver updates there's quite a few framework enhancements.
Most are either small or are laying the groundwork for user visible
features (especially dynamic PCM), the most directly visible change is
the dmaengine library. There's also a bunch of regmap API enhancements
pulled into the tree so that either the framework or drivers can take
advantage of the new features.
Changes include:
- Support for widgets not associated with a CODEC, an important part of
the dynamic PCM framework.
- A library factoring out the common code shared by dmaengine based DMA
drivers contributed by Lars-Peter Clausen. This will save a lot of
code and make it much easier to deploy enhancements to dmaengine.
- Support for binary controls, used for providing runtime configuration
of algorithm coefficients.
- A new DAPM widget type for regulator supplies allowing drivers for
devices that can power down unused supplies while active to do without
any per-driver code.
- DAPM widgets for DAIs, initially giving a speed boost for playback
startup and shutdown and also the basis for CODEC<->CODEC DAI link
support.
- Support for specifying the number of significant bits on audio
interfaces, useful for allowing applications to know how much effort to
put into generating data for a larger sample format.
- Conversion of the FSI driver used on some SH processors to DMAEngine.
- New CODEC drivers for Maxim MAX9768 and Wolfson Microelectronics WM2200.
Diffstat (limited to 'sound/soc/codecs')
68 files changed, 7501 insertions, 1110 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 7c205e77d83a..6508e8b790bb 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX98088 if I2C select SND_SOC_MAX98095 if I2C select SND_SOC_MAX9850 if I2C + select SND_SOC_MAX9768 if I2C select SND_SOC_MAX9877 if I2C select SND_SOC_PCM3008 select SND_SOC_RT5631 if I2C @@ -62,6 +63,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WL1273 if MFD_WL1273_CORE select SND_SOC_WM1250_EV1 if I2C select SND_SOC_WM2000 if I2C + select SND_SOC_WM2200 if I2C select SND_SOC_WM5100 if I2C select SND_SOC_WM8350 if MFD_WM8350 select SND_SOC_WM8400 if MFD_WM8400 @@ -292,6 +294,9 @@ config SND_SOC_WM1250_EV1 config SND_SOC_WM2000 tristate +config SND_SOC_WM2200 + tristate + config SND_SOC_WM5100 tristate @@ -425,6 +430,9 @@ config SND_SOC_WM9713 config SND_SOC_LM4857 tristate +config SND_SOC_MAX9768 + tristate + config SND_SOC_MAX9877 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index de8078178f86..6662eb0cdcc0 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o snd-soc-jz4740-codec-objs := jz4740.o snd-soc-l3-objs := l3.o snd-soc-lm4857-objs := lm4857.o +snd-soc-max9768-objs := max9768.o snd-soc-max98088-objs := max98088.o snd-soc-max98095-objs := max98095.o snd-soc-max9850-objs := max9850.o @@ -51,6 +52,7 @@ snd-soc-uda1380-objs := uda1380.o snd-soc-wl1273-objs := wl1273.o snd-soc-wm1250-ev1-objs := wm1250-ev1.o snd-soc-wm2000-objs := wm2000.o +snd-soc-wm2200-objs := wm2200.o snd-soc-wm5100-objs := wm5100.o wm5100-tables.o snd-soc-wm8350-objs := wm8350.o snd-soc-wm8400-objs := wm8400.o @@ -129,6 +131,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o +obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o @@ -153,6 +156,7 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o +obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 982d201c2e86..12e3b4118557 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec) if (ad1836->type == AD1836) { /* left/right diff:PGA/MUX */ snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); - ret = snd_soc_add_controls(codec, ad1836_controls, + ret = snd_soc_add_codec_controls(codec, ad1836_controls, ARRAY_SIZE(ad1836_controls)); if (ret) return ret; @@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec) snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); } - ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2); + ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2); if (ret) return ret; - ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs); + ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs); if (ret) return ret; diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9bba7f849464..8c39dddd7d00 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -228,7 +228,7 @@ 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_controls(codec, ad1980_snd_ac97_controls, + snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls, ARRAY_SIZE(ad1980_snd_ac97_controls)); return 0; diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 971ba4529171..44f59064d8de 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec) return ret; } - codec->dapm.idle_bias_off = true; - if (pdata) { if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) return -EINVAL; @@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec) pdata->drc_setting[i]); } - snd_soc_add_controls(codec, adau1373_drc_controls, + snd_soc_add_codec_controls(codec, adau1373_drc_controls, pdata->num_drc); val = 0; @@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec) } if (!lineout_differential) { - snd_soc_add_controls(codec, adau1373_lineout2_controls, + snd_soc_add_codec_controls(codec, adau1373_lineout2_controls, ARRAY_SIZE(adau1373_lineout2_controls)); } @@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = { .suspend = adau1373_suspend, .resume = adau1373_resume, .set_bias_level = adau1373_set_bias_level, + .idle_bias_off = true, .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), .reg_cache_default = adau1373_default_regs, .reg_word_size = sizeof(uint8_t), diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 6b325ea03869..78e9ce48bb99 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec) { int ret; - codec->dapm.idle_bias_off = 1; codec->control_data = to_i2c_client(codec->dev); ret = adau1701_load_firmware(codec); @@ -473,6 +472,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) static struct snd_soc_codec_driver adau1701_codec_drv = { .probe = adau1701_probe, .set_bias_level = adau1701_set_bias_level, + .idle_bias_off = true, .reg_cache_size = ADAU1701_NUM_REGS, .reg_word_size = sizeof(u16), diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index d27b5e4cce99..ceb96ecf5588 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -46,75 +46,15 @@ #define DRV_NAME "ak4104-codec" struct ak4104_private { - enum snd_soc_control_type control_type; - void *control_data; + struct regmap *regmap; }; -static int ak4104_fill_cache(struct snd_soc_codec *codec) -{ - int i; - u8 *reg_cache = codec->reg_cache; - struct spi_device *spi = codec->control_data; - - for (i = 0; i < codec->driver->reg_cache_size; i++) { - int ret = spi_w8r8(spi, i | AK4104_READ); - if (ret < 0) { - dev_err(&spi->dev, "SPI write failure\n"); - return ret; - } - - reg_cache[i] = ret; - } - - return 0; -} - -static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u8 *reg_cache = codec->reg_cache; - - if (reg >= codec->driver->reg_cache_size) - return -EINVAL; - - return reg_cache[reg]; -} - -static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 *cache = codec->reg_cache; - struct spi_device *spi = codec->control_data; - - if (reg >= codec->driver->reg_cache_size) - return -EINVAL; - - /* only write to the hardware if value has changed */ - if (cache[reg] != value) { - u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value }; - - if (spi_write(spi, tmp, sizeof(tmp))) { - dev_err(&spi->dev, "SPI write failed\n"); - return -EIO; - } - - cache[reg] = value; - } - - return 0; -} - static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; int val = 0; - - val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); - if (val < 0) - return val; - - val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1); + int ret; /* set DAI format */ switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -135,7 +75,13 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) return -EINVAL; - return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); + ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, + AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, + val); + if (ret < 0) + return ret; + + return 0; } static int ak4104_hw_params(struct snd_pcm_substream *substream, @@ -148,7 +94,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, /* set the IEC958 bits: consumer mode, no copyright bit */ val |= IEC958_AES0_CON_NOT_COPYRIGHT; - ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val); + snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val); val = 0; @@ -167,7 +113,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); + return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val); } static const struct snd_soc_dai_ops ak4101_dai_ops = { @@ -192,67 +138,57 @@ static struct snd_soc_dai_driver ak4104_dai = { static int ak4104_probe(struct snd_soc_codec *codec) { struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); - int ret, val; - - codec->control_data = ak4104->control_data; + int ret; - /* read all regs and fill the cache */ - ret = ak4104_fill_cache(codec); - if (ret < 0) { - dev_err(codec->dev, "failed to fill register cache\n"); + codec->control_data = ak4104->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); + if (ret != 0) return ret; - } - - /* read the 'reserved' register - according to the datasheet, it - * should contain 0x5b. Not a good way to verify the presence of - * the device, but there is no hardware ID register. */ - if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) != - AK4104_RESERVED_VAL) - return -ENODEV; /* set power-up and non-reset bits */ - val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); - val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; - ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); + ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, + AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, + AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); if (ret < 0) return ret; /* enable transmitter */ - val = ak4104_read_reg_cache(codec, AK4104_REG_TX); - val |= AK4104_TX_TXE; - ret = ak4104_spi_write(codec, AK4104_REG_TX, val); + ret = snd_soc_update_bits(codec, AK4104_REG_TX, + AK4104_TX_TXE, AK4104_TX_TXE); if (ret < 0) return ret; - dev_info(codec->dev, "SPI device initialized\n"); return 0; } static int ak4104_remove(struct snd_soc_codec *codec) { - int val, ret; - - val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); - if (val < 0) - return val; - - /* clear power-up and non-reset bits */ - val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); - ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); + snd_soc_update_bits(codec, AK4104_REG_CONTROL1, + AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); - return ret; + return 0; } static struct snd_soc_codec_driver soc_codec_device_ak4104 = { .probe = ak4104_probe, .remove = ak4104_remove, - .reg_cache_size = AK4104_NUM_REGS, - .reg_word_size = sizeof(u8), +}; + +static const struct regmap_config ak4104_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = AK4104_NUM_REGS - 1, + .read_flag_mask = AK4104_READ, + .write_flag_mask = AK4104_WRITE, + + .cache_type = REGCACHE_RBTREE, }; static int ak4104_spi_probe(struct spi_device *spi) { struct ak4104_private *ak4104; + unsigned int val; int ret; spi->bits_per_word = 8; @@ -266,17 +202,41 @@ static int ak4104_spi_probe(struct spi_device *spi) if (ak4104 == NULL) return -ENOMEM; - ak4104->control_data = spi; - ak4104->control_type = SND_SOC_SPI; + ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap); + if (IS_ERR(ak4104->regmap)) { + ret = PTR_ERR(ak4104->regmap); + return ret; + } + + /* read the 'reserved' register - according to the datasheet, it + * should contain 0x5b. Not a good way to verify the presence of + * the device, but there is no hardware ID register. */ + ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); + if (ret != 0) + goto err; + if (val != AK4104_RESERVED_VAL) { + ret = -ENODEV; + goto err; + } + spi_set_drvdata(spi, ak4104); ret = snd_soc_register_codec(&spi->dev, &soc_codec_device_ak4104, &ak4104_dai, 1); + if (ret != 0) + goto err; + + return 0; + +err: + regmap_exit(ak4104->regmap); return ret; } static int __devexit ak4104_spi_remove(struct spi_device *spi) { + struct ak4104_private *ak4101 = spi_get_drvdata(spi); + regmap_exit(ak4101->regmap); snd_soc_unregister_codec(&spi->dev); return 0; } @@ -290,17 +250,7 @@ static struct spi_driver ak4104_spi_driver = { .remove = __devexit_p(ak4104_spi_remove), }; -static int __init ak4104_init(void) -{ - return spi_register_driver(&ak4104_spi_driver); -} -module_init(ak4104_init); - -static void __exit ak4104_exit(void) -{ - spi_unregister_driver(&ak4104_spi_driver); -} -module_exit(ak4104_exit); +module_spi_driver(ak4104_spi_driver); MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 9e809e05d066..838ae8b22b50 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> +#include <linux/regmap.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -27,24 +28,43 @@ #include "ak4535.h" -#define AK4535_VERSION "0.3" - /* codec private data */ struct ak4535_priv { + struct regmap *regmap; unsigned int sysclk; - enum snd_soc_control_type control_type; }; /* * ak4535 register cache */ -static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { - 0x00, 0x80, 0x00, 0x03, - 0x02, 0x00, 0x11, 0x01, - 0x00, 0x40, 0x36, 0x10, - 0x00, 0x00, 0x57, 0x00, +static const struct reg_default ak4535_reg_defaults[] = { + { 0, 0x00 }, + { 1, 0x80 }, + { 2, 0x00 }, + { 3, 0x03 }, + { 4, 0x02 }, + { 5, 0x00 }, + { 6, 0x11 }, + { 7, 0x01 }, + { 8, 0x00 }, + { 9, 0x40 }, + { 10, 0x36 }, + { 11, 0x10 }, + { 12, 0x00 }, + { 13, 0x00 }, + { 14, 0x57 }, }; +static bool ak4535_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case AK4535_STATUS: + return true; + default: + return false; + } +} + static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; @@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec) struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); int ret; - printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); - - ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type); + codec->control_data = ak4535->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec) /* power on device */ ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, ak4535_snd_controls, + snd_soc_add_codec_controls(codec, ak4535_snd_controls, ARRAY_SIZE(ak4535_snd_controls)); return 0; } @@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec) return 0; } +static const struct regmap_config ak4535_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = AK4535_STATUS, + .volatile_reg = ak4535_volatile, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = ak4535_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults), +}; + static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .probe = ak4535_probe, .remove = ak4535_remove, .suspend = ak4535_suspend, .resume = ak4535_resume, .set_bias_level = ak4535_set_bias_level, - .reg_cache_size = ARRAY_SIZE(ak4535_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = ak4535_reg, .dapm_widgets = ak4535_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), .dapm_routes = ak4535_audio_map, .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, if (ak4535 == NULL) return -ENOMEM; + ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap); + if (IS_ERR(ak4535->regmap)) { + ret = PTR_ERR(ak4535->regmap); + dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); + return ret; + } + i2c_set_clientdata(i2c, ak4535); - ak4535->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4535, &ak4535_dai, 1); + if (ret != 0) + regmap_exit(ak4535->regmap); + return ret; } static __devexit int ak4535_i2c_remove(struct i2c_client *client) { + struct ak4535_priv *ak4535 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); + regmap_exit(ak4535->regmap); return 0; } @@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id); static struct i2c_driver ak4535_i2c_driver = { .driver = { - .name = "ak4535-codec", + .name = "ak4535", .owner = THIS_MODULE, }, .probe = ak4535_i2c_probe, .remove = __devexit_p(ak4535_i2c_remove), .id_table = ak4535_i2c_id, }; -#endif -static int __init ak4535_modinit(void) -{ - int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&ak4535_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n", - ret); - } -#endif - return ret; -} -module_init(ak4535_modinit); - -static void __exit ak4535_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&ak4535_i2c_driver); -#endif -} -module_exit(ak4535_exit); +module_i2c_driver(ak4535_i2c_driver); MODULE_DESCRIPTION("Soc AK4535 driver"); MODULE_AUTHOR("Richard Purdie"); diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h index 0431e5f634a2..402de1d274bf 100644 --- a/sound/soc/codecs/ak4535.h +++ b/sound/soc/codecs/ak4535.h @@ -34,6 +34,4 @@ #define AK4535_VOL 0xe #define AK4535_STATUS 0xf -#define AK4535_CACHEREGNUM 0x10 - #endif diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 5ef70b5d27e4..16bd1e7d2384 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -476,7 +476,7 @@ static int ak4642_probe(struct snd_soc_codec *codec) return ret; } - snd_soc_add_controls(codec, ak4642_snd_controls, + snd_soc_add_codec_controls(codec, ak4642_snd_controls, ARRAY_SIZE(ak4642_snd_controls)); ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index a53b152e6a07..5fb7c2a80e6d 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec) return ret; } - snd_soc_add_controls(codec, ak4671_snd_controls, + snd_soc_add_codec_controls(codec, ak4671_snd_controls, ARRAY_SIZE(ak4671_snd_controls)); ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 08f24198c8da..d47b62ddb210 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec) switch (alc5623->id) { case 0x21: - snd_soc_add_controls(codec, alc5621_vol_snd_controls, + snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls, ARRAY_SIZE(alc5621_vol_snd_controls)); break; case 0x22: - snd_soc_add_controls(codec, alc5622_vol_snd_controls, + snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls, ARRAY_SIZE(alc5622_vol_snd_controls)); break; case 0x23: - snd_soc_add_controls(codec, alc5623_vol_snd_controls, + snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls, ARRAY_SIZE(alc5623_vol_snd_controls)); break; default: return -EINVAL; } - snd_soc_add_controls(codec, alc5623_snd_controls, + snd_soc_add_codec_controls(codec, alc5623_snd_controls, ARRAY_SIZE(alc5623_snd_controls)); snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index af9c27ae02f0..e2111e0ccad7 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); /* -16.5db min scale, 1.5db steps, no mute */ static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); static const unsigned int boost_tlv[] = { - TLV_DB_RANGE_HEAD(3), - 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), - 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), - 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), + TLV_DB_RANGE_HEAD(2), + 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), + 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), }; /* 0db min scale, 6 db steps, no mute */ static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); /* 0db min scalem 0.75db steps, no mute */ -static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0); +static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0); static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { /* left starts at bit 8, right at bit 0 */ @@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = { ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), SOC_SINGLE_TLV("Voice DAC Playback Volume", ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), - SOC_SINGLE_TLV("Phone Capture Volume", + SOC_SINGLE("Voice DAC Playback Switch", + ALC5632_VOICE_DAC_VOL, 12, 1, 1), + SOC_SINGLE_TLV("Phone Playback Volume", ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), - SOC_DOUBLE_TLV("LineIn Capture Volume", + SOC_DOUBLE_TLV("LineIn Playback Volume", ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), SOC_DOUBLE_TLV("Master Playback Volume", ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), SOC_DOUBLE("Master Playback Switch", ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), - SOC_SINGLE_TLV("Mic1 Capture Volume", + SOC_SINGLE_TLV("Mic1 Playback Volume", ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), - SOC_SINGLE_TLV("Mic2 Capture Volume", + SOC_SINGLE_TLV("Mic2 Playback Volume", ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), SOC_DOUBLE_TLV("Rec Capture Volume", ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), SOC_SINGLE_TLV("Mic 1 Boost Volume", - ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv), + ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv), SOC_SINGLE_TLV("Mic 2 Boost Volume", - ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv), - SOC_SINGLE_TLV("Digital Boost Volume", + ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv), + SOC_SINGLE_TLV("DMIC Boost Capture Volume", ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), + SOC_SINGLE("DMIC En Capture Switch", + ALC5632_DIGI_BOOST_CTRL, 15, 1, 0), + SOC_SINGLE("DMIC PreFilter Capture Switch", + ALC5632_DIGI_BOOST_CTRL, 12, 1, 0), }; /* @@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1), /* Left Record Mixer */ static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { -SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), -SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), -SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), -SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), -SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), -SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), -SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), +SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), +SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), +SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), +SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), +SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), +SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), +SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), }; /* Right Record Mixer */ static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { -SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), -SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), -SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), -SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), -SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), -SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), -SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), +SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), +SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), +SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), +SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), +SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), +SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), +SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), }; -static const char *alc5632_spk_n_sour_sel[] = { +/* Dmic Mixer */ +static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = { +SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1), +}; +static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = { +SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1), +}; + +static const char * const alc5632_spk_n_sour_sel[] = { "RN/-R", "RP/+R", "LN/-R", "Mute"}; -static const char *alc5632_hpl_out_input_sel[] = { +static const char * const alc5632_hpl_out_input_sel[] = { "Vmid", "HP Left Mix"}; -static const char *alc5632_hpr_out_input_sel[] = { +static const char * const alc5632_hpr_out_input_sel[] = { "Vmid", "HP Right Mix"}; -static const char *alc5632_spkout_input_sel[] = { +static const char * const alc5632_spkout_input_sel[] = { "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; -static const char *alc5632_aux_out_input_sel[] = { +static const char * const alc5632_aux_out_input_sel[] = { "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; +static const char * const alc5632_adcr_func_sel[] = { + "Stereo ADC", "Voice ADC"}; +static const char * const alc5632_i2s_out_sel[] = { + "ADC LR", "Voice Stereo Digital"}; /* auxout output mux */ static const struct soc_enum alc5632_aux_out_input_enum = @@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum = static const struct snd_kcontrol_new alc5632_amp_mux_controls = SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); +/* ADC output select */ +static const struct soc_enum alc5632_adcr_func_enum = + SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel); +static const struct snd_kcontrol_new alc5632_adcr_func_controls = + SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); + +/* I2S out select */ +static const struct soc_enum alc5632_i2s_out_enum = + SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel); +static const struct snd_kcontrol_new alc5632_i2s_out_controls = + SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { /* Muxes */ @@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &alc5632_hpr_out_mux_controls), SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, &alc5632_spkoutn_mux_controls), +SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, + &alc5632_adcr_func_controls), +SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0, + &alc5632_i2s_out_controls), /* output mixers */ SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, @@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0, SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, &alc5632_speaker_mixer_controls[0], ARRAY_SIZE(alc5632_speaker_mixer_controls)), +SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0, + &alc5632_dmicl_mixer_controls[0], + ARRAY_SIZE(alc5632_dmicl_mixer_controls)), +SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0, + &alc5632_dmicr_mixer_controls[0], + ARRAY_SIZE(alc5632_dmicr_mixer_controls)), /* input mixers */ SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, @@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0, &alc5632_captureR_mixer_controls[0], ARRAY_SIZE(alc5632_captureR_mixer_controls)), -SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback", - ALC5632_PWR_MANAG_ADD2, 9, 0), -SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback", - ALC5632_PWR_MANAG_ADD2, 8, 0), +SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0), + +SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0), +SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0), +SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0), +SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0), +SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0), + SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), SND_SOC_DAPM_MIXER("DAC Right Channel", ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", - ALC5632_PWR_MANAG_ADD2, 7, 0), -SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", - ALC5632_PWR_MANAG_ADD2, 6, 0), +SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), @@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"), SND_SOC_DAPM_OUTPUT("HPR"), SND_SOC_DAPM_OUTPUT("SPKOUT"), SND_SOC_DAPM_OUTPUT("SPKOUTN"), + SND_SOC_DAPM_INPUT("LINEINL"), SND_SOC_DAPM_INPUT("LINEINR"), SND_SOC_DAPM_INPUT("PHONEP"), SND_SOC_DAPM_INPUT("PHONEN"), +SND_SOC_DAPM_INPUT("DMICDAT"), SND_SOC_DAPM_INPUT("MIC1"), SND_SOC_DAPM_INPUT("MIC2"), SND_SOC_DAPM_VMID("Vmid"), @@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"), static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { + /* Playback streams */ + {"Left DAC", NULL, "AIFRXL"}, + {"Right DAC", NULL, "AIFRXR"}, + /* virtual mixer - mixes left & right channels */ {"I2S Mix", NULL, "Left DAC"}, {"I2S Mix", NULL, "Right DAC"}, @@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, - + {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"}, {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, + {"HPOut Mix", NULL, "HP Mix"}, + {"HPOut Mix", NULL, "HPR Mix"}, + {"HPOut Mix", NULL, "HPL Mix"}, /* speaker mixer */ {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, @@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, - - + {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"}, /* mono mixer */ {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, - {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"}, {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, + {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"}, /* Left record mixer */ - {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, - {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"}, - {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, - {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, - {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, - {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, - {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"}, + {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"}, + {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"}, + {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"}, + {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"}, + {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"}, + {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"}, /*Right record mixer */ - {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, - {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"}, - {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, - {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, - {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, - {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, - {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"}, + {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"}, + {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"}, + {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"}, + {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"}, + {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"}, + {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"}, /* headphone left mux */ {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, @@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { /* left ADC */ {"Left ADC", NULL, "Left Capture Mix"}, + {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"}, + {"Left ADC", NULL, "DMICL Mix"}, + {"ADCLR", NULL, "Left ADC"}, /* right ADC */ - {"Right ADC", NULL, "Right Capture Mix"}, - + {"Right ADC", NULL, "Right Capture Mix"}, + {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"}, + {"Right ADC", NULL, "DMICR Mix"}, + {"ADCR Mux", "Stereo ADC", "Right ADC"}, + {"ADCR Mux", "Voice ADC", "Right ADC"}, + {"ADCLR", NULL, "ADCR Mux"}, + {"VAIFTX", NULL, "ADCR Mux"}, + + /* Digital I2S out */ + {"I2SOut Mux", "ADC LR", "ADCLR"}, + {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"}, + {"AIFTXL", NULL, "I2SOut Mux"}, + {"AIFTXR", NULL, "I2SOut Mux"}, + + /* Voice Mix */ + {"Voice DAC", NULL, "VAIFRX"}, + {"Voice Mix", NULL, "Voice DAC"}, + + /* Speaker Output */ {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, @@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai, struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); switch (freq) { + case 4096000: case 8192000: case 11289600: case 12288000: @@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec) switch (alc5632->id) { case 0x5c: - snd_soc_add_controls(codec, alc5632_vol_snd_controls, + snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls, ARRAY_SIZE(alc5632_vol_snd_controls)); break; default: diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h index 357651ec074e..1b5bda594ea3 100644 --- a/sound/soc/codecs/alc5632.h +++ b/sound/soc/codecs/alc5632.h @@ -51,6 +51,7 @@ #define ALC5632_ADC_REC_MONOMIX (1 << 0) #define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ +#define ALC5632_I2S_OUT_CTL 0x1A /* undocumented reg. found in path scheme */ /* ALC5632_OUTPUT_MIXER_CTRL : */ /* same remark as for reg 2 line vs speaker */ #define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 06d2ea18a54c..064cd6a93516 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -157,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec) codec->control_data = davinci_vc; /* Set controls */ - snd_soc_add_controls(codec, cq93vc_snd_controls, + snd_soc_add_codec_controls(codec, cq93vc_snd_controls, ARRAY_SIZE(cq93vc_snd_controls)); /* Off, with power on */ diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 055536645da9..1d672f528662 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec) } /* Add the non-DAPM controls */ - ret = snd_soc_add_controls(codec, cs4270_snd_controls, + ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls, ARRAY_SIZE(cs4270_snd_controls)); if (ret < 0) { dev_err(codec->dev, "failed to add controls\n"); @@ -715,7 +715,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id); */ static struct i2c_driver cs4270_i2c_driver = { .driver = { - .name = "cs4270-codec", + .name = "cs4270", .owner = THIS_MODULE, }, .id_table = cs4270_id, diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index f6fe846b6a6c..bf7141280a74 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) /* Power-up sequence requires 85 uS */ udelay(85); - return snd_soc_add_controls(codec, cs4271_snd_controls, + return snd_soc_add_codec_controls(codec, cs4271_snd_controls, ARRAY_SIZE(cs4271_snd_controls)); } diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 9d38db8f1919..78979b3e0e95 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, priv->config[id].mmcc &= 0xC0; priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; priv->config[id].spc &= 0xFC; - priv->config[id].spc &= MCK_SCLK_64FS; + priv->config[id].spc |= MCK_SCLK_MCLK; } else { /* CS42L73 Slave */ priv->config[id].spc &= 0xFC; diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 319039240e0f..ba4fafb93e56 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec) codec->control_data = lm4857->i2c; - ret = snd_soc_add_controls(codec, lm4857_controls, + ret = snd_soc_add_codec_controls(codec, lm4857_controls, ARRAY_SIZE(lm4857_controls)); if (ret) return ret; diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c new file mode 100644 index 000000000000..17b3ec2d05cb --- /dev/null +++ b/sound/soc/codecs/max9768.c @@ -0,0 +1,247 @@ +/* + * MAX9768 AMP driver + * + * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/gpio.h> +#include <linux/regmap.h> + +#include <sound/core.h> +#include <sound/soc.h> +#include <sound/tlv.h> +#include <sound/max9768.h> + +/* "Registers" */ +#define MAX9768_VOL 0 +#define MAX9768_CTRL 3 + +/* Commands */ +#define MAX9768_CTRL_PWM 0x15 +#define MAX9768_CTRL_FILTERLESS 0x16 + +struct max9768 { + struct regmap *regmap; + int mute_gpio; + int shdn_gpio; + u32 flags; +}; + +static struct reg_default max9768_default_regs[] = { + { 0, 0 }, + { 3, MAX9768_CTRL_FILTERLESS}, +}; + +static int max9768_get_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); + int val = gpio_get_value_cansleep(max9768->mute_gpio); + + ucontrol->value.integer.value[0] = !val; + + return 0; +} + +static int max9768_set_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); + + gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]); + + return 0; +} + +static const unsigned int volume_tlv[] = { + TLV_DB_RANGE_HEAD(43), + 0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0), + 3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0), + 4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0), + 5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0), + 6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0), + 7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0), + 8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0), + 9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0), + 10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0), + 11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0), + 12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0), + 13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0), + 14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0), + 15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0), + 18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0), + 19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0), + 20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0), + 21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0), + 22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0), + 23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0), + 24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0), + 25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0), + 26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0), + 27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0), + 28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0), + 31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0), + 32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0), + 35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0), + 38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0), + 40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0), + 41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0), + 42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0), + 43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0), + 44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0), + 45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0), + 46, 46, TLV_DB_SCALE_ITEM(50, 0, 0), + 47, 50, TLV_DB_SCALE_ITEM(120, 40, 0), + 51, 57, TLV_DB_SCALE_ITEM(290, 50, 0), + 58, 58, TLV_DB_SCALE_ITEM(650, 0, 0), + 59, 62, TLV_DB_SCALE_ITEM(700, 60, 0), + 63, 63, TLV_DB_SCALE_ITEM(950, 0, 0), +}; + +static const struct snd_kcontrol_new max9768_volume[] = { + SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv), +}; + +static const struct snd_kcontrol_new max9768_mute[] = { + SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio), +}; + +static int max9768_probe(struct snd_soc_codec *codec) +{ + struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); + int ret; + + codec->control_data = max9768->regmap; + ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP); + if (ret) + return ret; + + if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) { + ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM); + if (ret) + return ret; + } + + if (gpio_is_valid(max9768->mute_gpio)) { + ret = snd_soc_add_codec_controls(codec, max9768_mute, + ARRAY_SIZE(max9768_mute)); + if (ret) + return ret; + } + + return 0; +} + +static struct snd_soc_codec_driver max9768_codec_driver = { + .probe = max9768_probe, + .controls = max9768_volume, + .num_controls = ARRAY_SIZE(max9768_volume), +}; + +static const struct regmap_config max9768_i2c_regmap_config = { + .reg_bits = 2, + .val_bits = 6, + .max_register = 3, + .reg_defaults = max9768_default_regs, + .num_reg_defaults = ARRAY_SIZE(max9768_default_regs), + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit max9768_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max9768 *max9768; + struct max9768_pdata *pdata = client->dev.platform_data; + int err; + + max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL); + if (!max9768) + return -ENOMEM; + + if (pdata) { + /* Mute on powerup to avoid clicks */ + err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute"); + max9768->mute_gpio = err ?: pdata->mute_gpio; + + /* Activate chip by releasing shutdown, enables I2C */ + err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown"); + max9768->shdn_gpio = err ?: pdata->shdn_gpio; + + max9768->flags = pdata->flags; + } else { + max9768->shdn_gpio = -EINVAL; + max9768->mute_gpio = -EINVAL; + } + + i2c_set_clientdata(client, max9768); + + max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config); + if (IS_ERR(max9768->regmap)) { + err = PTR_ERR(max9768->regmap); + goto err_gpio_free; + } + + err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); + if (err) + goto err_regmap_free; + + return 0; + + err_regmap_free: + regmap_exit(max9768->regmap); + err_gpio_free: + if (gpio_is_valid(max9768->shdn_gpio)) + gpio_free(max9768->shdn_gpio); + if (gpio_is_valid(max9768->mute_gpio)) + gpio_free(max9768->mute_gpio); + + return err; +} + +static int __devexit max9768_i2c_remove(struct i2c_client *client) +{ + struct max9768 *max9768 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + regmap_exit(max9768->regmap); + + if (gpio_is_valid(max9768->shdn_gpio)) + gpio_free(max9768->shdn_gpio); + if (gpio_is_valid(max9768->mute_gpio)) + gpio_free(max9768->mute_gpio); + + return 0; +} + +static const struct i2c_device_id max9768_i2c_id[] = { + { "max9768", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max9768_i2c_id); + +static struct i2c_driver max9768_i2c_driver = { + .driver = { + .name = "max9768", + .owner = THIS_MODULE, + }, + .probe = max9768_i2c_probe, + .remove = __devexit_p(max9768_i2c_remove), + .id_table = max9768_i2c_id, +}; +module_i2c_driver(max9768_i2c_driver); + +MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); +MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 006efcfe6dda..af7324b79dd0 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1908,7 +1908,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec) max98088->eq_enum.texts = max98088->eq_texts; max98088->eq_enum.max = max98088->eq_textcnt; - ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); + ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); if (ret != 0) dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); } @@ -2030,7 +2030,7 @@ static int max98088_probe(struct snd_soc_codec *codec) max98088_handle_pdata(codec); - snd_soc_add_controls(codec, max98088_snd_controls, + snd_soc_add_codec_controls(codec, max98088_snd_controls, ARRAY_SIZE(max98088_snd_controls)); err_access: diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index fcfa7497d7b7..0bb511a0388d 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = { static int max98095_add_widgets(struct snd_soc_codec *codec) { - snd_soc_add_controls(codec, max98095_snd_controls, + snd_soc_add_codec_controls(codec, max98095_snd_controls, ARRAY_SIZE(max98095_snd_controls)); return 0; @@ -1984,7 +1984,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec) max98095->eq_enum.texts = max98095->eq_texts; max98095->eq_enum.max = max98095->eq_textcnt; - ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); + ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); if (ret != 0) dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); } @@ -2139,7 +2139,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec) max98095->bq_enum.texts = max98095->bq_texts; max98095->bq_enum.max = max98095->bq_textcnt; - ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); + ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); if (ret != 0) dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret); } diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index dcf6f2a1600a..3a2ba3d8fd6d 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c @@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = { /* This function is called from ASoC machine driver */ int max9877_add_controls(struct snd_soc_codec *codec) { - return snd_soc_add_controls(codec, max9877_controls, + return snd_soc_add_codec_controls(codec, max9877_controls, ARRAY_SIZE(max9877_controls)); } EXPORT_SYMBOL_GPL(max9877_add_controls); diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index f99baa0b8c39..50dbdb9357ea 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) { pr_debug("codec_probe called\n"); - codec->dapm.idle_bias_off = 1; - /* PCM interface config * This sets the pcm rx slot conguration to max 6 slots * for max 4 dais (2 stereo and 2 mono) @@ -871,7 +869,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) snd_soc_write(codec, SN95031_SSR2, 0x10); snd_soc_write(codec, SN95031_SSR3, 0x40); - snd_soc_add_controls(codec, sn95031_snd_controls, + snd_soc_add_codec_controls(codec, sn95031_snd_controls, ARRAY_SIZE(sn95031_snd_controls)); return 0; @@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = { .read = sn95031_read, .write = sn95031_write, .set_bias_level = sn95031_set_vaud_bias, + .idle_bias_off = true, .dapm_widgets = sn95031_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), .dapm_routes = sn95031_audio_map, diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 333dd98af39c..de2b20544ceb 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, SSM2602_ROUT1V, ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); - ret = snd_soc_add_controls(codec, ssm2602_snd_controls, + ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls, ARRAY_SIZE(ssm2602_snd_controls)); if (ret) return ret; diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index cc0566c22ec1..982e437799a8 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, stac9766_snd_ac97_controls, + snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls, ARRAY_SIZE(stac9766_snd_ac97_controls)); return 0; diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index dfa41a96599b..16d55f91a653 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec) snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); - snd_soc_add_controls(codec, tlv320aic23_snd_controls, + snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls, ARRAY_SIZE(tlv320aic23_snd_controls)); return 0; diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index a038daec682b..802064b5030d 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec) /* register controls */ dev_dbg(codec->dev, "Registering controls\n"); - err = snd_soc_add_controls(codec, aic26_snd_controls, + err = snd_soc_add_codec_controls(codec, aic26_snd_controls, ARRAY_SIZE(aic26_snd_controls)); WARN_ON(err < 0); diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 372b0b83bd9f..b0a73d37ed52 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -671,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec) } aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, aic32x4_snd_controls, + snd_soc_add_codec_controls(codec, aic32x4_snd_controls, ARRAY_SIZE(aic32x4_snd_controls)); aic32x4_add_widgets(codec); diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 492f22f8a4d7..8d20f6ec20f3 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = { 0x00, 0x00, 0x02, /* 100 */ }; -/* - * read from the aic3x register space. Only use for this function is if - * wanting to read volatile bits from those registers that has both read-only - * and read/write bits. All other cases should use snd_soc_read. - */ -static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg, - u8 *value) -{ - u8 *cache = codec->reg_cache; - - if (codec->cache_only) - return -EINVAL; - if (reg >= AIC3X_CACHEREGNUM) - return -1; - - codec->cache_bypass = 1; - *value = snd_soc_read(codec, reg); - codec->cache_bypass = 0; - - cache[reg] = *value; - - return 0; -} - #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ @@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, return 0; } -void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state) -{ - u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; - u8 bit = gpio ? 3: 0; - u8 val = snd_soc_read(codec, reg) & ~(1 << bit); - snd_soc_write(codec, reg, val | (!!state << bit)); -} -EXPORT_SYMBOL_GPL(aic3x_set_gpio); - -int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio) -{ - u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; - u8 val = 0, bit = gpio ? 2 : 1; - - aic3x_read(codec, reg, &val); - return (val >> bit) & 1; -} -EXPORT_SYMBOL_GPL(aic3x_get_gpio); - void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, int headset_debounce, int button_debounce) { @@ -1221,23 +1178,6 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); } -EXPORT_SYMBOL_GPL(aic3x_set_headset_detection); - -int aic3x_headset_detected(struct snd_soc_codec *codec) -{ - u8 val = 0; - aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); - return (val >> 4) & 1; -} -EXPORT_SYMBOL_GPL(aic3x_headset_detected); - -int aic3x_button_pressed(struct snd_soc_codec *codec) -{ - u8 val = 0; - aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); - return (val >> 5) & 1; -} -EXPORT_SYMBOL_GPL(aic3x_button_pressed); #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ @@ -1377,7 +1317,6 @@ static int aic3x_probe(struct snd_soc_codec *codec) INIT_LIST_HEAD(&aic3x->list); aic3x->codec = codec; - codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); if (ret != 0) { @@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec) (aic3x->setup->gpio_func[1] & 0xf) << 4); } - snd_soc_add_controls(codec, aic3x_snd_controls, + snd_soc_add_codec_controls(codec, aic3x_snd_controls, ARRAY_SIZE(aic3x_snd_controls)); if (aic3x->model == AIC3X_MODEL_3007) - snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); + snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); aic3x_add_widgets(codec); list_add(&aic3x->list, &reset_list); @@ -1471,6 +1410,7 @@ static int aic3x_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_aic3x = { .set_bias_level = aic3x_set_bias_level, + .idle_bias_off = true, .reg_cache_size = ARRAY_SIZE(aic3x_reg), .reg_word_size = sizeof(u8), .reg_cache_default = aic3x_reg, diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 06a19784b162..6f097fb60683 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -212,9 +212,6 @@ /* Default input volume */ #define DEFAULT_GAIN 0x20 -void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); -int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); - /* headset detection / button API */ /* The AIC3x supports detection of stereo headsets (GND + left + right signal) @@ -252,10 +249,4 @@ enum { #define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 #define AIC3X_BUTTON_DEBOUNCE_MASK 3 -/* see the enums above for valid parameters to this function */ -void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, - int headset_debounce, int button_debounce); -int aic3x_headset_detected(struct snd_soc_codec *codec); -int aic3x_button_pressed(struct snd_soc_codec *codec); - #endif /* _AIC3X_H */ diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index c06c3e4b9127..4587ddd0fbf8 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1395,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) codec->control_data = dac33->control_data; codec->hw_write = (hw_write_t) i2c_master_send; - codec->dapm.idle_bias_off = 1; dac33->codec = codec; /* Read the tlv320dac33 ID registers */ @@ -1438,7 +1437,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) /* Only add the FIFO controls, if we have valid IRQ number */ if (dac33->irq >= 0) - snd_soc_add_controls(codec, dac33_mode_snd_controls, + snd_soc_add_codec_controls(codec, dac33_mode_snd_controls, ARRAY_SIZE(dac33_mode_snd_controls)); err_power: @@ -1476,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { .read = dac33_read_reg_cache, .write = dac33_write_locked, .set_bias_level = dac33_set_bias_level, + .idle_bias_off = true, .reg_cache_size = ARRAY_SIZE(dac33_reg), .reg_word_size = sizeof(u8), .reg_cache_default = dac33_reg, diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 363b99dad8e9..6fe4aa3ac544 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec) data = i2c_get_clientdata(tpa6130a2_client); if (data->id == TPA6140A2) - return snd_soc_add_controls(codec, tpa6140a2_controls, + return snd_soc_add_codec_controls(codec, tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls)); else - return snd_soc_add_controls(codec, tpa6130a2_controls, + return snd_soc_add_codec_controls(codec, tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls)); } EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a193f5fa4b3a..170cf9a8fc79 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, unsigned short mask, bitmask; if (twl4030->configured) { - printk(KERN_ERR "twl4030 operation mode cannot be " - "changed on-the-fly\n"); + dev_err(codec->dev, + "operation mode cannot be changed on-the-fly\n"); return -EBUSY; } @@ -1800,7 +1800,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, mode |= TWL4030_APLL_RATE_96000; break; default: - printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n", + dev_err(codec->dev, "%s: unknown rate %d\n", __func__, params_rate(params)); return -EINVAL; } @@ -1817,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, format |= TWL4030_DATA_WIDTH_32S_24W; break; default: - printk(KERN_ERR "TWL4030 hw params: unknown format %d\n", + dev_err(codec->dev, "%s: unknown format %d\n", __func__, params_format(params)); return -EINVAL; } @@ -1867,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, case 38400000: break; default: - dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq); + dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq); return -EINVAL; } if ((freq / 1000) != twl4030->sysclk) { dev_err(codec->dev, - "Mismatch in APLL mclk: %u (configured: %u)\n", + "Mismatch in HFCLKIN: %u (configured: %u)\n", freq, twl4030->sysclk * 1000); return -EINVAL; } @@ -1983,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, * not available. */ if (twl4030->sysclk != 26000) { - dev_err(codec->dev, "The board is configured for %u Hz, while" - "the Voice interface needs 26MHz APLL mclk\n", - twl4030->sysclk * 1000); + dev_err(codec->dev, + "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n", + __func__, twl4030->sysclk); return -EINVAL; } @@ -1996,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, & TWL4030_OPT_MODE; if (mode != TWL4030_OPTION_2) { - printk(KERN_ERR "TWL4030 voice startup: " - "the codec mode is not option2\n"); + dev_err(codec->dev, "%s: the codec mode is not option2\n", + __func__); return -EINVAL; } @@ -2038,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, mode |= TWL4030_SEL_16K; break; default: - printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", + dev_err(codec->dev, "%s: unknown rate %d\n", __func__, params_rate(params)); return -EINVAL; } @@ -2067,13 +2067,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); if (freq != 26000000) { - dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" - "interface needs 26MHz APLL mclk\n", freq); + dev_err(codec->dev, + "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n", + __func__, freq / 1000); return -EINVAL; } if ((freq / 1000) != twl4030->sysclk) { dev_err(codec->dev, - "Mismatch in APLL mclk: %u (configured: %u)\n", + "Mismatch in HFCLKIN: %u (configured: %u)\n", freq, twl4030->sysclk * 1000); return -EINVAL; } @@ -2221,13 +2222,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); if (twl4030 == NULL) { - printk("Can not allocate memroy\n"); + dev_err(codec->dev, "Can not allocate memory\n"); return -ENOMEM; } snd_soc_codec_set_drvdata(codec, twl4030); /* Set the defaults, and power up the codec */ twl4030->sysclk = twl4030_audio_get_mclk() / 1000; - codec->dapm.idle_bias_off = 1; twl4030_init_chip(codec); @@ -2253,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .read = twl4030_read_reg_cache, .write = twl4030_write, .set_bias_level = twl4030_set_bias_level, + .idle_bias_off = true, .reg_cache_size = sizeof(twl4030_reg), .reg_word_size = sizeof(u8), .reg_cache_default = twl4030_reg, diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 1a64edf671a2..2d8c6b825e57 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1540,7 +1540,6 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->codec = codec; codec->control_data = dev_get_drvdata(codec->dev->parent); - codec->ignore_pmdown_time = 1; if (pdata && pdata->hs_left_step && pdata->hs_right_step) { priv->hs_left_step = pdata->hs_left_step; @@ -1626,6 +1625,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .reg_cache_size = ARRAY_SIZE(twl6040_reg), .reg_word_size = sizeof(u8), .reg_cache_default = twl6040_reg, + .ignore_pmdown_time = true, .controls = twl6040_snd_controls, .num_controls = ARRAY_SIZE(twl6040_snd_controls), diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 8f4f469d6411..797b0dde2c68 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -531,15 +531,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) switch (pd->model) { case UDA134X_UDA1340: case UDA134X_UDA1344: - ret = snd_soc_add_controls(codec, uda1340_snd_controls, + ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls, ARRAY_SIZE(uda1340_snd_controls)); break; case UDA134X_UDA1341: - ret = snd_soc_add_controls(codec, uda1341_snd_controls, + ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls, ARRAY_SIZE(uda1341_snd_controls)); break; case UDA134X_UDA1345: - ret = snd_soc_add_controls(codec, uda1345_snd_controls, + ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls, ARRAY_SIZE(uda1345_snd_controls)); break; default: diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 44aacf927ba9..3d868dc40092 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -464,7 +464,7 @@ static int wl1273_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, wl1273); - r = snd_soc_add_controls(codec, wl1273_controls, + r = snd_soc_add_codec_controls(codec, wl1273_controls, ARRAY_SIZE(wl1273_controls)); if (r) kfree(wl1273); diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index c2880907fced..a75c3766aede 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -733,8 +733,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; const char *filename; - const struct firmware *fw; - int reg, ret; + const struct firmware *fw = NULL; + int ret; + int reg; u16 id; wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), @@ -751,7 +752,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = PTR_ERR(wm2000->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); - goto err; + goto out; } /* Verify that this is a WM2000 */ @@ -763,7 +764,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; - goto err_regmap; + goto out_regmap_exit; } reg = wm2000_read(i2c, WM2000_REG_REVISON); @@ -782,7 +783,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); - goto err_regmap; + goto out_regmap_exit; } /* Pre-cook the concatenation of the register address onto the image */ @@ -793,15 +794,13 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; - goto err_fw; + goto out_regmap_exit; } wm2000->anc_download[0] = 0x80; wm2000->anc_download[1] = 0x00; memcpy(wm2000->anc_download + 2, fw->data, fw->size); - release_firmware(fw); - wm2000->anc_eng_ena = 1; wm2000->anc_active = 1; wm2000->spk_ena = 1; @@ -809,18 +808,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, wm2000_reset(wm2000); - ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, - NULL, 0); - if (ret != 0) - goto err_fw; + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); + if (!ret) + goto out; - return 0; - -err_fw: - release_firmware(fw); -err_regmap: +out_regmap_exit: regmap_exit(wm2000->regmap); -err: +out: + release_firmware(fw); return ret; } diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c new file mode 100644 index 000000000000..acbdc5fde923 --- /dev/null +++ b/sound/soc/codecs/wm2200.c @@ -0,0 +1,2286 @@ +/* + * wm2200.c -- WM2200 ALSA SoC Audio driver + * + * Copyright 2012 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/gcd.h> +#include <linux/gpio.h> +#include <linux/i2c.h> +#include <linux/pm_runtime.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/fixed.h> +#include <linux/slab.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/jack.h> +#include <sound/initval.h> +#include <sound/tlv.h> +#include <sound/wm2200.h> + +#include "wm2200.h" + +/* The code assumes DCVDD is generated internally */ +#define WM2200_NUM_CORE_SUPPLIES 2 +static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = { + "DBVDD", + "LDOVDD", +}; + +struct wm2200_fll { + int fref; + int fout; + int src; + struct completion lock; +}; + +/* codec private data */ +struct wm2200_priv { + struct regmap *regmap; + struct device *dev; + struct snd_soc_codec *codec; + struct wm2200_pdata pdata; + struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES]; + + struct completion fll_lock; + int fll_fout; + int fll_fref; + int fll_src; + + int rev; + int sysclk; +}; + +static struct reg_default wm2200_reg_defaults[] = { + { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ + { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ + { 0x0103, 0x0011 }, /* R259 - Clocking 4 */ + { 0x0111, 0x0000 }, /* R273 - FLL Control 1 */ + { 0x0112, 0x0000 }, /* R274 - FLL Control 2 */ + { 0x0113, 0x0000 }, /* R275 - FLL Control 3 */ + { 0x0114, 0x0000 }, /* R276 - FLL Control 4 */ + { 0x0116, 0x0177 }, /* R278 - FLL Control 6 */ + { 0x0117, 0x0004 }, /* R279 - FLL Control 7 */ + { 0x0119, 0x0000 }, /* R281 - FLL EFS 1 */ + { 0x011A, 0x0002 }, /* R282 - FLL EFS 2 */ + { 0x0200, 0x0000 }, /* R512 - Mic Charge Pump 1 */ + { 0x0201, 0x03FF }, /* R513 - Mic Charge Pump 2 */ + { 0x0202, 0x9BDE }, /* R514 - DM Charge Pump 1 */ + { 0x020C, 0x0000 }, /* R524 - Mic Bias Ctrl 1 */ + { 0x020D, 0x0000 }, /* R525 - Mic Bias Ctrl 2 */ + { 0x020F, 0x0000 }, /* R527 - Ear Piece Ctrl 1 */ + { 0x0210, 0x0000 }, /* R528 - Ear Piece Ctrl 2 */ + { 0x0301, 0x0000 }, /* R769 - Input Enables */ + { 0x0302, 0x2240 }, /* R770 - IN1L Control */ + { 0x0303, 0x0040 }, /* R771 - IN1R Control */ + { 0x0304, 0x2240 }, /* R772 - IN2L Control */ + { 0x0305, 0x0040 }, /* R773 - IN2R Control */ + { 0x0306, 0x2240 }, /* R774 - IN3L Control */ + { 0x0307, 0x0040 }, /* R775 - IN3R Control */ + { 0x030A, 0x0000 }, /* R778 - RXANC_SRC */ + { 0x030B, 0x0022 }, /* R779 - Input Volume Ramp */ + { 0x030C, 0x0180 }, /* R780 - ADC Digital Volume 1L */ + { 0x030D, 0x0180 }, /* R781 - ADC Digital Volume 1R */ + { 0x030E, 0x0180 }, /* R782 - ADC Digital Volume 2L */ + { 0x030F, 0x0180 }, /* R783 - ADC Digital Volume 2R */ + { 0x0310, 0x0180 }, /* R784 - ADC Digital Volume 3L */ + { 0x0311, 0x0180 }, /* R785 - ADC Digital Volume 3R */ + { 0x0400, 0x0000 }, /* R1024 - Output Enables */ + { 0x0401, 0x0000 }, /* R1025 - DAC Volume Limit 1L */ + { 0x0402, 0x0000 }, /* R1026 - DAC Volume Limit 1R */ + { 0x0403, 0x0000 }, /* R1027 - DAC Volume Limit 2L */ + { 0x0404, 0x0000 }, /* R1028 - DAC Volume Limit 2R */ + { 0x0409, 0x0000 }, /* R1033 - DAC AEC Control 1 */ + { 0x040A, 0x0022 }, /* R1034 - Output Volume Ramp */ + { 0x040B, 0x0180 }, /* R1035 - DAC Digital Volume 1L */ + { 0x040C, 0x0180 }, /* R1036 - DAC Digital Volume 1R */ + { 0x040D, 0x0180 }, /* R1037 - DAC Digital Volume 2L */ + { 0x040E, 0x0180 }, /* R1038 - DAC Digital Volume 2R */ + { 0x0417, 0x0069 }, /* R1047 - PDM 1 */ + { 0x0418, 0x0000 }, /* R1048 - PDM 2 */ + { 0x0500, 0x0000 }, /* R1280 - Audio IF 1_1 */ + { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */ + { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */ + { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */ + { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */ + { 0x0505, 0x0001 }, /* R1285 - Audio IF 1_6 */ + { 0x0506, 0x0001 }, /* R1286 - Audio IF 1_7 */ + { 0x0507, 0x0000 }, /* R1287 - Audio IF 1_8 */ + { 0x0508, 0x0000 }, /* R1288 - Audio IF 1_9 */ + { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */ + { 0x050A, 0x0000 }, /* R1290 - Audio IF 1_11 */ + { 0x050B, 0x0000 }, /* R1291 - Audio IF 1_12 */ + { 0x050C, 0x0000 }, /* R1292 - Audio IF 1_13 */ + { 0x050D, 0x0000 }, /* R1293 - Audio IF 1_14 */ + { 0x050E, 0x0000 }, /* R1294 - Audio IF 1_15 */ + { 0x050F, 0x0000 }, /* R1295 - Audio IF 1_16 */ + { 0x0510, 0x0000 }, /* R1296 - Audio IF 1_17 */ + { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */ + { 0x0512, 0x0000 }, /* R1298 - Audio IF 1_19 */ + { 0x0513, 0x0000 }, /* R1299 - Audio IF 1_20 */ + { 0x0514, 0x0000 }, /* R1300 - Audio IF 1_21 */ + { 0x0515, 0x0001 }, /* R1301 - Audio IF 1_22 */ + { 0x0600, 0x0000 }, /* R1536 - OUT1LMIX Input 1 Source */ + { 0x0601, 0x0080 }, /* R1537 - OUT1LMIX Input 1 Volume */ + { 0x0602, 0x0000 }, /* R1538 - OUT1LMIX Input 2 Source */ + { 0x0603, 0x0080 }, /* R1539 - OUT1LMIX Input 2 Volume */ + { 0x0604, 0x0000 }, /* R1540 - OUT1LMIX Input 3 Source */ + { 0x0605, 0x0080 }, /* R1541 - OUT1LMIX Input 3 Volume */ + { 0x0606, 0x0000 }, /* R1542 - OUT1LMIX Input 4 Source */ + { 0x0607, 0x0080 }, /* R1543 - OUT1LMIX Input 4 Volume */ + { 0x0608, 0x0000 }, /* R1544 - OUT1RMIX Input 1 Source */ + { 0x0609, 0x0080 }, /* R1545 - OUT1RMIX Input 1 Volume */ + { 0x060A, 0x0000 }, /* R1546 - OUT1RMIX Input 2 Source */ + { 0x060B, 0x0080 }, /* R1547 - OUT1RMIX Input 2 Volume */ + { 0x060C, 0x0000 }, /* R1548 - OUT1RMIX Input 3 Source */ + { 0x060D, 0x0080 }, /* R1549 - OUT1RMIX Input 3 Volume */ + { 0x060E, 0x0000 }, /* R1550 - OUT1RMIX Input 4 Source */ + { 0x060F, 0x0080 }, /* R1551 - OUT1RMIX Input 4 Volume */ + { 0x0610, 0x0000 }, /* R1552 - OUT2LMIX Input 1 Source */ + { 0x0611, 0x0080 }, /* R1553 - OUT2LMIX Input 1 Volume */ + { 0x0612, 0x0000 }, /* R1554 - OUT2LMIX Input 2 Source */ + { 0x0613, 0x0080 }, /* R1555 - OUT2LMIX Input 2 Volume */ + { 0x0614, 0x0000 }, /* R1556 - OUT2LMIX Input 3 Source */ + { 0x0615, 0x0080 }, /* R1557 - OUT2LMIX Input 3 Volume */ + { 0x0616, 0x0000 }, /* R1558 - OUT2LMIX Input 4 Source */ + { 0x0617, 0x0080 }, /* R1559 - OUT2LMIX Input 4 Volume */ + { 0x0618, 0x0000 }, /* R1560 - OUT2RMIX Input 1 Source */ + { 0x0619, 0x0080 }, /* R1561 - OUT2RMIX Input 1 Volume */ + { 0x061A, 0x0000 }, /* R1562 - OUT2RMIX Input 2 Source */ + { 0x061B, 0x0080 }, /* R1563 - OUT2RMIX Input 2 Volume */ + { 0x061C, 0x0000 }, /* R1564 - OUT2RMIX Input 3 Source */ + { 0x061D, 0x0080 }, /* R1565 - OUT2RMIX Input 3 Volume */ + { 0x061E, 0x0000 }, /* R1566 - OUT2RMIX Input 4 Source */ + { 0x061F, 0x0080 }, /* R1567 - OUT2RMIX Input 4 Volume */ + { 0x0620, 0x0000 }, /* R1568 - AIF1TX1MIX Input 1 Source */ + { 0x0621, 0x0080 }, /* R1569 - AIF1TX1MIX Input 1 Volume */ + { 0x0622, 0x0000 }, /* R1570 - AIF1TX1MIX Input 2 Source */ + { 0x0623, 0x0080 }, /* R1571 - AIF1TX1MIX Input 2 Volume */ + { 0x0624, 0x0000 }, /* R1572 - AIF1TX1MIX Input 3 Source */ + { 0x0625, 0x0080 }, /* R1573 - AIF1TX1MIX Input 3 Volume */ + { 0x0626, 0x0000 }, /* R1574 - AIF1TX1MIX Input 4 Source */ + { 0x0627, 0x0080 }, /* R1575 - AIF1TX1MIX Input 4 Volume */ + { 0x0628, 0x0000 }, /* R1576 - AIF1TX2MIX Input 1 Source */ + { 0x0629, 0x0080 }, /* R1577 - AIF1TX2MIX Input 1 Volume */ + { 0x062A, 0x0000 }, /* R1578 - AIF1TX2MIX Input 2 Source */ + { 0x062B, 0x0080 }, /* R1579 - AIF1TX2MIX Input 2 Volume */ + { 0x062C, 0x0000 }, /* R1580 - AIF1TX2MIX Input 3 Source */ + { 0x062D, 0x0080 }, /* R1581 - AIF1TX2MIX Input 3 Volume */ + { 0x062E, 0x0000 }, /* R1582 - AIF1TX2MIX Input 4 Source */ + { 0x062F, 0x0080 }, /* R1583 - AIF1TX2MIX Input 4 Volume */ + { 0x0630, 0x0000 }, /* R1584 - AIF1TX3MIX Input 1 Source */ + { 0x0631, 0x0080 }, /* R1585 - AIF1TX3MIX Input 1 Volume */ + { 0x0632, 0x0000 }, /* R1586 - AIF1TX3MIX Input 2 Source */ + { 0x0633, 0x0080 }, /* R1587 - AIF1TX3MIX Input 2 Volume */ + { 0x0634, 0x0000 }, /* R1588 - AIF1TX3MIX Input 3 Source */ + { 0x0635, 0x0080 }, /* R1589 - AIF1TX3MIX Input 3 Volume */ + { 0x0636, 0x0000 }, /* R1590 - AIF1TX3MIX Input 4 Source */ + { 0x0637, 0x0080 }, /* R1591 - AIF1TX3MIX Input 4 Volume */ + { 0x0638, 0x0000 }, /* R1592 - AIF1TX4MIX Input 1 Source */ + { 0x0639, 0x0080 }, /* R1593 - AIF1TX4MIX Input 1 Volume */ + { 0x063A, 0x0000 }, /* R1594 - AIF1TX4MIX Input 2 Source */ + { 0x063B, 0x0080 }, /* R1595 - AIF1TX4MIX Input 2 Volume */ + { 0x063C, 0x0000 }, /* R1596 - AIF1TX4MIX Input 3 Source */ + { 0x063D, 0x0080 }, /* R1597 - AIF1TX4MIX Input 3 Volume */ + { 0x063E, 0x0000 }, /* R1598 - AIF1TX4MIX Input 4 Source */ + { 0x063F, 0x0080 }, /* R1599 - AIF1TX4MIX Input 4 Volume */ + { 0x0640, 0x0000 }, /* R1600 - AIF1TX5MIX Input 1 Source */ + { 0x0641, 0x0080 }, /* R1601 - AIF1TX5MIX Input 1 Volume */ + { 0x0642, 0x0000 }, /* R1602 - AIF1TX5MIX Input 2 Source */ + { 0x0643, 0x0080 }, /* R1603 - AIF1TX5MIX Input 2 Volume */ + { 0x0644, 0x0000 }, /* R1604 - AIF1TX5MIX Input 3 Source */ + { 0x0645, 0x0080 }, /* R1605 - AIF1TX5MIX Input 3 Volume */ + { 0x0646, 0x0000 }, /* R1606 - AIF1TX5MIX Input 4 Source */ + { 0x0647, 0x0080 }, /* R1607 - AIF1TX5MIX Input 4 Volume */ + { 0x0648, 0x0000 }, /* R1608 - AIF1TX6MIX Input 1 Source */ + { 0x0649, 0x0080 }, /* R1609 - AIF1TX6MIX Input 1 Volume */ + { 0x064A, 0x0000 }, /* R1610 - AIF1TX6MIX Input 2 Source */ + { 0x064B, 0x0080 }, /* R1611 - AIF1TX6MIX Input 2 Volume */ + { 0x064C, 0x0000 }, /* R1612 - AIF1TX6MIX Input 3 Source */ + { 0x064D, 0x0080 }, /* R1613 - AIF1TX6MIX Input 3 Volume */ + { 0x064E, 0x0000 }, /* R1614 - AIF1TX6MIX Input 4 Source */ + { 0x064F, 0x0080 }, /* R1615 - AIF1TX6MIX Input 4 Volume */ + { 0x0650, 0x0000 }, /* R1616 - EQLMIX Input 1 Source */ + { 0x0651, 0x0080 }, /* R1617 - EQLMIX Input 1 Volume */ + { 0x0652, 0x0000 }, /* R1618 - EQLMIX Input 2 Source */ + { 0x0653, 0x0080 }, /* R1619 - EQLMIX Input 2 Volume */ + { 0x0654, 0x0000 }, /* R1620 - EQLMIX Input 3 Source */ + { 0x0655, 0x0080 }, /* R1621 - EQLMIX Input 3 Volume */ + { 0x0656, 0x0000 }, /* R1622 - EQLMIX Input 4 Source */ + { 0x0657, 0x0080 }, /* R1623 - EQLMIX Input 4 Volume */ + { 0x0658, 0x0000 }, /* R1624 - EQRMIX Input 1 Source */ + { 0x0659, 0x0080 }, /* R1625 - EQRMIX Input 1 Volume */ + { 0x065A, 0x0000 }, /* R1626 - EQRMIX Input 2 Source */ + { 0x065B, 0x0080 }, /* R1627 - EQRMIX Input 2 Volume */ + { 0x065C, 0x0000 }, /* R1628 - EQRMIX Input 3 Source */ + { 0x065D, 0x0080 }, /* R1629 - EQRMIX Input 3 Volume */ + { 0x065E, 0x0000 }, /* R1630 - EQRMIX Input 4 Source */ + { 0x065F, 0x0080 }, /* R1631 - EQRMIX Input 4 Volume */ + { 0x0660, 0x0000 }, /* R1632 - LHPF1MIX Input 1 Source */ + { 0x0661, 0x0080 }, /* R1633 - LHPF1MIX Input 1 Volume */ + { 0x0662, 0x0000 }, /* R1634 - LHPF1MIX Input 2 Source */ + { 0x0663, 0x0080 }, /* R1635 - LHPF1MIX Input 2 Volume */ + { 0x0664, 0x0000 }, /* R1636 - LHPF1MIX Input 3 Source */ + { 0x0665, 0x0080 }, /* R1637 - LHPF1MIX Input 3 Volume */ + { 0x0666, 0x0000 }, /* R1638 - LHPF1MIX Input 4 Source */ + { 0x0667, 0x0080 }, /* R1639 - LHPF1MIX Input 4 Volume */ + { 0x0668, 0x0000 }, /* R1640 - LHPF2MIX Input 1 Source */ + { 0x0669, 0x0080 }, /* R1641 - LHPF2MIX Input 1 Volume */ + { 0x066A, 0x0000 }, /* R1642 - LHPF2MIX Input 2 Source */ + { 0x066B, 0x0080 }, /* R1643 - LHPF2MIX Input 2 Volume */ + { 0x066C, 0x0000 }, /* R1644 - LHPF2MIX Input 3 Source */ + { 0x066D, 0x0080 }, /* R1645 - LHPF2MIX Input 3 Volume */ + { 0x066E, 0x0000 }, /* R1646 - LHPF2MIX Input 4 Source */ + { 0x066F, 0x0080 }, /* R1647 - LHPF2MIX Input 4 Volume */ + { 0x0670, 0x0000 }, /* R1648 - DSP1LMIX Input 1 Source */ + { 0x0671, 0x0080 }, /* R1649 - DSP1LMIX Input 1 Volume */ + { 0x0672, 0x0000 }, /* R1650 - DSP1LMIX Input 2 Source */ + { 0x0673, 0x0080 }, /* R1651 - DSP1LMIX Input 2 Volume */ + { 0x0674, 0x0000 }, /* R1652 - DSP1LMIX Input 3 Source */ + { 0x0675, 0x0080 }, /* R1653 - DSP1LMIX Input 3 Volume */ + { 0x0676, 0x0000 }, /* R1654 - DSP1LMIX Input 4 Source */ + { 0x0677, 0x0080 }, /* R1655 - DSP1LMIX Input 4 Volume */ + { 0x0678, 0x0000 }, /* R1656 - DSP1RMIX Input 1 Source */ + { 0x0679, 0x0080 }, /* R1657 - DSP1RMIX Input 1 Volume */ + { 0x067A, 0x0000 }, /* R1658 - DSP1RMIX Input 2 Source */ + { 0x067B, 0x0080 }, /* R1659 - DSP1RMIX Input 2 Volume */ + { 0x067C, 0x0000 }, /* R1660 - DSP1RMIX Input 3 Source */ + { 0x067D, 0x0080 }, /* R1661 - DSP1RMIX Input 3 Volume */ + { 0x067E, 0x0000 }, /* R1662 - DSP1RMIX Input 4 Source */ + { 0x067F, 0x0080 }, /* R1663 - DSP1RMIX Input 4 Volume */ + { 0x0680, 0x0000 }, /* R1664 - DSP1AUX1MIX Input 1 Source */ + { 0x0681, 0x0000 }, /* R1665 - DSP1AUX2MIX Input 1 Source */ + { 0x0682, 0x0000 }, /* R1666 - DSP1AUX3MIX Input 1 Source */ + { 0x0683, 0x0000 }, /* R1667 - DSP1AUX4MIX Input 1 Source */ + { 0x0684, 0x0000 }, /* R1668 - DSP1AUX5MIX Input 1 Source */ + { 0x0685, 0x0000 }, /* R1669 - DSP1AUX6MIX Input 1 Source */ + { 0x0686, 0x0000 }, /* R1670 - DSP2LMIX Input 1 Source */ + { 0x0687, 0x0080 }, /* R1671 - DSP2LMIX Input 1 Volume */ + { 0x0688, 0x0000 }, /* R1672 - DSP2LMIX Input 2 Source */ + { 0x0689, 0x0080 }, /* R1673 - DSP2LMIX Input 2 Volume */ + { 0x068A, 0x0000 }, /* R1674 - DSP2LMIX Input 3 Source */ + { 0x068B, 0x0080 }, /* R1675 - DSP2LMIX Input 3 Volume */ + { 0x068C, 0x0000 }, /* R1676 - DSP2LMIX Input 4 Source */ + { 0x068D, 0x0080 }, /* R1677 - DSP2LMIX Input 4 Volume */ + { 0x068E, 0x0000 }, /* R1678 - DSP2RMIX Input 1 Source */ + { 0x068F, 0x0080 }, /* R1679 - DSP2RMIX Input 1 Volume */ + { 0x0690, 0x0000 }, /* R1680 - DSP2RMIX Input 2 Source */ + { 0x0691, 0x0080 }, /* R1681 - DSP2RMIX Input 2 Volume */ + { 0x0692, 0x0000 }, /* R1682 - DSP2RMIX Input 3 Source */ + { 0x0693, 0x0080 }, /* R1683 - DSP2RMIX Input 3 Volume */ + { 0x0694, 0x0000 }, /* R1684 - DSP2RMIX Input 4 Source */ + { 0x0695, 0x0080 }, /* R1685 - DSP2RMIX Input 4 Volume */ + { 0x0696, 0x0000 }, /* R1686 - DSP2AUX1MIX Input 1 Source */ + { 0x0697, 0x0000 }, /* R1687 - DSP2AUX2MIX Input 1 Source */ + { 0x0698, 0x0000 }, /* R1688 - DSP2AUX3MIX Input 1 Source */ + { 0x0699, 0x0000 }, /* R1689 - DSP2AUX4MIX Input 1 Source */ + { 0x069A, 0x0000 }, /* R1690 - DSP2AUX5MIX Input 1 Source */ + { 0x069B, 0x0000 }, /* R1691 - DSP2AUX6MIX Input 1 Source */ + { 0x0700, 0xA101 }, /* R1792 - GPIO CTRL 1 */ + { 0x0701, 0xA101 }, /* R1793 - GPIO CTRL 2 */ + { 0x0702, 0xA101 }, /* R1794 - GPIO CTRL 3 */ + { 0x0703, 0xA101 }, /* R1795 - GPIO CTRL 4 */ + { 0x0709, 0x0000 }, /* R1801 - Misc Pad Ctrl 1 */ + { 0x0801, 0x00FF }, /* R2049 - Interrupt Status 1 Mask */ + { 0x0804, 0xFFFF }, /* R2052 - Interrupt Status 2 Mask */ + { 0x0808, 0x0000 }, /* R2056 - Interrupt Control */ + { 0x0900, 0x0000 }, /* R2304 - EQL_1 */ + { 0x0901, 0x0000 }, /* R2305 - EQL_2 */ + { 0x0902, 0x0000 }, /* R2306 - EQL_3 */ + { 0x0903, 0x0000 }, /* R2307 - EQL_4 */ + { 0x0904, 0x0000 }, /* R2308 - EQL_5 */ + { 0x0905, 0x0000 }, /* R2309 - EQL_6 */ + { 0x0906, 0x0000 }, /* R2310 - EQL_7 */ + { 0x0907, 0x0000 }, /* R2311 - EQL_8 */ + { 0x0908, 0x0000 }, /* R2312 - EQL_9 */ + { 0x0909, 0x0000 }, /* R2313 - EQL_10 */ + { 0x090A, 0x0000 }, /* R2314 - EQL_11 */ + { 0x090B, 0x0000 }, /* R2315 - EQL_12 */ + { 0x090C, 0x0000 }, /* R2316 - EQL_13 */ + { 0x090D, 0x0000 }, /* R2317 - EQL_14 */ + { 0x090E, 0x0000 }, /* R2318 - EQL_15 */ + { 0x090F, 0x0000 }, /* R2319 - EQL_16 */ + { 0x0910, 0x0000 }, /* R2320 - EQL_17 */ + { 0x0911, 0x0000 }, /* R2321 - EQL_18 */ + { 0x0912, 0x0000 }, /* R2322 - EQL_19 */ + { 0x0913, 0x0000 }, /* R2323 - EQL_20 */ + { 0x0916, 0x0000 }, /* R2326 - EQR_1 */ + { 0x0917, 0x0000 }, /* R2327 - EQR_2 */ + { 0x0918, 0x0000 }, /* R2328 - EQR_3 */ + { 0x0919, 0x0000 }, /* R2329 - EQR_4 */ + { 0x091A, 0x0000 }, /* R2330 - EQR_5 */ + { 0x091B, 0x0000 }, /* R2331 - EQR_6 */ + { 0x091C, 0x0000 }, /* R2332 - EQR_7 */ + { 0x091D, 0x0000 }, /* R2333 - EQR_8 */ + { 0x091E, 0x0000 }, /* R2334 - EQR_9 */ + { 0x091F, 0x0000 }, /* R2335 - EQR_10 */ + { 0x0920, 0x0000 }, /* R2336 - EQR_11 */ + { 0x0921, 0x0000 }, /* R2337 - EQR_12 */ + { 0x0922, 0x0000 }, /* R2338 - EQR_13 */ + { 0x0923, 0x0000 }, /* R2339 - EQR_14 */ + { 0x0924, 0x0000 }, /* R2340 - EQR_15 */ + { 0x0925, 0x0000 }, /* R2341 - EQR_16 */ + { 0x0926, 0x0000 }, /* R2342 - EQR_17 */ + { 0x0927, 0x0000 }, /* R2343 - EQR_18 */ + { 0x0928, 0x0000 }, /* R2344 - EQR_19 */ + { 0x0929, 0x0000 }, /* R2345 - EQR_20 */ + { 0x093E, 0x0000 }, /* R2366 - HPLPF1_1 */ + { 0x093F, 0x0000 }, /* R2367 - HPLPF1_2 */ + { 0x0942, 0x0000 }, /* R2370 - HPLPF2_1 */ + { 0x0943, 0x0000 }, /* R2371 - HPLPF2_2 */ + { 0x0A00, 0x0000 }, /* R2560 - DSP1 Control 1 */ + { 0x0A02, 0x0000 }, /* R2562 - DSP1 Control 2 */ + { 0x0A03, 0x0000 }, /* R2563 - DSP1 Control 3 */ + { 0x0A04, 0x0000 }, /* R2564 - DSP1 Control 4 */ + { 0x0A06, 0x0000 }, /* R2566 - DSP1 Control 5 */ + { 0x0A07, 0x0000 }, /* R2567 - DSP1 Control 6 */ + { 0x0A08, 0x0000 }, /* R2568 - DSP1 Control 7 */ + { 0x0A09, 0x0000 }, /* R2569 - DSP1 Control 8 */ + { 0x0A0A, 0x0000 }, /* R2570 - DSP1 Control 9 */ + { 0x0A0B, 0x0000 }, /* R2571 - DSP1 Control 10 */ + { 0x0A0C, 0x0000 }, /* R2572 - DSP1 Control 11 */ + { 0x0A0D, 0x0000 }, /* R2573 - DSP1 Control 12 */ + { 0x0A0F, 0x0000 }, /* R2575 - DSP1 Control 13 */ + { 0x0A10, 0x0000 }, /* R2576 - DSP1 Control 14 */ + { 0x0A11, 0x0000 }, /* R2577 - DSP1 Control 15 */ + { 0x0A12, 0x0000 }, /* R2578 - DSP1 Control 16 */ + { 0x0A13, 0x0000 }, /* R2579 - DSP1 Control 17 */ + { 0x0A14, 0x0000 }, /* R2580 - DSP1 Control 18 */ + { 0x0A16, 0x0000 }, /* R2582 - DSP1 Control 19 */ + { 0x0A17, 0x0000 }, /* R2583 - DSP1 Control 20 */ + { 0x0A18, 0x0000 }, /* R2584 - DSP1 Control 21 */ + { 0x0A1A, 0x1800 }, /* R2586 - DSP1 Control 22 */ + { 0x0A1B, 0x1000 }, /* R2587 - DSP1 Control 23 */ + { 0x0A1C, 0x0400 }, /* R2588 - DSP1 Control 24 */ + { 0x0A1E, 0x0000 }, /* R2590 - DSP1 Control 25 */ + { 0x0A20, 0x0000 }, /* R2592 - DSP1 Control 26 */ + { 0x0A21, 0x0000 }, /* R2593 - DSP1 Control 27 */ + { 0x0A22, 0x0000 }, /* R2594 - DSP1 Control 28 */ + { 0x0A23, 0x0000 }, /* R2595 - DSP1 Control 29 */ + { 0x0A24, 0x0000 }, /* R2596 - DSP1 Control 30 */ + { 0x0A26, 0x0000 }, /* R2598 - DSP1 Control 31 */ + { 0x0B00, 0x0000 }, /* R2816 - DSP2 Control 1 */ + { 0x0B02, 0x0000 }, /* R2818 - DSP2 Control 2 */ + { 0x0B03, 0x0000 }, /* R2819 - DSP2 Control 3 */ + { 0x0B04, 0x0000 }, /* R2820 - DSP2 Control 4 */ + { 0x0B06, 0x0000 }, /* R2822 - DSP2 Control 5 */ + { 0x0B07, 0x0000 }, /* R2823 - DSP2 Control 6 */ + { 0x0B08, 0x0000 }, /* R2824 - DSP2 Control 7 */ + { 0x0B09, 0x0000 }, /* R2825 - DSP2 Control 8 */ + { 0x0B0A, 0x0000 }, /* R2826 - DSP2 Control 9 */ + { 0x0B0B, 0x0000 }, /* R2827 - DSP2 Control 10 */ + { 0x0B0C, 0x0000 }, /* R2828 - DSP2 Control 11 */ + { 0x0B0D, 0x0000 }, /* R2829 - DSP2 Control 12 */ + { 0x0B0F, 0x0000 }, /* R2831 - DSP2 Control 13 */ + { 0x0B10, 0x0000 }, /* R2832 - DSP2 Control 14 */ + { 0x0B11, 0x0000 }, /* R2833 - DSP2 Control 15 */ + { 0x0B12, 0x0000 }, /* R2834 - DSP2 Control 16 */ + { 0x0B13, 0x0000 }, /* R2835 - DSP2 Control 17 */ + { 0x0B14, 0x0000 }, /* R2836 - DSP2 Control 18 */ + { 0x0B16, 0x0000 }, /* R2838 - DSP2 Control 19 */ + { 0x0B17, 0x0000 }, /* R2839 - DSP2 Control 20 */ + { 0x0B18, 0x0000 }, /* R2840 - DSP2 Control 21 */ + { 0x0B1A, 0x0800 }, /* R2842 - DSP2 Control 22 */ + { 0x0B1B, 0x1000 }, /* R2843 - DSP2 Control 23 */ + { 0x0B1C, 0x0400 }, /* R2844 - DSP2 Control 24 */ + { 0x0B1E, 0x0000 }, /* R2846 - DSP2 Control 25 */ + { 0x0B20, 0x0000 }, /* R2848 - DSP2 Control 26 */ + { 0x0B21, 0x0000 }, /* R2849 - DSP2 Control 27 */ + { 0x0B22, 0x0000 }, /* R2850 - DSP2 Control 28 */ + { 0x0B23, 0x0000 }, /* R2851 - DSP2 Control 29 */ + { 0x0B24, 0x0000 }, /* R2852 - DSP2 Control 30 */ + { 0x0B26, 0x0000 }, /* R2854 - DSP2 Control 31 */ +}; + +static bool wm2200_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM2200_SOFTWARE_RESET: + case WM2200_DEVICE_REVISION: + case WM2200_ADPS1_IRQ0: + case WM2200_ADPS1_IRQ1: + case WM2200_INTERRUPT_STATUS_1: + case WM2200_INTERRUPT_STATUS_2: + case WM2200_INTERRUPT_RAW_STATUS_2: + return true; + default: + return false; + } +} + +static bool wm2200_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM2200_SOFTWARE_RESET: + case WM2200_DEVICE_REVISION: + case WM2200_TONE_GENERATOR_1: + case WM2200_CLOCKING_3: + case WM2200_CLOCKING_4: + case WM2200_FLL_CONTROL_1: + case WM2200_FLL_CONTROL_2: + case WM2200_FLL_CONTROL_3: + case WM2200_FLL_CONTROL_4: + case WM2200_FLL_CONTROL_6: + case WM2200_FLL_CONTROL_7: + case WM2200_FLL_EFS_1: + case WM2200_FLL_EFS_2: + case WM2200_MIC_CHARGE_PUMP_1: + case WM2200_MIC_CHARGE_PUMP_2: + case WM2200_DM_CHARGE_PUMP_1: + case WM2200_MIC_BIAS_CTRL_1: + case WM2200_MIC_BIAS_CTRL_2: + case WM2200_EAR_PIECE_CTRL_1: + case WM2200_EAR_PIECE_CTRL_2: + case WM2200_INPUT_ENABLES: + case WM2200_IN1L_CONTROL: + case WM2200_IN1R_CONTROL: + case WM2200_IN2L_CONTROL: + case WM2200_IN2R_CONTROL: + case WM2200_IN3L_CONTROL: + case WM2200_IN3R_CONTROL: + case WM2200_RXANC_SRC: + case WM2200_INPUT_VOLUME_RAMP: + case WM2200_ADC_DIGITAL_VOLUME_1L: + case WM2200_ADC_DIGITAL_VOLUME_1R: + case WM2200_ADC_DIGITAL_VOLUME_2L: + case WM2200_ADC_DIGITAL_VOLUME_2R: + case WM2200_ADC_DIGITAL_VOLUME_3L: + case WM2200_ADC_DIGITAL_VOLUME_3R: + case WM2200_OUTPUT_ENABLES: + case WM2200_DAC_VOLUME_LIMIT_1L: + case WM2200_DAC_VOLUME_LIMIT_1R: + case WM2200_DAC_VOLUME_LIMIT_2L: + case WM2200_DAC_VOLUME_LIMIT_2R: + case WM2200_DAC_AEC_CONTROL_1: + case WM2200_OUTPUT_VOLUME_RAMP: + case WM2200_DAC_DIGITAL_VOLUME_1L: + case WM2200_DAC_DIGITAL_VOLUME_1R: + case WM2200_DAC_DIGITAL_VOLUME_2L: + case WM2200_DAC_DIGITAL_VOLUME_2R: + case WM2200_PDM_1: + case WM2200_PDM_2: + case WM2200_AUDIO_IF_1_1: + case WM2200_AUDIO_IF_1_2: + case WM2200_AUDIO_IF_1_3: + case WM2200_AUDIO_IF_1_4: + case WM2200_AUDIO_IF_1_5: + case WM2200_AUDIO_IF_1_6: + case WM2200_AUDIO_IF_1_7: + case WM2200_AUDIO_IF_1_8: + case WM2200_AUDIO_IF_1_9: + case WM2200_AUDIO_IF_1_10: + case WM2200_AUDIO_IF_1_11: + case WM2200_AUDIO_IF_1_12: + case WM2200_AUDIO_IF_1_13: + case WM2200_AUDIO_IF_1_14: + case WM2200_AUDIO_IF_1_15: + case WM2200_AUDIO_IF_1_16: + case WM2200_AUDIO_IF_1_17: + case WM2200_AUDIO_IF_1_18: + case WM2200_AUDIO_IF_1_19: + case WM2200_AUDIO_IF_1_20: + case WM2200_AUDIO_IF_1_21: + case WM2200_AUDIO_IF_1_22: + case WM2200_OUT1LMIX_INPUT_1_SOURCE: + case WM2200_OUT1LMIX_INPUT_1_VOLUME: + case WM2200_OUT1LMIX_INPUT_2_SOURCE: + case WM2200_OUT1LMIX_INPUT_2_VOLUME: + case WM2200_OUT1LMIX_INPUT_3_SOURCE: + case WM2200_OUT1LMIX_INPUT_3_VOLUME: + case WM2200_OUT1LMIX_INPUT_4_SOURCE: + case WM2200_OUT1LMIX_INPUT_4_VOLUME: + case WM2200_OUT1RMIX_INPUT_1_SOURCE: + case WM2200_OUT1RMIX_INPUT_1_VOLUME: + case WM2200_OUT1RMIX_INPUT_2_SOURCE: + case WM2200_OUT1RMIX_INPUT_2_VOLUME: + case WM2200_OUT1RMIX_INPUT_3_SOURCE: + case WM2200_OUT1RMIX_INPUT_3_VOLUME: + case WM2200_OUT1RMIX_INPUT_4_SOURCE: + case WM2200_OUT1RMIX_INPUT_4_VOLUME: + case WM2200_OUT2LMIX_INPUT_1_SOURCE: + case WM2200_OUT2LMIX_INPUT_1_VOLUME: + case WM2200_OUT2LMIX_INPUT_2_SOURCE: + case WM2200_OUT2LMIX_INPUT_2_VOLUME: + case WM2200_OUT2LMIX_INPUT_3_SOURCE: + case WM2200_OUT2LMIX_INPUT_3_VOLUME: + case WM2200_OUT2LMIX_INPUT_4_SOURCE: + case WM2200_OUT2LMIX_INPUT_4_VOLUME: + case WM2200_OUT2RMIX_INPUT_1_SOURCE: + case WM2200_OUT2RMIX_INPUT_1_VOLUME: + case WM2200_OUT2RMIX_INPUT_2_SOURCE: + case WM2200_OUT2RMIX_INPUT_2_VOLUME: + case WM2200_OUT2RMIX_INPUT_3_SOURCE: + case WM2200_OUT2RMIX_INPUT_3_VOLUME: + case WM2200_OUT2RMIX_INPUT_4_SOURCE: + case WM2200_OUT2RMIX_INPUT_4_VOLUME: + case WM2200_AIF1TX1MIX_INPUT_1_SOURCE: + case WM2200_AIF1TX1MIX_INPUT_1_VOLUME: + case WM2200_AIF1TX1MIX_INPUT_2_SOURCE: + case WM2200_AIF1TX1MIX_INPUT_2_VOLUME: + case WM2200_AIF1TX1MIX_INPUT_3_SOURCE: + case WM2200_AIF1TX1MIX_INPUT_3_VOLUME: + case WM2200_AIF1TX1MIX_INPUT_4_SOURCE: + case WM2200_AIF1TX1MIX_INPUT_4_VOLUME: + case WM2200_AIF1TX2MIX_INPUT_1_SOURCE: + case WM2200_AIF1TX2MIX_INPUT_1_VOLUME: + case WM2200_AIF1TX2MIX_INPUT_2_SOURCE: + case WM2200_AIF1TX2MIX_INPUT_2_VOLUME: + case WM2200_AIF1TX2MIX_INPUT_3_SOURCE: + case WM2200_AIF1TX2MIX_INPUT_3_VOLUME: + case WM2200_AIF1TX2MIX_INPUT_4_SOURCE: + case WM2200_AIF1TX2MIX_INPUT_4_VOLUME: + case WM2200_AIF1TX3MIX_INPUT_1_SOURCE: + case WM2200_AIF1TX3MIX_INPUT_1_VOLUME: + case WM2200_AIF1TX3MIX_INPUT_2_SOURCE: + case WM2200_AIF1TX3MIX_INPUT_2_VOLUME: + case WM2200_AIF1TX3MIX_INPUT_3_SOURCE: + case WM2200_AIF1TX3MIX_INPUT_3_VOLUME: + case WM2200_AIF1TX3MIX_INPUT_4_SOURCE: + case WM2200_AIF1TX3MIX_INPUT_4_VOLUME: + case WM2200_AIF1TX4MIX_INPUT_1_SOURCE: + case WM2200_AIF1TX4MIX_INPUT_1_VOLUME: + case WM2200_AIF1TX4MIX_INPUT_2_SOURCE: + case WM2200_AIF1TX4MIX_INPUT_2_VOLUME: + case WM2200_AIF1TX4MIX_INPUT_3_SOURCE: + case WM2200_AIF1TX4MIX_INPUT_3_VOLUME: + case WM2200_AIF1TX4MIX_INPUT_4_SOURCE: + case WM2200_AIF1TX4MIX_INPUT_4_VOLUME: + case WM2200_AIF1TX5MIX_INPUT_1_SOURCE: + case WM2200_AIF1TX5MIX_INPUT_1_VOLUME: + case WM2200_AIF1TX5MIX_INPUT_2_SOURCE: + case WM2200_AIF1TX5MIX_INPUT_2_VOLUME: + case WM2200_AIF1TX5MIX_INPUT_3_SOURCE: + case WM2200_AIF1TX5MIX_INPUT_3_VOLUME: + case WM2200_AIF1TX5MIX_INPUT_4_SOURCE: + case WM2200_AIF1TX5MIX_INPUT_4_VOLUME: + case WM2200_AIF1TX6MIX_INPUT_1_SOURCE: + case WM2200_AIF1TX6MIX_INPUT_1_VOLUME: + case WM2200_AIF1TX6MIX_INPUT_2_SOURCE: + case WM2200_AIF1TX6MIX_INPUT_2_VOLUME: + case WM2200_AIF1TX6MIX_INPUT_3_SOURCE: + case WM2200_AIF1TX6MIX_INPUT_3_VOLUME: + case WM2200_AIF1TX6MIX_INPUT_4_SOURCE: + case WM2200_AIF1TX6MIX_INPUT_4_VOLUME: + case WM2200_EQLMIX_INPUT_1_SOURCE: + case WM2200_EQLMIX_INPUT_1_VOLUME: + case WM2200_EQLMIX_INPUT_2_SOURCE: + case WM2200_EQLMIX_INPUT_2_VOLUME: + case WM2200_EQLMIX_INPUT_3_SOURCE: + case WM2200_EQLMIX_INPUT_3_VOLUME: + case WM2200_EQLMIX_INPUT_4_SOURCE: + case WM2200_EQLMIX_INPUT_4_VOLUME: + case WM2200_EQRMIX_INPUT_1_SOURCE: + case WM2200_EQRMIX_INPUT_1_VOLUME: + case WM2200_EQRMIX_INPUT_2_SOURCE: + case WM2200_EQRMIX_INPUT_2_VOLUME: + case WM2200_EQRMIX_INPUT_3_SOURCE: + case WM2200_EQRMIX_INPUT_3_VOLUME: + case WM2200_EQRMIX_INPUT_4_SOURCE: + case WM2200_EQRMIX_INPUT_4_VOLUME: + case WM2200_LHPF1MIX_INPUT_1_SOURCE: + case WM2200_LHPF1MIX_INPUT_1_VOLUME: + case WM2200_LHPF1MIX_INPUT_2_SOURCE: + case WM2200_LHPF1MIX_INPUT_2_VOLUME: + case WM2200_LHPF1MIX_INPUT_3_SOURCE: + case WM2200_LHPF1MIX_INPUT_3_VOLUME: + case WM2200_LHPF1MIX_INPUT_4_SOURCE: + case WM2200_LHPF1MIX_INPUT_4_VOLUME: + case WM2200_LHPF2MIX_INPUT_1_SOURCE: + case WM2200_LHPF2MIX_INPUT_1_VOLUME: + case WM2200_LHPF2MIX_INPUT_2_SOURCE: + case WM2200_LHPF2MIX_INPUT_2_VOLUME: + case WM2200_LHPF2MIX_INPUT_3_SOURCE: + case WM2200_LHPF2MIX_INPUT_3_VOLUME: + case WM2200_LHPF2MIX_INPUT_4_SOURCE: + case WM2200_LHPF2MIX_INPUT_4_VOLUME: + case WM2200_DSP1LMIX_INPUT_1_SOURCE: + case WM2200_DSP1LMIX_INPUT_1_VOLUME: + case WM2200_DSP1LMIX_INPUT_2_SOURCE: + case WM2200_DSP1LMIX_INPUT_2_VOLUME: + case WM2200_DSP1LMIX_INPUT_3_SOURCE: + case WM2200_DSP1LMIX_INPUT_3_VOLUME: + case WM2200_DSP1LMIX_INPUT_4_SOURCE: + case WM2200_DSP1LMIX_INPUT_4_VOLUME: + case WM2200_DSP1RMIX_INPUT_1_SOURCE: + case WM2200_DSP1RMIX_INPUT_1_VOLUME: + case WM2200_DSP1RMIX_INPUT_2_SOURCE: + case WM2200_DSP1RMIX_INPUT_2_VOLUME: + case WM2200_DSP1RMIX_INPUT_3_SOURCE: + case WM2200_DSP1RMIX_INPUT_3_VOLUME: + case WM2200_DSP1RMIX_INPUT_4_SOURCE: + case WM2200_DSP1RMIX_INPUT_4_VOLUME: + case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE: + case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE: + case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE: + case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE: + case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE: + case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE: + case WM2200_DSP2LMIX_INPUT_1_SOURCE: + case WM2200_DSP2LMIX_INPUT_1_VOLUME: + case WM2200_DSP2LMIX_INPUT_2_SOURCE: + case WM2200_DSP2LMIX_INPUT_2_VOLUME: + case WM2200_DSP2LMIX_INPUT_3_SOURCE: + case WM2200_DSP2LMIX_INPUT_3_VOLUME: + case WM2200_DSP2LMIX_INPUT_4_SOURCE: + case WM2200_DSP2LMIX_INPUT_4_VOLUME: + case WM2200_DSP2RMIX_INPUT_1_SOURCE: + case WM2200_DSP2RMIX_INPUT_1_VOLUME: + case WM2200_DSP2RMIX_INPUT_2_SOURCE: + case WM2200_DSP2RMIX_INPUT_2_VOLUME: + case WM2200_DSP2RMIX_INPUT_3_SOURCE: + case WM2200_DSP2RMIX_INPUT_3_VOLUME: + case WM2200_DSP2RMIX_INPUT_4_SOURCE: + case WM2200_DSP2RMIX_INPUT_4_VOLUME: + case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE: + case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE: + case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE: + case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE: + case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE: + case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE: + case WM2200_GPIO_CTRL_1: + case WM2200_GPIO_CTRL_2: + case WM2200_GPIO_CTRL_3: + case WM2200_GPIO_CTRL_4: + case WM2200_ADPS1_IRQ0: + case WM2200_ADPS1_IRQ1: + case WM2200_MISC_PAD_CTRL_1: + case WM2200_INTERRUPT_STATUS_1: + case WM2200_INTERRUPT_STATUS_1_MASK: + case WM2200_INTERRUPT_STATUS_2: + case WM2200_INTERRUPT_RAW_STATUS_2: + case WM2200_INTERRUPT_STATUS_2_MASK: + case WM2200_INTERRUPT_CONTROL: + case WM2200_EQL_1: + case WM2200_EQL_2: + case WM2200_EQL_3: + case WM2200_EQL_4: + case WM2200_EQL_5: + case WM2200_EQL_6: + case WM2200_EQL_7: + case WM2200_EQL_8: + case WM2200_EQL_9: + case WM2200_EQL_10: + case WM2200_EQL_11: + case WM2200_EQL_12: + case WM2200_EQL_13: + case WM2200_EQL_14: + case WM2200_EQL_15: + case WM2200_EQL_16: + case WM2200_EQL_17: + case WM2200_EQL_18: + case WM2200_EQL_19: + case WM2200_EQL_20: + case WM2200_EQR_1: + case WM2200_EQR_2: + case WM2200_EQR_3: + case WM2200_EQR_4: + case WM2200_EQR_5: + case WM2200_EQR_6: + case WM2200_EQR_7: + case WM2200_EQR_8: + case WM2200_EQR_9: + case WM2200_EQR_10: + case WM2200_EQR_11: + case WM2200_EQR_12: + case WM2200_EQR_13: + case WM2200_EQR_14: + case WM2200_EQR_15: + case WM2200_EQR_16: + case WM2200_EQR_17: + case WM2200_EQR_18: + case WM2200_EQR_19: + case WM2200_EQR_20: + case WM2200_HPLPF1_1: + case WM2200_HPLPF1_2: + case WM2200_HPLPF2_1: + case WM2200_HPLPF2_2: + case WM2200_DSP1_CONTROL_1: + case WM2200_DSP1_CONTROL_2: + case WM2200_DSP1_CONTROL_3: + case WM2200_DSP1_CONTROL_4: + case WM2200_DSP1_CONTROL_5: + case WM2200_DSP1_CONTROL_6: + case WM2200_DSP1_CONTROL_7: + case WM2200_DSP1_CONTROL_8: + case WM2200_DSP1_CONTROL_9: + case WM2200_DSP1_CONTROL_10: + case WM2200_DSP1_CONTROL_11: + case WM2200_DSP1_CONTROL_12: + case WM2200_DSP1_CONTROL_13: + case WM2200_DSP1_CONTROL_14: + case WM2200_DSP1_CONTROL_15: + case WM2200_DSP1_CONTROL_16: + case WM2200_DSP1_CONTROL_17: + case WM2200_DSP1_CONTROL_18: + case WM2200_DSP1_CONTROL_19: + case WM2200_DSP1_CONTROL_20: + case WM2200_DSP1_CONTROL_21: + case WM2200_DSP1_CONTROL_22: + case WM2200_DSP1_CONTROL_23: + case WM2200_DSP1_CONTROL_24: + case WM2200_DSP1_CONTROL_25: + case WM2200_DSP1_CONTROL_26: + case WM2200_DSP1_CONTROL_27: + case WM2200_DSP1_CONTROL_28: + case WM2200_DSP1_CONTROL_29: + case WM2200_DSP1_CONTROL_30: + case WM2200_DSP1_CONTROL_31: + case WM2200_DSP2_CONTROL_1: + case WM2200_DSP2_CONTROL_2: + case WM2200_DSP2_CONTROL_3: + case WM2200_DSP2_CONTROL_4: + case WM2200_DSP2_CONTROL_5: + case WM2200_DSP2_CONTROL_6: + case WM2200_DSP2_CONTROL_7: + case WM2200_DSP2_CONTROL_8: + case WM2200_DSP2_CONTROL_9: + case WM2200_DSP2_CONTROL_10: + case WM2200_DSP2_CONTROL_11: + case WM2200_DSP2_CONTROL_12: + case WM2200_DSP2_CONTROL_13: + case WM2200_DSP2_CONTROL_14: + case WM2200_DSP2_CONTROL_15: + case WM2200_DSP2_CONTROL_16: + case WM2200_DSP2_CONTROL_17: + case WM2200_DSP2_CONTROL_18: + case WM2200_DSP2_CONTROL_19: + case WM2200_DSP2_CONTROL_20: + case WM2200_DSP2_CONTROL_21: + case WM2200_DSP2_CONTROL_22: + case WM2200_DSP2_CONTROL_23: + case WM2200_DSP2_CONTROL_24: + case WM2200_DSP2_CONTROL_25: + case WM2200_DSP2_CONTROL_26: + case WM2200_DSP2_CONTROL_27: + case WM2200_DSP2_CONTROL_28: + case WM2200_DSP2_CONTROL_29: + case WM2200_DSP2_CONTROL_30: + case WM2200_DSP2_CONTROL_31: + return true; + default: + return false; + } +} + +static const struct reg_default wm2200_reva_patch[] = { + { 0x07, 0x0003 }, + { 0x102, 0x0200 }, + { 0x203, 0x0084 }, + { 0x201, 0x83FF }, + { 0x20C, 0x0062 }, + { 0x20D, 0x0062 }, + { 0x207, 0x2002 }, + { 0x208, 0x20C0 }, + { 0x21D, 0x01C0 }, + { 0x50A, 0x0001 }, + { 0x50B, 0x0002 }, + { 0x50C, 0x0003 }, + { 0x50D, 0x0004 }, + { 0x50E, 0x0005 }, + { 0x510, 0x0001 }, + { 0x511, 0x0002 }, + { 0x512, 0x0003 }, + { 0x513, 0x0004 }, + { 0x514, 0x0005 }, + { 0x515, 0x0000 }, + { 0x201, 0x8084 }, + { 0x202, 0xBBDE }, + { 0x203, 0x00EC }, + { 0x500, 0x8000 }, + { 0x507, 0x1820 }, + { 0x508, 0x1820 }, + { 0x505, 0x0300 }, + { 0x506, 0x0300 }, + { 0x302, 0x2280 }, + { 0x303, 0x0080 }, + { 0x304, 0x2280 }, + { 0x305, 0x0080 }, + { 0x306, 0x2280 }, + { 0x307, 0x0080 }, + { 0x401, 0x0080 }, + { 0x402, 0x0080 }, + { 0x417, 0x3069 }, + { 0x900, 0x6318 }, + { 0x901, 0x6300 }, + { 0x902, 0x0FC8 }, + { 0x903, 0x03FE }, + { 0x904, 0x00E0 }, + { 0x905, 0x1EC4 }, + { 0x906, 0xF136 }, + { 0x907, 0x0409 }, + { 0x908, 0x04CC }, + { 0x909, 0x1C9B }, + { 0x90A, 0xF337 }, + { 0x90B, 0x040B }, + { 0x90C, 0x0CBB }, + { 0x90D, 0x16F8 }, + { 0x90E, 0xF7D9 }, + { 0x90F, 0x040A }, + { 0x910, 0x1F14 }, + { 0x911, 0x058C }, + { 0x912, 0x0563 }, + { 0x913, 0x4000 }, + { 0x916, 0x6318 }, + { 0x917, 0x6300 }, + { 0x918, 0x0FC8 }, + { 0x919, 0x03FE }, + { 0x91A, 0x00E0 }, + { 0x91B, 0x1EC4 }, + { 0x91C, 0xF136 }, + { 0x91D, 0x0409 }, + { 0x91E, 0x04CC }, + { 0x91F, 0x1C9B }, + { 0x920, 0xF337 }, + { 0x921, 0x040B }, + { 0x922, 0x0CBB }, + { 0x923, 0x16F8 }, + { 0x924, 0xF7D9 }, + { 0x925, 0x040A }, + { 0x926, 0x1F14 }, + { 0x927, 0x058C }, + { 0x928, 0x0563 }, + { 0x929, 0x4000 }, + { 0x709, 0x2000 }, + { 0x207, 0x200E }, + { 0x208, 0x20D4 }, + { 0x20A, 0x0080 }, + { 0x07, 0x0000 }, +}; + +static int wm2200_reset(struct wm2200_priv *wm2200) +{ + if (wm2200->pdata.reset) { + gpio_set_value_cansleep(wm2200->pdata.reset, 0); + gpio_set_value_cansleep(wm2200->pdata.reset, 1); + + return 0; + } else { + return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET, + 0x2200); + } +} + +static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0); +static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); +static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); + +static const char *wm2200_mixer_texts[] = { + "None", + "Tone Generator", + "AEC loopback", + "IN1L", + "IN1R", + "IN2L", + "IN2R", + "IN3L", + "IN3R", + "AIF1RX1", + "AIF1RX2", + "AIF1RX3", + "AIF1RX4", + "AIF1RX5", + "AIF1RX6", + "EQL", + "EQR", + "LHPF1", + "LHPF2", + "LHPF3", + "LHPF4", + "DSP1.1", + "DSP1.2", + "DSP1.3", + "DSP1.4", + "DSP1.5", + "DSP1.6", + "DSP2.1", + "DSP2.2", + "DSP2.3", + "DSP2.4", + "DSP2.5", + "DSP2.6", +}; + +static int wm2200_mixer_values[] = { + 0x00, + 0x04, /* Tone */ + 0x08, /* AEC */ + 0x10, /* Input */ + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x20, /* AIF */ + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x50, /* EQ */ + 0x51, + 0x52, + 0x60, /* LHPF1 */ + 0x61, /* LHPF2 */ + 0x68, /* DSP1 */ + 0x69, + 0x6a, + 0x6b, + 0x6c, + 0x6d, + 0x70, /* DSP2 */ + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, +}; + +#define WM2200_MIXER_CONTROLS(name, base) \ + SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \ + WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ + SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \ + WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ + SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \ + WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ + SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \ + WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv) + +#define WM2200_MUX_ENUM_DECL(name, reg) \ + SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ + wm2200_mixer_texts, wm2200_mixer_values) + +#define WM2200_MUX_CTL_DECL(name) \ + const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_VALUE_ENUM("Route", name##_enum) + +#define WM2200_MIXER_ENUMS(name, base_reg) \ + static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ + static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ + static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ + static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ + static WM2200_MUX_CTL_DECL(name##_in1); \ + static WM2200_MUX_CTL_DECL(name##_in2); \ + static WM2200_MUX_CTL_DECL(name##_in3); \ + static WM2200_MUX_CTL_DECL(name##_in4) + +static const struct snd_kcontrol_new wm2200_snd_controls[] = { +SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, + WM2200_IN1_OSR_SHIFT, 1, 0), +SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL, + WM2200_IN2_OSR_SHIFT, 1, 0), +SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL, + WM2200_IN3_OSR_SHIFT, 1, 0), + +SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL, + WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), +SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL, + WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), +SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL, + WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), + +SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, + WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, + WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, + WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1), + +SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L, + WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L, + WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT, + 0xbf, 0, digital_tlv), +SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L, + WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT, + 0xbf, 0, digital_tlv), + +SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L, + WM2200_OUT1_OSR_SHIFT, 1, 0), +SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L, + WM2200_OUT2_OSR_SHIFT, 1, 0), + +SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L, + WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L, + WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0, + digital_tlv), +SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L, + WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT, + 0x46, 0, out_tlv), + +SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L, + WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1), +SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L, + WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0, + digital_tlv), +SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT, + WM2200_SPK1R_MUTE_SHIFT, 1, 0), +}; + +WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE); + +WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE); + +WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE); + +WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); + +WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); +WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); + +#define WM2200_MUX(name, ctrl) \ + SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + +#define WM2200_MIXER_WIDGETS(name, name_str) \ + WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ + WM2200_MUX(name_str " Input 2", &name##_in2_mux), \ + WM2200_MUX(name_str " Input 3", &name##_in3_mux), \ + WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ + SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) + +#define WM2200_MIXER_INPUT_ROUTES(name) \ + { name, "Tone Generator", "Tone Generator" }, \ + { name, "IN1L", "IN1L PGA" }, \ + { name, "IN1R", "IN1R PGA" }, \ + { name, "IN2L", "IN2L PGA" }, \ + { name, "IN2R", "IN2R PGA" }, \ + { name, "IN3L", "IN3L PGA" }, \ + { name, "IN3R", "IN3R PGA" }, \ + { name, "DSP1.1", "DSP1" }, \ + { name, "DSP1.2", "DSP1" }, \ + { name, "DSP1.3", "DSP1" }, \ + { name, "DSP1.4", "DSP1" }, \ + { name, "DSP1.5", "DSP1" }, \ + { name, "DSP1.6", "DSP1" }, \ + { name, "DSP2.1", "DSP2" }, \ + { name, "DSP2.2", "DSP2" }, \ + { name, "DSP2.3", "DSP2" }, \ + { name, "DSP2.4", "DSP2" }, \ + { name, "DSP2.5", "DSP2" }, \ + { name, "DSP2.6", "DSP2" }, \ + { name, "AIF1RX1", "AIF1RX1" }, \ + { name, "AIF1RX2", "AIF1RX2" }, \ + { name, "AIF1RX3", "AIF1RX3" }, \ + { name, "AIF1RX4", "AIF1RX4" }, \ + { name, "AIF1RX5", "AIF1RX5" }, \ + { name, "AIF1RX6", "AIF1RX6" }, \ + { name, "EQL", "EQL" }, \ + { name, "EQR", "EQR" }, \ + { name, "LHPF1", "LHPF1" }, \ + { name, "LHPF2", "LHPF2" } + +#define WM2200_MIXER_ROUTES(widget, name) \ + { widget, NULL, name " Mixer" }, \ + { name " Mixer", NULL, name " Input 1" }, \ + { name " Mixer", NULL, name " Input 2" }, \ + { name " Mixer", NULL, name " Input 3" }, \ + { name " Mixer", NULL, name " Input 4" }, \ + WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \ + WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \ + WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ + WM2200_MIXER_INPUT_ROUTES(name " Input 4") + +static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { +SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT, + 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT, + 0, NULL, 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), +SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20), + +SND_SOC_DAPM_INPUT("IN1L"), +SND_SOC_DAPM_INPUT("IN1R"), +SND_SOC_DAPM_INPUT("IN2L"), +SND_SOC_DAPM_INPUT("IN2R"), +SND_SOC_DAPM_INPUT("IN3L"), +SND_SOC_DAPM_INPUT("IN3R"), + +SND_SOC_DAPM_SIGGEN("TONE"), +SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1, + WM2200_TONE_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0, + NULL, 0), + +SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0, + WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1, + WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2, + WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3, + WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4, + WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5, + WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0), + +SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0, + NULL, 0), +SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, + NULL, 0), + +SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), +SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, + WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1, + WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2, + WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3, + WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4, + WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, + WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), + +SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, + WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, + WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1, + WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1, + WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1, + WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1, + WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1, + WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1, + WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2, + WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2, + WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2, + WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2, + WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2, + WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2, + WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT, + 0, NULL, 0), +SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT, + 0, NULL, 0), + +SND_SOC_DAPM_OUTPUT("EPOUTLN"), +SND_SOC_DAPM_OUTPUT("EPOUTLP"), +SND_SOC_DAPM_OUTPUT("EPOUTRN"), +SND_SOC_DAPM_OUTPUT("EPOUTRP"), +SND_SOC_DAPM_OUTPUT("SPK"), + +WM2200_MIXER_WIDGETS(EQL, "EQL"), +WM2200_MIXER_WIDGETS(EQR, "EQR"), + +WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), +WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), + +WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"), +WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"), +WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"), +WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"), + +WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), +WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), +WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), +WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), +WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), +WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), + +WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"), +WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"), +WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"), +WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"), +}; + +static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { + /* Everything needs SYSCLK but only hook up things on the edge + * of the chip */ + { "IN1L", NULL, "SYSCLK" }, + { "IN1R", NULL, "SYSCLK" }, + { "IN2L", NULL, "SYSCLK" }, + { "IN2R", NULL, "SYSCLK" }, + { "IN3L", NULL, "SYSCLK" }, + { "IN3R", NULL, "SYSCLK" }, + { "OUT1L", NULL, "SYSCLK" }, + { "OUT1R", NULL, "SYSCLK" }, + { "OUT2L", NULL, "SYSCLK" }, + { "OUT2R", NULL, "SYSCLK" }, + { "AIF1RX1", NULL, "SYSCLK" }, + { "AIF1RX2", NULL, "SYSCLK" }, + { "AIF1RX3", NULL, "SYSCLK" }, + { "AIF1RX4", NULL, "SYSCLK" }, + { "AIF1RX5", NULL, "SYSCLK" }, + { "AIF1RX6", NULL, "SYSCLK" }, + { "AIF1TX1", NULL, "SYSCLK" }, + { "AIF1TX2", NULL, "SYSCLK" }, + { "AIF1TX3", NULL, "SYSCLK" }, + { "AIF1TX4", NULL, "SYSCLK" }, + { "AIF1TX5", NULL, "SYSCLK" }, + { "AIF1TX6", NULL, "SYSCLK" }, + + { "IN1L", NULL, "AVDD" }, + { "IN1R", NULL, "AVDD" }, + { "IN2L", NULL, "AVDD" }, + { "IN2R", NULL, "AVDD" }, + { "IN3L", NULL, "AVDD" }, + { "IN3R", NULL, "AVDD" }, + { "OUT1L", NULL, "AVDD" }, + { "OUT1R", NULL, "AVDD" }, + + { "IN1L PGA", NULL, "IN1L" }, + { "IN1R PGA", NULL, "IN1R" }, + { "IN2L PGA", NULL, "IN2L" }, + { "IN2R PGA", NULL, "IN2R" }, + { "IN3L PGA", NULL, "IN3L" }, + { "IN3R PGA", NULL, "IN3R" }, + + { "Tone Generator", NULL, "TONE" }, + + { "CP2", NULL, "CPVDD" }, + { "MICBIAS1", NULL, "CP2" }, + { "MICBIAS2", NULL, "CP2" }, + + { "CP1", NULL, "CPVDD" }, + { "EPD_LN", NULL, "CP1" }, + { "EPD_LP", NULL, "CP1" }, + { "EPD_RN", NULL, "CP1" }, + { "EPD_RP", NULL, "CP1" }, + + { "EPD_LP", NULL, "OUT1L" }, + { "EPD_OUTP_LP", NULL, "EPD_LP" }, + { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" }, + { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" }, + + { "EPD_LN", NULL, "OUT1L" }, + { "EPD_OUTP_LN", NULL, "EPD_LN" }, + { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" }, + { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" }, + + { "EPD_RP", NULL, "OUT1R" }, + { "EPD_OUTP_RP", NULL, "EPD_RP" }, + { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" }, + { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" }, + + { "EPD_RN", NULL, "OUT1R" }, + { "EPD_OUTP_RN", NULL, "EPD_RN" }, + { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" }, + { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" }, + + { "SPK", NULL, "OUT2L" }, + { "SPK", NULL, "OUT2R" }, + + WM2200_MIXER_ROUTES("DSP1", "DSP1L"), + WM2200_MIXER_ROUTES("DSP1", "DSP1R"), + WM2200_MIXER_ROUTES("DSP2", "DSP2L"), + WM2200_MIXER_ROUTES("DSP2", "DSP2R"), + + WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), + WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), + WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), + WM2200_MIXER_ROUTES("OUT2R", "OUT2R"), + + WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), + WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), + WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), + WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), + WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), + WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), + + WM2200_MIXER_ROUTES("EQL", "EQL"), + WM2200_MIXER_ROUTES("EQR", "EQR"), + + WM2200_MIXER_ROUTES("LHPF1", "LHPF1"), + WM2200_MIXER_ROUTES("LHPF2", "LHPF2"), +}; + +static int wm2200_probe(struct snd_soc_codec *codec) +{ + struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev); + int ret; + + wm2200->codec = codec; + codec->control_data = wm2200->regmap; + codec->dapm.bias_level = SND_SOC_BIAS_OFF; + + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + return ret; +} + +static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + int lrclk, bclk, fmt_val; + + lrclk = 0; + bclk = 0; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + fmt_val = 0; + break; + case SND_SOC_DAIFMT_DSP_B: + fmt_val = 1; + break; + case SND_SOC_DAIFMT_I2S: + fmt_val = 2; + break; + case SND_SOC_DAIFMT_LEFT_J: + fmt_val = 3; + break; + default: + dev_err(codec->dev, "Unsupported DAI format %d\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBS_CFM: + lrclk |= WM2200_AIF1TX_LRCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + bclk |= WM2200_AIF1_BCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + lrclk |= WM2200_AIF1TX_LRCLK_MSTR; + bclk |= WM2200_AIF1_BCLK_MSTR; + break; + default: + dev_err(codec->dev, "Unsupported master mode %d\n", + fmt & SND_SOC_DAIFMT_MASTER_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + bclk |= WM2200_AIF1_BCLK_INV; + lrclk |= WM2200_AIF1TX_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + bclk |= WM2200_AIF1_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + lrclk |= WM2200_AIF1TX_LRCLK_INV; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR | + WM2200_AIF1_BCLK_INV, bclk); + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2, + WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, + lrclk); + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3, + WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, + lrclk); + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5, + WM2200_AIF1_FMT_MASK << 1, fmt_val << 1); + + return 0; +} + +static int wm2200_sr_code[] = { + 0, + 12000, + 24000, + 48000, + 96000, + 192000, + 384000, + 768000, + 0, + 11025, + 22050, + 44100, + 88200, + 176400, + 352800, + 705600, + 4000, + 8000, + 16000, + 32000, + 64000, + 128000, + 256000, + 512000, +}; + +#define WM2200_NUM_BCLK_RATES 12 + +static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = { + 6144000, + 3072000, + 2048000, + 1536000, + 768000, + 512000, + 384000, + 256000, + 192000, + 128000, + 96000, + 64000, +}; + +static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { + 5644800, + 2882400, + 1881600, + 1411200, + 705600, + 470400, + 352800, + 176400, + 117600, + 88200, + 58800, +}; + +static int wm2200_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); + int i, bclk, lrclk, wl, fl, sr_code; + int *bclk_rates; + + /* Data sizes if not using TDM */ + wl = snd_pcm_format_width(params_format(params)); + if (wl < 0) + return wl; + fl = snd_soc_params_to_frame_size(params); + if (fl < 0) + return fl; + + dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n", + wl, fl); + + /* Target BCLK rate */ + bclk = snd_soc_params_to_bclk(params); + if (bclk < 0) + return bclk; + + if (!wm2200->sysclk) { + dev_err(codec->dev, "SYSCLK has no rate set\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++) + if (wm2200_sr_code[i] == params_rate(params)) + break; + if (i == ARRAY_SIZE(wm2200_sr_code)) { + dev_err(codec->dev, "Unsupported sample rate: %dHz\n", + params_rate(params)); + return -EINVAL; + } + sr_code = i; + + dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n", + bclk, wm2200->sysclk); + + if (wm2200->sysclk % 4000) + bclk_rates = wm2200_bclk_rates_cd; + else + bclk_rates = wm2200_bclk_rates_dat; + + for (i = 0; i < WM2200_NUM_BCLK_RATES; i++) + if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0)) + break; + if (i == WM2200_NUM_BCLK_RATES) { + dev_err(codec->dev, + "No valid BCLK for %dHz found from %dHz SYSCLK\n", + bclk, wm2200->sysclk); + return -EINVAL; + } + + bclk = i; + dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]); + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, + WM2200_AIF1_BCLK_DIV_MASK, bclk); + + lrclk = bclk_rates[bclk] / params_rate(params); + dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + dai->symmetric_rates) + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7, + WM2200_AIF1RX_BCPF_MASK, lrclk); + else + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6, + WM2200_AIF1TX_BCPF_MASK, lrclk); + + i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9, + WM2200_AIF1RX_WL_MASK | + WM2200_AIF1RX_SLOT_LEN_MASK, i); + else + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8, + WM2200_AIF1TX_WL_MASK | + WM2200_AIF1TX_SLOT_LEN_MASK, i); + + snd_soc_update_bits(codec, WM2200_CLOCKING_4, + WM2200_SAMPLE_RATE_1_MASK, sr_code); + + return 0; +} + +static const struct snd_soc_dai_ops wm2200_dai_ops = { + .set_fmt = wm2200_set_fmt, + .hw_params = wm2200_hw_params, +}; + +static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id, + int source, unsigned int freq, int dir) +{ + struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); + int fval; + + switch (clk_id) { + case WM2200_CLK_SYSCLK: + break; + + default: + dev_err(codec->dev, "Unknown clock %d\n", clk_id); + return -EINVAL; + } + + switch (source) { + case WM2200_CLKSRC_MCLK1: + case WM2200_CLKSRC_MCLK2: + case WM2200_CLKSRC_FLL: + case WM2200_CLKSRC_BCLK1: + break; + default: + dev_err(codec->dev, "Invalid source %d\n", source); + return -EINVAL; + } + + switch (freq) { + case 22579200: + case 24576000: + fval = 2; + break; + default: + dev_err(codec->dev, "Invalid clock rate: %d\n", freq); + return -EINVAL; + } + + /* TODO: Check if MCLKs are in use and enable/disable pulls to + * match. + */ + + snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK | + WM2200_SYSCLK_SRC_MASK, + fval << WM2200_SYSCLK_FREQ_SHIFT | source); + + wm2200->sysclk = freq; + + return 0; +} + +struct _fll_div { + u16 fll_fratio; + u16 fll_outdiv; + u16 fll_refclk_div; + u16 n; + u16 theta; + u16 lambda; +}; + +static struct { + unsigned int min; + unsigned int max; + u16 fll_fratio; + int ratio; +} fll_fratios[] = { + { 0, 64000, 4, 16 }, + { 64000, 128000, 3, 8 }, + { 128000, 256000, 2, 4 }, + { 256000, 1000000, 1, 2 }, + { 1000000, 13500000, 0, 1 }, +}; + +static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, + unsigned int Fout) +{ + unsigned int target; + unsigned int div; + unsigned int fratio, gcd_fll; + int i; + + /* Fref must be <=13.5MHz */ + div = 1; + fll_div->fll_refclk_div = 0; + while ((Fref / div) > 13500000) { + div *= 2; + fll_div->fll_refclk_div++; + + if (div > 8) { + pr_err("Can't scale %dMHz input down to <=13.5MHz\n", + Fref); + return -EINVAL; + } + } + + pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); + + /* Apply the division for our remaining calculations */ + Fref /= div; + + /* Fvco should be 90-100MHz; don't check the upper bound */ + div = 2; + while (Fout * div < 90000000) { + div++; + if (div > 64) { + pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", + Fout); + return -EINVAL; + } + } + target = Fout * div; + fll_div->fll_outdiv = div - 1; + + pr_debug("FLL Fvco=%dHz\n", target); + + /* Find an appropraite FLL_FRATIO and factor it out of the target */ + for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { + if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { + fll_div->fll_fratio = fll_fratios[i].fll_fratio; + fratio = fll_fratios[i].ratio; + break; + } + } + if (i == ARRAY_SIZE(fll_fratios)) { + pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); + return -EINVAL; + } + + fll_div->n = target / (fratio * Fref); + + if (target % Fref == 0) { + fll_div->theta = 0; + fll_div->lambda = 0; + } else { + gcd_fll = gcd(target, fratio * Fref); + + fll_div->theta = (target - (fll_div->n * fratio * Fref)) + / gcd_fll; + fll_div->lambda = (fratio * Fref) / gcd_fll; + } + + pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", + fll_div->n, fll_div->theta, fll_div->lambda); + pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", + fll_div->fll_fratio, fratio, fll_div->fll_outdiv, + fll_div->fll_refclk_div); + + return 0; +} + +static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source, + unsigned int Fref, unsigned int Fout) +{ + struct i2c_client *i2c = to_i2c_client(codec->dev); + struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); + struct _fll_div factors; + int ret, i, timeout; + + if (!Fout) { + dev_dbg(codec->dev, "FLL disabled"); + + if (wm2200->fll_fout) + pm_runtime_put(codec->dev); + + wm2200->fll_fout = 0; + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, + WM2200_FLL_ENA, 0); + return 0; + } + + switch (source) { + case WM2200_FLL_SRC_MCLK1: + case WM2200_FLL_SRC_MCLK2: + case WM2200_FLL_SRC_BCLK: + break; + default: + dev_err(codec->dev, "Invalid FLL source %d\n", source); + return -EINVAL; + } + + ret = fll_factors(&factors, Fref, Fout); + if (ret < 0) + return ret; + + /* Disable the FLL while we reconfigure */ + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0); + + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2, + WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK, + (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) | + factors.fll_fratio); + if (factors.theta) { + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3, + WM2200_FLL_FRACN_ENA, + WM2200_FLL_FRACN_ENA); + snd_soc_update_bits(codec, WM2200_FLL_EFS_2, + WM2200_FLL_EFS_ENA, + WM2200_FLL_EFS_ENA); + } else { + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3, + WM2200_FLL_FRACN_ENA, 0); + snd_soc_update_bits(codec, WM2200_FLL_EFS_2, + WM2200_FLL_EFS_ENA, 0); + } + + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK, + factors.theta); + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK, + factors.n); + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7, + WM2200_FLL_CLK_REF_DIV_MASK | + WM2200_FLL_CLK_REF_SRC_MASK, + (factors.fll_refclk_div + << WM2200_FLL_CLK_REF_DIV_SHIFT) | source); + snd_soc_update_bits(codec, WM2200_FLL_EFS_1, + WM2200_FLL_LAMBDA_MASK, factors.lambda); + + /* Clear any pending completions */ + try_wait_for_completion(&wm2200->fll_lock); + + pm_runtime_get_sync(codec->dev); + + snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, + WM2200_FLL_ENA, WM2200_FLL_ENA); + + if (i2c->irq) + timeout = 2; + else + timeout = 50; + + snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA, + WM2200_SYSCLK_ENA); + + /* Poll for the lock; will use the interrupt to exit quickly */ + for (i = 0; i < timeout; i++) { + if (i2c->irq) { + ret = wait_for_completion_timeout(&wm2200->fll_lock, + msecs_to_jiffies(25)); + if (ret > 0) + break; + } else { + msleep(1); + } + + ret = snd_soc_read(codec, + WM2200_INTERRUPT_RAW_STATUS_2); + if (ret < 0) { + dev_err(codec->dev, + "Failed to read FLL status: %d\n", + ret); + continue; + } + if (ret & WM2200_FLL_LOCK_STS) + break; + } + if (i == timeout) { + dev_err(codec->dev, "FLL lock timed out\n"); + pm_runtime_put(codec->dev); + return -ETIMEDOUT; + } + + wm2200->fll_src = source; + wm2200->fll_fref = Fref; + wm2200->fll_fout = Fout; + + dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout); + + return 0; +} + +static int wm2200_dai_probe(struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + unsigned int val = 0; + int ret; + + ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1); + if (ret >= 0) { + if ((ret & WM2200_GP1_FN_MASK) != 0) { + dai->symmetric_rates = true; + val = WM2200_AIF1TX_LRCLK_SRC; + } + } else { + dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret); + } + + snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2, + WM2200_AIF1TX_LRCLK_SRC, val); + + return 0; +} + +#define WM2200_RATES SNDRV_PCM_RATE_8000_48000 + +#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver wm2200_dai = { + .name = "wm2200", + .probe = wm2200_dai_probe, + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM2200_RATES, + .formats = WM2200_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = WM2200_RATES, + .formats = WM2200_FORMATS, + }, + .ops = &wm2200_dai_ops, +}; + +static struct snd_soc_codec_driver soc_codec_wm2200 = { + .probe = wm2200_probe, + + .idle_bias_off = true, + .ignore_pmdown_time = true, + .set_sysclk = wm2200_set_sysclk, + .set_pll = wm2200_set_fll, + + .controls = wm2200_snd_controls, + .num_controls = ARRAY_SIZE(wm2200_snd_controls), + .dapm_widgets = wm2200_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), + .dapm_routes = wm2200_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), +}; + +static irqreturn_t wm2200_irq(int irq, void *data) +{ + struct wm2200_priv *wm2200 = data; + unsigned int val, mask; + int ret; + + ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val); + if (ret != 0) { + dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret); + return IRQ_NONE; + } + + ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK, + &mask); + if (ret != 0) { + dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret); + mask = 0; + } + + val &= ~mask; + + if (val & WM2200_FLL_LOCK_EINT) { + dev_dbg(wm2200->dev, "FLL locked\n"); + complete(&wm2200->fll_lock); + } + + if (val) { + regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val); + + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } +} + +static const struct regmap_config wm2200_regmap = { + .reg_bits = 16, + .val_bits = 16, + + .max_register = WM2200_MAX_REGISTER, + .reg_defaults = wm2200_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), + .volatile_reg = wm2200_volatile_register, + .readable_reg = wm2200_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + +static const unsigned int wm2200_dig_vu[] = { + WM2200_DAC_DIGITAL_VOLUME_1L, + WM2200_DAC_DIGITAL_VOLUME_1R, + WM2200_DAC_DIGITAL_VOLUME_2L, + WM2200_DAC_DIGITAL_VOLUME_2R, + WM2200_ADC_DIGITAL_VOLUME_1L, + WM2200_ADC_DIGITAL_VOLUME_1R, + WM2200_ADC_DIGITAL_VOLUME_2L, + WM2200_ADC_DIGITAL_VOLUME_2R, + WM2200_ADC_DIGITAL_VOLUME_3L, + WM2200_ADC_DIGITAL_VOLUME_3R, +}; + +static const unsigned int wm2200_mic_ctrl_reg[] = { + WM2200_IN1L_CONTROL, + WM2200_IN2L_CONTROL, + WM2200_IN3L_CONTROL, +}; + +static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev); + struct wm2200_priv *wm2200; + unsigned int reg; + int ret, i; + + wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv), + GFP_KERNEL); + if (wm2200 == NULL) + return -ENOMEM; + + wm2200->dev = &i2c->dev; + init_completion(&wm2200->fll_lock); + + wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap); + if (IS_ERR(wm2200->regmap)) { + ret = PTR_ERR(wm2200->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + + if (pdata) + wm2200->pdata = *pdata; + + i2c_set_clientdata(i2c, wm2200); + + for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) + wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; + + ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request core supplies: %d\n", + ret); + goto err_regmap; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", + ret); + goto err_core; + } + + if (wm2200->pdata.ldo_ena) { + ret = gpio_request_one(wm2200->pdata.ldo_ena, + GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA"); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", + wm2200->pdata.ldo_ena, ret); + goto err_enable; + } + msleep(2); + } + + if (wm2200->pdata.reset) { + ret = gpio_request_one(wm2200->pdata.reset, + GPIOF_OUT_INIT_HIGH, "WM2200 /RESET"); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", + wm2200->pdata.reset, ret); + goto err_ldo; + } + } + + ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); + goto err_reset; + } + switch (reg) { + case 0x2200: + break; + + default: + dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg); + ret = -EINVAL; + goto err_reset; + } + + ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read revision register\n"); + goto err_reset; + } + + wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK; + + dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A'); + + switch (wm2200->rev) { + case 0: + ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch, + ARRAY_SIZE(wm2200_reva_patch)); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register patch: %d\n", + ret); + } + break; + default: + break; + } + + ret = wm2200_reset(wm2200); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset\n"); + goto err_reset; + } + + for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) { + if (!wm2200->pdata.gpio_defaults[i]) + continue; + + regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i, + wm2200->pdata.gpio_defaults[i]); + } + + for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++) + regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i], + WM2200_OUT_VU, WM2200_OUT_VU); + + /* Assign slots 1-6 to channels 1-6 for both TX and RX */ + for (i = 0; i < 6; i++) { + regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i); + regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i); + } + + for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) { + regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i], + WM2200_IN1_MODE_MASK | + WM2200_IN1_DMIC_SUP_MASK, + (wm2200->pdata.in_mode[i] << + WM2200_IN1_MODE_SHIFT) | + (wm2200->pdata.dmic_sup[i] << + WM2200_IN1_DMIC_SUP_SHIFT)); + } + + if (i2c->irq) { + ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "wm2200", wm2200); + if (ret == 0) + regmap_update_bits(wm2200->regmap, + WM2200_INTERRUPT_STATUS_2_MASK, + WM2200_FLL_LOCK_EINT, 0); + else + dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", + i2c->irq, ret); + } + + pm_runtime_set_active(&i2c->dev); + pm_runtime_enable(&i2c->dev); + pm_request_idle(&i2c->dev); + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200, + &wm2200_dai, 1); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err_pm_runtime; + } + + return 0; + +err_pm_runtime: + pm_runtime_disable(&i2c->dev); +err_reset: + if (wm2200->pdata.reset) { + gpio_set_value_cansleep(wm2200->pdata.reset, 0); + gpio_free(wm2200->pdata.reset); + } +err_ldo: + if (wm2200->pdata.ldo_ena) { + gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); + gpio_free(wm2200->pdata.ldo_ena); + } +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); +err_core: + regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); +err_regmap: + regmap_exit(wm2200->regmap); +err: + return ret; +} + +static __devexit int wm2200_i2c_remove(struct i2c_client *i2c) +{ + struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c); + + snd_soc_unregister_codec(&i2c->dev); + if (i2c->irq) + free_irq(i2c->irq, wm2200); + if (wm2200->pdata.reset) { + gpio_set_value_cansleep(wm2200->pdata.reset, 0); + gpio_free(wm2200->pdata.reset); + } + if (wm2200->pdata.ldo_ena) { + gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); + gpio_free(wm2200->pdata.ldo_ena); + } + regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); + regmap_exit(wm2200->regmap); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int wm2200_runtime_suspend(struct device *dev) +{ + struct wm2200_priv *wm2200 = dev_get_drvdata(dev); + + regcache_cache_only(wm2200->regmap, true); + regcache_mark_dirty(wm2200->regmap); + if (wm2200->pdata.ldo_ena) + gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); + regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); + + return 0; +} + +static int wm2200_runtime_resume(struct device *dev) +{ + struct wm2200_priv *wm2200 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), + wm2200->core_supplies); + if (ret != 0) { + dev_err(dev, "Failed to enable supplies: %d\n", + ret); + return ret; + } + + if (wm2200->pdata.ldo_ena) { + gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1); + msleep(2); + } + + regcache_cache_only(wm2200->regmap, false); + regcache_sync(wm2200->regmap); + + return 0; +} +#endif + +static struct dev_pm_ops wm2200_pm = { + SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume, + NULL) +}; + +static const struct i2c_device_id wm2200_i2c_id[] = { + { "wm2200", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id); + +static struct i2c_driver wm2200_i2c_driver = { + .driver = { + .name = "wm2200", + .owner = THIS_MODULE, + .pm = &wm2200_pm, + }, + .probe = wm2200_i2c_probe, + .remove = __devexit_p(wm2200_i2c_remove), + .id_table = wm2200_i2c_id, +}; + +static int __init wm2200_modinit(void) +{ + return i2c_add_driver(&wm2200_i2c_driver); +} +module_init(wm2200_modinit); + +static void __exit wm2200_exit(void) +{ + i2c_del_driver(&wm2200_i2c_driver); +} +module_exit(wm2200_exit); + +MODULE_DESCRIPTION("ASoC WM2200 driver"); +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm2200.h b/sound/soc/codecs/wm2200.h new file mode 100644 index 000000000000..5d719d6b4a8d --- /dev/null +++ b/sound/soc/codecs/wm2200.h @@ -0,0 +1,3674 @@ +/* + * wm2200.h - WM2200 audio codec interface + * + * Copyright 2012 Wolfson Microelectronics PLC. + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _WM2200_H +#define _WM2200_H + +#define WM2200_CLK_SYSCLK 1 + +#define WM2200_CLKSRC_MCLK1 0 +#define WM2200_CLKSRC_MCLK2 1 +#define WM2200_CLKSRC_FLL 4 +#define WM2200_CLKSRC_BCLK1 8 + +#define WM2200_FLL_SRC_MCLK1 0 +#define WM2200_FLL_SRC_MCLK2 1 +#define WM2200_FLL_SRC_BCLK 2 + +/* + * Register values. + */ +#define WM2200_SOFTWARE_RESET 0x00 +#define WM2200_DEVICE_REVISION 0x01 +#define WM2200_TONE_GENERATOR_1 0x0B +#define WM2200_CLOCKING_3 0x102 +#define WM2200_CLOCKING_4 0x103 +#define WM2200_FLL_CONTROL_1 0x111 +#define WM2200_FLL_CONTROL_2 0x112 +#define WM2200_FLL_CONTROL_3 0x113 +#define WM2200_FLL_CONTROL_4 0x114 +#define WM2200_FLL_CONTROL_6 0x116 +#define WM2200_FLL_CONTROL_7 0x117 +#define WM2200_FLL_EFS_1 0x119 +#define WM2200_FLL_EFS_2 0x11A +#define WM2200_MIC_CHARGE_PUMP_1 0x200 +#define WM2200_MIC_CHARGE_PUMP_2 0x201 +#define WM2200_DM_CHARGE_PUMP_1 0x202 +#define WM2200_MIC_BIAS_CTRL_1 0x20C +#define WM2200_MIC_BIAS_CTRL_2 0x20D +#define WM2200_EAR_PIECE_CTRL_1 0x20F +#define WM2200_EAR_PIECE_CTRL_2 0x210 +#define WM2200_INPUT_ENABLES 0x301 +#define WM2200_IN1L_CONTROL 0x302 +#define WM2200_IN1R_CONTROL 0x303 +#define WM2200_IN2L_CONTROL 0x304 +#define WM2200_IN2R_CONTROL 0x305 +#define WM2200_IN3L_CONTROL 0x306 +#define WM2200_IN3R_CONTROL 0x307 +#define WM2200_RXANC_SRC 0x30A +#define WM2200_INPUT_VOLUME_RAMP 0x30B +#define WM2200_ADC_DIGITAL_VOLUME_1L 0x30C +#define WM2200_ADC_DIGITAL_VOLUME_1R 0x30D +#define WM2200_ADC_DIGITAL_VOLUME_2L 0x30E +#define WM2200_ADC_DIGITAL_VOLUME_2R 0x30F +#define WM2200_ADC_DIGITAL_VOLUME_3L 0x310 +#define WM2200_ADC_DIGITAL_VOLUME_3R 0x311 +#define WM2200_OUTPUT_ENABLES 0x400 +#define WM2200_DAC_VOLUME_LIMIT_1L 0x401 +#define WM2200_DAC_VOLUME_LIMIT_1R 0x402 +#define WM2200_DAC_VOLUME_LIMIT_2L 0x403 +#define WM2200_DAC_VOLUME_LIMIT_2R 0x404 +#define WM2200_DAC_AEC_CONTROL_1 0x409 +#define WM2200_OUTPUT_VOLUME_RAMP 0x40A +#define WM2200_DAC_DIGITAL_VOLUME_1L 0x40B +#define WM2200_DAC_DIGITAL_VOLUME_1R 0x40C +#define WM2200_DAC_DIGITAL_VOLUME_2L 0x40D +#define WM2200_DAC_DIGITAL_VOLUME_2R 0x40E +#define WM2200_PDM_1 0x417 +#define WM2200_PDM_2 0x418 +#define WM2200_AUDIO_IF_1_1 0x500 +#define WM2200_AUDIO_IF_1_2 0x501 +#define WM2200_AUDIO_IF_1_3 0x502 +#define WM2200_AUDIO_IF_1_4 0x503 +#define WM2200_AUDIO_IF_1_5 0x504 +#define WM2200_AUDIO_IF_1_6 0x505 +#define WM2200_AUDIO_IF_1_7 0x506 +#define WM2200_AUDIO_IF_1_8 0x507 +#define WM2200_AUDIO_IF_1_9 0x508 +#define WM2200_AUDIO_IF_1_10 0x509 +#define WM2200_AUDIO_IF_1_11 0x50A +#define WM2200_AUDIO_IF_1_12 0x50B +#define WM2200_AUDIO_IF_1_13 0x50C +#define WM2200_AUDIO_IF_1_14 0x50D +#define WM2200_AUDIO_IF_1_15 0x50E +#define WM2200_AUDIO_IF_1_16 0x50F +#define WM2200_AUDIO_IF_1_17 0x510 +#define WM2200_AUDIO_IF_1_18 0x511 +#define WM2200_AUDIO_IF_1_19 0x512 +#define WM2200_AUDIO_IF_1_20 0x513 +#define WM2200_AUDIO_IF_1_21 0x514 +#define WM2200_AUDIO_IF_1_22 0x515 +#define WM2200_OUT1LMIX_INPUT_1_SOURCE 0x600 +#define WM2200_OUT1LMIX_INPUT_1_VOLUME 0x601 +#define WM2200_OUT1LMIX_INPUT_2_SOURCE 0x602 +#define WM2200_OUT1LMIX_INPUT_2_VOLUME 0x603 +#define WM2200_OUT1LMIX_INPUT_3_SOURCE 0x604 +#define WM2200_OUT1LMIX_INPUT_3_VOLUME 0x605 +#define WM2200_OUT1LMIX_INPUT_4_SOURCE 0x606 +#define WM2200_OUT1LMIX_INPUT_4_VOLUME 0x607 +#define WM2200_OUT1RMIX_INPUT_1_SOURCE 0x608 +#define WM2200_OUT1RMIX_INPUT_1_VOLUME 0x609 +#define WM2200_OUT1RMIX_INPUT_2_SOURCE 0x60A +#define WM2200_OUT1RMIX_INPUT_2_VOLUME 0x60B +#define WM2200_OUT1RMIX_INPUT_3_SOURCE 0x60C +#define WM2200_OUT1RMIX_INPUT_3_VOLUME 0x60D +#define WM2200_OUT1RMIX_INPUT_4_SOURCE 0x60E +#define WM2200_OUT1RMIX_INPUT_4_VOLUME 0x60F +#define WM2200_OUT2LMIX_INPUT_1_SOURCE 0x610 +#define WM2200_OUT2LMIX_INPUT_1_VOLUME 0x611 +#define WM2200_OUT2LMIX_INPUT_2_SOURCE 0x612 +#define WM2200_OUT2LMIX_INPUT_2_VOLUME 0x613 +#define WM2200_OUT2LMIX_INPUT_3_SOURCE 0x614 +#define WM2200_OUT2LMIX_INPUT_3_VOLUME 0x615 +#define WM2200_OUT2LMIX_INPUT_4_SOURCE 0x616 +#define WM2200_OUT2LMIX_INPUT_4_VOLUME 0x617 +#define WM2200_OUT2RMIX_INPUT_1_SOURCE 0x618 +#define WM2200_OUT2RMIX_INPUT_1_VOLUME 0x619 +#define WM2200_OUT2RMIX_INPUT_2_SOURCE 0x61A +#define WM2200_OUT2RMIX_INPUT_2_VOLUME 0x61B +#define WM2200_OUT2RMIX_INPUT_3_SOURCE 0x61C +#define WM2200_OUT2RMIX_INPUT_3_VOLUME 0x61D +#define WM2200_OUT2RMIX_INPUT_4_SOURCE 0x61E +#define WM2200_OUT2RMIX_INPUT_4_VOLUME 0x61F +#define WM2200_AIF1TX1MIX_INPUT_1_SOURCE 0x620 +#define WM2200_AIF1TX1MIX_INPUT_1_VOLUME 0x621 +#define WM2200_AIF1TX1MIX_INPUT_2_SOURCE 0x622 +#define WM2200_AIF1TX1MIX_INPUT_2_VOLUME 0x623 +#define WM2200_AIF1TX1MIX_INPUT_3_SOURCE 0x624 +#define WM2200_AIF1TX1MIX_INPUT_3_VOLUME 0x625 +#define WM2200_AIF1TX1MIX_INPUT_4_SOURCE 0x626 +#define WM2200_AIF1TX1MIX_INPUT_4_VOLUME 0x627 +#define WM2200_AIF1TX2MIX_INPUT_1_SOURCE 0x628 +#define WM2200_AIF1TX2MIX_INPUT_1_VOLUME 0x629 +#define WM2200_AIF1TX2MIX_INPUT_2_SOURCE 0x62A +#define WM2200_AIF1TX2MIX_INPUT_2_VOLUME 0x62B +#define WM2200_AIF1TX2MIX_INPUT_3_SOURCE 0x62C +#define WM2200_AIF1TX2MIX_INPUT_3_VOLUME 0x62D +#define WM2200_AIF1TX2MIX_INPUT_4_SOURCE 0x62E +#define WM2200_AIF1TX2MIX_INPUT_4_VOLUME 0x62F +#define WM2200_AIF1TX3MIX_INPUT_1_SOURCE 0x630 +#define WM2200_AIF1TX3MIX_INPUT_1_VOLUME 0x631 +#define WM2200_AIF1TX3MIX_INPUT_2_SOURCE 0x632 +#define WM2200_AIF1TX3MIX_INPUT_2_VOLUME 0x633 +#define WM2200_AIF1TX3MIX_INPUT_3_SOURCE 0x634 +#define WM2200_AIF1TX3MIX_INPUT_3_VOLUME 0x635 +#define WM2200_AIF1TX3MIX_INPUT_4_SOURCE 0x636 +#define WM2200_AIF1TX3MIX_INPUT_4_VOLUME 0x637 +#define WM2200_AIF1TX4MIX_INPUT_1_SOURCE 0x638 +#define WM2200_AIF1TX4MIX_INPUT_1_VOLUME 0x639 +#define WM2200_AIF1TX4MIX_INPUT_2_SOURCE 0x63A +#define WM2200_AIF1TX4MIX_INPUT_2_VOLUME 0x63B +#define WM2200_AIF1TX4MIX_INPUT_3_SOURCE 0x63C +#define WM2200_AIF1TX4MIX_INPUT_3_VOLUME 0x63D +#define WM2200_AIF1TX4MIX_INPUT_4_SOURCE 0x63E +#define WM2200_AIF1TX4MIX_INPUT_4_VOLUME 0x63F +#define WM2200_AIF1TX5MIX_INPUT_1_SOURCE 0x640 +#define WM2200_AIF1TX5MIX_INPUT_1_VOLUME 0x641 +#define WM2200_AIF1TX5MIX_INPUT_2_SOURCE 0x642 +#define WM2200_AIF1TX5MIX_INPUT_2_VOLUME 0x643 +#define WM2200_AIF1TX5MIX_INPUT_3_SOURCE 0x644 +#define WM2200_AIF1TX5MIX_INPUT_3_VOLUME 0x645 +#define WM2200_AIF1TX5MIX_INPUT_4_SOURCE 0x646 +#define WM2200_AIF1TX5MIX_INPUT_4_VOLUME 0x647 +#define WM2200_AIF1TX6MIX_INPUT_1_SOURCE 0x648 +#define WM2200_AIF1TX6MIX_INPUT_1_VOLUME 0x649 +#define WM2200_AIF1TX6MIX_INPUT_2_SOURCE 0x64A +#define WM2200_AIF1TX6MIX_INPUT_2_VOLUME 0x64B +#define WM2200_AIF1TX6MIX_INPUT_3_SOURCE 0x64C +#define WM2200_AIF1TX6MIX_INPUT_3_VOLUME 0x64D +#define WM2200_AIF1TX6MIX_INPUT_4_SOURCE 0x64E +#define WM2200_AIF1TX6MIX_INPUT_4_VOLUME 0x64F +#define WM2200_EQLMIX_INPUT_1_SOURCE 0x650 +#define WM2200_EQLMIX_INPUT_1_VOLUME 0x651 +#define WM2200_EQLMIX_INPUT_2_SOURCE 0x652 +#define WM2200_EQLMIX_INPUT_2_VOLUME 0x653 +#define WM2200_EQLMIX_INPUT_3_SOURCE 0x654 +#define WM2200_EQLMIX_INPUT_3_VOLUME 0x655 +#define WM2200_EQLMIX_INPUT_4_SOURCE 0x656 +#define WM2200_EQLMIX_INPUT_4_VOLUME 0x657 +#define WM2200_EQRMIX_INPUT_1_SOURCE 0x658 +#define WM2200_EQRMIX_INPUT_1_VOLUME 0x659 +#define WM2200_EQRMIX_INPUT_2_SOURCE 0x65A +#define WM2200_EQRMIX_INPUT_2_VOLUME 0x65B +#define WM2200_EQRMIX_INPUT_3_SOURCE 0x65C +#define WM2200_EQRMIX_INPUT_3_VOLUME 0x65D +#define WM2200_EQRMIX_INPUT_4_SOURCE 0x65E +#define WM2200_EQRMIX_INPUT_4_VOLUME 0x65F +#define WM2200_LHPF1MIX_INPUT_1_SOURCE 0x660 +#define WM2200_LHPF1MIX_INPUT_1_VOLUME 0x661 +#define WM2200_LHPF1MIX_INPUT_2_SOURCE 0x662 +#define WM2200_LHPF1MIX_INPUT_2_VOLUME 0x663 +#define WM2200_LHPF1MIX_INPUT_3_SOURCE 0x664 +#define WM2200_LHPF1MIX_INPUT_3_VOLUME 0x665 +#define WM2200_LHPF1MIX_INPUT_4_SOURCE 0x666 +#define WM2200_LHPF1MIX_INPUT_4_VOLUME 0x667 +#define WM2200_LHPF2MIX_INPUT_1_SOURCE 0x668 +#define WM2200_LHPF2MIX_INPUT_1_VOLUME 0x669 +#define WM2200_LHPF2MIX_INPUT_2_SOURCE 0x66A +#define WM2200_LHPF2MIX_INPUT_2_VOLUME 0x66B +#define WM2200_LHPF2MIX_INPUT_3_SOURCE 0x66C +#define WM2200_LHPF2MIX_INPUT_3_VOLUME 0x66D +#define WM2200_LHPF2MIX_INPUT_4_SOURCE 0x66E +#define WM2200_LHPF2MIX_INPUT_4_VOLUME 0x66F +#define WM2200_DSP1LMIX_INPUT_1_SOURCE 0x670 +#define WM2200_DSP1LMIX_INPUT_1_VOLUME 0x671 +#define WM2200_DSP1LMIX_INPUT_2_SOURCE 0x672 +#define WM2200_DSP1LMIX_INPUT_2_VOLUME 0x673 +#define WM2200_DSP1LMIX_INPUT_3_SOURCE 0x674 +#define WM2200_DSP1LMIX_INPUT_3_VOLUME 0x675 +#define WM2200_DSP1LMIX_INPUT_4_SOURCE 0x676 +#define WM2200_DSP1LMIX_INPUT_4_VOLUME 0x677 +#define WM2200_DSP1RMIX_INPUT_1_SOURCE 0x678 +#define WM2200_DSP1RMIX_INPUT_1_VOLUME 0x679 +#define WM2200_DSP1RMIX_INPUT_2_SOURCE 0x67A +#define WM2200_DSP1RMIX_INPUT_2_VOLUME 0x67B +#define WM2200_DSP1RMIX_INPUT_3_SOURCE 0x67C +#define WM2200_DSP1RMIX_INPUT_3_VOLUME 0x67D +#define WM2200_DSP1RMIX_INPUT_4_SOURCE 0x67E +#define WM2200_DSP1RMIX_INPUT_4_VOLUME 0x67F +#define WM2200_DSP1AUX1MIX_INPUT_1_SOURCE 0x680 +#define WM2200_DSP1AUX2MIX_INPUT_1_SOURCE 0x681 +#define WM2200_DSP1AUX3MIX_INPUT_1_SOURCE 0x682 +#define WM2200_DSP1AUX4MIX_INPUT_1_SOURCE 0x683 +#define WM2200_DSP1AUX5MIX_INPUT_1_SOURCE 0x684 +#define WM2200_DSP1AUX6MIX_INPUT_1_SOURCE 0x685 +#define WM2200_DSP2LMIX_INPUT_1_SOURCE 0x686 +#define WM2200_DSP2LMIX_INPUT_1_VOLUME 0x687 +#define WM2200_DSP2LMIX_INPUT_2_SOURCE 0x688 +#define WM2200_DSP2LMIX_INPUT_2_VOLUME 0x689 +#define WM2200_DSP2LMIX_INPUT_3_SOURCE 0x68A +#define WM2200_DSP2LMIX_INPUT_3_VOLUME 0x68B +#define WM2200_DSP2LMIX_INPUT_4_SOURCE 0x68C +#define WM2200_DSP2LMIX_INPUT_4_VOLUME 0x68D +#define WM2200_DSP2RMIX_INPUT_1_SOURCE 0x68E +#define WM2200_DSP2RMIX_INPUT_1_VOLUME 0x68F +#define WM2200_DSP2RMIX_INPUT_2_SOURCE 0x690 +#define WM2200_DSP2RMIX_INPUT_2_VOLUME 0x691 +#define WM2200_DSP2RMIX_INPUT_3_SOURCE 0x692 +#define WM2200_DSP2RMIX_INPUT_3_VOLUME 0x693 +#define WM2200_DSP2RMIX_INPUT_4_SOURCE 0x694 +#define WM2200_DSP2RMIX_INPUT_4_VOLUME 0x695 +#define WM2200_DSP2AUX1MIX_INPUT_1_SOURCE 0x696 +#define WM2200_DSP2AUX2MIX_INPUT_1_SOURCE 0x697 +#define WM2200_DSP2AUX3MIX_INPUT_1_SOURCE 0x698 +#define WM2200_DSP2AUX4MIX_INPUT_1_SOURCE 0x699 +#define WM2200_DSP2AUX5MIX_INPUT_1_SOURCE 0x69A +#define WM2200_DSP2AUX6MIX_INPUT_1_SOURCE 0x69B +#define WM2200_GPIO_CTRL_1 0x700 +#define WM2200_GPIO_CTRL_2 0x701 +#define WM2200_GPIO_CTRL_3 0x702 +#define WM2200_GPIO_CTRL_4 0x703 +#define WM2200_ADPS1_IRQ0 0x707 +#define WM2200_ADPS1_IRQ1 0x708 +#define WM2200_MISC_PAD_CTRL_1 0x709 +#define WM2200_INTERRUPT_STATUS_1 0x800 +#define WM2200_INTERRUPT_STATUS_1_MASK 0x801 +#define WM2200_INTERRUPT_STATUS_2 0x802 +#define WM2200_INTERRUPT_RAW_STATUS_2 0x803 +#define WM2200_INTERRUPT_STATUS_2_MASK 0x804 +#define WM2200_INTERRUPT_CONTROL 0x808 +#define WM2200_EQL_1 0x900 +#define WM2200_EQL_2 0x901 +#define WM2200_EQL_3 0x902 +#define WM2200_EQL_4 0x903 +#define WM2200_EQL_5 0x904 +#define WM2200_EQL_6 0x905 +#define WM2200_EQL_7 0x906 +#define WM2200_EQL_8 0x907 +#define WM2200_EQL_9 0x908 +#define WM2200_EQL_10 0x909 +#define WM2200_EQL_11 0x90A +#define WM2200_EQL_12 0x90B +#define WM2200_EQL_13 0x90C +#define WM2200_EQL_14 0x90D +#define WM2200_EQL_15 0x90E +#define WM2200_EQL_16 0x90F +#define WM2200_EQL_17 0x910 +#define WM2200_EQL_18 0x911 +#define WM2200_EQL_19 0x912 +#define WM2200_EQL_20 0x913 +#define WM2200_EQR_1 0x916 +#define WM2200_EQR_2 0x917 +#define WM2200_EQR_3 0x918 +#define WM2200_EQR_4 0x919 +#define WM2200_EQR_5 0x91A +#define WM2200_EQR_6 0x91B +#define WM2200_EQR_7 0x91C +#define WM2200_EQR_8 0x91D +#define WM2200_EQR_9 0x91E +#define WM2200_EQR_10 0x91F +#define WM2200_EQR_11 0x920 +#define WM2200_EQR_12 0x921 +#define WM2200_EQR_13 0x922 +#define WM2200_EQR_14 0x923 +#define WM2200_EQR_15 0x924 +#define WM2200_EQR_16 0x925 +#define WM2200_EQR_17 0x926 +#define WM2200_EQR_18 0x927 +#define WM2200_EQR_19 0x928 +#define WM2200_EQR_20 0x929 +#define WM2200_HPLPF1_1 0x93E +#define WM2200_HPLPF1_2 0x93F +#define WM2200_HPLPF2_1 0x942 +#define WM2200_HPLPF2_2 0x943 +#define WM2200_DSP1_CONTROL_1 0xA00 +#define WM2200_DSP1_CONTROL_2 0xA02 +#define WM2200_DSP1_CONTROL_3 0xA03 +#define WM2200_DSP1_CONTROL_4 0xA04 +#define WM2200_DSP1_CONTROL_5 0xA06 +#define WM2200_DSP1_CONTROL_6 0xA07 +#define WM2200_DSP1_CONTROL_7 0xA08 +#define WM2200_DSP1_CONTROL_8 0xA09 +#define WM2200_DSP1_CONTROL_9 0xA0A +#define WM2200_DSP1_CONTROL_10 0xA0B +#define WM2200_DSP1_CONTROL_11 0xA0C +#define WM2200_DSP1_CONTROL_12 0xA0D +#define WM2200_DSP1_CONTROL_13 0xA0F +#define WM2200_DSP1_CONTROL_14 0xA10 +#define WM2200_DSP1_CONTROL_15 0xA11 +#define WM2200_DSP1_CONTROL_16 0xA12 +#define WM2200_DSP1_CONTROL_17 0xA13 +#define WM2200_DSP1_CONTROL_18 0xA14 +#define WM2200_DSP1_CONTROL_19 0xA16 +#define WM2200_DSP1_CONTROL_20 0xA17 +#define WM2200_DSP1_CONTROL_21 0xA18 +#define WM2200_DSP1_CONTROL_22 0xA1A +#define WM2200_DSP1_CONTROL_23 0xA1B +#define WM2200_DSP1_CONTROL_24 0xA1C +#define WM2200_DSP1_CONTROL_25 0xA1E +#define WM2200_DSP1_CONTROL_26 0xA20 +#define WM2200_DSP1_CONTROL_27 0xA21 +#define WM2200_DSP1_CONTROL_28 0xA22 +#define WM2200_DSP1_CONTROL_29 0xA23 +#define WM2200_DSP1_CONTROL_30 0xA24 +#define WM2200_DSP1_CONTROL_31 0xA26 +#define WM2200_DSP2_CONTROL_1 0xB00 +#define WM2200_DSP2_CONTROL_2 0xB02 +#define WM2200_DSP2_CONTROL_3 0xB03 +#define WM2200_DSP2_CONTROL_4 0xB04 +#define WM2200_DSP2_CONTROL_5 0xB06 +#define WM2200_DSP2_CONTROL_6 0xB07 +#define WM2200_DSP2_CONTROL_7 0xB08 +#define WM2200_DSP2_CONTROL_8 0xB09 +#define WM2200_DSP2_CONTROL_9 0xB0A +#define WM2200_DSP2_CONTROL_10 0xB0B +#define WM2200_DSP2_CONTROL_11 0xB0C +#define WM2200_DSP2_CONTROL_12 0xB0D +#define WM2200_DSP2_CONTROL_13 0xB0F +#define WM2200_DSP2_CONTROL_14 0xB10 +#define WM2200_DSP2_CONTROL_15 0xB11 +#define WM2200_DSP2_CONTROL_16 0xB12 +#define WM2200_DSP2_CONTROL_17 0xB13 +#define WM2200_DSP2_CONTROL_18 0xB14 +#define WM2200_DSP2_CONTROL_19 0xB16 +#define WM2200_DSP2_CONTROL_20 0xB17 +#define WM2200_DSP2_CONTROL_21 0xB18 +#define WM2200_DSP2_CONTROL_22 0xB1A +#define WM2200_DSP2_CONTROL_23 0xB1B +#define WM2200_DSP2_CONTROL_24 0xB1C +#define WM2200_DSP2_CONTROL_25 0xB1E +#define WM2200_DSP2_CONTROL_26 0xB20 +#define WM2200_DSP2_CONTROL_27 0xB21 +#define WM2200_DSP2_CONTROL_28 0xB22 +#define WM2200_DSP2_CONTROL_29 0xB23 +#define WM2200_DSP2_CONTROL_30 0xB24 +#define WM2200_DSP2_CONTROL_31 0xB26 +#define WM2200_ANC_CTRL1 0xD00 +#define WM2200_ANC_CTRL2 0xD01 +#define WM2200_ANC_CTRL3 0xD02 +#define WM2200_ANC_CTRL7 0xD08 +#define WM2200_ANC_CTRL8 0xD09 +#define WM2200_ANC_CTRL9 0xD0A +#define WM2200_ANC_CTRL10 0xD0B +#define WM2200_ANC_CTRL11 0xD0C +#define WM2200_ANC_CTRL12 0xD0D +#define WM2200_ANC_CTRL13 0xD0E +#define WM2200_ANC_CTRL14 0xD0F +#define WM2200_ANC_CTRL15 0xD10 +#define WM2200_ANC_CTRL16 0xD11 +#define WM2200_ANC_CTRL17 0xD12 +#define WM2200_ANC_CTRL18 0xD15 +#define WM2200_ANC_CTRL19 0xD16 +#define WM2200_ANC_CTRL20 0xD17 +#define WM2200_ANC_CTRL21 0xD18 +#define WM2200_ANC_CTRL22 0xD19 +#define WM2200_ANC_CTRL23 0xD1A +#define WM2200_ANC_CTRL24 0xD1B +#define WM2200_ANC_CTRL25 0xD1C +#define WM2200_ANC_CTRL26 0xD1D +#define WM2200_ANC_CTRL27 0xD1E +#define WM2200_ANC_CTRL28 0xD1F +#define WM2200_ANC_CTRL29 0xD20 +#define WM2200_ANC_CTRL30 0xD21 +#define WM2200_ANC_CTRL31 0xD23 +#define WM2200_ANC_CTRL32 0xD24 +#define WM2200_ANC_CTRL33 0xD25 +#define WM2200_ANC_CTRL34 0xD27 +#define WM2200_ANC_CTRL35 0xD28 +#define WM2200_ANC_CTRL36 0xD29 +#define WM2200_ANC_CTRL37 0xD2A +#define WM2200_ANC_CTRL38 0xD2B +#define WM2200_ANC_CTRL39 0xD2C +#define WM2200_ANC_CTRL40 0xD2D +#define WM2200_ANC_CTRL41 0xD2E +#define WM2200_ANC_CTRL42 0xD2F +#define WM2200_ANC_CTRL43 0xD30 +#define WM2200_ANC_CTRL44 0xD31 +#define WM2200_ANC_CTRL45 0xD32 +#define WM2200_ANC_CTRL46 0xD33 +#define WM2200_ANC_CTRL47 0xD34 +#define WM2200_ANC_CTRL48 0xD35 +#define WM2200_ANC_CTRL49 0xD36 +#define WM2200_ANC_CTRL50 0xD37 +#define WM2200_ANC_CTRL51 0xD38 +#define WM2200_ANC_CTRL52 0xD39 +#define WM2200_ANC_CTRL53 0xD3A +#define WM2200_ANC_CTRL54 0xD3B +#define WM2200_ANC_CTRL55 0xD3C +#define WM2200_ANC_CTRL56 0xD3D +#define WM2200_ANC_CTRL57 0xD3E +#define WM2200_ANC_CTRL58 0xD3F +#define WM2200_ANC_CTRL59 0xD40 +#define WM2200_ANC_CTRL60 0xD41 +#define WM2200_ANC_CTRL61 0xD42 +#define WM2200_ANC_CTRL62 0xD43 +#define WM2200_ANC_CTRL63 0xD44 +#define WM2200_ANC_CTRL64 0xD45 +#define WM2200_ANC_CTRL65 0xD46 +#define WM2200_ANC_CTRL66 0xD47 +#define WM2200_ANC_CTRL67 0xD48 +#define WM2200_ANC_CTRL68 0xD49 +#define WM2200_ANC_CTRL69 0xD4A +#define WM2200_ANC_CTRL70 0xD4B +#define WM2200_ANC_CTRL71 0xD4C +#define WM2200_ANC_CTRL72 0xD4D +#define WM2200_ANC_CTRL73 0xD4E +#define WM2200_ANC_CTRL74 0xD4F +#define WM2200_ANC_CTRL75 0xD50 +#define WM2200_ANC_CTRL76 0xD51 +#define WM2200_ANC_CTRL77 0xD52 +#define WM2200_ANC_CTRL78 0xD53 +#define WM2200_ANC_CTRL79 0xD54 +#define WM2200_ANC_CTRL80 0xD55 +#define WM2200_ANC_CTRL81 0xD56 +#define WM2200_ANC_CTRL82 0xD57 +#define WM2200_ANC_CTRL83 0xD58 +#define WM2200_ANC_CTRL84 0xD5B +#define WM2200_ANC_CTRL85 0xD5C +#define WM2200_ANC_CTRL86 0xD5F +#define WM2200_ANC_CTRL87 0xD60 +#define WM2200_ANC_CTRL88 0xD61 +#define WM2200_ANC_CTRL89 0xD62 +#define WM2200_ANC_CTRL90 0xD63 +#define WM2200_ANC_CTRL91 0xD64 +#define WM2200_ANC_CTRL92 0xD65 +#define WM2200_ANC_CTRL93 0xD66 +#define WM2200_ANC_CTRL94 0xD67 +#define WM2200_ANC_CTRL95 0xD68 +#define WM2200_ANC_CTRL96 0xD69 +#define WM2200_DSP1_DM_0 0x3000 +#define WM2200_DSP1_DM_1 0x3001 +#define WM2200_DSP1_DM_2 0x3002 +#define WM2200_DSP1_DM_3 0x3003 +#define WM2200_DSP1_DM_2044 0x37FC +#define WM2200_DSP1_DM_2045 0x37FD +#define WM2200_DSP1_DM_2046 0x37FE +#define WM2200_DSP1_DM_2047 0x37FF +#define WM2200_DSP1_PM_0 0x3800 +#define WM2200_DSP1_PM_1 0x3801 +#define WM2200_DSP1_PM_2 0x3802 +#define WM2200_DSP1_PM_3 0x3803 +#define WM2200_DSP1_PM_4 0x3804 +#define WM2200_DSP1_PM_5 0x3805 +#define WM2200_DSP1_PM_762 0x3AFA +#define WM2200_DSP1_PM_763 0x3AFB +#define WM2200_DSP1_PM_764 0x3AFC +#define WM2200_DSP1_PM_765 0x3AFD +#define WM2200_DSP1_PM_766 0x3AFE +#define WM2200_DSP1_PM_767 0x3AFF +#define WM2200_DSP1_ZM_0 0x3C00 +#define WM2200_DSP1_ZM_1 0x3C01 +#define WM2200_DSP1_ZM_2 0x3C02 +#define WM2200_DSP1_ZM_3 0x3C03 +#define WM2200_DSP1_ZM_1020 0x3FFC +#define WM2200_DSP1_ZM_1021 0x3FFD +#define WM2200_DSP1_ZM_1022 0x3FFE +#define WM2200_DSP1_ZM_1023 0x3FFF +#define WM2200_DSP2_DM_0 0x4000 +#define WM2200_DSP2_DM_1 0x4001 +#define WM2200_DSP2_DM_2 0x4002 +#define WM2200_DSP2_DM_3 0x4003 +#define WM2200_DSP2_DM_2044 0x47FC +#define WM2200_DSP2_DM_2045 0x47FD +#define WM2200_DSP2_DM_2046 0x47FE +#define WM2200_DSP2_DM_2047 0x47FF +#define WM2200_DSP2_PM_0 0x4800 +#define WM2200_DSP2_PM_1 0x4801 +#define WM2200_DSP2_PM_2 0x4802 +#define WM2200_DSP2_PM_3 0x4803 +#define WM2200_DSP2_PM_4 0x4804 +#define WM2200_DSP2_PM_5 0x4805 +#define WM2200_DSP2_PM_762 0x4AFA +#define WM2200_DSP2_PM_763 0x4AFB +#define WM2200_DSP2_PM_764 0x4AFC +#define WM2200_DSP2_PM_765 0x4AFD +#define WM2200_DSP2_PM_766 0x4AFE +#define WM2200_DSP2_PM_767 0x4AFF +#define WM2200_DSP2_ZM_0 0x4C00 +#define WM2200_DSP2_ZM_1 0x4C01 +#define WM2200_DSP2_ZM_2 0x4C02 +#define WM2200_DSP2_ZM_3 0x4C03 +#define WM2200_DSP2_ZM_1020 0x4FFC +#define WM2200_DSP2_ZM_1021 0x4FFD +#define WM2200_DSP2_ZM_1022 0x4FFE +#define WM2200_DSP2_ZM_1023 0x4FFF + +#define WM2200_REGISTER_COUNT 494 +#define WM2200_MAX_REGISTER 0x4FFF + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - software reset + */ +#define WM2200_SW_RESET_CHIP_ID1_MASK 0xFFFF /* SW_RESET_CHIP_ID1 - [15:0] */ +#define WM2200_SW_RESET_CHIP_ID1_SHIFT 0 /* SW_RESET_CHIP_ID1 - [15:0] */ +#define WM2200_SW_RESET_CHIP_ID1_WIDTH 16 /* SW_RESET_CHIP_ID1 - [15:0] */ + +/* + * R1 (0x01) - Device Revision + */ +#define WM2200_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */ +#define WM2200_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */ +#define WM2200_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */ + +/* + * R11 (0x0B) - Tone Generator 1 + */ +#define WM2200_TONE_ENA 0x0001 /* TONE_ENA */ +#define WM2200_TONE_ENA_MASK 0x0001 /* TONE_ENA */ +#define WM2200_TONE_ENA_SHIFT 0 /* TONE_ENA */ +#define WM2200_TONE_ENA_WIDTH 1 /* TONE_ENA */ + +/* + * R258 (0x102) - Clocking 3 + */ +#define WM2200_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */ +#define WM2200_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */ +#define WM2200_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */ +#define WM2200_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */ +#define WM2200_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */ +#define WM2200_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */ +#define WM2200_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ +#define WM2200_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */ +#define WM2200_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */ +#define WM2200_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */ + +/* + * R259 (0x103) - Clocking 4 + */ +#define WM2200_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */ +#define WM2200_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */ +#define WM2200_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */ + +/* + * R273 (0x111) - FLL Control 1 + */ +#define WM2200_FLL_ENA 0x0001 /* FLL_ENA */ +#define WM2200_FLL_ENA_MASK 0x0001 /* FLL_ENA */ +#define WM2200_FLL_ENA_SHIFT 0 /* FLL_ENA */ +#define WM2200_FLL_ENA_WIDTH 1 /* FLL_ENA */ + +/* + * R274 (0x112) - FLL Control 2 + */ +#define WM2200_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */ +#define WM2200_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */ +#define WM2200_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */ +#define WM2200_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ +#define WM2200_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ +#define WM2200_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ + +/* + * R275 (0x113) - FLL Control 3 + */ +#define WM2200_FLL_FRACN_ENA 0x0001 /* FLL_FRACN_ENA */ +#define WM2200_FLL_FRACN_ENA_MASK 0x0001 /* FLL_FRACN_ENA */ +#define WM2200_FLL_FRACN_ENA_SHIFT 0 /* FLL_FRACN_ENA */ +#define WM2200_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */ + +/* + * R276 (0x114) - FLL Control 4 + */ +#define WM2200_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */ +#define WM2200_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */ +#define WM2200_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */ + +/* + * R278 (0x116) - FLL Control 6 + */ +#define WM2200_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */ +#define WM2200_FLL_N_SHIFT 0 /* FLL_N - [9:0] */ +#define WM2200_FLL_N_WIDTH 10 /* FLL_N - [9:0] */ + +/* + * R279 (0x117) - FLL Control 7 + */ +#define WM2200_FLL_CLK_REF_DIV_MASK 0x0030 /* FLL_CLK_REF_DIV - [5:4] */ +#define WM2200_FLL_CLK_REF_DIV_SHIFT 4 /* FLL_CLK_REF_DIV - [5:4] */ +#define WM2200_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [5:4] */ +#define WM2200_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */ +#define WM2200_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */ +#define WM2200_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */ + +/* + * R281 (0x119) - FLL EFS 1 + */ +#define WM2200_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */ +#define WM2200_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */ +#define WM2200_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */ + +/* + * R282 (0x11A) - FLL EFS 2 + */ +#define WM2200_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */ +#define WM2200_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */ +#define WM2200_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */ +#define WM2200_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */ + +/* + * R512 (0x200) - Mic Charge Pump 1 + */ +#define WM2200_CPMIC_BYPASS_MODE 0x0020 /* CPMIC_BYPASS_MODE */ +#define WM2200_CPMIC_BYPASS_MODE_MASK 0x0020 /* CPMIC_BYPASS_MODE */ +#define WM2200_CPMIC_BYPASS_MODE_SHIFT 5 /* CPMIC_BYPASS_MODE */ +#define WM2200_CPMIC_BYPASS_MODE_WIDTH 1 /* CPMIC_BYPASS_MODE */ +#define WM2200_CPMIC_ENA 0x0001 /* CPMIC_ENA */ +#define WM2200_CPMIC_ENA_MASK 0x0001 /* CPMIC_ENA */ +#define WM2200_CPMIC_ENA_SHIFT 0 /* CPMIC_ENA */ +#define WM2200_CPMIC_ENA_WIDTH 1 /* CPMIC_ENA */ + +/* + * R513 (0x201) - Mic Charge Pump 2 + */ +#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_MASK 0xF800 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */ +#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_SHIFT 11 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */ +#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_WIDTH 5 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */ + +/* + * R514 (0x202) - DM Charge Pump 1 + */ +#define WM2200_CPDM_ENA 0x0001 /* CPDM_ENA */ +#define WM2200_CPDM_ENA_MASK 0x0001 /* CPDM_ENA */ +#define WM2200_CPDM_ENA_SHIFT 0 /* CPDM_ENA */ +#define WM2200_CPDM_ENA_WIDTH 1 /* CPDM_ENA */ + +/* + * R524 (0x20C) - Mic Bias Ctrl 1 + */ +#define WM2200_MICB1_DISCH 0x0040 /* MICB1_DISCH */ +#define WM2200_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */ +#define WM2200_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */ +#define WM2200_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ +#define WM2200_MICB1_RATE 0x0020 /* MICB1_RATE */ +#define WM2200_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ +#define WM2200_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ +#define WM2200_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ +#define WM2200_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */ +#define WM2200_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */ +#define WM2200_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */ +#define WM2200_MICB1_MODE 0x0002 /* MICB1_MODE */ +#define WM2200_MICB1_MODE_MASK 0x0002 /* MICB1_MODE */ +#define WM2200_MICB1_MODE_SHIFT 1 /* MICB1_MODE */ +#define WM2200_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ +#define WM2200_MICB1_ENA 0x0001 /* MICB1_ENA */ +#define WM2200_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */ +#define WM2200_MICB1_ENA_SHIFT 0 /* MICB1_ENA */ +#define WM2200_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ + +/* + * R525 (0x20D) - Mic Bias Ctrl 2 + */ +#define WM2200_MICB2_DISCH 0x0040 /* MICB2_DISCH */ +#define WM2200_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */ +#define WM2200_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */ +#define WM2200_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ +#define WM2200_MICB2_RATE 0x0020 /* MICB2_RATE */ +#define WM2200_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ +#define WM2200_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ +#define WM2200_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ +#define WM2200_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */ +#define WM2200_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */ +#define WM2200_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */ +#define WM2200_MICB2_MODE 0x0002 /* MICB2_MODE */ +#define WM2200_MICB2_MODE_MASK 0x0002 /* MICB2_MODE */ +#define WM2200_MICB2_MODE_SHIFT 1 /* MICB2_MODE */ +#define WM2200_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ +#define WM2200_MICB2_ENA 0x0001 /* MICB2_ENA */ +#define WM2200_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */ +#define WM2200_MICB2_ENA_SHIFT 0 /* MICB2_ENA */ +#define WM2200_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ + +/* + * R527 (0x20F) - Ear Piece Ctrl 1 + */ +#define WM2200_EPD_LP_ENA 0x4000 /* EPD_LP_ENA */ +#define WM2200_EPD_LP_ENA_MASK 0x4000 /* EPD_LP_ENA */ +#define WM2200_EPD_LP_ENA_SHIFT 14 /* EPD_LP_ENA */ +#define WM2200_EPD_LP_ENA_WIDTH 1 /* EPD_LP_ENA */ +#define WM2200_EPD_OUTP_LP_ENA 0x2000 /* EPD_OUTP_LP_ENA */ +#define WM2200_EPD_OUTP_LP_ENA_MASK 0x2000 /* EPD_OUTP_LP_ENA */ +#define WM2200_EPD_OUTP_LP_ENA_SHIFT 13 /* EPD_OUTP_LP_ENA */ +#define WM2200_EPD_OUTP_LP_ENA_WIDTH 1 /* EPD_OUTP_LP_ENA */ +#define WM2200_EPD_RMV_SHRT_LP 0x1000 /* EPD_RMV_SHRT_LP */ +#define WM2200_EPD_RMV_SHRT_LP_MASK 0x1000 /* EPD_RMV_SHRT_LP */ +#define WM2200_EPD_RMV_SHRT_LP_SHIFT 12 /* EPD_RMV_SHRT_LP */ +#define WM2200_EPD_RMV_SHRT_LP_WIDTH 1 /* EPD_RMV_SHRT_LP */ +#define WM2200_EPD_LN_ENA 0x0800 /* EPD_LN_ENA */ +#define WM2200_EPD_LN_ENA_MASK 0x0800 /* EPD_LN_ENA */ +#define WM2200_EPD_LN_ENA_SHIFT 11 /* EPD_LN_ENA */ +#define WM2200_EPD_LN_ENA_WIDTH 1 /* EPD_LN_ENA */ +#define WM2200_EPD_OUTP_LN_ENA 0x0400 /* EPD_OUTP_LN_ENA */ +#define WM2200_EPD_OUTP_LN_ENA_MASK 0x0400 /* EPD_OUTP_LN_ENA */ +#define WM2200_EPD_OUTP_LN_ENA_SHIFT 10 /* EPD_OUTP_LN_ENA */ +#define WM2200_EPD_OUTP_LN_ENA_WIDTH 1 /* EPD_OUTP_LN_ENA */ +#define WM2200_EPD_RMV_SHRT_LN 0x0200 /* EPD_RMV_SHRT_LN */ +#define WM2200_EPD_RMV_SHRT_LN_MASK 0x0200 /* EPD_RMV_SHRT_LN */ +#define WM2200_EPD_RMV_SHRT_LN_SHIFT 9 /* EPD_RMV_SHRT_LN */ +#define WM2200_EPD_RMV_SHRT_LN_WIDTH 1 /* EPD_RMV_SHRT_LN */ + +/* + * R528 (0x210) - Ear Piece Ctrl 2 + */ +#define WM2200_EPD_RP_ENA 0x4000 /* EPD_RP_ENA */ +#define WM2200_EPD_RP_ENA_MASK 0x4000 /* EPD_RP_ENA */ +#define WM2200_EPD_RP_ENA_SHIFT 14 /* EPD_RP_ENA */ +#define WM2200_EPD_RP_ENA_WIDTH 1 /* EPD_RP_ENA */ +#define WM2200_EPD_OUTP_RP_ENA 0x2000 /* EPD_OUTP_RP_ENA */ +#define WM2200_EPD_OUTP_RP_ENA_MASK 0x2000 /* EPD_OUTP_RP_ENA */ +#define WM2200_EPD_OUTP_RP_ENA_SHIFT 13 /* EPD_OUTP_RP_ENA */ +#define WM2200_EPD_OUTP_RP_ENA_WIDTH 1 /* EPD_OUTP_RP_ENA */ +#define WM2200_EPD_RMV_SHRT_RP 0x1000 /* EPD_RMV_SHRT_RP */ +#define WM2200_EPD_RMV_SHRT_RP_MASK 0x1000 /* EPD_RMV_SHRT_RP */ +#define WM2200_EPD_RMV_SHRT_RP_SHIFT 12 /* EPD_RMV_SHRT_RP */ +#define WM2200_EPD_RMV_SHRT_RP_WIDTH 1 /* EPD_RMV_SHRT_RP */ +#define WM2200_EPD_RN_ENA 0x0800 /* EPD_RN_ENA */ +#define WM2200_EPD_RN_ENA_MASK 0x0800 /* EPD_RN_ENA */ +#define WM2200_EPD_RN_ENA_SHIFT 11 /* EPD_RN_ENA */ +#define WM2200_EPD_RN_ENA_WIDTH 1 /* EPD_RN_ENA */ +#define WM2200_EPD_OUTP_RN_ENA 0x0400 /* EPD_OUTP_RN_ENA */ +#define WM2200_EPD_OUTP_RN_ENA_MASK 0x0400 /* EPD_OUTP_RN_ENA */ +#define WM2200_EPD_OUTP_RN_ENA_SHIFT 10 /* EPD_OUTP_RN_ENA */ +#define WM2200_EPD_OUTP_RN_ENA_WIDTH 1 /* EPD_OUTP_RN_ENA */ +#define WM2200_EPD_RMV_SHRT_RN 0x0200 /* EPD_RMV_SHRT_RN */ +#define WM2200_EPD_RMV_SHRT_RN_MASK 0x0200 /* EPD_RMV_SHRT_RN */ +#define WM2200_EPD_RMV_SHRT_RN_SHIFT 9 /* EPD_RMV_SHRT_RN */ +#define WM2200_EPD_RMV_SHRT_RN_WIDTH 1 /* EPD_RMV_SHRT_RN */ + +/* + * R769 (0x301) - Input Enables + */ +#define WM2200_IN3L_ENA 0x0020 /* IN3L_ENA */ +#define WM2200_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */ +#define WM2200_IN3L_ENA_SHIFT 5 /* IN3L_ENA */ +#define WM2200_IN3L_ENA_WIDTH 1 /* IN3L_ENA */ +#define WM2200_IN3R_ENA 0x0010 /* IN3R_ENA */ +#define WM2200_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */ +#define WM2200_IN3R_ENA_SHIFT 4 /* IN3R_ENA */ +#define WM2200_IN3R_ENA_WIDTH 1 /* IN3R_ENA */ +#define WM2200_IN2L_ENA 0x0008 /* IN2L_ENA */ +#define WM2200_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */ +#define WM2200_IN2L_ENA_SHIFT 3 /* IN2L_ENA */ +#define WM2200_IN2L_ENA_WIDTH 1 /* IN2L_ENA */ +#define WM2200_IN2R_ENA 0x0004 /* IN2R_ENA */ +#define WM2200_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */ +#define WM2200_IN2R_ENA_SHIFT 2 /* IN2R_ENA */ +#define WM2200_IN2R_ENA_WIDTH 1 /* IN2R_ENA */ +#define WM2200_IN1L_ENA 0x0002 /* IN1L_ENA */ +#define WM2200_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */ +#define WM2200_IN1L_ENA_SHIFT 1 /* IN1L_ENA */ +#define WM2200_IN1L_ENA_WIDTH 1 /* IN1L_ENA */ +#define WM2200_IN1R_ENA 0x0001 /* IN1R_ENA */ +#define WM2200_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */ +#define WM2200_IN1R_ENA_SHIFT 0 /* IN1R_ENA */ +#define WM2200_IN1R_ENA_WIDTH 1 /* IN1R_ENA */ + +/* + * R770 (0x302) - IN1L Control + */ +#define WM2200_IN1_OSR 0x2000 /* IN1_OSR */ +#define WM2200_IN1_OSR_MASK 0x2000 /* IN1_OSR */ +#define WM2200_IN1_OSR_SHIFT 13 /* IN1_OSR */ +#define WM2200_IN1_OSR_WIDTH 1 /* IN1_OSR */ +#define WM2200_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */ +#define WM2200_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */ +#define WM2200_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */ +#define WM2200_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */ +#define WM2200_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */ +#define WM2200_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */ +#define WM2200_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */ +#define WM2200_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */ +#define WM2200_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */ + +/* + * R771 (0x303) - IN1R Control + */ +#define WM2200_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */ +#define WM2200_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */ +#define WM2200_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */ + +/* + * R772 (0x304) - IN2L Control + */ +#define WM2200_IN2_OSR 0x2000 /* IN2_OSR */ +#define WM2200_IN2_OSR_MASK 0x2000 /* IN2_OSR */ +#define WM2200_IN2_OSR_SHIFT 13 /* IN2_OSR */ +#define WM2200_IN2_OSR_WIDTH 1 /* IN2_OSR */ +#define WM2200_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */ +#define WM2200_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */ +#define WM2200_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */ +#define WM2200_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */ +#define WM2200_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */ +#define WM2200_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */ +#define WM2200_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */ +#define WM2200_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */ +#define WM2200_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */ + +/* + * R773 (0x305) - IN2R Control + */ +#define WM2200_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */ +#define WM2200_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */ +#define WM2200_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */ + +/* + * R774 (0x306) - IN3L Control + */ +#define WM2200_IN3_OSR 0x2000 /* IN3_OSR */ +#define WM2200_IN3_OSR_MASK 0x2000 /* IN3_OSR */ +#define WM2200_IN3_OSR_SHIFT 13 /* IN3_OSR */ +#define WM2200_IN3_OSR_WIDTH 1 /* IN3_OSR */ +#define WM2200_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */ +#define WM2200_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */ +#define WM2200_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */ +#define WM2200_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */ +#define WM2200_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */ +#define WM2200_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */ +#define WM2200_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */ +#define WM2200_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */ +#define WM2200_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */ + +/* + * R775 (0x307) - IN3R Control + */ +#define WM2200_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */ +#define WM2200_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */ +#define WM2200_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */ + +/* + * R778 (0x30A) - RXANC_SRC + */ +#define WM2200_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */ +#define WM2200_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */ +#define WM2200_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */ + +/* + * R779 (0x30B) - Input Volume Ramp + */ +#define WM2200_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */ +#define WM2200_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */ +#define WM2200_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */ +#define WM2200_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */ +#define WM2200_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */ +#define WM2200_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */ + +/* + * R780 (0x30C) - ADC Digital Volume 1L + */ +#define WM2200_IN_VU 0x0200 /* IN_VU */ +#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ +#define WM2200_IN_VU_SHIFT 9 /* IN_VU */ +#define WM2200_IN_VU_WIDTH 1 /* IN_VU */ +#define WM2200_IN1L_MUTE 0x0100 /* IN1L_MUTE */ +#define WM2200_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */ +#define WM2200_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */ +#define WM2200_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */ +#define WM2200_IN1L_DIG_VOL_MASK 0x00FF /* IN1L_DIG_VOL - [7:0] */ +#define WM2200_IN1L_DIG_VOL_SHIFT 0 /* IN1L_DIG_VOL - [7:0] */ +#define WM2200_IN1L_DIG_VOL_WIDTH 8 /* IN1L_DIG_VOL - [7:0] */ + +/* + * R781 (0x30D) - ADC Digital Volume 1R + */ +#define WM2200_IN_VU 0x0200 /* IN_VU */ +#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ +#define WM2200_IN_VU_SHIFT 9 /* IN_VU */ +#define WM2200_IN_VU_WIDTH 1 /* IN_VU */ +#define WM2200_IN1R_MUTE 0x0100 /* IN1R_MUTE */ +#define WM2200_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */ +#define WM2200_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */ +#define WM2200_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */ +#define WM2200_IN1R_DIG_VOL_MASK 0x00FF /* IN1R_DIG_VOL - [7:0] */ +#define WM2200_IN1R_DIG_VOL_SHIFT 0 /* IN1R_DIG_VOL - [7:0] */ +#define WM2200_IN1R_DIG_VOL_WIDTH 8 /* IN1R_DIG_VOL - [7:0] */ + +/* + * R782 (0x30E) - ADC Digital Volume 2L + */ +#define WM2200_IN_VU 0x0200 /* IN_VU */ +#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ +#define WM2200_IN_VU_SHIFT 9 /* IN_VU */ +#define WM2200_IN_VU_WIDTH 1 /* IN_VU */ +#define WM2200_IN2L_MUTE 0x0100 /* IN2L_MUTE */ +#define WM2200_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */ +#define WM2200_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */ +#define WM2200_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */ +#define WM2200_IN2L_DIG_VOL_MASK 0x00FF /* IN2L_DIG_VOL - [7:0] */ +#define WM2200_IN2L_DIG_VOL_SHIFT 0 /* IN2L_DIG_VOL - [7:0] */ +#define WM2200_IN2L_DIG_VOL_WIDTH 8 /* IN2L_DIG_VOL - [7:0] */ + +/* + * R783 (0x30F) - ADC Digital Volume 2R + */ +#define WM2200_IN_VU 0x0200 /* IN_VU */ +#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ +#define WM2200_IN_VU_SHIFT 9 /* IN_VU */ +#define WM2200_IN_VU_WIDTH 1 /* IN_VU */ +#define WM2200_IN2R_MUTE 0x0100 /* IN2R_MUTE */ +#define WM2200_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */ +#define WM2200_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */ +#define WM2200_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */ +#define WM2200_IN2R_DIG_VOL_MASK 0x00FF /* IN2R_DIG_VOL - [7:0] */ +#define WM2200_IN2R_DIG_VOL_SHIFT 0 /* IN2R_DIG_VOL - [7:0] */ +#define WM2200_IN2R_DIG_VOL_WIDTH 8 /* IN2R_DIG_VOL - [7:0] */ + +/* + * R784 (0x310) - ADC Digital Volume 3L + */ +#define WM2200_IN_VU 0x0200 /* IN_VU */ +#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ +#define WM2200_IN_VU_SHIFT 9 /* IN_VU */ +#define WM2200_IN_VU_WIDTH 1 /* IN_VU */ +#define WM2200_IN3L_MUTE 0x0100 /* IN3L_MUTE */ +#define WM2200_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */ +#define WM2200_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */ +#define WM2200_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */ +#define WM2200_IN3L_DIG_VOL_MASK 0x00FF /* IN3L_DIG_VOL - [7:0] */ +#define WM2200_IN3L_DIG_VOL_SHIFT 0 /* IN3L_DIG_VOL - [7:0] */ +#define WM2200_IN3L_DIG_VOL_WIDTH 8 /* IN3L_DIG_VOL - [7:0] */ + +/* + * R785 (0x311) - ADC Digital Volume 3R + */ +#define WM2200_IN_VU 0x0200 /* IN_VU */ +#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ +#define WM2200_IN_VU_SHIFT 9 /* IN_VU */ +#define WM2200_IN_VU_WIDTH 1 /* IN_VU */ +#define WM2200_IN3R_MUTE 0x0100 /* IN3R_MUTE */ +#define WM2200_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */ +#define WM2200_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */ +#define WM2200_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */ +#define WM2200_IN3R_DIG_VOL_MASK 0x00FF /* IN3R_DIG_VOL - [7:0] */ +#define WM2200_IN3R_DIG_VOL_SHIFT 0 /* IN3R_DIG_VOL - [7:0] */ +#define WM2200_IN3R_DIG_VOL_WIDTH 8 /* IN3R_DIG_VOL - [7:0] */ + +/* + * R1024 (0x400) - Output Enables + */ +#define WM2200_OUT2L_ENA 0x0008 /* OUT2L_ENA */ +#define WM2200_OUT2L_ENA_MASK 0x0008 /* OUT2L_ENA */ +#define WM2200_OUT2L_ENA_SHIFT 3 /* OUT2L_ENA */ +#define WM2200_OUT2L_ENA_WIDTH 1 /* OUT2L_ENA */ +#define WM2200_OUT2R_ENA 0x0004 /* OUT2R_ENA */ +#define WM2200_OUT2R_ENA_MASK 0x0004 /* OUT2R_ENA */ +#define WM2200_OUT2R_ENA_SHIFT 2 /* OUT2R_ENA */ +#define WM2200_OUT2R_ENA_WIDTH 1 /* OUT2R_ENA */ +#define WM2200_OUT1L_ENA 0x0002 /* OUT1L_ENA */ +#define WM2200_OUT1L_ENA_MASK 0x0002 /* OUT1L_ENA */ +#define WM2200_OUT1L_ENA_SHIFT 1 /* OUT1L_ENA */ +#define WM2200_OUT1L_ENA_WIDTH 1 /* OUT1L_ENA */ +#define WM2200_OUT1R_ENA 0x0001 /* OUT1R_ENA */ +#define WM2200_OUT1R_ENA_MASK 0x0001 /* OUT1R_ENA */ +#define WM2200_OUT1R_ENA_SHIFT 0 /* OUT1R_ENA */ +#define WM2200_OUT1R_ENA_WIDTH 1 /* OUT1R_ENA */ + +/* + * R1025 (0x401) - DAC Volume Limit 1L + */ +#define WM2200_OUT1_OSR 0x2000 /* OUT1_OSR */ +#define WM2200_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */ +#define WM2200_OUT1_OSR_SHIFT 13 /* OUT1_OSR */ +#define WM2200_OUT1_OSR_WIDTH 1 /* OUT1_OSR */ +#define WM2200_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */ +#define WM2200_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */ +#define WM2200_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */ +#define WM2200_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */ +#define WM2200_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */ +#define WM2200_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */ +#define WM2200_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */ + +/* + * R1026 (0x402) - DAC Volume Limit 1R + */ +#define WM2200_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */ +#define WM2200_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */ +#define WM2200_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */ +#define WM2200_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */ +#define WM2200_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */ +#define WM2200_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */ +#define WM2200_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */ + +/* + * R1027 (0x403) - DAC Volume Limit 2L + */ +#define WM2200_OUT2_OSR 0x2000 /* OUT2_OSR */ +#define WM2200_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */ +#define WM2200_OUT2_OSR_SHIFT 13 /* OUT2_OSR */ +#define WM2200_OUT2_OSR_WIDTH 1 /* OUT2_OSR */ +#define WM2200_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */ +#define WM2200_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */ +#define WM2200_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */ +#define WM2200_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */ + +/* + * R1028 (0x404) - DAC Volume Limit 2R + */ +#define WM2200_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */ +#define WM2200_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */ +#define WM2200_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */ +#define WM2200_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */ + +/* + * R1033 (0x409) - DAC AEC Control 1 + */ +#define WM2200_AEC_LOOPBACK_ENA 0x0004 /* AEC_LOOPBACK_ENA */ +#define WM2200_AEC_LOOPBACK_ENA_MASK 0x0004 /* AEC_LOOPBACK_ENA */ +#define WM2200_AEC_LOOPBACK_ENA_SHIFT 2 /* AEC_LOOPBACK_ENA */ +#define WM2200_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */ +#define WM2200_AEC_LOOPBACK_SRC_MASK 0x0003 /* AEC_LOOPBACK_SRC - [1:0] */ +#define WM2200_AEC_LOOPBACK_SRC_SHIFT 0 /* AEC_LOOPBACK_SRC - [1:0] */ +#define WM2200_AEC_LOOPBACK_SRC_WIDTH 2 /* AEC_LOOPBACK_SRC - [1:0] */ + +/* + * R1034 (0x40A) - Output Volume Ramp + */ +#define WM2200_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */ +#define WM2200_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */ +#define WM2200_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */ +#define WM2200_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */ +#define WM2200_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */ +#define WM2200_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */ + +/* + * R1035 (0x40B) - DAC Digital Volume 1L + */ +#define WM2200_OUT_VU 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ +#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ +#define WM2200_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */ +#define WM2200_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */ +#define WM2200_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */ +#define WM2200_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */ +#define WM2200_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */ +#define WM2200_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */ +#define WM2200_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */ + +/* + * R1036 (0x40C) - DAC Digital Volume 1R + */ +#define WM2200_OUT_VU 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ +#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ +#define WM2200_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */ +#define WM2200_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */ +#define WM2200_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */ +#define WM2200_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */ +#define WM2200_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */ +#define WM2200_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */ +#define WM2200_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */ + +/* + * R1037 (0x40D) - DAC Digital Volume 2L + */ +#define WM2200_OUT_VU 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ +#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ +#define WM2200_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */ +#define WM2200_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */ +#define WM2200_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */ +#define WM2200_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */ +#define WM2200_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */ +#define WM2200_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */ +#define WM2200_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */ + +/* + * R1038 (0x40E) - DAC Digital Volume 2R + */ +#define WM2200_OUT_VU 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ +#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ +#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ +#define WM2200_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */ +#define WM2200_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */ +#define WM2200_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */ +#define WM2200_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */ +#define WM2200_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */ +#define WM2200_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */ +#define WM2200_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */ + +/* + * R1047 (0x417) - PDM 1 + */ +#define WM2200_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */ +#define WM2200_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */ +#define WM2200_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */ +#define WM2200_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */ +#define WM2200_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */ +#define WM2200_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */ +#define WM2200_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */ +#define WM2200_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */ +#define WM2200_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */ +#define WM2200_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */ +#define WM2200_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */ +#define WM2200_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */ +#define WM2200_SPK1_MUTE_SEQL_MASK 0x00FF /* SPK1_MUTE_SEQL - [7:0] */ +#define WM2200_SPK1_MUTE_SEQL_SHIFT 0 /* SPK1_MUTE_SEQL - [7:0] */ +#define WM2200_SPK1_MUTE_SEQL_WIDTH 8 /* SPK1_MUTE_SEQL - [7:0] */ + +/* + * R1048 (0x418) - PDM 2 + */ +#define WM2200_SPK1_FMT 0x0001 /* SPK1_FMT */ +#define WM2200_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */ +#define WM2200_SPK1_FMT_SHIFT 0 /* SPK1_FMT */ +#define WM2200_SPK1_FMT_WIDTH 1 /* SPK1_FMT */ + +/* + * R1280 (0x500) - Audio IF 1_1 + */ +#define WM2200_AIF1_BCLK_INV 0x0040 /* AIF1_BCLK_INV */ +#define WM2200_AIF1_BCLK_INV_MASK 0x0040 /* AIF1_BCLK_INV */ +#define WM2200_AIF1_BCLK_INV_SHIFT 6 /* AIF1_BCLK_INV */ +#define WM2200_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ +#define WM2200_AIF1_BCLK_FRC 0x0020 /* AIF1_BCLK_FRC */ +#define WM2200_AIF1_BCLK_FRC_MASK 0x0020 /* AIF1_BCLK_FRC */ +#define WM2200_AIF1_BCLK_FRC_SHIFT 5 /* AIF1_BCLK_FRC */ +#define WM2200_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */ +#define WM2200_AIF1_BCLK_MSTR 0x0010 /* AIF1_BCLK_MSTR */ +#define WM2200_AIF1_BCLK_MSTR_MASK 0x0010 /* AIF1_BCLK_MSTR */ +#define WM2200_AIF1_BCLK_MSTR_SHIFT 4 /* AIF1_BCLK_MSTR */ +#define WM2200_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */ +#define WM2200_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */ +#define WM2200_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */ +#define WM2200_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */ + +/* + * R1281 (0x501) - Audio IF 1_2 + */ +#define WM2200_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */ +#define WM2200_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */ +#define WM2200_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */ +#define WM2200_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */ +#define WM2200_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */ +#define WM2200_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */ +#define WM2200_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */ +#define WM2200_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */ +#define WM2200_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */ +#define WM2200_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */ +#define WM2200_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */ +#define WM2200_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */ +#define WM2200_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */ +#define WM2200_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */ +#define WM2200_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */ +#define WM2200_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */ +#define WM2200_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */ +#define WM2200_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */ +#define WM2200_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */ +#define WM2200_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */ + +/* + * R1282 (0x502) - Audio IF 1_3 + */ +#define WM2200_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */ +#define WM2200_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */ +#define WM2200_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */ +#define WM2200_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */ +#define WM2200_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */ +#define WM2200_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */ +#define WM2200_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */ +#define WM2200_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */ +#define WM2200_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */ +#define WM2200_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */ +#define WM2200_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */ +#define WM2200_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */ + +/* + * R1283 (0x503) - Audio IF 1_4 + */ +#define WM2200_AIF1_TRI 0x0040 /* AIF1_TRI */ +#define WM2200_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */ +#define WM2200_AIF1_TRI_SHIFT 6 /* AIF1_TRI */ +#define WM2200_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ + +/* + * R1284 (0x504) - Audio IF 1_5 + */ +#define WM2200_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */ +#define WM2200_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */ +#define WM2200_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */ + +/* + * R1285 (0x505) - Audio IF 1_6 + */ +#define WM2200_AIF1TX_BCPF_MASK 0x07FF /* AIF1TX_BCPF - [10:0] */ +#define WM2200_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [10:0] */ +#define WM2200_AIF1TX_BCPF_WIDTH 11 /* AIF1TX_BCPF - [10:0] */ + +/* + * R1286 (0x506) - Audio IF 1_7 + */ +#define WM2200_AIF1RX_BCPF_MASK 0x07FF /* AIF1RX_BCPF - [10:0] */ +#define WM2200_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [10:0] */ +#define WM2200_AIF1RX_BCPF_WIDTH 11 /* AIF1RX_BCPF - [10:0] */ + +/* + * R1287 (0x507) - Audio IF 1_8 + */ +#define WM2200_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */ +#define WM2200_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */ +#define WM2200_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */ +#define WM2200_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */ +#define WM2200_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */ +#define WM2200_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */ + +/* + * R1288 (0x508) - Audio IF 1_9 + */ +#define WM2200_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */ +#define WM2200_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */ +#define WM2200_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */ +#define WM2200_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */ +#define WM2200_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */ +#define WM2200_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */ + +/* + * R1289 (0x509) - Audio IF 1_10 + */ +#define WM2200_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */ +#define WM2200_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */ +#define WM2200_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */ + +/* + * R1290 (0x50A) - Audio IF 1_11 + */ +#define WM2200_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */ +#define WM2200_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */ +#define WM2200_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */ + +/* + * R1291 (0x50B) - Audio IF 1_12 + */ +#define WM2200_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */ +#define WM2200_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */ +#define WM2200_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */ + +/* + * R1292 (0x50C) - Audio IF 1_13 + */ +#define WM2200_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */ +#define WM2200_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */ +#define WM2200_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */ + +/* + * R1293 (0x50D) - Audio IF 1_14 + */ +#define WM2200_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */ +#define WM2200_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */ +#define WM2200_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */ + +/* + * R1294 (0x50E) - Audio IF 1_15 + */ +#define WM2200_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */ +#define WM2200_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */ +#define WM2200_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */ + +/* + * R1295 (0x50F) - Audio IF 1_16 + */ +#define WM2200_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */ +#define WM2200_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */ +#define WM2200_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */ + +/* + * R1296 (0x510) - Audio IF 1_17 + */ +#define WM2200_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */ +#define WM2200_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */ +#define WM2200_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */ + +/* + * R1297 (0x511) - Audio IF 1_18 + */ +#define WM2200_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */ +#define WM2200_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */ +#define WM2200_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */ + +/* + * R1298 (0x512) - Audio IF 1_19 + */ +#define WM2200_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */ +#define WM2200_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */ +#define WM2200_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */ + +/* + * R1299 (0x513) - Audio IF 1_20 + */ +#define WM2200_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */ +#define WM2200_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */ +#define WM2200_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */ + +/* + * R1300 (0x514) - Audio IF 1_21 + */ +#define WM2200_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */ +#define WM2200_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */ +#define WM2200_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */ + +/* + * R1301 (0x515) - Audio IF 1_22 + */ +#define WM2200_AIF1RX6_ENA 0x0800 /* AIF1RX6_ENA */ +#define WM2200_AIF1RX6_ENA_MASK 0x0800 /* AIF1RX6_ENA */ +#define WM2200_AIF1RX6_ENA_SHIFT 11 /* AIF1RX6_ENA */ +#define WM2200_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */ +#define WM2200_AIF1RX5_ENA 0x0400 /* AIF1RX5_ENA */ +#define WM2200_AIF1RX5_ENA_MASK 0x0400 /* AIF1RX5_ENA */ +#define WM2200_AIF1RX5_ENA_SHIFT 10 /* AIF1RX5_ENA */ +#define WM2200_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */ +#define WM2200_AIF1RX4_ENA 0x0200 /* AIF1RX4_ENA */ +#define WM2200_AIF1RX4_ENA_MASK 0x0200 /* AIF1RX4_ENA */ +#define WM2200_AIF1RX4_ENA_SHIFT 9 /* AIF1RX4_ENA */ +#define WM2200_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */ +#define WM2200_AIF1RX3_ENA 0x0100 /* AIF1RX3_ENA */ +#define WM2200_AIF1RX3_ENA_MASK 0x0100 /* AIF1RX3_ENA */ +#define WM2200_AIF1RX3_ENA_SHIFT 8 /* AIF1RX3_ENA */ +#define WM2200_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */ +#define WM2200_AIF1RX2_ENA 0x0080 /* AIF1RX2_ENA */ +#define WM2200_AIF1RX2_ENA_MASK 0x0080 /* AIF1RX2_ENA */ +#define WM2200_AIF1RX2_ENA_SHIFT 7 /* AIF1RX2_ENA */ +#define WM2200_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */ +#define WM2200_AIF1RX1_ENA 0x0040 /* AIF1RX1_ENA */ +#define WM2200_AIF1RX1_ENA_MASK 0x0040 /* AIF1RX1_ENA */ +#define WM2200_AIF1RX1_ENA_SHIFT 6 /* AIF1RX1_ENA */ +#define WM2200_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */ +#define WM2200_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */ +#define WM2200_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */ +#define WM2200_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */ +#define WM2200_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */ +#define WM2200_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */ +#define WM2200_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */ +#define WM2200_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */ +#define WM2200_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */ +#define WM2200_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */ +#define WM2200_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */ +#define WM2200_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */ +#define WM2200_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */ +#define WM2200_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */ +#define WM2200_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */ +#define WM2200_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */ +#define WM2200_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */ +#define WM2200_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */ +#define WM2200_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */ +#define WM2200_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */ +#define WM2200_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */ +#define WM2200_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */ +#define WM2200_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */ +#define WM2200_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */ +#define WM2200_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */ + +/* + * R1536 (0x600) - OUT1LMIX Input 1 Source + */ +#define WM2200_OUT1LMIX_SRC1_MASK 0x007F /* OUT1LMIX_SRC1 - [6:0] */ +#define WM2200_OUT1LMIX_SRC1_SHIFT 0 /* OUT1LMIX_SRC1 - [6:0] */ +#define WM2200_OUT1LMIX_SRC1_WIDTH 7 /* OUT1LMIX_SRC1 - [6:0] */ + +/* + * R1537 (0x601) - OUT1LMIX Input 1 Volume + */ +#define WM2200_OUT1LMIX_VOL1_MASK 0x00FE /* OUT1LMIX_VOL1 - [7:1] */ +#define WM2200_OUT1LMIX_VOL1_SHIFT 1 /* OUT1LMIX_VOL1 - [7:1] */ +#define WM2200_OUT1LMIX_VOL1_WIDTH 7 /* OUT1LMIX_VOL1 - [7:1] */ + +/* + * R1538 (0x602) - OUT1LMIX Input 2 Source + */ +#define WM2200_OUT1LMIX_SRC2_MASK 0x007F /* OUT1LMIX_SRC2 - [6:0] */ +#define WM2200_OUT1LMIX_SRC2_SHIFT 0 /* OUT1LMIX_SRC2 - [6:0] */ +#define WM2200_OUT1LMIX_SRC2_WIDTH 7 /* OUT1LMIX_SRC2 - [6:0] */ + +/* + * R1539 (0x603) - OUT1LMIX Input 2 Volume + */ +#define WM2200_OUT1LMIX_VOL2_MASK 0x00FE /* OUT1LMIX_VOL2 - [7:1] */ +#define WM2200_OUT1LMIX_VOL2_SHIFT 1 /* OUT1LMIX_VOL2 - [7:1] */ +#define WM2200_OUT1LMIX_VOL2_WIDTH 7 /* OUT1LMIX_VOL2 - [7:1] */ + +/* + * R1540 (0x604) - OUT1LMIX Input 3 Source + */ +#define WM2200_OUT1LMIX_SRC3_MASK 0x007F /* OUT1LMIX_SRC3 - [6:0] */ +#define WM2200_OUT1LMIX_SRC3_SHIFT 0 /* OUT1LMIX_SRC3 - [6:0] */ +#define WM2200_OUT1LMIX_SRC3_WIDTH 7 /* OUT1LMIX_SRC3 - [6:0] */ + +/* + * R1541 (0x605) - OUT1LMIX Input 3 Volume + */ +#define WM2200_OUT1LMIX_VOL3_MASK 0x00FE /* OUT1LMIX_VOL3 - [7:1] */ +#define WM2200_OUT1LMIX_VOL3_SHIFT 1 /* OUT1LMIX_VOL3 - [7:1] */ +#define WM2200_OUT1LMIX_VOL3_WIDTH 7 /* OUT1LMIX_VOL3 - [7:1] */ + +/* + * R1542 (0x606) - OUT1LMIX Input 4 Source + */ +#define WM2200_OUT1LMIX_SRC4_MASK 0x007F /* OUT1LMIX_SRC4 - [6:0] */ +#define WM2200_OUT1LMIX_SRC4_SHIFT 0 /* OUT1LMIX_SRC4 - [6:0] */ +#define WM2200_OUT1LMIX_SRC4_WIDTH 7 /* OUT1LMIX_SRC4 - [6:0] */ + +/* + * R1543 (0x607) - OUT1LMIX Input 4 Volume + */ +#define WM2200_OUT1LMIX_VOL4_MASK 0x00FE /* OUT1LMIX_VOL4 - [7:1] */ +#define WM2200_OUT1LMIX_VOL4_SHIFT 1 /* OUT1LMIX_VOL4 - [7:1] */ +#define WM2200_OUT1LMIX_VOL4_WIDTH 7 /* OUT1LMIX_VOL4 - [7:1] */ + +/* + * R1544 (0x608) - OUT1RMIX Input 1 Source + */ +#define WM2200_OUT1RMIX_SRC1_MASK 0x007F /* OUT1RMIX_SRC1 - [6:0] */ +#define WM2200_OUT1RMIX_SRC1_SHIFT 0 /* OUT1RMIX_SRC1 - [6:0] */ +#define WM2200_OUT1RMIX_SRC1_WIDTH 7 /* OUT1RMIX_SRC1 - [6:0] */ + +/* + * R1545 (0x609) - OUT1RMIX Input 1 Volume + */ +#define WM2200_OUT1RMIX_VOL1_MASK 0x00FE /* OUT1RMIX_VOL1 - [7:1] */ +#define WM2200_OUT1RMIX_VOL1_SHIFT 1 /* OUT1RMIX_VOL1 - [7:1] */ +#define WM2200_OUT1RMIX_VOL1_WIDTH 7 /* OUT1RMIX_VOL1 - [7:1] */ + +/* + * R1546 (0x60A) - OUT1RMIX Input 2 Source + */ +#define WM2200_OUT1RMIX_SRC2_MASK 0x007F /* OUT1RMIX_SRC2 - [6:0] */ +#define WM2200_OUT1RMIX_SRC2_SHIFT 0 /* OUT1RMIX_SRC2 - [6:0] */ +#define WM2200_OUT1RMIX_SRC2_WIDTH 7 /* OUT1RMIX_SRC2 - [6:0] */ + +/* + * R1547 (0x60B) - OUT1RMIX Input 2 Volume + */ +#define WM2200_OUT1RMIX_VOL2_MASK 0x00FE /* OUT1RMIX_VOL2 - [7:1] */ +#define WM2200_OUT1RMIX_VOL2_SHIFT 1 /* OUT1RMIX_VOL2 - [7:1] */ +#define WM2200_OUT1RMIX_VOL2_WIDTH 7 /* OUT1RMIX_VOL2 - [7:1] */ + +/* + * R1548 (0x60C) - OUT1RMIX Input 3 Source + */ +#define WM2200_OUT1RMIX_SRC3_MASK 0x007F /* OUT1RMIX_SRC3 - [6:0] */ +#define WM2200_OUT1RMIX_SRC3_SHIFT 0 /* OUT1RMIX_SRC3 - [6:0] */ +#define WM2200_OUT1RMIX_SRC3_WIDTH 7 /* OUT1RMIX_SRC3 - [6:0] */ + +/* + * R1549 (0x60D) - OUT1RMIX Input 3 Volume + */ +#define WM2200_OUT1RMIX_VOL3_MASK 0x00FE /* OUT1RMIX_VOL3 - [7:1] */ +#define WM2200_OUT1RMIX_VOL3_SHIFT 1 /* OUT1RMIX_VOL3 - [7:1] */ +#define WM2200_OUT1RMIX_VOL3_WIDTH 7 /* OUT1RMIX_VOL3 - [7:1] */ + +/* + * R1550 (0x60E) - OUT1RMIX Input 4 Source + */ +#define WM2200_OUT1RMIX_SRC4_MASK 0x007F /* OUT1RMIX_SRC4 - [6:0] */ +#define WM2200_OUT1RMIX_SRC4_SHIFT 0 /* OUT1RMIX_SRC4 - [6:0] */ +#define WM2200_OUT1RMIX_SRC4_WIDTH 7 /* OUT1RMIX_SRC4 - [6:0] */ + +/* + * R1551 (0x60F) - OUT1RMIX Input 4 Volume + */ +#define WM2200_OUT1RMIX_VOL4_MASK 0x00FE /* OUT1RMIX_VOL4 - [7:1] */ +#define WM2200_OUT1RMIX_VOL4_SHIFT 1 /* OUT1RMIX_VOL4 - [7:1] */ +#define WM2200_OUT1RMIX_VOL4_WIDTH 7 /* OUT1RMIX_VOL4 - [7:1] */ + +/* + * R1552 (0x610) - OUT2LMIX Input 1 Source + */ +#define WM2200_OUT2LMIX_SRC1_MASK 0x007F /* OUT2LMIX_SRC1 - [6:0] */ +#define WM2200_OUT2LMIX_SRC1_SHIFT 0 /* OUT2LMIX_SRC1 - [6:0] */ +#define WM2200_OUT2LMIX_SRC1_WIDTH 7 /* OUT2LMIX_SRC1 - [6:0] */ + +/* + * R1553 (0x611) - OUT2LMIX Input 1 Volume + */ +#define WM2200_OUT2LMIX_VOL1_MASK 0x00FE /* OUT2LMIX_VOL1 - [7:1] */ +#define WM2200_OUT2LMIX_VOL1_SHIFT 1 /* OUT2LMIX_VOL1 - [7:1] */ +#define WM2200_OUT2LMIX_VOL1_WIDTH 7 /* OUT2LMIX_VOL1 - [7:1] */ + +/* + * R1554 (0x612) - OUT2LMIX Input 2 Source + */ +#define WM2200_OUT2LMIX_SRC2_MASK 0x007F /* OUT2LMIX_SRC2 - [6:0] */ +#define WM2200_OUT2LMIX_SRC2_SHIFT 0 /* OUT2LMIX_SRC2 - [6:0] */ +#define WM2200_OUT2LMIX_SRC2_WIDTH 7 /* OUT2LMIX_SRC2 - [6:0] */ + +/* + * R1555 (0x613) - OUT2LMIX Input 2 Volume + */ +#define WM2200_OUT2LMIX_VOL2_MASK 0x00FE /* OUT2LMIX_VOL2 - [7:1] */ +#define WM2200_OUT2LMIX_VOL2_SHIFT 1 /* OUT2LMIX_VOL2 - [7:1] */ +#define WM2200_OUT2LMIX_VOL2_WIDTH 7 /* OUT2LMIX_VOL2 - [7:1] */ + +/* + * R1556 (0x614) - OUT2LMIX Input 3 Source + */ +#define WM2200_OUT2LMIX_SRC3_MASK 0x007F /* OUT2LMIX_SRC3 - [6:0] */ +#define WM2200_OUT2LMIX_SRC3_SHIFT 0 /* OUT2LMIX_SRC3 - [6:0] */ +#define WM2200_OUT2LMIX_SRC3_WIDTH 7 /* OUT2LMIX_SRC3 - [6:0] */ + +/* + * R1557 (0x615) - OUT2LMIX Input 3 Volume + */ +#define WM2200_OUT2LMIX_VOL3_MASK 0x00FE /* OUT2LMIX_VOL3 - [7:1] */ +#define WM2200_OUT2LMIX_VOL3_SHIFT 1 /* OUT2LMIX_VOL3 - [7:1] */ +#define WM2200_OUT2LMIX_VOL3_WIDTH 7 /* OUT2LMIX_VOL3 - [7:1] */ + +/* + * R1558 (0x616) - OUT2LMIX Input 4 Source + */ +#define WM2200_OUT2LMIX_SRC4_MASK 0x007F /* OUT2LMIX_SRC4 - [6:0] */ +#define WM2200_OUT2LMIX_SRC4_SHIFT 0 /* OUT2LMIX_SRC4 - [6:0] */ +#define WM2200_OUT2LMIX_SRC4_WIDTH 7 /* OUT2LMIX_SRC4 - [6:0] */ + +/* + * R1559 (0x617) - OUT2LMIX Input 4 Volume + */ +#define WM2200_OUT2LMIX_VOL4_MASK 0x00FE /* OUT2LMIX_VOL4 - [7:1] */ +#define WM2200_OUT2LMIX_VOL4_SHIFT 1 /* OUT2LMIX_VOL4 - [7:1] */ +#define WM2200_OUT2LMIX_VOL4_WIDTH 7 /* OUT2LMIX_VOL4 - [7:1] */ + +/* + * R1560 (0x618) - OUT2RMIX Input 1 Source + */ +#define WM2200_OUT2RMIX_SRC1_MASK 0x007F /* OUT2RMIX_SRC1 - [6:0] */ +#define WM2200_OUT2RMIX_SRC1_SHIFT 0 /* OUT2RMIX_SRC1 - [6:0] */ +#define WM2200_OUT2RMIX_SRC1_WIDTH 7 /* OUT2RMIX_SRC1 - [6:0] */ + +/* + * R1561 (0x619) - OUT2RMIX Input 1 Volume + */ +#define WM2200_OUT2RMIX_VOL1_MASK 0x00FE /* OUT2RMIX_VOL1 - [7:1] */ +#define WM2200_OUT2RMIX_VOL1_SHIFT 1 /* OUT2RMIX_VOL1 - [7:1] */ +#define WM2200_OUT2RMIX_VOL1_WIDTH 7 /* OUT2RMIX_VOL1 - [7:1] */ + +/* + * R1562 (0x61A) - OUT2RMIX Input 2 Source + */ +#define WM2200_OUT2RMIX_SRC2_MASK 0x007F /* OUT2RMIX_SRC2 - [6:0] */ +#define WM2200_OUT2RMIX_SRC2_SHIFT 0 /* OUT2RMIX_SRC2 - [6:0] */ +#define WM2200_OUT2RMIX_SRC2_WIDTH 7 /* OUT2RMIX_SRC2 - [6:0] */ + +/* + * R1563 (0x61B) - OUT2RMIX Input 2 Volume + */ +#define WM2200_OUT2RMIX_VOL2_MASK 0x00FE /* OUT2RMIX_VOL2 - [7:1] */ +#define WM2200_OUT2RMIX_VOL2_SHIFT 1 /* OUT2RMIX_VOL2 - [7:1] */ +#define WM2200_OUT2RMIX_VOL2_WIDTH 7 /* OUT2RMIX_VOL2 - [7:1] */ + +/* + * R1564 (0x61C) - OUT2RMIX Input 3 Source + */ +#define WM2200_OUT2RMIX_SRC3_MASK 0x007F /* OUT2RMIX_SRC3 - [6:0] */ +#define WM2200_OUT2RMIX_SRC3_SHIFT 0 /* OUT2RMIX_SRC3 - [6:0] */ +#define WM2200_OUT2RMIX_SRC3_WIDTH 7 /* OUT2RMIX_SRC3 - [6:0] */ + +/* + * R1565 (0x61D) - OUT2RMIX Input 3 Volume + */ +#define WM2200_OUT2RMIX_VOL3_MASK 0x00FE /* OUT2RMIX_VOL3 - [7:1] */ +#define WM2200_OUT2RMIX_VOL3_SHIFT 1 /* OUT2RMIX_VOL3 - [7:1] */ +#define WM2200_OUT2RMIX_VOL3_WIDTH 7 /* OUT2RMIX_VOL3 - [7:1] */ + +/* + * R1566 (0x61E) - OUT2RMIX Input 4 Source + */ +#define WM2200_OUT2RMIX_SRC4_MASK 0x007F /* OUT2RMIX_SRC4 - [6:0] */ +#define WM2200_OUT2RMIX_SRC4_SHIFT 0 /* OUT2RMIX_SRC4 - [6:0] */ +#define WM2200_OUT2RMIX_SRC4_WIDTH 7 /* OUT2RMIX_SRC4 - [6:0] */ + +/* + * R1567 (0x61F) - OUT2RMIX Input 4 Volume + */ +#define WM2200_OUT2RMIX_VOL4_MASK 0x00FE /* OUT2RMIX_VOL4 - [7:1] */ +#define WM2200_OUT2RMIX_VOL4_SHIFT 1 /* OUT2RMIX_VOL4 - [7:1] */ +#define WM2200_OUT2RMIX_VOL4_WIDTH 7 /* OUT2RMIX_VOL4 - [7:1] */ + +/* + * R1568 (0x620) - AIF1TX1MIX Input 1 Source + */ +#define WM2200_AIF1TX1MIX_SRC1_MASK 0x007F /* AIF1TX1MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC1_SHIFT 0 /* AIF1TX1MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC1_WIDTH 7 /* AIF1TX1MIX_SRC1 - [6:0] */ + +/* + * R1569 (0x621) - AIF1TX1MIX Input 1 Volume + */ +#define WM2200_AIF1TX1MIX_VOL1_MASK 0x00FE /* AIF1TX1MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL1_SHIFT 1 /* AIF1TX1MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL1_WIDTH 7 /* AIF1TX1MIX_VOL1 - [7:1] */ + +/* + * R1570 (0x622) - AIF1TX1MIX Input 2 Source + */ +#define WM2200_AIF1TX1MIX_SRC2_MASK 0x007F /* AIF1TX1MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC2_SHIFT 0 /* AIF1TX1MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC2_WIDTH 7 /* AIF1TX1MIX_SRC2 - [6:0] */ + +/* + * R1571 (0x623) - AIF1TX1MIX Input 2 Volume + */ +#define WM2200_AIF1TX1MIX_VOL2_MASK 0x00FE /* AIF1TX1MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL2_SHIFT 1 /* AIF1TX1MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL2_WIDTH 7 /* AIF1TX1MIX_VOL2 - [7:1] */ + +/* + * R1572 (0x624) - AIF1TX1MIX Input 3 Source + */ +#define WM2200_AIF1TX1MIX_SRC3_MASK 0x007F /* AIF1TX1MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC3_SHIFT 0 /* AIF1TX1MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC3_WIDTH 7 /* AIF1TX1MIX_SRC3 - [6:0] */ + +/* + * R1573 (0x625) - AIF1TX1MIX Input 3 Volume + */ +#define WM2200_AIF1TX1MIX_VOL3_MASK 0x00FE /* AIF1TX1MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL3_SHIFT 1 /* AIF1TX1MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL3_WIDTH 7 /* AIF1TX1MIX_VOL3 - [7:1] */ + +/* + * R1574 (0x626) - AIF1TX1MIX Input 4 Source + */ +#define WM2200_AIF1TX1MIX_SRC4_MASK 0x007F /* AIF1TX1MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC4_SHIFT 0 /* AIF1TX1MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX1MIX_SRC4_WIDTH 7 /* AIF1TX1MIX_SRC4 - [6:0] */ + +/* + * R1575 (0x627) - AIF1TX1MIX Input 4 Volume + */ +#define WM2200_AIF1TX1MIX_VOL4_MASK 0x00FE /* AIF1TX1MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL4_SHIFT 1 /* AIF1TX1MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX1MIX_VOL4_WIDTH 7 /* AIF1TX1MIX_VOL4 - [7:1] */ + +/* + * R1576 (0x628) - AIF1TX2MIX Input 1 Source + */ +#define WM2200_AIF1TX2MIX_SRC1_MASK 0x007F /* AIF1TX2MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC1_SHIFT 0 /* AIF1TX2MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC1_WIDTH 7 /* AIF1TX2MIX_SRC1 - [6:0] */ + +/* + * R1577 (0x629) - AIF1TX2MIX Input 1 Volume + */ +#define WM2200_AIF1TX2MIX_VOL1_MASK 0x00FE /* AIF1TX2MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL1_SHIFT 1 /* AIF1TX2MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL1_WIDTH 7 /* AIF1TX2MIX_VOL1 - [7:1] */ + +/* + * R1578 (0x62A) - AIF1TX2MIX Input 2 Source + */ +#define WM2200_AIF1TX2MIX_SRC2_MASK 0x007F /* AIF1TX2MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC2_SHIFT 0 /* AIF1TX2MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC2_WIDTH 7 /* AIF1TX2MIX_SRC2 - [6:0] */ + +/* + * R1579 (0x62B) - AIF1TX2MIX Input 2 Volume + */ +#define WM2200_AIF1TX2MIX_VOL2_MASK 0x00FE /* AIF1TX2MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL2_SHIFT 1 /* AIF1TX2MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL2_WIDTH 7 /* AIF1TX2MIX_VOL2 - [7:1] */ + +/* + * R1580 (0x62C) - AIF1TX2MIX Input 3 Source + */ +#define WM2200_AIF1TX2MIX_SRC3_MASK 0x007F /* AIF1TX2MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC3_SHIFT 0 /* AIF1TX2MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC3_WIDTH 7 /* AIF1TX2MIX_SRC3 - [6:0] */ + +/* + * R1581 (0x62D) - AIF1TX2MIX Input 3 Volume + */ +#define WM2200_AIF1TX2MIX_VOL3_MASK 0x00FE /* AIF1TX2MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL3_SHIFT 1 /* AIF1TX2MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL3_WIDTH 7 /* AIF1TX2MIX_VOL3 - [7:1] */ + +/* + * R1582 (0x62E) - AIF1TX2MIX Input 4 Source + */ +#define WM2200_AIF1TX2MIX_SRC4_MASK 0x007F /* AIF1TX2MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC4_SHIFT 0 /* AIF1TX2MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX2MIX_SRC4_WIDTH 7 /* AIF1TX2MIX_SRC4 - [6:0] */ + +/* + * R1583 (0x62F) - AIF1TX2MIX Input 4 Volume + */ +#define WM2200_AIF1TX2MIX_VOL4_MASK 0x00FE /* AIF1TX2MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL4_SHIFT 1 /* AIF1TX2MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX2MIX_VOL4_WIDTH 7 /* AIF1TX2MIX_VOL4 - [7:1] */ + +/* + * R1584 (0x630) - AIF1TX3MIX Input 1 Source + */ +#define WM2200_AIF1TX3MIX_SRC1_MASK 0x007F /* AIF1TX3MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC1_SHIFT 0 /* AIF1TX3MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC1_WIDTH 7 /* AIF1TX3MIX_SRC1 - [6:0] */ + +/* + * R1585 (0x631) - AIF1TX3MIX Input 1 Volume + */ +#define WM2200_AIF1TX3MIX_VOL1_MASK 0x00FE /* AIF1TX3MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL1_SHIFT 1 /* AIF1TX3MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL1_WIDTH 7 /* AIF1TX3MIX_VOL1 - [7:1] */ + +/* + * R1586 (0x632) - AIF1TX3MIX Input 2 Source + */ +#define WM2200_AIF1TX3MIX_SRC2_MASK 0x007F /* AIF1TX3MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC2_SHIFT 0 /* AIF1TX3MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC2_WIDTH 7 /* AIF1TX3MIX_SRC2 - [6:0] */ + +/* + * R1587 (0x633) - AIF1TX3MIX Input 2 Volume + */ +#define WM2200_AIF1TX3MIX_VOL2_MASK 0x00FE /* AIF1TX3MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL2_SHIFT 1 /* AIF1TX3MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL2_WIDTH 7 /* AIF1TX3MIX_VOL2 - [7:1] */ + +/* + * R1588 (0x634) - AIF1TX3MIX Input 3 Source + */ +#define WM2200_AIF1TX3MIX_SRC3_MASK 0x007F /* AIF1TX3MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC3_SHIFT 0 /* AIF1TX3MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC3_WIDTH 7 /* AIF1TX3MIX_SRC3 - [6:0] */ + +/* + * R1589 (0x635) - AIF1TX3MIX Input 3 Volume + */ +#define WM2200_AIF1TX3MIX_VOL3_MASK 0x00FE /* AIF1TX3MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL3_SHIFT 1 /* AIF1TX3MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL3_WIDTH 7 /* AIF1TX3MIX_VOL3 - [7:1] */ + +/* + * R1590 (0x636) - AIF1TX3MIX Input 4 Source + */ +#define WM2200_AIF1TX3MIX_SRC4_MASK 0x007F /* AIF1TX3MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC4_SHIFT 0 /* AIF1TX3MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX3MIX_SRC4_WIDTH 7 /* AIF1TX3MIX_SRC4 - [6:0] */ + +/* + * R1591 (0x637) - AIF1TX3MIX Input 4 Volume + */ +#define WM2200_AIF1TX3MIX_VOL4_MASK 0x00FE /* AIF1TX3MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL4_SHIFT 1 /* AIF1TX3MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX3MIX_VOL4_WIDTH 7 /* AIF1TX3MIX_VOL4 - [7:1] */ + +/* + * R1592 (0x638) - AIF1TX4MIX Input 1 Source + */ +#define WM2200_AIF1TX4MIX_SRC1_MASK 0x007F /* AIF1TX4MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC1_SHIFT 0 /* AIF1TX4MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC1_WIDTH 7 /* AIF1TX4MIX_SRC1 - [6:0] */ + +/* + * R1593 (0x639) - AIF1TX4MIX Input 1 Volume + */ +#define WM2200_AIF1TX4MIX_VOL1_MASK 0x00FE /* AIF1TX4MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL1_SHIFT 1 /* AIF1TX4MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL1_WIDTH 7 /* AIF1TX4MIX_VOL1 - [7:1] */ + +/* + * R1594 (0x63A) - AIF1TX4MIX Input 2 Source + */ +#define WM2200_AIF1TX4MIX_SRC2_MASK 0x007F /* AIF1TX4MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC2_SHIFT 0 /* AIF1TX4MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC2_WIDTH 7 /* AIF1TX4MIX_SRC2 - [6:0] */ + +/* + * R1595 (0x63B) - AIF1TX4MIX Input 2 Volume + */ +#define WM2200_AIF1TX4MIX_VOL2_MASK 0x00FE /* AIF1TX4MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL2_SHIFT 1 /* AIF1TX4MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL2_WIDTH 7 /* AIF1TX4MIX_VOL2 - [7:1] */ + +/* + * R1596 (0x63C) - AIF1TX4MIX Input 3 Source + */ +#define WM2200_AIF1TX4MIX_SRC3_MASK 0x007F /* AIF1TX4MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC3_SHIFT 0 /* AIF1TX4MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC3_WIDTH 7 /* AIF1TX4MIX_SRC3 - [6:0] */ + +/* + * R1597 (0x63D) - AIF1TX4MIX Input 3 Volume + */ +#define WM2200_AIF1TX4MIX_VOL3_MASK 0x00FE /* AIF1TX4MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL3_SHIFT 1 /* AIF1TX4MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL3_WIDTH 7 /* AIF1TX4MIX_VOL3 - [7:1] */ + +/* + * R1598 (0x63E) - AIF1TX4MIX Input 4 Source + */ +#define WM2200_AIF1TX4MIX_SRC4_MASK 0x007F /* AIF1TX4MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC4_SHIFT 0 /* AIF1TX4MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX4MIX_SRC4_WIDTH 7 /* AIF1TX4MIX_SRC4 - [6:0] */ + +/* + * R1599 (0x63F) - AIF1TX4MIX Input 4 Volume + */ +#define WM2200_AIF1TX4MIX_VOL4_MASK 0x00FE /* AIF1TX4MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL4_SHIFT 1 /* AIF1TX4MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX4MIX_VOL4_WIDTH 7 /* AIF1TX4MIX_VOL4 - [7:1] */ + +/* + * R1600 (0x640) - AIF1TX5MIX Input 1 Source + */ +#define WM2200_AIF1TX5MIX_SRC1_MASK 0x007F /* AIF1TX5MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC1_SHIFT 0 /* AIF1TX5MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC1_WIDTH 7 /* AIF1TX5MIX_SRC1 - [6:0] */ + +/* + * R1601 (0x641) - AIF1TX5MIX Input 1 Volume + */ +#define WM2200_AIF1TX5MIX_VOL1_MASK 0x00FE /* AIF1TX5MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL1_SHIFT 1 /* AIF1TX5MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL1_WIDTH 7 /* AIF1TX5MIX_VOL1 - [7:1] */ + +/* + * R1602 (0x642) - AIF1TX5MIX Input 2 Source + */ +#define WM2200_AIF1TX5MIX_SRC2_MASK 0x007F /* AIF1TX5MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC2_SHIFT 0 /* AIF1TX5MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC2_WIDTH 7 /* AIF1TX5MIX_SRC2 - [6:0] */ + +/* + * R1603 (0x643) - AIF1TX5MIX Input 2 Volume + */ +#define WM2200_AIF1TX5MIX_VOL2_MASK 0x00FE /* AIF1TX5MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL2_SHIFT 1 /* AIF1TX5MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL2_WIDTH 7 /* AIF1TX5MIX_VOL2 - [7:1] */ + +/* + * R1604 (0x644) - AIF1TX5MIX Input 3 Source + */ +#define WM2200_AIF1TX5MIX_SRC3_MASK 0x007F /* AIF1TX5MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC3_SHIFT 0 /* AIF1TX5MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC3_WIDTH 7 /* AIF1TX5MIX_SRC3 - [6:0] */ + +/* + * R1605 (0x645) - AIF1TX5MIX Input 3 Volume + */ +#define WM2200_AIF1TX5MIX_VOL3_MASK 0x00FE /* AIF1TX5MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL3_SHIFT 1 /* AIF1TX5MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL3_WIDTH 7 /* AIF1TX5MIX_VOL3 - [7:1] */ + +/* + * R1606 (0x646) - AIF1TX5MIX Input 4 Source + */ +#define WM2200_AIF1TX5MIX_SRC4_MASK 0x007F /* AIF1TX5MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC4_SHIFT 0 /* AIF1TX5MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX5MIX_SRC4_WIDTH 7 /* AIF1TX5MIX_SRC4 - [6:0] */ + +/* + * R1607 (0x647) - AIF1TX5MIX Input 4 Volume + */ +#define WM2200_AIF1TX5MIX_VOL4_MASK 0x00FE /* AIF1TX5MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL4_SHIFT 1 /* AIF1TX5MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX5MIX_VOL4_WIDTH 7 /* AIF1TX5MIX_VOL4 - [7:1] */ + +/* + * R1608 (0x648) - AIF1TX6MIX Input 1 Source + */ +#define WM2200_AIF1TX6MIX_SRC1_MASK 0x007F /* AIF1TX6MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC1_SHIFT 0 /* AIF1TX6MIX_SRC1 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC1_WIDTH 7 /* AIF1TX6MIX_SRC1 - [6:0] */ + +/* + * R1609 (0x649) - AIF1TX6MIX Input 1 Volume + */ +#define WM2200_AIF1TX6MIX_VOL1_MASK 0x00FE /* AIF1TX6MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL1_SHIFT 1 /* AIF1TX6MIX_VOL1 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL1_WIDTH 7 /* AIF1TX6MIX_VOL1 - [7:1] */ + +/* + * R1610 (0x64A) - AIF1TX6MIX Input 2 Source + */ +#define WM2200_AIF1TX6MIX_SRC2_MASK 0x007F /* AIF1TX6MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC2_SHIFT 0 /* AIF1TX6MIX_SRC2 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC2_WIDTH 7 /* AIF1TX6MIX_SRC2 - [6:0] */ + +/* + * R1611 (0x64B) - AIF1TX6MIX Input 2 Volume + */ +#define WM2200_AIF1TX6MIX_VOL2_MASK 0x00FE /* AIF1TX6MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL2_SHIFT 1 /* AIF1TX6MIX_VOL2 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL2_WIDTH 7 /* AIF1TX6MIX_VOL2 - [7:1] */ + +/* + * R1612 (0x64C) - AIF1TX6MIX Input 3 Source + */ +#define WM2200_AIF1TX6MIX_SRC3_MASK 0x007F /* AIF1TX6MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC3_SHIFT 0 /* AIF1TX6MIX_SRC3 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC3_WIDTH 7 /* AIF1TX6MIX_SRC3 - [6:0] */ + +/* + * R1613 (0x64D) - AIF1TX6MIX Input 3 Volume + */ +#define WM2200_AIF1TX6MIX_VOL3_MASK 0x00FE /* AIF1TX6MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL3_SHIFT 1 /* AIF1TX6MIX_VOL3 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL3_WIDTH 7 /* AIF1TX6MIX_VOL3 - [7:1] */ + +/* + * R1614 (0x64E) - AIF1TX6MIX Input 4 Source + */ +#define WM2200_AIF1TX6MIX_SRC4_MASK 0x007F /* AIF1TX6MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC4_SHIFT 0 /* AIF1TX6MIX_SRC4 - [6:0] */ +#define WM2200_AIF1TX6MIX_SRC4_WIDTH 7 /* AIF1TX6MIX_SRC4 - [6:0] */ + +/* + * R1615 (0x64F) - AIF1TX6MIX Input 4 Volume + */ +#define WM2200_AIF1TX6MIX_VOL4_MASK 0x00FE /* AIF1TX6MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL4_SHIFT 1 /* AIF1TX6MIX_VOL4 - [7:1] */ +#define WM2200_AIF1TX6MIX_VOL4_WIDTH 7 /* AIF1TX6MIX_VOL4 - [7:1] */ + +/* + * R1616 (0x650) - EQLMIX Input 1 Source + */ +#define WM2200_EQLMIX_SRC1_MASK 0x007F /* EQLMIX_SRC1 - [6:0] */ +#define WM2200_EQLMIX_SRC1_SHIFT 0 /* EQLMIX_SRC1 - [6:0] */ +#define WM2200_EQLMIX_SRC1_WIDTH 7 /* EQLMIX_SRC1 - [6:0] */ + +/* + * R1617 (0x651) - EQLMIX Input 1 Volume + */ +#define WM2200_EQLMIX_VOL1_MASK 0x00FE /* EQLMIX_VOL1 - [7:1] */ +#define WM2200_EQLMIX_VOL1_SHIFT 1 /* EQLMIX_VOL1 - [7:1] */ +#define WM2200_EQLMIX_VOL1_WIDTH 7 /* EQLMIX_VOL1 - [7:1] */ + +/* + * R1618 (0x652) - EQLMIX Input 2 Source + */ +#define WM2200_EQLMIX_SRC2_MASK 0x007F /* EQLMIX_SRC2 - [6:0] */ +#define WM2200_EQLMIX_SRC2_SHIFT 0 /* EQLMIX_SRC2 - [6:0] */ +#define WM2200_EQLMIX_SRC2_WIDTH 7 /* EQLMIX_SRC2 - [6:0] */ + +/* + * R1619 (0x653) - EQLMIX Input 2 Volume + */ +#define WM2200_EQLMIX_VOL2_MASK 0x00FE /* EQLMIX_VOL2 - [7:1] */ +#define WM2200_EQLMIX_VOL2_SHIFT 1 /* EQLMIX_VOL2 - [7:1] */ +#define WM2200_EQLMIX_VOL2_WIDTH 7 /* EQLMIX_VOL2 - [7:1] */ + +/* + * R1620 (0x654) - EQLMIX Input 3 Source + */ +#define WM2200_EQLMIX_SRC3_MASK 0x007F /* EQLMIX_SRC3 - [6:0] */ +#define WM2200_EQLMIX_SRC3_SHIFT 0 /* EQLMIX_SRC3 - [6:0] */ +#define WM2200_EQLMIX_SRC3_WIDTH 7 /* EQLMIX_SRC3 - [6:0] */ + +/* + * R1621 (0x655) - EQLMIX Input 3 Volume + */ +#define WM2200_EQLMIX_VOL3_MASK 0x00FE /* EQLMIX_VOL3 - [7:1] */ +#define WM2200_EQLMIX_VOL3_SHIFT 1 /* EQLMIX_VOL3 - [7:1] */ +#define WM2200_EQLMIX_VOL3_WIDTH 7 /* EQLMIX_VOL3 - [7:1] */ + +/* + * R1622 (0x656) - EQLMIX Input 4 Source + */ +#define WM2200_EQLMIX_SRC4_MASK 0x007F /* EQLMIX_SRC4 - [6:0] */ +#define WM2200_EQLMIX_SRC4_SHIFT 0 /* EQLMIX_SRC4 - [6:0] */ +#define WM2200_EQLMIX_SRC4_WIDTH 7 /* EQLMIX_SRC4 - [6:0] */ + +/* + * R1623 (0x657) - EQLMIX Input 4 Volume + */ +#define WM2200_EQLMIX_VOL4_MASK 0x00FE /* EQLMIX_VOL4 - [7:1] */ +#define WM2200_EQLMIX_VOL4_SHIFT 1 /* EQLMIX_VOL4 - [7:1] */ +#define WM2200_EQLMIX_VOL4_WIDTH 7 /* EQLMIX_VOL4 - [7:1] */ + +/* + * R1624 (0x658) - EQRMIX Input 1 Source + */ +#define WM2200_EQRMIX_SRC1_MASK 0x007F /* EQRMIX_SRC1 - [6:0] */ +#define WM2200_EQRMIX_SRC1_SHIFT 0 /* EQRMIX_SRC1 - [6:0] */ +#define WM2200_EQRMIX_SRC1_WIDTH 7 /* EQRMIX_SRC1 - [6:0] */ + +/* + * R1625 (0x659) - EQRMIX Input 1 Volume + */ +#define WM2200_EQRMIX_VOL1_MASK 0x00FE /* EQRMIX_VOL1 - [7:1] */ +#define WM2200_EQRMIX_VOL1_SHIFT 1 /* EQRMIX_VOL1 - [7:1] */ +#define WM2200_EQRMIX_VOL1_WIDTH 7 /* EQRMIX_VOL1 - [7:1] */ + +/* + * R1626 (0x65A) - EQRMIX Input 2 Source + */ +#define WM2200_EQRMIX_SRC2_MASK 0x007F /* EQRMIX_SRC2 - [6:0] */ +#define WM2200_EQRMIX_SRC2_SHIFT 0 /* EQRMIX_SRC2 - [6:0] */ +#define WM2200_EQRMIX_SRC2_WIDTH 7 /* EQRMIX_SRC2 - [6:0] */ + +/* + * R1627 (0x65B) - EQRMIX Input 2 Volume + */ +#define WM2200_EQRMIX_VOL2_MASK 0x00FE /* EQRMIX_VOL2 - [7:1] */ +#define WM2200_EQRMIX_VOL2_SHIFT 1 /* EQRMIX_VOL2 - [7:1] */ +#define WM2200_EQRMIX_VOL2_WIDTH 7 /* EQRMIX_VOL2 - [7:1] */ + +/* + * R1628 (0x65C) - EQRMIX Input 3 Source + */ +#define WM2200_EQRMIX_SRC3_MASK 0x007F /* EQRMIX_SRC3 - [6:0] */ +#define WM2200_EQRMIX_SRC3_SHIFT 0 /* EQRMIX_SRC3 - [6:0] */ +#define WM2200_EQRMIX_SRC3_WIDTH 7 /* EQRMIX_SRC3 - [6:0] */ + +/* + * R1629 (0x65D) - EQRMIX Input 3 Volume + */ +#define WM2200_EQRMIX_VOL3_MASK 0x00FE /* EQRMIX_VOL3 - [7:1] */ +#define WM2200_EQRMIX_VOL3_SHIFT 1 /* EQRMIX_VOL3 - [7:1] */ +#define WM2200_EQRMIX_VOL3_WIDTH 7 /* EQRMIX_VOL3 - [7:1] */ + +/* + * R1630 (0x65E) - EQRMIX Input 4 Source + */ +#define WM2200_EQRMIX_SRC4_MASK 0x007F /* EQRMIX_SRC4 - [6:0] */ +#define WM2200_EQRMIX_SRC4_SHIFT 0 /* EQRMIX_SRC4 - [6:0] */ +#define WM2200_EQRMIX_SRC4_WIDTH 7 /* EQRMIX_SRC4 - [6:0] */ + +/* + * R1631 (0x65F) - EQRMIX Input 4 Volume + */ +#define WM2200_EQRMIX_VOL4_MASK 0x00FE /* EQRMIX_VOL4 - [7:1] */ +#define WM2200_EQRMIX_VOL4_SHIFT 1 /* EQRMIX_VOL4 - [7:1] */ +#define WM2200_EQRMIX_VOL4_WIDTH 7 /* EQRMIX_VOL4 - [7:1] */ + +/* + * R1632 (0x660) - LHPF1MIX Input 1 Source + */ +#define WM2200_LHPF1MIX_SRC1_MASK 0x007F /* LHPF1MIX_SRC1 - [6:0] */ +#define WM2200_LHPF1MIX_SRC1_SHIFT 0 /* LHPF1MIX_SRC1 - [6:0] */ +#define WM2200_LHPF1MIX_SRC1_WIDTH 7 /* LHPF1MIX_SRC1 - [6:0] */ + +/* + * R1633 (0x661) - LHPF1MIX Input 1 Volume + */ +#define WM2200_LHPF1MIX_VOL1_MASK 0x00FE /* LHPF1MIX_VOL1 - [7:1] */ +#define WM2200_LHPF1MIX_VOL1_SHIFT 1 /* LHPF1MIX_VOL1 - [7:1] */ +#define WM2200_LHPF1MIX_VOL1_WIDTH 7 /* LHPF1MIX_VOL1 - [7:1] */ + +/* + * R1634 (0x662) - LHPF1MIX Input 2 Source + */ +#define WM2200_LHPF1MIX_SRC2_MASK 0x007F /* LHPF1MIX_SRC2 - [6:0] */ +#define WM2200_LHPF1MIX_SRC2_SHIFT 0 /* LHPF1MIX_SRC2 - [6:0] */ +#define WM2200_LHPF1MIX_SRC2_WIDTH 7 /* LHPF1MIX_SRC2 - [6:0] */ + +/* + * R1635 (0x663) - LHPF1MIX Input 2 Volume + */ +#define WM2200_LHPF1MIX_VOL2_MASK 0x00FE /* LHPF1MIX_VOL2 - [7:1] */ +#define WM2200_LHPF1MIX_VOL2_SHIFT 1 /* LHPF1MIX_VOL2 - [7:1] */ +#define WM2200_LHPF1MIX_VOL2_WIDTH 7 /* LHPF1MIX_VOL2 - [7:1] */ + +/* + * R1636 (0x664) - LHPF1MIX Input 3 Source + */ +#define WM2200_LHPF1MIX_SRC3_MASK 0x007F /* LHPF1MIX_SRC3 - [6:0] */ +#define WM2200_LHPF1MIX_SRC3_SHIFT 0 /* LHPF1MIX_SRC3 - [6:0] */ +#define WM2200_LHPF1MIX_SRC3_WIDTH 7 /* LHPF1MIX_SRC3 - [6:0] */ + +/* + * R1637 (0x665) - LHPF1MIX Input 3 Volume + */ +#define WM2200_LHPF1MIX_VOL3_MASK 0x00FE /* LHPF1MIX_VOL3 - [7:1] */ +#define WM2200_LHPF1MIX_VOL3_SHIFT 1 /* LHPF1MIX_VOL3 - [7:1] */ +#define WM2200_LHPF1MIX_VOL3_WIDTH 7 /* LHPF1MIX_VOL3 - [7:1] */ + +/* + * R1638 (0x666) - LHPF1MIX Input 4 Source + */ +#define WM2200_LHPF1MIX_SRC4_MASK 0x007F /* LHPF1MIX_SRC4 - [6:0] */ +#define WM2200_LHPF1MIX_SRC4_SHIFT 0 /* LHPF1MIX_SRC4 - [6:0] */ +#define WM2200_LHPF1MIX_SRC4_WIDTH 7 /* LHPF1MIX_SRC4 - [6:0] */ + +/* + * R1639 (0x667) - LHPF1MIX Input 4 Volume + */ +#define WM2200_LHPF1MIX_VOL4_MASK 0x00FE /* LHPF1MIX_VOL4 - [7:1] */ +#define WM2200_LHPF1MIX_VOL4_SHIFT 1 /* LHPF1MIX_VOL4 - [7:1] */ +#define WM2200_LHPF1MIX_VOL4_WIDTH 7 /* LHPF1MIX_VOL4 - [7:1] */ + +/* + * R1640 (0x668) - LHPF2MIX Input 1 Source + */ +#define WM2200_LHPF2MIX_SRC1_MASK 0x007F /* LHPF2MIX_SRC1 - [6:0] */ +#define WM2200_LHPF2MIX_SRC1_SHIFT 0 /* LHPF2MIX_SRC1 - [6:0] */ +#define WM2200_LHPF2MIX_SRC1_WIDTH 7 /* LHPF2MIX_SRC1 - [6:0] */ + +/* + * R1641 (0x669) - LHPF2MIX Input 1 Volume + */ +#define WM2200_LHPF2MIX_VOL1_MASK 0x00FE /* LHPF2MIX_VOL1 - [7:1] */ +#define WM2200_LHPF2MIX_VOL1_SHIFT 1 /* LHPF2MIX_VOL1 - [7:1] */ +#define WM2200_LHPF2MIX_VOL1_WIDTH 7 /* LHPF2MIX_VOL1 - [7:1] */ + +/* + * R1642 (0x66A) - LHPF2MIX Input 2 Source + */ +#define WM2200_LHPF2MIX_SRC2_MASK 0x007F /* LHPF2MIX_SRC2 - [6:0] */ +#define WM2200_LHPF2MIX_SRC2_SHIFT 0 /* LHPF2MIX_SRC2 - [6:0] */ +#define WM2200_LHPF2MIX_SRC2_WIDTH 7 /* LHPF2MIX_SRC2 - [6:0] */ + +/* + * R1643 (0x66B) - LHPF2MIX Input 2 Volume + */ +#define WM2200_LHPF2MIX_VOL2_MASK 0x00FE /* LHPF2MIX_VOL2 - [7:1] */ +#define WM2200_LHPF2MIX_VOL2_SHIFT 1 /* LHPF2MIX_VOL2 - [7:1] */ +#define WM2200_LHPF2MIX_VOL2_WIDTH 7 /* LHPF2MIX_VOL2 - [7:1] */ + +/* + * R1644 (0x66C) - LHPF2MIX Input 3 Source + */ +#define WM2200_LHPF2MIX_SRC3_MASK 0x007F /* LHPF2MIX_SRC3 - [6:0] */ +#define WM2200_LHPF2MIX_SRC3_SHIFT 0 /* LHPF2MIX_SRC3 - [6:0] */ +#define WM2200_LHPF2MIX_SRC3_WIDTH 7 /* LHPF2MIX_SRC3 - [6:0] */ + +/* + * R1645 (0x66D) - LHPF2MIX Input 3 Volume + */ +#define WM2200_LHPF2MIX_VOL3_MASK 0x00FE /* LHPF2MIX_VOL3 - [7:1] */ +#define WM2200_LHPF2MIX_VOL3_SHIFT 1 /* LHPF2MIX_VOL3 - [7:1] */ +#define WM2200_LHPF2MIX_VOL3_WIDTH 7 /* LHPF2MIX_VOL3 - [7:1] */ + +/* + * R1646 (0x66E) - LHPF2MIX Input 4 Source + */ +#define WM2200_LHPF2MIX_SRC4_MASK 0x007F /* LHPF2MIX_SRC4 - [6:0] */ +#define WM2200_LHPF2MIX_SRC4_SHIFT 0 /* LHPF2MIX_SRC4 - [6:0] */ +#define WM2200_LHPF2MIX_SRC4_WIDTH 7 /* LHPF2MIX_SRC4 - [6:0] */ + +/* + * R1647 (0x66F) - LHPF2MIX Input 4 Volume + */ +#define WM2200_LHPF2MIX_VOL4_MASK 0x00FE /* LHPF2MIX_VOL4 - [7:1] */ +#define WM2200_LHPF2MIX_VOL4_SHIFT 1 /* LHPF2MIX_VOL4 - [7:1] */ +#define WM2200_LHPF2MIX_VOL4_WIDTH 7 /* LHPF2MIX_VOL4 - [7:1] */ + +/* + * R1648 (0x670) - DSP1LMIX Input 1 Source + */ +#define WM2200_DSP1LMIX_SRC1_MASK 0x007F /* DSP1LMIX_SRC1 - [6:0] */ +#define WM2200_DSP1LMIX_SRC1_SHIFT 0 /* DSP1LMIX_SRC1 - [6:0] */ +#define WM2200_DSP1LMIX_SRC1_WIDTH 7 /* DSP1LMIX_SRC1 - [6:0] */ + +/* + * R1649 (0x671) - DSP1LMIX Input 1 Volume + */ +#define WM2200_DSP1LMIX_VOL1_MASK 0x00FE /* DSP1LMIX_VOL1 - [7:1] */ +#define WM2200_DSP1LMIX_VOL1_SHIFT 1 /* DSP1LMIX_VOL1 - [7:1] */ +#define WM2200_DSP1LMIX_VOL1_WIDTH 7 /* DSP1LMIX_VOL1 - [7:1] */ + +/* + * R1650 (0x672) - DSP1LMIX Input 2 Source + */ +#define WM2200_DSP1LMIX_SRC2_MASK 0x007F /* DSP1LMIX_SRC2 - [6:0] */ +#define WM2200_DSP1LMIX_SRC2_SHIFT 0 /* DSP1LMIX_SRC2 - [6:0] */ +#define WM2200_DSP1LMIX_SRC2_WIDTH 7 /* DSP1LMIX_SRC2 - [6:0] */ + +/* + * R1651 (0x673) - DSP1LMIX Input 2 Volume + */ +#define WM2200_DSP1LMIX_VOL2_MASK 0x00FE /* DSP1LMIX_VOL2 - [7:1] */ +#define WM2200_DSP1LMIX_VOL2_SHIFT 1 /* DSP1LMIX_VOL2 - [7:1] */ +#define WM2200_DSP1LMIX_VOL2_WIDTH 7 /* DSP1LMIX_VOL2 - [7:1] */ + +/* + * R1652 (0x674) - DSP1LMIX Input 3 Source + */ +#define WM2200_DSP1LMIX_SRC3_MASK 0x007F /* DSP1LMIX_SRC3 - [6:0] */ +#define WM2200_DSP1LMIX_SRC3_SHIFT 0 /* DSP1LMIX_SRC3 - [6:0] */ +#define WM2200_DSP1LMIX_SRC3_WIDTH 7 /* DSP1LMIX_SRC3 - [6:0] */ + +/* + * R1653 (0x675) - DSP1LMIX Input 3 Volume + */ +#define WM2200_DSP1LMIX_VOL3_MASK 0x00FE /* DSP1LMIX_VOL3 - [7:1] */ +#define WM2200_DSP1LMIX_VOL3_SHIFT 1 /* DSP1LMIX_VOL3 - [7:1] */ +#define WM2200_DSP1LMIX_VOL3_WIDTH 7 /* DSP1LMIX_VOL3 - [7:1] */ + +/* + * R1654 (0x676) - DSP1LMIX Input 4 Source + */ +#define WM2200_DSP1LMIX_SRC4_MASK 0x007F /* DSP1LMIX_SRC4 - [6:0] */ +#define WM2200_DSP1LMIX_SRC4_SHIFT 0 /* DSP1LMIX_SRC4 - [6:0] */ +#define WM2200_DSP1LMIX_SRC4_WIDTH 7 /* DSP1LMIX_SRC4 - [6:0] */ + +/* + * R1655 (0x677) - DSP1LMIX Input 4 Volume + */ +#define WM2200_DSP1LMIX_VOL4_MASK 0x00FE /* DSP1LMIX_VOL4 - [7:1] */ +#define WM2200_DSP1LMIX_VOL4_SHIFT 1 /* DSP1LMIX_VOL4 - [7:1] */ +#define WM2200_DSP1LMIX_VOL4_WIDTH 7 /* DSP1LMIX_VOL4 - [7:1] */ + +/* + * R1656 (0x678) - DSP1RMIX Input 1 Source + */ +#define WM2200_DSP1RMIX_SRC1_MASK 0x007F /* DSP1RMIX_SRC1 - [6:0] */ +#define WM2200_DSP1RMIX_SRC1_SHIFT 0 /* DSP1RMIX_SRC1 - [6:0] */ +#define WM2200_DSP1RMIX_SRC1_WIDTH 7 /* DSP1RMIX_SRC1 - [6:0] */ + +/* + * R1657 (0x679) - DSP1RMIX Input 1 Volume + */ +#define WM2200_DSP1RMIX_VOL1_MASK 0x00FE /* DSP1RMIX_VOL1 - [7:1] */ +#define WM2200_DSP1RMIX_VOL1_SHIFT 1 /* DSP1RMIX_VOL1 - [7:1] */ +#define WM2200_DSP1RMIX_VOL1_WIDTH 7 /* DSP1RMIX_VOL1 - [7:1] */ + +/* + * R1658 (0x67A) - DSP1RMIX Input 2 Source + */ +#define WM2200_DSP1RMIX_SRC2_MASK 0x007F /* DSP1RMIX_SRC2 - [6:0] */ +#define WM2200_DSP1RMIX_SRC2_SHIFT 0 /* DSP1RMIX_SRC2 - [6:0] */ +#define WM2200_DSP1RMIX_SRC2_WIDTH 7 /* DSP1RMIX_SRC2 - [6:0] */ + +/* + * R1659 (0x67B) - DSP1RMIX Input 2 Volume + */ +#define WM2200_DSP1RMIX_VOL2_MASK 0x00FE /* DSP1RMIX_VOL2 - [7:1] */ +#define WM2200_DSP1RMIX_VOL2_SHIFT 1 /* DSP1RMIX_VOL2 - [7:1] */ +#define WM2200_DSP1RMIX_VOL2_WIDTH 7 /* DSP1RMIX_VOL2 - [7:1] */ + +/* + * R1660 (0x67C) - DSP1RMIX Input 3 Source + */ +#define WM2200_DSP1RMIX_SRC3_MASK 0x007F /* DSP1RMIX_SRC3 - [6:0] */ +#define WM2200_DSP1RMIX_SRC3_SHIFT 0 /* DSP1RMIX_SRC3 - [6:0] */ +#define WM2200_DSP1RMIX_SRC3_WIDTH 7 /* DSP1RMIX_SRC3 - [6:0] */ + +/* + * R1661 (0x67D) - DSP1RMIX Input 3 Volume + */ +#define WM2200_DSP1RMIX_VOL3_MASK 0x00FE /* DSP1RMIX_VOL3 - [7:1] */ +#define WM2200_DSP1RMIX_VOL3_SHIFT 1 /* DSP1RMIX_VOL3 - [7:1] */ +#define WM2200_DSP1RMIX_VOL3_WIDTH 7 /* DSP1RMIX_VOL3 - [7:1] */ + +/* + * R1662 (0x67E) - DSP1RMIX Input 4 Source + */ +#define WM2200_DSP1RMIX_SRC4_MASK 0x007F /* DSP1RMIX_SRC4 - [6:0] */ +#define WM2200_DSP1RMIX_SRC4_SHIFT 0 /* DSP1RMIX_SRC4 - [6:0] */ +#define WM2200_DSP1RMIX_SRC4_WIDTH 7 /* DSP1RMIX_SRC4 - [6:0] */ + +/* + * R1663 (0x67F) - DSP1RMIX Input 4 Volume + */ +#define WM2200_DSP1RMIX_VOL4_MASK 0x00FE /* DSP1RMIX_VOL4 - [7:1] */ +#define WM2200_DSP1RMIX_VOL4_SHIFT 1 /* DSP1RMIX_VOL4 - [7:1] */ +#define WM2200_DSP1RMIX_VOL4_WIDTH 7 /* DSP1RMIX_VOL4 - [7:1] */ + +/* + * R1664 (0x680) - DSP1AUX1MIX Input 1 Source + */ +#define WM2200_DSP1AUX1MIX_SRC1_MASK 0x007F /* DSP1AUX1MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX1MIX_SRC1_SHIFT 0 /* DSP1AUX1MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX1MIX_SRC1_WIDTH 7 /* DSP1AUX1MIX_SRC1 - [6:0] */ + +/* + * R1665 (0x681) - DSP1AUX2MIX Input 1 Source + */ +#define WM2200_DSP1AUX2MIX_SRC1_MASK 0x007F /* DSP1AUX2MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX2MIX_SRC1_SHIFT 0 /* DSP1AUX2MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX2MIX_SRC1_WIDTH 7 /* DSP1AUX2MIX_SRC1 - [6:0] */ + +/* + * R1666 (0x682) - DSP1AUX3MIX Input 1 Source + */ +#define WM2200_DSP1AUX3MIX_SRC1_MASK 0x007F /* DSP1AUX3MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX3MIX_SRC1_SHIFT 0 /* DSP1AUX3MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX3MIX_SRC1_WIDTH 7 /* DSP1AUX3MIX_SRC1 - [6:0] */ + +/* + * R1667 (0x683) - DSP1AUX4MIX Input 1 Source + */ +#define WM2200_DSP1AUX4MIX_SRC1_MASK 0x007F /* DSP1AUX4MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX4MIX_SRC1_SHIFT 0 /* DSP1AUX4MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX4MIX_SRC1_WIDTH 7 /* DSP1AUX4MIX_SRC1 - [6:0] */ + +/* + * R1668 (0x684) - DSP1AUX5MIX Input 1 Source + */ +#define WM2200_DSP1AUX5MIX_SRC1_MASK 0x007F /* DSP1AUX5MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX5MIX_SRC1_SHIFT 0 /* DSP1AUX5MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX5MIX_SRC1_WIDTH 7 /* DSP1AUX5MIX_SRC1 - [6:0] */ + +/* + * R1669 (0x685) - DSP1AUX6MIX Input 1 Source + */ +#define WM2200_DSP1AUX6MIX_SRC1_MASK 0x007F /* DSP1AUX6MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX6MIX_SRC1_SHIFT 0 /* DSP1AUX6MIX_SRC1 - [6:0] */ +#define WM2200_DSP1AUX6MIX_SRC1_WIDTH 7 /* DSP1AUX6MIX_SRC1 - [6:0] */ + +/* + * R1670 (0x686) - DSP2LMIX Input 1 Source + */ +#define WM2200_DSP2LMIX_SRC1_MASK 0x007F /* DSP2LMIX_SRC1 - [6:0] */ +#define WM2200_DSP2LMIX_SRC1_SHIFT 0 /* DSP2LMIX_SRC1 - [6:0] */ +#define WM2200_DSP2LMIX_SRC1_WIDTH 7 /* DSP2LMIX_SRC1 - [6:0] */ + +/* + * R1671 (0x687) - DSP2LMIX Input 1 Volume + */ +#define WM2200_DSP2LMIX_VOL1_MASK 0x00FE /* DSP2LMIX_VOL1 - [7:1] */ +#define WM2200_DSP2LMIX_VOL1_SHIFT 1 /* DSP2LMIX_VOL1 - [7:1] */ +#define WM2200_DSP2LMIX_VOL1_WIDTH 7 /* DSP2LMIX_VOL1 - [7:1] */ + +/* + * R1672 (0x688) - DSP2LMIX Input 2 Source + */ +#define WM2200_DSP2LMIX_SRC2_MASK 0x007F /* DSP2LMIX_SRC2 - [6:0] */ +#define WM2200_DSP2LMIX_SRC2_SHIFT 0 /* DSP2LMIX_SRC2 - [6:0] */ +#define WM2200_DSP2LMIX_SRC2_WIDTH 7 /* DSP2LMIX_SRC2 - [6:0] */ + +/* + * R1673 (0x689) - DSP2LMIX Input 2 Volume + */ +#define WM2200_DSP2LMIX_VOL2_MASK 0x00FE /* DSP2LMIX_VOL2 - [7:1] */ +#define WM2200_DSP2LMIX_VOL2_SHIFT 1 /* DSP2LMIX_VOL2 - [7:1] */ +#define WM2200_DSP2LMIX_VOL2_WIDTH 7 /* DSP2LMIX_VOL2 - [7:1] */ + +/* + * R1674 (0x68A) - DSP2LMIX Input 3 Source + */ +#define WM2200_DSP2LMIX_SRC3_MASK 0x007F /* DSP2LMIX_SRC3 - [6:0] */ +#define WM2200_DSP2LMIX_SRC3_SHIFT 0 /* DSP2LMIX_SRC3 - [6:0] */ +#define WM2200_DSP2LMIX_SRC3_WIDTH 7 /* DSP2LMIX_SRC3 - [6:0] */ + +/* + * R1675 (0x68B) - DSP2LMIX Input 3 Volume + */ +#define WM2200_DSP2LMIX_VOL3_MASK 0x00FE /* DSP2LMIX_VOL3 - [7:1] */ +#define WM2200_DSP2LMIX_VOL3_SHIFT 1 /* DSP2LMIX_VOL3 - [7:1] */ +#define WM2200_DSP2LMIX_VOL3_WIDTH 7 /* DSP2LMIX_VOL3 - [7:1] */ + +/* + * R1676 (0x68C) - DSP2LMIX Input 4 Source + */ +#define WM2200_DSP2LMIX_SRC4_MASK 0x007F /* DSP2LMIX_SRC4 - [6:0] */ +#define WM2200_DSP2LMIX_SRC4_SHIFT 0 /* DSP2LMIX_SRC4 - [6:0] */ +#define WM2200_DSP2LMIX_SRC4_WIDTH 7 /* DSP2LMIX_SRC4 - [6:0] */ + +/* + * R1677 (0x68D) - DSP2LMIX Input 4 Volume + */ +#define WM2200_DSP2LMIX_VOL4_MASK 0x00FE /* DSP2LMIX_VOL4 - [7:1] */ +#define WM2200_DSP2LMIX_VOL4_SHIFT 1 /* DSP2LMIX_VOL4 - [7:1] */ +#define WM2200_DSP2LMIX_VOL4_WIDTH 7 /* DSP2LMIX_VOL4 - [7:1] */ + +/* + * R1678 (0x68E) - DSP2RMIX Input 1 Source + */ +#define WM2200_DSP2RMIX_SRC1_MASK 0x007F /* DSP2RMIX_SRC1 - [6:0] */ +#define WM2200_DSP2RMIX_SRC1_SHIFT 0 /* DSP2RMIX_SRC1 - [6:0] */ +#define WM2200_DSP2RMIX_SRC1_WIDTH 7 /* DSP2RMIX_SRC1 - [6:0] */ + +/* + * R1679 (0x68F) - DSP2RMIX Input 1 Volume + */ +#define WM2200_DSP2RMIX_VOL1_MASK 0x00FE /* DSP2RMIX_VOL1 - [7:1] */ +#define WM2200_DSP2RMIX_VOL1_SHIFT 1 /* DSP2RMIX_VOL1 - [7:1] */ +#define WM2200_DSP2RMIX_VOL1_WIDTH 7 /* DSP2RMIX_VOL1 - [7:1] */ + +/* + * R1680 (0x690) - DSP2RMIX Input 2 Source + */ +#define WM2200_DSP2RMIX_SRC2_MASK 0x007F /* DSP2RMIX_SRC2 - [6:0] */ +#define WM2200_DSP2RMIX_SRC2_SHIFT 0 /* DSP2RMIX_SRC2 - [6:0] */ +#define WM2200_DSP2RMIX_SRC2_WIDTH 7 /* DSP2RMIX_SRC2 - [6:0] */ + +/* + * R1681 (0x691) - DSP2RMIX Input 2 Volume + */ +#define WM2200_DSP2RMIX_VOL2_MASK 0x00FE /* DSP2RMIX_VOL2 - [7:1] */ +#define WM2200_DSP2RMIX_VOL2_SHIFT 1 /* DSP2RMIX_VOL2 - [7:1] */ +#define WM2200_DSP2RMIX_VOL2_WIDTH 7 /* DSP2RMIX_VOL2 - [7:1] */ + +/* + * R1682 (0x692) - DSP2RMIX Input 3 Source + */ +#define WM2200_DSP2RMIX_SRC3_MASK 0x007F /* DSP2RMIX_SRC3 - [6:0] */ +#define WM2200_DSP2RMIX_SRC3_SHIFT 0 /* DSP2RMIX_SRC3 - [6:0] */ +#define WM2200_DSP2RMIX_SRC3_WIDTH 7 /* DSP2RMIX_SRC3 - [6:0] */ + +/* + * R1683 (0x693) - DSP2RMIX Input 3 Volume + */ +#define WM2200_DSP2RMIX_VOL3_MASK 0x00FE /* DSP2RMIX_VOL3 - [7:1] */ +#define WM2200_DSP2RMIX_VOL3_SHIFT 1 /* DSP2RMIX_VOL3 - [7:1] */ +#define WM2200_DSP2RMIX_VOL3_WIDTH 7 /* DSP2RMIX_VOL3 - [7:1] */ + +/* + * R1684 (0x694) - DSP2RMIX Input 4 Source + */ +#define WM2200_DSP2RMIX_SRC4_MASK 0x007F /* DSP2RMIX_SRC4 - [6:0] */ +#define WM2200_DSP2RMIX_SRC4_SHIFT 0 /* DSP2RMIX_SRC4 - [6:0] */ +#define WM2200_DSP2RMIX_SRC4_WIDTH 7 /* DSP2RMIX_SRC4 - [6:0] */ + +/* + * R1685 (0x695) - DSP2RMIX Input 4 Volume + */ +#define WM2200_DSP2RMIX_VOL4_MASK 0x00FE /* DSP2RMIX_VOL4 - [7:1] */ +#define WM2200_DSP2RMIX_VOL4_SHIFT 1 /* DSP2RMIX_VOL4 - [7:1] */ +#define WM2200_DSP2RMIX_VOL4_WIDTH 7 /* DSP2RMIX_VOL4 - [7:1] */ + +/* + * R1686 (0x696) - DSP2AUX1MIX Input 1 Source + */ +#define WM2200_DSP2AUX1MIX_SRC1_MASK 0x007F /* DSP2AUX1MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX1MIX_SRC1_SHIFT 0 /* DSP2AUX1MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX1MIX_SRC1_WIDTH 7 /* DSP2AUX1MIX_SRC1 - [6:0] */ + +/* + * R1687 (0x697) - DSP2AUX2MIX Input 1 Source + */ +#define WM2200_DSP2AUX2MIX_SRC1_MASK 0x007F /* DSP2AUX2MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX2MIX_SRC1_SHIFT 0 /* DSP2AUX2MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX2MIX_SRC1_WIDTH 7 /* DSP2AUX2MIX_SRC1 - [6:0] */ + +/* + * R1688 (0x698) - DSP2AUX3MIX Input 1 Source + */ +#define WM2200_DSP2AUX3MIX_SRC1_MASK 0x007F /* DSP2AUX3MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX3MIX_SRC1_SHIFT 0 /* DSP2AUX3MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX3MIX_SRC1_WIDTH 7 /* DSP2AUX3MIX_SRC1 - [6:0] */ + +/* + * R1689 (0x699) - DSP2AUX4MIX Input 1 Source + */ +#define WM2200_DSP2AUX4MIX_SRC1_MASK 0x007F /* DSP2AUX4MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX4MIX_SRC1_SHIFT 0 /* DSP2AUX4MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX4MIX_SRC1_WIDTH 7 /* DSP2AUX4MIX_SRC1 - [6:0] */ + +/* + * R1690 (0x69A) - DSP2AUX5MIX Input 1 Source + */ +#define WM2200_DSP2AUX5MIX_SRC1_MASK 0x007F /* DSP2AUX5MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX5MIX_SRC1_SHIFT 0 /* DSP2AUX5MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX5MIX_SRC1_WIDTH 7 /* DSP2AUX5MIX_SRC1 - [6:0] */ + +/* + * R1691 (0x69B) - DSP2AUX6MIX Input 1 Source + */ +#define WM2200_DSP2AUX6MIX_SRC1_MASK 0x007F /* DSP2AUX6MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX6MIX_SRC1_SHIFT 0 /* DSP2AUX6MIX_SRC1 - [6:0] */ +#define WM2200_DSP2AUX6MIX_SRC1_WIDTH 7 /* DSP2AUX6MIX_SRC1 - [6:0] */ + +/* + * R1792 (0x700) - GPIO CTRL 1 + */ +#define WM2200_GP1_DIR 0x8000 /* GP1_DIR */ +#define WM2200_GP1_DIR_MASK 0x8000 /* GP1_DIR */ +#define WM2200_GP1_DIR_SHIFT 15 /* GP1_DIR */ +#define WM2200_GP1_DIR_WIDTH 1 /* GP1_DIR */ +#define WM2200_GP1_PU 0x4000 /* GP1_PU */ +#define WM2200_GP1_PU_MASK 0x4000 /* GP1_PU */ +#define WM2200_GP1_PU_SHIFT 14 /* GP1_PU */ +#define WM2200_GP1_PU_WIDTH 1 /* GP1_PU */ +#define WM2200_GP1_PD 0x2000 /* GP1_PD */ +#define WM2200_GP1_PD_MASK 0x2000 /* GP1_PD */ +#define WM2200_GP1_PD_SHIFT 13 /* GP1_PD */ +#define WM2200_GP1_PD_WIDTH 1 /* GP1_PD */ +#define WM2200_GP1_POL 0x0400 /* GP1_POL */ +#define WM2200_GP1_POL_MASK 0x0400 /* GP1_POL */ +#define WM2200_GP1_POL_SHIFT 10 /* GP1_POL */ +#define WM2200_GP1_POL_WIDTH 1 /* GP1_POL */ +#define WM2200_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ +#define WM2200_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ +#define WM2200_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ +#define WM2200_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ +#define WM2200_GP1_DB 0x0100 /* GP1_DB */ +#define WM2200_GP1_DB_MASK 0x0100 /* GP1_DB */ +#define WM2200_GP1_DB_SHIFT 8 /* GP1_DB */ +#define WM2200_GP1_DB_WIDTH 1 /* GP1_DB */ +#define WM2200_GP1_LVL 0x0040 /* GP1_LVL */ +#define WM2200_GP1_LVL_MASK 0x0040 /* GP1_LVL */ +#define WM2200_GP1_LVL_SHIFT 6 /* GP1_LVL */ +#define WM2200_GP1_LVL_WIDTH 1 /* GP1_LVL */ +#define WM2200_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */ +#define WM2200_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */ +#define WM2200_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */ + +/* + * R1793 (0x701) - GPIO CTRL 2 + */ +#define WM2200_GP2_DIR 0x8000 /* GP2_DIR */ +#define WM2200_GP2_DIR_MASK 0x8000 /* GP2_DIR */ +#define WM2200_GP2_DIR_SHIFT 15 /* GP2_DIR */ +#define WM2200_GP2_DIR_WIDTH 1 /* GP2_DIR */ +#define WM2200_GP2_PU 0x4000 /* GP2_PU */ +#define WM2200_GP2_PU_MASK 0x4000 /* GP2_PU */ +#define WM2200_GP2_PU_SHIFT 14 /* GP2_PU */ +#define WM2200_GP2_PU_WIDTH 1 /* GP2_PU */ +#define WM2200_GP2_PD 0x2000 /* GP2_PD */ +#define WM2200_GP2_PD_MASK 0x2000 /* GP2_PD */ +#define WM2200_GP2_PD_SHIFT 13 /* GP2_PD */ +#define WM2200_GP2_PD_WIDTH 1 /* GP2_PD */ +#define WM2200_GP2_POL 0x0400 /* GP2_POL */ +#define WM2200_GP2_POL_MASK 0x0400 /* GP2_POL */ +#define WM2200_GP2_POL_SHIFT 10 /* GP2_POL */ +#define WM2200_GP2_POL_WIDTH 1 /* GP2_POL */ +#define WM2200_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ +#define WM2200_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ +#define WM2200_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ +#define WM2200_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ +#define WM2200_GP2_DB 0x0100 /* GP2_DB */ +#define WM2200_GP2_DB_MASK 0x0100 /* GP2_DB */ +#define WM2200_GP2_DB_SHIFT 8 /* GP2_DB */ +#define WM2200_GP2_DB_WIDTH 1 /* GP2_DB */ +#define WM2200_GP2_LVL 0x0040 /* GP2_LVL */ +#define WM2200_GP2_LVL_MASK 0x0040 /* GP2_LVL */ +#define WM2200_GP2_LVL_SHIFT 6 /* GP2_LVL */ +#define WM2200_GP2_LVL_WIDTH 1 /* GP2_LVL */ +#define WM2200_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */ +#define WM2200_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */ +#define WM2200_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */ + +/* + * R1794 (0x702) - GPIO CTRL 3 + */ +#define WM2200_GP3_DIR 0x8000 /* GP3_DIR */ +#define WM2200_GP3_DIR_MASK 0x8000 /* GP3_DIR */ +#define WM2200_GP3_DIR_SHIFT 15 /* GP3_DIR */ +#define WM2200_GP3_DIR_WIDTH 1 /* GP3_DIR */ +#define WM2200_GP3_PU 0x4000 /* GP3_PU */ +#define WM2200_GP3_PU_MASK 0x4000 /* GP3_PU */ +#define WM2200_GP3_PU_SHIFT 14 /* GP3_PU */ +#define WM2200_GP3_PU_WIDTH 1 /* GP3_PU */ +#define WM2200_GP3_PD 0x2000 /* GP3_PD */ +#define WM2200_GP3_PD_MASK 0x2000 /* GP3_PD */ +#define WM2200_GP3_PD_SHIFT 13 /* GP3_PD */ +#define WM2200_GP3_PD_WIDTH 1 /* GP3_PD */ +#define WM2200_GP3_POL 0x0400 /* GP3_POL */ +#define WM2200_GP3_POL_MASK 0x0400 /* GP3_POL */ +#define WM2200_GP3_POL_SHIFT 10 /* GP3_POL */ +#define WM2200_GP3_POL_WIDTH 1 /* GP3_POL */ +#define WM2200_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ +#define WM2200_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ +#define WM2200_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ +#define WM2200_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ +#define WM2200_GP3_DB 0x0100 /* GP3_DB */ +#define WM2200_GP3_DB_MASK 0x0100 /* GP3_DB */ +#define WM2200_GP3_DB_SHIFT 8 /* GP3_DB */ +#define WM2200_GP3_DB_WIDTH 1 /* GP3_DB */ +#define WM2200_GP3_LVL 0x0040 /* GP3_LVL */ +#define WM2200_GP3_LVL_MASK 0x0040 /* GP3_LVL */ +#define WM2200_GP3_LVL_SHIFT 6 /* GP3_LVL */ +#define WM2200_GP3_LVL_WIDTH 1 /* GP3_LVL */ +#define WM2200_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */ +#define WM2200_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */ +#define WM2200_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */ + +/* + * R1795 (0x703) - GPIO CTRL 4 + */ +#define WM2200_GP4_DIR 0x8000 /* GP4_DIR */ +#define WM2200_GP4_DIR_MASK 0x8000 /* GP4_DIR */ +#define WM2200_GP4_DIR_SHIFT 15 /* GP4_DIR */ +#define WM2200_GP4_DIR_WIDTH 1 /* GP4_DIR */ +#define WM2200_GP4_PU 0x4000 /* GP4_PU */ +#define WM2200_GP4_PU_MASK 0x4000 /* GP4_PU */ +#define WM2200_GP4_PU_SHIFT 14 /* GP4_PU */ +#define WM2200_GP4_PU_WIDTH 1 /* GP4_PU */ +#define WM2200_GP4_PD 0x2000 /* GP4_PD */ +#define WM2200_GP4_PD_MASK 0x2000 /* GP4_PD */ +#define WM2200_GP4_PD_SHIFT 13 /* GP4_PD */ +#define WM2200_GP4_PD_WIDTH 1 /* GP4_PD */ +#define WM2200_GP4_POL 0x0400 /* GP4_POL */ +#define WM2200_GP4_POL_MASK 0x0400 /* GP4_POL */ +#define WM2200_GP4_POL_SHIFT 10 /* GP4_POL */ +#define WM2200_GP4_POL_WIDTH 1 /* GP4_POL */ +#define WM2200_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ +#define WM2200_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ +#define WM2200_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ +#define WM2200_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ +#define WM2200_GP4_DB 0x0100 /* GP4_DB */ +#define WM2200_GP4_DB_MASK 0x0100 /* GP4_DB */ +#define WM2200_GP4_DB_SHIFT 8 /* GP4_DB */ +#define WM2200_GP4_DB_WIDTH 1 /* GP4_DB */ +#define WM2200_GP4_LVL 0x0040 /* GP4_LVL */ +#define WM2200_GP4_LVL_MASK 0x0040 /* GP4_LVL */ +#define WM2200_GP4_LVL_SHIFT 6 /* GP4_LVL */ +#define WM2200_GP4_LVL_WIDTH 1 /* GP4_LVL */ +#define WM2200_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */ +#define WM2200_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */ +#define WM2200_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */ + +/* + * R1799 (0x707) - ADPS1 IRQ0 + */ +#define WM2200_DSP_IRQ1 0x0002 /* DSP_IRQ1 */ +#define WM2200_DSP_IRQ1_MASK 0x0002 /* DSP_IRQ1 */ +#define WM2200_DSP_IRQ1_SHIFT 1 /* DSP_IRQ1 */ +#define WM2200_DSP_IRQ1_WIDTH 1 /* DSP_IRQ1 */ +#define WM2200_DSP_IRQ0 0x0001 /* DSP_IRQ0 */ +#define WM2200_DSP_IRQ0_MASK 0x0001 /* DSP_IRQ0 */ +#define WM2200_DSP_IRQ0_SHIFT 0 /* DSP_IRQ0 */ +#define WM2200_DSP_IRQ0_WIDTH 1 /* DSP_IRQ0 */ + +/* + * R1800 (0x708) - ADPS1 IRQ1 + */ +#define WM2200_DSP_IRQ3 0x0002 /* DSP_IRQ3 */ +#define WM2200_DSP_IRQ3_MASK 0x0002 /* DSP_IRQ3 */ +#define WM2200_DSP_IRQ3_SHIFT 1 /* DSP_IRQ3 */ +#define WM2200_DSP_IRQ3_WIDTH 1 /* DSP_IRQ3 */ +#define WM2200_DSP_IRQ2 0x0001 /* DSP_IRQ2 */ +#define WM2200_DSP_IRQ2_MASK 0x0001 /* DSP_IRQ2 */ +#define WM2200_DSP_IRQ2_SHIFT 0 /* DSP_IRQ2 */ +#define WM2200_DSP_IRQ2_WIDTH 1 /* DSP_IRQ2 */ + +/* + * R1801 (0x709) - Misc Pad Ctrl 1 + */ +#define WM2200_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */ +#define WM2200_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */ +#define WM2200_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */ +#define WM2200_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ +#define WM2200_MCLK2_PD 0x2000 /* MCLK2_PD */ +#define WM2200_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */ +#define WM2200_MCLK2_PD_SHIFT 13 /* MCLK2_PD */ +#define WM2200_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ +#define WM2200_MCLK1_PD 0x1000 /* MCLK1_PD */ +#define WM2200_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */ +#define WM2200_MCLK1_PD_SHIFT 12 /* MCLK1_PD */ +#define WM2200_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ +#define WM2200_DACLRCLK1_PU 0x0400 /* DACLRCLK1_PU */ +#define WM2200_DACLRCLK1_PU_MASK 0x0400 /* DACLRCLK1_PU */ +#define WM2200_DACLRCLK1_PU_SHIFT 10 /* DACLRCLK1_PU */ +#define WM2200_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ +#define WM2200_DACLRCLK1_PD 0x0200 /* DACLRCLK1_PD */ +#define WM2200_DACLRCLK1_PD_MASK 0x0200 /* DACLRCLK1_PD */ +#define WM2200_DACLRCLK1_PD_SHIFT 9 /* DACLRCLK1_PD */ +#define WM2200_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ +#define WM2200_BCLK1_PU 0x0100 /* BCLK1_PU */ +#define WM2200_BCLK1_PU_MASK 0x0100 /* BCLK1_PU */ +#define WM2200_BCLK1_PU_SHIFT 8 /* BCLK1_PU */ +#define WM2200_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ +#define WM2200_BCLK1_PD 0x0080 /* BCLK1_PD */ +#define WM2200_BCLK1_PD_MASK 0x0080 /* BCLK1_PD */ +#define WM2200_BCLK1_PD_SHIFT 7 /* BCLK1_PD */ +#define WM2200_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ +#define WM2200_DACDAT1_PU 0x0040 /* DACDAT1_PU */ +#define WM2200_DACDAT1_PU_MASK 0x0040 /* DACDAT1_PU */ +#define WM2200_DACDAT1_PU_SHIFT 6 /* DACDAT1_PU */ +#define WM2200_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ +#define WM2200_DACDAT1_PD 0x0020 /* DACDAT1_PD */ +#define WM2200_DACDAT1_PD_MASK 0x0020 /* DACDAT1_PD */ +#define WM2200_DACDAT1_PD_SHIFT 5 /* DACDAT1_PD */ +#define WM2200_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ +#define WM2200_DMICDAT3_PD 0x0010 /* DMICDAT3_PD */ +#define WM2200_DMICDAT3_PD_MASK 0x0010 /* DMICDAT3_PD */ +#define WM2200_DMICDAT3_PD_SHIFT 4 /* DMICDAT3_PD */ +#define WM2200_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */ +#define WM2200_DMICDAT2_PD 0x0008 /* DMICDAT2_PD */ +#define WM2200_DMICDAT2_PD_MASK 0x0008 /* DMICDAT2_PD */ +#define WM2200_DMICDAT2_PD_SHIFT 3 /* DMICDAT2_PD */ +#define WM2200_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ +#define WM2200_DMICDAT1_PD 0x0004 /* DMICDAT1_PD */ +#define WM2200_DMICDAT1_PD_MASK 0x0004 /* DMICDAT1_PD */ +#define WM2200_DMICDAT1_PD_SHIFT 2 /* DMICDAT1_PD */ +#define WM2200_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ +#define WM2200_RSTB_PU 0x0002 /* RSTB_PU */ +#define WM2200_RSTB_PU_MASK 0x0002 /* RSTB_PU */ +#define WM2200_RSTB_PU_SHIFT 1 /* RSTB_PU */ +#define WM2200_RSTB_PU_WIDTH 1 /* RSTB_PU */ +#define WM2200_ADDR_PD 0x0001 /* ADDR_PD */ +#define WM2200_ADDR_PD_MASK 0x0001 /* ADDR_PD */ +#define WM2200_ADDR_PD_SHIFT 0 /* ADDR_PD */ +#define WM2200_ADDR_PD_WIDTH 1 /* ADDR_PD */ + +/* + * R2048 (0x800) - Interrupt Status 1 + */ +#define WM2200_DSP_IRQ0_EINT 0x0080 /* DSP_IRQ0_EINT */ +#define WM2200_DSP_IRQ0_EINT_MASK 0x0080 /* DSP_IRQ0_EINT */ +#define WM2200_DSP_IRQ0_EINT_SHIFT 7 /* DSP_IRQ0_EINT */ +#define WM2200_DSP_IRQ0_EINT_WIDTH 1 /* DSP_IRQ0_EINT */ +#define WM2200_DSP_IRQ1_EINT 0x0040 /* DSP_IRQ1_EINT */ +#define WM2200_DSP_IRQ1_EINT_MASK 0x0040 /* DSP_IRQ1_EINT */ +#define WM2200_DSP_IRQ1_EINT_SHIFT 6 /* DSP_IRQ1_EINT */ +#define WM2200_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */ +#define WM2200_DSP_IRQ2_EINT 0x0020 /* DSP_IRQ2_EINT */ +#define WM2200_DSP_IRQ2_EINT_MASK 0x0020 /* DSP_IRQ2_EINT */ +#define WM2200_DSP_IRQ2_EINT_SHIFT 5 /* DSP_IRQ2_EINT */ +#define WM2200_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */ +#define WM2200_DSP_IRQ3_EINT 0x0010 /* DSP_IRQ3_EINT */ +#define WM2200_DSP_IRQ3_EINT_MASK 0x0010 /* DSP_IRQ3_EINT */ +#define WM2200_DSP_IRQ3_EINT_SHIFT 4 /* DSP_IRQ3_EINT */ +#define WM2200_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */ +#define WM2200_GP4_EINT 0x0008 /* GP4_EINT */ +#define WM2200_GP4_EINT_MASK 0x0008 /* GP4_EINT */ +#define WM2200_GP4_EINT_SHIFT 3 /* GP4_EINT */ +#define WM2200_GP4_EINT_WIDTH 1 /* GP4_EINT */ +#define WM2200_GP3_EINT 0x0004 /* GP3_EINT */ +#define WM2200_GP3_EINT_MASK 0x0004 /* GP3_EINT */ +#define WM2200_GP3_EINT_SHIFT 2 /* GP3_EINT */ +#define WM2200_GP3_EINT_WIDTH 1 /* GP3_EINT */ +#define WM2200_GP2_EINT 0x0002 /* GP2_EINT */ +#define WM2200_GP2_EINT_MASK 0x0002 /* GP2_EINT */ +#define WM2200_GP2_EINT_SHIFT 1 /* GP2_EINT */ +#define WM2200_GP2_EINT_WIDTH 1 /* GP2_EINT */ +#define WM2200_GP1_EINT 0x0001 /* GP1_EINT */ +#define WM2200_GP1_EINT_MASK 0x0001 /* GP1_EINT */ +#define WM2200_GP1_EINT_SHIFT 0 /* GP1_EINT */ +#define WM2200_GP1_EINT_WIDTH 1 /* GP1_EINT */ + +/* + * R2049 (0x801) - Interrupt Status 1 Mask + */ +#define WM2200_IM_DSP_IRQ0_EINT 0x0080 /* IM_DSP_IRQ0_EINT */ +#define WM2200_IM_DSP_IRQ0_EINT_MASK 0x0080 /* IM_DSP_IRQ0_EINT */ +#define WM2200_IM_DSP_IRQ0_EINT_SHIFT 7 /* IM_DSP_IRQ0_EINT */ +#define WM2200_IM_DSP_IRQ0_EINT_WIDTH 1 /* IM_DSP_IRQ0_EINT */ +#define WM2200_IM_DSP_IRQ1_EINT 0x0040 /* IM_DSP_IRQ1_EINT */ +#define WM2200_IM_DSP_IRQ1_EINT_MASK 0x0040 /* IM_DSP_IRQ1_EINT */ +#define WM2200_IM_DSP_IRQ1_EINT_SHIFT 6 /* IM_DSP_IRQ1_EINT */ +#define WM2200_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */ +#define WM2200_IM_DSP_IRQ2_EINT 0x0020 /* IM_DSP_IRQ2_EINT */ +#define WM2200_IM_DSP_IRQ2_EINT_MASK 0x0020 /* IM_DSP_IRQ2_EINT */ +#define WM2200_IM_DSP_IRQ2_EINT_SHIFT 5 /* IM_DSP_IRQ2_EINT */ +#define WM2200_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */ +#define WM2200_IM_DSP_IRQ3_EINT 0x0010 /* IM_DSP_IRQ3_EINT */ +#define WM2200_IM_DSP_IRQ3_EINT_MASK 0x0010 /* IM_DSP_IRQ3_EINT */ +#define WM2200_IM_DSP_IRQ3_EINT_SHIFT 4 /* IM_DSP_IRQ3_EINT */ +#define WM2200_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */ +#define WM2200_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ +#define WM2200_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ +#define WM2200_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ +#define WM2200_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ +#define WM2200_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ +#define WM2200_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ +#define WM2200_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ +#define WM2200_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ +#define WM2200_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ +#define WM2200_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ +#define WM2200_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ +#define WM2200_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ +#define WM2200_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ +#define WM2200_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ +#define WM2200_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ +#define WM2200_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ + +/* + * R2050 (0x802) - Interrupt Status 2 + */ +#define WM2200_WSEQ_BUSY_EINT 0x0100 /* WSEQ_BUSY_EINT */ +#define WM2200_WSEQ_BUSY_EINT_MASK 0x0100 /* WSEQ_BUSY_EINT */ +#define WM2200_WSEQ_BUSY_EINT_SHIFT 8 /* WSEQ_BUSY_EINT */ +#define WM2200_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */ +#define WM2200_FLL_LOCK_EINT 0x0002 /* FLL_LOCK_EINT */ +#define WM2200_FLL_LOCK_EINT_MASK 0x0002 /* FLL_LOCK_EINT */ +#define WM2200_FLL_LOCK_EINT_SHIFT 1 /* FLL_LOCK_EINT */ +#define WM2200_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */ +#define WM2200_CLKGEN_EINT 0x0001 /* CLKGEN_EINT */ +#define WM2200_CLKGEN_EINT_MASK 0x0001 /* CLKGEN_EINT */ +#define WM2200_CLKGEN_EINT_SHIFT 0 /* CLKGEN_EINT */ +#define WM2200_CLKGEN_EINT_WIDTH 1 /* CLKGEN_EINT */ + +/* + * R2051 (0x803) - Interrupt Raw Status 2 + */ +#define WM2200_WSEQ_BUSY_STS 0x0100 /* WSEQ_BUSY_STS */ +#define WM2200_WSEQ_BUSY_STS_MASK 0x0100 /* WSEQ_BUSY_STS */ +#define WM2200_WSEQ_BUSY_STS_SHIFT 8 /* WSEQ_BUSY_STS */ +#define WM2200_WSEQ_BUSY_STS_WIDTH 1 /* WSEQ_BUSY_STS */ +#define WM2200_FLL_LOCK_STS 0x0002 /* FLL_LOCK_STS */ +#define WM2200_FLL_LOCK_STS_MASK 0x0002 /* FLL_LOCK_STS */ +#define WM2200_FLL_LOCK_STS_SHIFT 1 /* FLL_LOCK_STS */ +#define WM2200_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */ +#define WM2200_CLKGEN_STS 0x0001 /* CLKGEN_STS */ +#define WM2200_CLKGEN_STS_MASK 0x0001 /* CLKGEN_STS */ +#define WM2200_CLKGEN_STS_SHIFT 0 /* CLKGEN_STS */ +#define WM2200_CLKGEN_STS_WIDTH 1 /* CLKGEN_STS */ + +/* + * R2052 (0x804) - Interrupt Status 2 Mask + */ +#define WM2200_IM_WSEQ_BUSY_EINT 0x0100 /* IM_WSEQ_BUSY_EINT */ +#define WM2200_IM_WSEQ_BUSY_EINT_MASK 0x0100 /* IM_WSEQ_BUSY_EINT */ +#define WM2200_IM_WSEQ_BUSY_EINT_SHIFT 8 /* IM_WSEQ_BUSY_EINT */ +#define WM2200_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */ +#define WM2200_IM_FLL_LOCK_EINT 0x0002 /* IM_FLL_LOCK_EINT */ +#define WM2200_IM_FLL_LOCK_EINT_MASK 0x0002 /* IM_FLL_LOCK_EINT */ +#define WM2200_IM_FLL_LOCK_EINT_SHIFT 1 /* IM_FLL_LOCK_EINT */ +#define WM2200_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */ +#define WM2200_IM_CLKGEN_EINT 0x0001 /* IM_CLKGEN_EINT */ +#define WM2200_IM_CLKGEN_EINT_MASK 0x0001 /* IM_CLKGEN_EINT */ +#define WM2200_IM_CLKGEN_EINT_SHIFT 0 /* IM_CLKGEN_EINT */ +#define WM2200_IM_CLKGEN_EINT_WIDTH 1 /* IM_CLKGEN_EINT */ + +/* + * R2056 (0x808) - Interrupt Control + */ +#define WM2200_IM_IRQ 0x0001 /* IM_IRQ */ +#define WM2200_IM_IRQ_MASK 0x0001 /* IM_IRQ */ +#define WM2200_IM_IRQ_SHIFT 0 /* IM_IRQ */ +#define WM2200_IM_IRQ_WIDTH 1 /* IM_IRQ */ + +/* + * R2304 (0x900) - EQL_1 + */ +#define WM2200_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */ +#define WM2200_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */ +#define WM2200_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */ +#define WM2200_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */ +#define WM2200_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */ +#define WM2200_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */ +#define WM2200_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */ +#define WM2200_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */ +#define WM2200_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */ +#define WM2200_EQL_ENA 0x0001 /* EQL_ENA */ +#define WM2200_EQL_ENA_MASK 0x0001 /* EQL_ENA */ +#define WM2200_EQL_ENA_SHIFT 0 /* EQL_ENA */ +#define WM2200_EQL_ENA_WIDTH 1 /* EQL_ENA */ + +/* + * R2305 (0x901) - EQL_2 + */ +#define WM2200_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */ +#define WM2200_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */ +#define WM2200_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */ +#define WM2200_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */ +#define WM2200_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */ +#define WM2200_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */ + +/* + * R2306 (0x902) - EQL_3 + */ +#define WM2200_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */ +#define WM2200_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */ +#define WM2200_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */ + +/* + * R2307 (0x903) - EQL_4 + */ +#define WM2200_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */ +#define WM2200_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */ +#define WM2200_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */ + +/* + * R2308 (0x904) - EQL_5 + */ +#define WM2200_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */ +#define WM2200_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */ +#define WM2200_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */ + +/* + * R2309 (0x905) - EQL_6 + */ +#define WM2200_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */ +#define WM2200_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */ +#define WM2200_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */ + +/* + * R2310 (0x906) - EQL_7 + */ +#define WM2200_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */ +#define WM2200_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */ +#define WM2200_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */ + +/* + * R2311 (0x907) - EQL_8 + */ +#define WM2200_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */ +#define WM2200_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */ +#define WM2200_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */ + +/* + * R2312 (0x908) - EQL_9 + */ +#define WM2200_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */ +#define WM2200_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */ +#define WM2200_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */ + +/* + * R2313 (0x909) - EQL_10 + */ +#define WM2200_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */ +#define WM2200_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */ +#define WM2200_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */ + +/* + * R2314 (0x90A) - EQL_11 + */ +#define WM2200_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */ +#define WM2200_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */ +#define WM2200_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */ + +/* + * R2315 (0x90B) - EQL_12 + */ +#define WM2200_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */ +#define WM2200_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */ +#define WM2200_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */ + +/* + * R2316 (0x90C) - EQL_13 + */ +#define WM2200_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */ +#define WM2200_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */ +#define WM2200_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */ + +/* + * R2317 (0x90D) - EQL_14 + */ +#define WM2200_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */ +#define WM2200_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */ +#define WM2200_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */ + +/* + * R2318 (0x90E) - EQL_15 + */ +#define WM2200_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */ +#define WM2200_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */ +#define WM2200_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */ + +/* + * R2319 (0x90F) - EQL_16 + */ +#define WM2200_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */ +#define WM2200_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */ +#define WM2200_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */ + +/* + * R2320 (0x910) - EQL_17 + */ +#define WM2200_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */ +#define WM2200_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */ +#define WM2200_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */ + +/* + * R2321 (0x911) - EQL_18 + */ +#define WM2200_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */ +#define WM2200_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */ +#define WM2200_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */ + +/* + * R2322 (0x912) - EQL_19 + */ +#define WM2200_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */ +#define WM2200_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */ +#define WM2200_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */ + +/* + * R2323 (0x913) - EQL_20 + */ +#define WM2200_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */ +#define WM2200_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */ +#define WM2200_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */ + +/* + * R2326 (0x916) - EQR_1 + */ +#define WM2200_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */ +#define WM2200_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */ +#define WM2200_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */ +#define WM2200_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */ +#define WM2200_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */ +#define WM2200_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */ +#define WM2200_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */ +#define WM2200_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */ +#define WM2200_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */ +#define WM2200_EQR_ENA 0x0001 /* EQR_ENA */ +#define WM2200_EQR_ENA_MASK 0x0001 /* EQR_ENA */ +#define WM2200_EQR_ENA_SHIFT 0 /* EQR_ENA */ +#define WM2200_EQR_ENA_WIDTH 1 /* EQR_ENA */ + +/* + * R2327 (0x917) - EQR_2 + */ +#define WM2200_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */ +#define WM2200_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */ +#define WM2200_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */ +#define WM2200_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */ +#define WM2200_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */ +#define WM2200_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */ + +/* + * R2328 (0x918) - EQR_3 + */ +#define WM2200_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */ +#define WM2200_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */ +#define WM2200_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */ + +/* + * R2329 (0x919) - EQR_4 + */ +#define WM2200_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */ +#define WM2200_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */ +#define WM2200_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */ + +/* + * R2330 (0x91A) - EQR_5 + */ +#define WM2200_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */ +#define WM2200_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */ +#define WM2200_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */ + +/* + * R2331 (0x91B) - EQR_6 + */ +#define WM2200_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */ +#define WM2200_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */ +#define WM2200_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */ + +/* + * R2332 (0x91C) - EQR_7 + */ +#define WM2200_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */ +#define WM2200_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */ +#define WM2200_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */ + +/* + * R2333 (0x91D) - EQR_8 + */ +#define WM2200_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */ +#define WM2200_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */ +#define WM2200_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */ + +/* + * R2334 (0x91E) - EQR_9 + */ +#define WM2200_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */ +#define WM2200_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */ +#define WM2200_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */ + +/* + * R2335 (0x91F) - EQR_10 + */ +#define WM2200_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */ +#define WM2200_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */ +#define WM2200_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */ + +/* + * R2336 (0x920) - EQR_11 + */ +#define WM2200_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */ +#define WM2200_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */ +#define WM2200_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */ + +/* + * R2337 (0x921) - EQR_12 + */ +#define WM2200_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */ +#define WM2200_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */ +#define WM2200_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */ + +/* + * R2338 (0x922) - EQR_13 + */ +#define WM2200_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */ +#define WM2200_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */ +#define WM2200_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */ + +/* + * R2339 (0x923) - EQR_14 + */ +#define WM2200_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */ +#define WM2200_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */ +#define WM2200_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */ + +/* + * R2340 (0x924) - EQR_15 + */ +#define WM2200_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */ +#define WM2200_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */ +#define WM2200_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */ + +/* + * R2341 (0x925) - EQR_16 + */ +#define WM2200_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */ +#define WM2200_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */ +#define WM2200_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */ + +/* + * R2342 (0x926) - EQR_17 + */ +#define WM2200_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */ +#define WM2200_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */ +#define WM2200_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */ + +/* + * R2343 (0x927) - EQR_18 + */ +#define WM2200_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */ +#define WM2200_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */ +#define WM2200_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */ + +/* + * R2344 (0x928) - EQR_19 + */ +#define WM2200_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */ +#define WM2200_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */ +#define WM2200_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */ + +/* + * R2345 (0x929) - EQR_20 + */ +#define WM2200_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */ +#define WM2200_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */ +#define WM2200_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */ + +/* + * R2366 (0x93E) - HPLPF1_1 + */ +#define WM2200_LHPF1_MODE 0x0002 /* LHPF1_MODE */ +#define WM2200_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */ +#define WM2200_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */ +#define WM2200_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */ +#define WM2200_LHPF1_ENA 0x0001 /* LHPF1_ENA */ +#define WM2200_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */ +#define WM2200_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */ +#define WM2200_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */ + +/* + * R2367 (0x93F) - HPLPF1_2 + */ +#define WM2200_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */ +#define WM2200_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */ +#define WM2200_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */ + +/* + * R2370 (0x942) - HPLPF2_1 + */ +#define WM2200_LHPF2_MODE 0x0002 /* LHPF2_MODE */ +#define WM2200_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */ +#define WM2200_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */ +#define WM2200_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */ +#define WM2200_LHPF2_ENA 0x0001 /* LHPF2_ENA */ +#define WM2200_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */ +#define WM2200_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */ +#define WM2200_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */ + +/* + * R2371 (0x943) - HPLPF2_2 + */ +#define WM2200_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */ +#define WM2200_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */ +#define WM2200_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */ + +/* + * R2560 (0xA00) - DSP1 Control 1 + */ +#define WM2200_DSP1_RW_SEQUENCE_ENA 0x0001 /* DSP1_RW_SEQUENCE_ENA */ +#define WM2200_DSP1_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP1_RW_SEQUENCE_ENA */ +#define WM2200_DSP1_RW_SEQUENCE_ENA_SHIFT 0 /* DSP1_RW_SEQUENCE_ENA */ +#define WM2200_DSP1_RW_SEQUENCE_ENA_WIDTH 1 /* DSP1_RW_SEQUENCE_ENA */ + +/* + * R2562 (0xA02) - DSP1 Control 2 + */ +#define WM2200_DSP1_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_PM - [15:8] */ +#define WM2200_DSP1_PAGE_BASE_PM_0_SHIFT 8 /* DSP1_PAGE_BASE_PM - [15:8] */ +#define WM2200_DSP1_PAGE_BASE_PM_0_WIDTH 8 /* DSP1_PAGE_BASE_PM - [15:8] */ + +/* + * R2563 (0xA03) - DSP1 Control 3 + */ +#define WM2200_DSP1_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_DM - [15:8] */ +#define WM2200_DSP1_PAGE_BASE_DM_0_SHIFT 8 /* DSP1_PAGE_BASE_DM - [15:8] */ +#define WM2200_DSP1_PAGE_BASE_DM_0_WIDTH 8 /* DSP1_PAGE_BASE_DM - [15:8] */ + +/* + * R2564 (0xA04) - DSP1 Control 4 + */ +#define WM2200_DSP1_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_ZM - [15:8] */ +#define WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT 8 /* DSP1_PAGE_BASE_ZM - [15:8] */ +#define WM2200_DSP1_PAGE_BASE_ZM_0_WIDTH 8 /* DSP1_PAGE_BASE_ZM - [15:8] */ + +/* + * R2566 (0xA06) - DSP1 Control 5 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ + +/* + * R2567 (0xA07) - DSP1 Control 6 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ + +/* + * R2568 (0xA08) - DSP1 Control 7 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ + +/* + * R2569 (0xA09) - DSP1 Control 8 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ + +/* + * R2570 (0xA0A) - DSP1 Control 9 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ + +/* + * R2571 (0xA0B) - DSP1 Control 10 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ + +/* + * R2572 (0xA0C) - DSP1 Control 11 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ + +/* + * R2573 (0xA0D) - DSP1 Control 12 + */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ + +/* + * R2575 (0xA0F) - DSP1 Control 13 + */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ + +/* + * R2576 (0xA10) - DSP1 Control 14 + */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ + +/* + * R2577 (0xA11) - DSP1 Control 15 + */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ + +/* + * R2578 (0xA12) - DSP1 Control 16 + */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ + +/* + * R2579 (0xA13) - DSP1 Control 17 + */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ + +/* + * R2580 (0xA14) - DSP1 Control 18 + */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ + +/* + * R2582 (0xA16) - DSP1 Control 19 + */ +#define WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define WM2200_DSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define WM2200_DSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ + +/* + * R2583 (0xA17) - DSP1 Control 20 + */ +#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */ +#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */ +#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */ + +/* + * R2584 (0xA18) - DSP1 Control 21 + */ +#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */ +#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */ +#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */ + +/* + * R2586 (0xA1A) - DSP1 Control 22 + */ +#define WM2200_DSP1_DM_SIZE_MASK 0xFFFF /* DSP1_DM_SIZE - [15:0] */ +#define WM2200_DSP1_DM_SIZE_SHIFT 0 /* DSP1_DM_SIZE - [15:0] */ +#define WM2200_DSP1_DM_SIZE_WIDTH 16 /* DSP1_DM_SIZE - [15:0] */ + +/* + * R2587 (0xA1B) - DSP1 Control 23 + */ +#define WM2200_DSP1_PM_SIZE_MASK 0xFFFF /* DSP1_PM_SIZE - [15:0] */ +#define WM2200_DSP1_PM_SIZE_SHIFT 0 /* DSP1_PM_SIZE - [15:0] */ +#define WM2200_DSP1_PM_SIZE_WIDTH 16 /* DSP1_PM_SIZE - [15:0] */ + +/* + * R2588 (0xA1C) - DSP1 Control 24 + */ +#define WM2200_DSP1_ZM_SIZE_MASK 0xFFFF /* DSP1_ZM_SIZE - [15:0] */ +#define WM2200_DSP1_ZM_SIZE_SHIFT 0 /* DSP1_ZM_SIZE - [15:0] */ +#define WM2200_DSP1_ZM_SIZE_WIDTH 16 /* DSP1_ZM_SIZE - [15:0] */ + +/* + * R2590 (0xA1E) - DSP1 Control 25 + */ +#define WM2200_DSP1_PING_FULL 0x8000 /* DSP1_PING_FULL */ +#define WM2200_DSP1_PING_FULL_MASK 0x8000 /* DSP1_PING_FULL */ +#define WM2200_DSP1_PING_FULL_SHIFT 15 /* DSP1_PING_FULL */ +#define WM2200_DSP1_PING_FULL_WIDTH 1 /* DSP1_PING_FULL */ +#define WM2200_DSP1_PONG_FULL 0x4000 /* DSP1_PONG_FULL */ +#define WM2200_DSP1_PONG_FULL_MASK 0x4000 /* DSP1_PONG_FULL */ +#define WM2200_DSP1_PONG_FULL_SHIFT 14 /* DSP1_PONG_FULL */ +#define WM2200_DSP1_PONG_FULL_WIDTH 1 /* DSP1_PONG_FULL */ +#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */ +#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */ +#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */ + +/* + * R2592 (0xA20) - DSP1 Control 26 + */ +#define WM2200_DSP1_SCRATCH_0_MASK 0xFFFF /* DSP1_SCRATCH_0 - [15:0] */ +#define WM2200_DSP1_SCRATCH_0_SHIFT 0 /* DSP1_SCRATCH_0 - [15:0] */ +#define WM2200_DSP1_SCRATCH_0_WIDTH 16 /* DSP1_SCRATCH_0 - [15:0] */ + +/* + * R2593 (0xA21) - DSP1 Control 27 + */ +#define WM2200_DSP1_SCRATCH_1_MASK 0xFFFF /* DSP1_SCRATCH_1 - [15:0] */ +#define WM2200_DSP1_SCRATCH_1_SHIFT 0 /* DSP1_SCRATCH_1 - [15:0] */ +#define WM2200_DSP1_SCRATCH_1_WIDTH 16 /* DSP1_SCRATCH_1 - [15:0] */ + +/* + * R2594 (0xA22) - DSP1 Control 28 + */ +#define WM2200_DSP1_SCRATCH_2_MASK 0xFFFF /* DSP1_SCRATCH_2 - [15:0] */ +#define WM2200_DSP1_SCRATCH_2_SHIFT 0 /* DSP1_SCRATCH_2 - [15:0] */ +#define WM2200_DSP1_SCRATCH_2_WIDTH 16 /* DSP1_SCRATCH_2 - [15:0] */ + +/* + * R2595 (0xA23) - DSP1 Control 29 + */ +#define WM2200_DSP1_SCRATCH_3_MASK 0xFFFF /* DSP1_SCRATCH_3 - [15:0] */ +#define WM2200_DSP1_SCRATCH_3_SHIFT 0 /* DSP1_SCRATCH_3 - [15:0] */ +#define WM2200_DSP1_SCRATCH_3_WIDTH 16 /* DSP1_SCRATCH_3 - [15:0] */ + +/* + * R2596 (0xA24) - DSP1 Control 30 + */ +#define WM2200_DSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ +#define WM2200_DSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ +#define WM2200_DSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ +#define WM2200_DSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ +#define WM2200_DSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define WM2200_DSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define WM2200_DSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define WM2200_DSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define WM2200_DSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define WM2200_DSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define WM2200_DSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define WM2200_DSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define WM2200_DSP1_START 0x0001 /* DSP1_START */ +#define WM2200_DSP1_START_MASK 0x0001 /* DSP1_START */ +#define WM2200_DSP1_START_SHIFT 0 /* DSP1_START */ +#define WM2200_DSP1_START_WIDTH 1 /* DSP1_START */ + +/* + * R2598 (0xA26) - DSP1 Control 31 + */ +#define WM2200_DSP1_CLK_RATE_MASK 0x0018 /* DSP1_CLK_RATE - [4:3] */ +#define WM2200_DSP1_CLK_RATE_SHIFT 3 /* DSP1_CLK_RATE - [4:3] */ +#define WM2200_DSP1_CLK_RATE_WIDTH 2 /* DSP1_CLK_RATE - [4:3] */ +#define WM2200_DSP1_CLK_AVAIL 0x0004 /* DSP1_CLK_AVAIL */ +#define WM2200_DSP1_CLK_AVAIL_MASK 0x0004 /* DSP1_CLK_AVAIL */ +#define WM2200_DSP1_CLK_AVAIL_SHIFT 2 /* DSP1_CLK_AVAIL */ +#define WM2200_DSP1_CLK_AVAIL_WIDTH 1 /* DSP1_CLK_AVAIL */ +#define WM2200_DSP1_CLK_REQ_MASK 0x0003 /* DSP1_CLK_REQ - [1:0] */ +#define WM2200_DSP1_CLK_REQ_SHIFT 0 /* DSP1_CLK_REQ - [1:0] */ +#define WM2200_DSP1_CLK_REQ_WIDTH 2 /* DSP1_CLK_REQ - [1:0] */ + +/* + * R2816 (0xB00) - DSP2 Control 1 + */ +#define WM2200_DSP2_RW_SEQUENCE_ENA 0x0001 /* DSP2_RW_SEQUENCE_ENA */ +#define WM2200_DSP2_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP2_RW_SEQUENCE_ENA */ +#define WM2200_DSP2_RW_SEQUENCE_ENA_SHIFT 0 /* DSP2_RW_SEQUENCE_ENA */ +#define WM2200_DSP2_RW_SEQUENCE_ENA_WIDTH 1 /* DSP2_RW_SEQUENCE_ENA */ + +/* + * R2818 (0xB02) - DSP2 Control 2 + */ +#define WM2200_DSP2_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_PM - [15:8] */ +#define WM2200_DSP2_PAGE_BASE_PM_0_SHIFT 8 /* DSP2_PAGE_BASE_PM - [15:8] */ +#define WM2200_DSP2_PAGE_BASE_PM_0_WIDTH 8 /* DSP2_PAGE_BASE_PM - [15:8] */ + +/* + * R2819 (0xB03) - DSP2 Control 3 + */ +#define WM2200_DSP2_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_DM - [15:8] */ +#define WM2200_DSP2_PAGE_BASE_DM_0_SHIFT 8 /* DSP2_PAGE_BASE_DM - [15:8] */ +#define WM2200_DSP2_PAGE_BASE_DM_0_WIDTH 8 /* DSP2_PAGE_BASE_DM - [15:8] */ + +/* + * R2820 (0xB04) - DSP2 Control 4 + */ +#define WM2200_DSP2_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_ZM - [15:8] */ +#define WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT 8 /* DSP2_PAGE_BASE_ZM - [15:8] */ +#define WM2200_DSP2_PAGE_BASE_ZM_0_WIDTH 8 /* DSP2_PAGE_BASE_ZM - [15:8] */ + +/* + * R2822 (0xB06) - DSP2 Control 5 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ + +/* + * R2823 (0xB07) - DSP2 Control 6 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ + +/* + * R2824 (0xB08) - DSP2 Control 7 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ + +/* + * R2825 (0xB09) - DSP2 Control 8 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ + +/* + * R2826 (0xB0A) - DSP2 Control 9 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ + +/* + * R2827 (0xB0B) - DSP2 Control 10 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ + +/* + * R2828 (0xB0C) - DSP2 Control 11 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ + +/* + * R2829 (0xB0D) - DSP2 Control 12 + */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ + +/* + * R2831 (0xB0F) - DSP2 Control 13 + */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ + +/* + * R2832 (0xB10) - DSP2 Control 14 + */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ + +/* + * R2833 (0xB11) - DSP2 Control 15 + */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ + +/* + * R2834 (0xB12) - DSP2 Control 16 + */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ + +/* + * R2835 (0xB13) - DSP2 Control 17 + */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ + +/* + * R2836 (0xB14) - DSP2 Control 18 + */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ +#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ + +/* + * R2838 (0xB16) - DSP2 Control 19 + */ +#define WM2200_DSP2_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */ +#define WM2200_DSP2_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */ +#define WM2200_DSP2_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */ + +/* + * R2839 (0xB17) - DSP2 Control 20 + */ +#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */ +#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */ +#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */ + +/* + * R2840 (0xB18) - DSP2 Control 21 + */ +#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */ +#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */ +#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */ + +/* + * R2842 (0xB1A) - DSP2 Control 22 + */ +#define WM2200_DSP2_DM_SIZE_MASK 0xFFFF /* DSP2_DM_SIZE - [15:0] */ +#define WM2200_DSP2_DM_SIZE_SHIFT 0 /* DSP2_DM_SIZE - [15:0] */ +#define WM2200_DSP2_DM_SIZE_WIDTH 16 /* DSP2_DM_SIZE - [15:0] */ + +/* + * R2843 (0xB1B) - DSP2 Control 23 + */ +#define WM2200_DSP2_PM_SIZE_MASK 0xFFFF /* DSP2_PM_SIZE - [15:0] */ +#define WM2200_DSP2_PM_SIZE_SHIFT 0 /* DSP2_PM_SIZE - [15:0] */ +#define WM2200_DSP2_PM_SIZE_WIDTH 16 /* DSP2_PM_SIZE - [15:0] */ + +/* + * R2844 (0xB1C) - DSP2 Control 24 + */ +#define WM2200_DSP2_ZM_SIZE_MASK 0xFFFF /* DSP2_ZM_SIZE - [15:0] */ +#define WM2200_DSP2_ZM_SIZE_SHIFT 0 /* DSP2_ZM_SIZE - [15:0] */ +#define WM2200_DSP2_ZM_SIZE_WIDTH 16 /* DSP2_ZM_SIZE - [15:0] */ + +/* + * R2846 (0xB1E) - DSP2 Control 25 + */ +#define WM2200_DSP2_PING_FULL 0x8000 /* DSP2_PING_FULL */ +#define WM2200_DSP2_PING_FULL_MASK 0x8000 /* DSP2_PING_FULL */ +#define WM2200_DSP2_PING_FULL_SHIFT 15 /* DSP2_PING_FULL */ +#define WM2200_DSP2_PING_FULL_WIDTH 1 /* DSP2_PING_FULL */ +#define WM2200_DSP2_PONG_FULL 0x4000 /* DSP2_PONG_FULL */ +#define WM2200_DSP2_PONG_FULL_MASK 0x4000 /* DSP2_PONG_FULL */ +#define WM2200_DSP2_PONG_FULL_SHIFT 14 /* DSP2_PONG_FULL */ +#define WM2200_DSP2_PONG_FULL_WIDTH 1 /* DSP2_PONG_FULL */ +#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */ +#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */ +#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */ + +/* + * R2848 (0xB20) - DSP2 Control 26 + */ +#define WM2200_DSP2_SCRATCH_0_MASK 0xFFFF /* DSP2_SCRATCH_0 - [15:0] */ +#define WM2200_DSP2_SCRATCH_0_SHIFT 0 /* DSP2_SCRATCH_0 - [15:0] */ +#define WM2200_DSP2_SCRATCH_0_WIDTH 16 /* DSP2_SCRATCH_0 - [15:0] */ + +/* + * R2849 (0xB21) - DSP2 Control 27 + */ +#define WM2200_DSP2_SCRATCH_1_MASK 0xFFFF /* DSP2_SCRATCH_1 - [15:0] */ +#define WM2200_DSP2_SCRATCH_1_SHIFT 0 /* DSP2_SCRATCH_1 - [15:0] */ +#define WM2200_DSP2_SCRATCH_1_WIDTH 16 /* DSP2_SCRATCH_1 - [15:0] */ + +/* + * R2850 (0xB22) - DSP2 Control 28 + */ +#define WM2200_DSP2_SCRATCH_2_MASK 0xFFFF /* DSP2_SCRATCH_2 - [15:0] */ +#define WM2200_DSP2_SCRATCH_2_SHIFT 0 /* DSP2_SCRATCH_2 - [15:0] */ +#define WM2200_DSP2_SCRATCH_2_WIDTH 16 /* DSP2_SCRATCH_2 - [15:0] */ + +/* + * R2851 (0xB23) - DSP2 Control 29 + */ +#define WM2200_DSP2_SCRATCH_3_MASK 0xFFFF /* DSP2_SCRATCH_3 - [15:0] */ +#define WM2200_DSP2_SCRATCH_3_SHIFT 0 /* DSP2_SCRATCH_3 - [15:0] */ +#define WM2200_DSP2_SCRATCH_3_WIDTH 16 /* DSP2_SCRATCH_3 - [15:0] */ + +/* + * R2852 (0xB24) - DSP2 Control 30 + */ +#define WM2200_DSP2_DBG_CLK_ENA 0x0008 /* DSP2_DBG_CLK_ENA */ +#define WM2200_DSP2_DBG_CLK_ENA_MASK 0x0008 /* DSP2_DBG_CLK_ENA */ +#define WM2200_DSP2_DBG_CLK_ENA_SHIFT 3 /* DSP2_DBG_CLK_ENA */ +#define WM2200_DSP2_DBG_CLK_ENA_WIDTH 1 /* DSP2_DBG_CLK_ENA */ +#define WM2200_DSP2_SYS_ENA 0x0004 /* DSP2_SYS_ENA */ +#define WM2200_DSP2_SYS_ENA_MASK 0x0004 /* DSP2_SYS_ENA */ +#define WM2200_DSP2_SYS_ENA_SHIFT 2 /* DSP2_SYS_ENA */ +#define WM2200_DSP2_SYS_ENA_WIDTH 1 /* DSP2_SYS_ENA */ +#define WM2200_DSP2_CORE_ENA 0x0002 /* DSP2_CORE_ENA */ +#define WM2200_DSP2_CORE_ENA_MASK 0x0002 /* DSP2_CORE_ENA */ +#define WM2200_DSP2_CORE_ENA_SHIFT 1 /* DSP2_CORE_ENA */ +#define WM2200_DSP2_CORE_ENA_WIDTH 1 /* DSP2_CORE_ENA */ +#define WM2200_DSP2_START 0x0001 /* DSP2_START */ +#define WM2200_DSP2_START_MASK 0x0001 /* DSP2_START */ +#define WM2200_DSP2_START_SHIFT 0 /* DSP2_START */ +#define WM2200_DSP2_START_WIDTH 1 /* DSP2_START */ + +/* + * R2854 (0xB26) - DSP2 Control 31 + */ +#define WM2200_DSP2_CLK_RATE_MASK 0x0018 /* DSP2_CLK_RATE - [4:3] */ +#define WM2200_DSP2_CLK_RATE_SHIFT 3 /* DSP2_CLK_RATE - [4:3] */ +#define WM2200_DSP2_CLK_RATE_WIDTH 2 /* DSP2_CLK_RATE - [4:3] */ +#define WM2200_DSP2_CLK_AVAIL 0x0004 /* DSP2_CLK_AVAIL */ +#define WM2200_DSP2_CLK_AVAIL_MASK 0x0004 /* DSP2_CLK_AVAIL */ +#define WM2200_DSP2_CLK_AVAIL_SHIFT 2 /* DSP2_CLK_AVAIL */ +#define WM2200_DSP2_CLK_AVAIL_WIDTH 1 /* DSP2_CLK_AVAIL */ +#define WM2200_DSP2_CLK_REQ_MASK 0x0003 /* DSP2_CLK_REQ - [1:0] */ +#define WM2200_DSP2_CLK_REQ_SHIFT 0 /* DSP2_CLK_REQ - [1:0] */ +#define WM2200_DSP2_CLK_REQ_WIDTH 2 /* DSP2_CLK_REQ - [1:0] */ + +#endif diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 714256e609c1..b9c185ce64e4 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -18,6 +18,7 @@ #include <linux/gcd.h> #include <linux/gpio.h> #include <linux/i2c.h> +#include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> #include <linux/regulator/fixed.h> #include <linux/slab.h> @@ -55,9 +56,6 @@ struct wm5100_priv { struct snd_soc_codec *codec; struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; - struct regulator *cpvdd; - struct regulator *dbvdd2; - struct regulator *dbvdd3; int rev; @@ -74,6 +72,7 @@ struct wm5100_priv { bool jack_detecting; bool jack_mic; int jack_mode; + int jack_flips; struct wm5100_fll fll[2]; @@ -710,6 +709,8 @@ WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE), WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE), WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE), +SND_SOC_BYTES_MASK("DRC", WM5100_DRC1_CTRL1, 5, + WM5100_DRCL_ENA | WM5100_DRCR_ENA), WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE), WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE), @@ -777,85 +778,6 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w, return 0; } -static int wm5100_cp_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - int ret; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = regulator_enable(wm5100->cpvdd); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable CPVDD: %d\n", - ret); - return ret; - } - return ret; - - case SND_SOC_DAPM_POST_PMD: - ret = regulator_disable_deferred(wm5100->cpvdd, 20); - if (ret != 0) { - dev_err(codec->dev, "Failed to disable CPVDD: %d\n", - ret); - return ret; - } - return ret; - - default: - BUG(); - return 0; - } -} - -static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - struct regulator *regulator; - int ret; - - switch (w->shift) { - case 2: - regulator = wm5100->dbvdd2; - break; - case 3: - regulator = wm5100->dbvdd3; - break; - default: - BUG(); - return 0; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = regulator_enable(regulator); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n", - w->shift, ret); - return ret; - } - return ret; - - case SND_SOC_DAPM_POST_PMD: - ret = regulator_disable(regulator); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n", - w->shift, ret); - return ret; - } - return ret; - - default: - BUG(); - return 0; - } -} - static void wm5100_log_status3(struct wm5100_priv *wm5100, int val) { if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) @@ -926,18 +848,16 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0, SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), +SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), +SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), + SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, - wm5100_cp_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + NULL, 0), SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1, - WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + WM5100_CP2_BYPASS_SHIFT, 1, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT, 0, NULL, 0), @@ -1148,6 +1068,9 @@ SND_SOC_DAPM_POST("Post", wm5100_post_ev), }; static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { + { "CP1", NULL, "CPVDD" }, + { "CP2 Active", NULL, "CPVDD" }, + { "IN1L", NULL, "SYSCLK" }, { "IN1R", NULL, "SYSCLK" }, { "IN2L", NULL, "SYSCLK" }, @@ -1342,54 +1265,6 @@ static const __devinitdata struct reg_default wm5100_reva_patches[] = { { WM5100_AUDIO_IF_3_19, 1 }, }; -static int wm5100_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - int ret; - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); - if (ret != 0) { - dev_err(codec->dev, - "Failed to enable supplies: %d\n", - ret); - return ret; - } - - if (wm5100->pdata.ldo_ena) { - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, - 1); - msleep(2); - } - - regcache_cache_only(wm5100->regmap, false); - regcache_sync(wm5100->regmap); - } - break; - - case SND_SOC_BIAS_OFF: - regcache_cache_only(wm5100->regmap, true); - if (wm5100->pdata.ldo_ena) - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); - regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); - break; - } - codec->dapm.bias_level = level; - - return 0; -} - static int wm5100_dai_to_base(struct snd_soc_dai *dai) { switch (dai->id) { @@ -1917,6 +1792,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (!Fout) { dev_dbg(codec->dev, "FLL%d disabled", fll_id); + if (fll->fout) + pm_runtime_put(codec->dev); fll->fout = 0; snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); return 0; @@ -1961,6 +1838,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, /* Clear any pending completions */ try_wait_for_completion(&fll->lock); + pm_runtime_get_sync(codec->dev); + snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA); if (i2c->irq) @@ -1995,6 +1874,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, } if (i == timeout) { dev_err(codec->dev, "FLL%d lock timed out\n", fll_id); + pm_runtime_put(codec->dev); return -ETIMEDOUT; } @@ -2119,6 +1999,19 @@ static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode) wm5100->jack_mode); } +static void wm5100_report_headphone(struct wm5100_priv *wm5100) +{ + dev_dbg(wm5100->dev, "Headphone detected\n"); + wm5100->jack_detecting = false; + snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, + SND_JACK_HEADPHONE); + + /* Increase the detection rate a bit for responsiveness. */ + regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, + WM5100_ACCDET_RATE_MASK, + 7 << WM5100_ACCDET_RATE_SHIFT); +} + static void wm5100_micd_irq(struct wm5100_priv *wm5100) { unsigned int val; @@ -2143,6 +2036,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) dev_dbg(wm5100->dev, "Jack removal detected\n"); wm5100->jack_mic = false; wm5100->jack_detecting = true; + wm5100->jack_flips = 0; snd_soc_jack_report(wm5100->jack, 0, SND_JACK_LINEOUT | SND_JACK_HEADSET | SND_JACK_BTN_0); @@ -2161,6 +2055,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) if (wm5100->jack_detecting) { dev_dbg(wm5100->dev, "Microphone detected\n"); wm5100->jack_mic = true; + wm5100->jack_detecting = false; snd_soc_jack_report(wm5100->jack, SND_JACK_HEADSET, SND_JACK_HEADSET | SND_JACK_BTN_0); @@ -2181,10 +2076,16 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) /* If we detected a lower impedence during initial startup * then we probably have the wrong polarity, flip it. Don't * do this for the lowest impedences to speed up detection of - * plain headphones. + * plain headphones and give up if neither polarity looks + * sensible. */ if (wm5100->jack_detecting && (val & 0x3f8)) { - wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); + wm5100->jack_flips++; + + if (wm5100->jack_flips > 1) + wm5100_report_headphone(wm5100); + else + wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); return; } @@ -2198,16 +2099,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, SND_JACK_BTN_0); } else if (wm5100->jack_detecting) { - dev_dbg(wm5100->dev, "Headphone detected\n"); - snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, - SND_JACK_HEADPHONE); - - /* Increase the detection rate a bit for - * responsiveness. - */ - regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, - WM5100_ACCDET_RATE_MASK, - 7 << WM5100_ACCDET_RATE_SHIFT); + wm5100_report_headphone(wm5100); } } } @@ -2219,6 +2111,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) if (jack) { wm5100->jack = jack; wm5100->jack_detecting = true; + wm5100->jack_flips = 0; wm5100_set_detect_mode(wm5100, 0); @@ -2458,9 +2351,6 @@ static int wm5100_probe(struct snd_soc_codec *codec) return ret; } - regcache_cache_only(wm5100->regmap, true); - - for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, WM5100_OUT_VU); @@ -2486,14 +2376,6 @@ static int wm5100_probe(struct snd_soc_codec *codec) } } - /* We'll get woken up again when the system has something useful - * for us to do. - */ - if (wm5100->pdata.ldo_ena) - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); - regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); - return 0; err_gpio: @@ -2525,7 +2407,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { .set_sysclk = wm5100_set_sysclk, .set_pll = wm5100_set_fll, - .set_bias_level = wm5100_set_bias_level, .idle_bias_off = 1, .reg_cache_size = WM5100_MAX_REGISTER, .volatile_register = wm5100_soc_volatile, @@ -2551,6 +2432,13 @@ static const struct regmap_config wm5100_regmap = { .cache_type = REGCACHE_RBTREE, }; +static const unsigned int wm5100_mic_ctrl_reg[] = { + WM5100_IN1L_CONTROL, + WM5100_IN2L_CONTROL, + WM5100_IN3L_CONTROL, + WM5100_IN4L_CONTROL, +}; + static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2585,41 +2473,21 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; - ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); + ret = devm_regulator_bulk_get(&i2c->dev, + ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret); goto err_regmap; } - wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD"); - if (IS_ERR(wm5100->cpvdd)) { - ret = PTR_ERR(wm5100->cpvdd); - dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); - goto err_core; - } - - wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2"); - if (IS_ERR(wm5100->dbvdd2)) { - ret = PTR_ERR(wm5100->dbvdd2); - dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); - goto err_cpvdd; - } - - wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3"); - if (IS_ERR(wm5100->dbvdd3)) { - ret = PTR_ERR(wm5100->dbvdd3); - dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); - goto err_dbvdd2; - } - ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), wm5100->core_supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", ret); - goto err_dbvdd3; + goto err_regmap; } if (wm5100->pdata.ldo_ena) { @@ -2701,7 +2569,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, } for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { - regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL, + regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i], WM5100_IN1_MODE_MASK | WM5100_IN1_DMIC_SUP_MASK, (wm5100->pdata.in_mode[i] << @@ -2762,6 +2630,10 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, } } + pm_runtime_set_active(&i2c->dev); + pm_runtime_enable(&i2c->dev); + pm_request_idle(&i2c->dev); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm5100, wm5100_dai, ARRAY_SIZE(wm5100_dai)); @@ -2788,15 +2660,6 @@ err_ldo: err_enable: regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), wm5100->core_supplies); -err_dbvdd3: - regulator_put(wm5100->dbvdd3); -err_dbvdd2: - regulator_put(wm5100->dbvdd2); -err_cpvdd: - regulator_put(wm5100->cpvdd); -err_core: - regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); err_regmap: regmap_exit(wm5100->regmap); err: @@ -2819,16 +2682,56 @@ static __devexit int wm5100_i2c_remove(struct i2c_client *i2c) gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); gpio_free(wm5100->pdata.ldo_ena); } - regulator_put(wm5100->dbvdd3); - regulator_put(wm5100->dbvdd2); - regulator_put(wm5100->cpvdd); - regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); regmap_exit(wm5100->regmap); return 0; } +#ifdef CONFIG_PM_RUNTIME +static int wm5100_runtime_suspend(struct device *dev) +{ + struct wm5100_priv *wm5100 = dev_get_drvdata(dev); + + regcache_cache_only(wm5100->regmap, true); + regcache_mark_dirty(wm5100->regmap); + if (wm5100->pdata.ldo_ena) + gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); + regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); + + return 0; +} + +static int wm5100_runtime_resume(struct device *dev) +{ + struct wm5100_priv *wm5100 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); + if (ret != 0) { + dev_err(dev, "Failed to enable supplies: %d\n", + ret); + return ret; + } + + if (wm5100->pdata.ldo_ena) { + gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1); + msleep(2); + } + + regcache_cache_only(wm5100->regmap, false); + regcache_sync(wm5100->regmap); + + return 0; +} +#endif + +static struct dev_pm_ops wm5100_pm = { + SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume, + NULL) +}; + static const struct i2c_device_id wm5100_i2c_id[] = { { "wm5100", 0 }, { } @@ -2839,6 +2742,7 @@ static struct i2c_driver wm5100_i2c_driver = { .driver = { .name = "wm5100", .owner = THIS_MODULE, + .pm = &wm5100_pm, }, .probe = wm5100_i2c_probe, .remove = __devexit_p(wm5100_i2c_remove), diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index ff95e62c56b9..4fe9d191e277 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -599,7 +599,7 @@ static int wm8737_probe(struct snd_soc_codec *codec) /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); - snd_soc_add_controls(codec, wm8737_snd_controls, + snd_soc_add_codec_controls(codec, wm8737_snd_controls, ARRAY_SIZE(wm8737_snd_controls)); wm8737_add_widgets(codec); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 21ed75de41f3..e27e7b62b365 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1557,7 +1557,8 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi) struct wm8753_priv *wm8753; int ret; - wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); + wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv), + GFP_KERNEL); if (wm8753 == NULL) return -ENOMEM; @@ -1577,10 +1578,12 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi) dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); goto err_regmap; } + + return 0; + err_regmap: regmap_exit(wm8753->regmap); err: - kfree(wm8753); return ret; } @@ -1612,7 +1615,8 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, struct wm8753_priv *wm8753; int ret; - wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); + wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv), + GFP_KERNEL); if (wm8753 == NULL) return -ENOMEM; @@ -1632,10 +1636,12 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); goto err_regmap; } + + return 0; + err_regmap: regmap_exit(wm8753->regmap); err: - kfree(wm8753); return ret; } @@ -1645,7 +1651,6 @@ static __devexit int wm8753_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); regmap_exit(wm8753->regmap); - kfree(wm8753); return 0; } diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 19374a9e5ba6..a5127b4ff9e1 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -580,8 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec) wm8770 = snd_soc_codec_get_drvdata(codec); wm8770->codec = codec; - codec->dapm.idle_bias_off = 1; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); @@ -643,7 +641,7 @@ static int wm8770_probe(struct snd_soc_codec *codec) /* mute all DACs */ snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); - snd_soc_add_controls(codec, wm8770_snd_controls, + snd_soc_add_codec_controls(codec, wm8770_snd_controls, ARRAY_SIZE(wm8770_snd_controls)); snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, ARRAY_SIZE(wm8770_dapm_widgets)); @@ -679,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { .suspend = wm8770_suspend, .resume = wm8770_resume, .set_bias_level = wm8770_set_bias_level, + .idle_bias_off = true, .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), .reg_word_size = sizeof (u16), .reg_cache_default = wm8770_reg_defs diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 33e97d1d8f46..a19db5a0a17a 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -30,6 +30,11 @@ #include "wm8776.h" +enum wm8776_chip_type { + WM8775 = 1, + WM8776, +}; + /* codec private data */ struct wm8776_priv { enum snd_soc_control_type control_type; @@ -512,7 +517,8 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client) } static const struct i2c_device_id wm8776_i2c_id[] = { - { "wm8776", 0 }, + { "wm8775", WM8775 }, + { "wm8776", WM8776 }, { } }; MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id); diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 8abe3757a979..7ee8dcf1fe32 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -549,7 +549,6 @@ static int wm8804_probe(struct snd_soc_codec *codec) wm8804 = snd_soc_codec_get_drvdata(codec); - codec->dapm.idle_bias_off = 1; codec->control_data = wm8804->regmap; ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); @@ -678,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { .suspend = wm8804_suspend, .resume = wm8804_resume, .set_bias_level = wm8804_set_bias_level, + .idle_bias_off = true, .controls = wm8804_snd_controls, .num_controls = ARRAY_SIZE(wm8804_snd_controls), diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 14afc1193343..65d525d74c54 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1176,11 +1176,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) switch (wm8904->devtype) { case WM8904: - snd_soc_add_controls(codec, wm8904_adc_snd_controls, + snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls, ARRAY_SIZE(wm8904_adc_snd_controls)); - snd_soc_add_controls(codec, wm8904_dac_snd_controls, + snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls, ARRAY_SIZE(wm8904_dac_snd_controls)); - snd_soc_add_controls(codec, wm8904_snd_controls, + snd_soc_add_codec_controls(codec, wm8904_snd_controls, ARRAY_SIZE(wm8904_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, @@ -1201,7 +1201,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) break; case WM8912: - snd_soc_add_controls(codec, wm8904_dac_snd_controls, + snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls, ARRAY_SIZE(wm8904_dac_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, @@ -2020,7 +2020,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; - ret = snd_soc_add_controls(codec, &control, 1); + ret = snd_soc_add_codec_controls(codec, &control, 1); if (ret != 0) dev_err(codec->dev, "Failed to add ReTune Mobile control: %d\n", ret); @@ -2033,7 +2033,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) int ret, i; if (!pdata) { - snd_soc_add_controls(codec, wm8904_eq_controls, + snd_soc_add_codec_controls(codec, wm8904_eq_controls, ARRAY_SIZE(wm8904_eq_controls)); return; } @@ -2061,7 +2061,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) wm8904->drc_enum.max = pdata->num_drc_cfgs; wm8904->drc_enum.texts = wm8904->drc_texts; - ret = snd_soc_add_controls(codec, &control, 1); + ret = snd_soc_add_codec_controls(codec, &control, 1); if (ret != 0) dev_err(codec->dev, "Failed to add DRC mode control: %d\n", ret); @@ -2075,7 +2075,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) if (pdata->num_retune_mobile_cfgs) wm8904_handle_retune_mobile_pdata(codec); else - snd_soc_add_controls(codec, wm8904_eq_controls, + snd_soc_add_codec_controls(codec, wm8904_eq_controls, ARRAY_SIZE(wm8904_eq_controls)); } @@ -2088,7 +2088,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) int ret, i; codec->cache_sync = 1; - codec->dapm.idle_bias_off = 1; codec->control_data = wm8904->regmap; switch (wm8904->devtype) { @@ -2237,6 +2236,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { .suspend = wm8904_suspend, .resume = wm8904_resume, .set_bias_level = wm8904_set_bias_level, + .idle_bias_off = true, }; static const struct regmap_config wm8904_regmap = { diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index ae1933ed3e07..d2883affea3b 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -717,7 +717,7 @@ static int wm8940_probe(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_add_controls(codec, wm8940_snd_controls, + ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls, ARRAY_SIZE(wm8940_snd_controls)); if (ret) return ret; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 8d4ea43d40a3..1332692ef81b 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, return 0; if (fw->size < 32) { - dev_err(codec->dev, "%s: firmware too short (%d bytes)\n", + dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n", name, fw->size); goto err; } @@ -920,11 +920,11 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) wm8994->dsp_active = -1; - snd_soc_add_controls(codec, wm8958_mbc_snd_controls, + snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls, ARRAY_SIZE(wm8958_mbc_snd_controls)); - snd_soc_add_controls(codec, wm8958_vss_snd_controls, + snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls, ARRAY_SIZE(wm8958_vss_snd_controls)); - snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls, + snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls, ARRAY_SIZE(wm8958_enh_eq_snd_controls)); @@ -958,7 +958,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) wm8994->mbc_enum.max = pdata->num_mbc_cfgs; wm8994->mbc_enum.texts = wm8994->mbc_texts; - ret = snd_soc_add_controls(wm8994->codec, control, 1); + ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); if (ret != 0) dev_err(wm8994->codec->dev, "Failed to add MBC mode controls: %d\n", ret); @@ -986,7 +986,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) wm8994->vss_enum.max = pdata->num_vss_cfgs; wm8994->vss_enum.texts = wm8994->vss_texts; - ret = snd_soc_add_controls(wm8994->codec, control, 1); + ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); if (ret != 0) dev_err(wm8994->codec->dev, "Failed to add VSS mode controls: %d\n", ret); @@ -1015,7 +1015,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; - ret = snd_soc_add_controls(wm8994->codec, control, 1); + ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); if (ret != 0) dev_err(wm8994->codec->dev, "Failed to add VSS HPFmode controls: %d\n", @@ -1045,7 +1045,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; - ret = snd_soc_add_controls(wm8994->codec, control, 1); + ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); if (ret != 0) dev_err(wm8994->codec->dev, "Failed to add enhanced EQ controls: %d\n", diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index e5caae32e541..840d72086d04 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -940,7 +940,7 @@ static int wm8960_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100); snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100); - snd_soc_add_controls(codec, wm8960_snd_controls, + snd_soc_add_codec_controls(codec, wm8960_snd_controls, ARRAY_SIZE(wm8960_snd_controls)); wm8960_add_widgets(codec); diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 4f20c72a0f1d..05ea7c274093 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -1022,7 +1022,7 @@ static int wm8961_probe(struct snd_soc_codec *codec) wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8961_snd_controls, + snd_soc_add_codec_controls(codec, wm8961_snd_controls, ARRAY_SIZE(wm8961_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, ARRAY_SIZE(wm8961_dapm_widgets)); diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index cc4049e9174b..445d2090661c 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -20,6 +20,7 @@ #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/input.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> @@ -96,7 +97,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \ struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - regcache_cache_only(wm8962->regmap, true); \ + regcache_mark_dirty(wm8962->regmap); \ } \ return 0; \ } @@ -207,8 +208,6 @@ static struct reg_default wm8962_reg[] = { { 126, 0x000D }, /* R126 - Analogue Clocking3 */ { 127, 0x0000 }, /* R127 - PLL Software Reset */ - { 129, 0x0000 }, /* R129 - PLL2 */ - { 131, 0x0000 }, /* R131 - PLL 4 */ { 136, 0x0067 }, /* R136 - PLL 9 */ @@ -1832,65 +1831,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5, 4, 1, 0, inmix_tlv), }; -static int sysclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - unsigned long timeout; - int src; - int fll; - - /* Ignore attempts to run the event during startup */ - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) - return 0; - - src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK; - - switch (src) { - case 0: /* MCLK */ - fll = 0; - break; - case 0x200: /* FLL */ - fll = 1; - break; - default: - dev_err(codec->dev, "Unknown SYSCLK source %x\n", src); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (fll) { - try_wait_for_completion(&wm8962->fll_lock); - - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, - WM8962_FLL_ENA, WM8962_FLL_ENA); - - timeout = msecs_to_jiffies(5); - timeout = wait_for_completion_timeout(&wm8962->fll_lock, - timeout); - - if (wm8962->irq && timeout == 0) - dev_err(codec->dev, - "Timed out starting FLL\n"); - } - break; - - case SND_SOC_DAPM_POST_PMD: - if (fll) - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, - WM8962_FLL_ENA, 0); - break; - - default: - BUG(); - return -EINVAL; - } - - return 0; -} - static int cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2176,8 +2116,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"), SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), -SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), @@ -2291,9 +2230,11 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = { { "STL", "Left", "ADCL" }, { "STL", "Right", "ADCR" }, + { "STL", NULL, "Class G" }, { "STR", "Left", "ADCL" }, { "STR", "Right", "ADCR" }, + { "STR", NULL, "Class G" }, { "DACL", NULL, "SYSCLK" }, { "DACL", NULL, "TOCLK" }, @@ -2405,13 +2346,13 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_add_controls(codec, wm8962_snd_controls, + snd_soc_add_codec_controls(codec, wm8962_snd_controls, ARRAY_SIZE(wm8962_snd_controls)); if (pdata && pdata->spk_mono) - snd_soc_add_controls(codec, wm8962_spk_mono_controls, + snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls, ARRAY_SIZE(wm8962_spk_mono_controls)); else - snd_soc_add_controls(codec, wm8962_spk_stereo_controls, + snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls, ARRAY_SIZE(wm8962_spk_stereo_controls)); @@ -2445,7 +2386,7 @@ static const int bclk_divs[] = { }; static const int sysclk_rates[] = { - 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, + 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144 }; static void wm8962_configure_bclk(struct snd_soc_codec *codec) @@ -2479,6 +2420,8 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) return; } + dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]); + snd_soc_update_bits(codec, WM8962_CLOCKING_4, WM8962_SYSCLK_RATE_MASK, clocking4); @@ -2537,9 +2480,6 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) static int wm8962_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - int ret; - if (level == codec->dapm.bias_level) return 0; @@ -2556,51 +2496,15 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), - wm8962->supplies); - if (ret != 0) { - dev_err(codec->dev, - "Failed to enable supplies: %d\n", - ret); - return ret; - } - - regcache_cache_only(wm8962->regmap, false); - regcache_sync(wm8962->regmap); - - snd_soc_update_bits(codec, WM8962_ANTI_POP, - WM8962_STARTUP_BIAS_ENA | - WM8962_VMID_BUF_ENA, - WM8962_STARTUP_BIAS_ENA | - WM8962_VMID_BUF_ENA); - - /* Bias enable at 2*50k for ramp */ - snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, - WM8962_VMID_SEL_MASK | - WM8962_BIAS_ENA, - WM8962_BIAS_ENA | 0x180); - - msleep(5); - } - /* VMID 2*250k */ snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, WM8962_VMID_SEL_MASK, 0x100); break; case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, - WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0); - - snd_soc_update_bits(codec, WM8962_ANTI_POP, - WM8962_STARTUP_BIAS_ENA | - WM8962_VMID_BUF_ENA, 0); - - regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), - wm8962->supplies); break; } + codec->dapm.bias_level = level; return 0; } @@ -2634,6 +2538,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, int adctl3 = 0; wm8962->bclk = snd_soc_params_to_bclk(params); + if (params_channels(params) == 1) + wm8962->bclk *= 2; + wm8962->lrclk = params_rate(params); for (i = 0; i < ARRAY_SIZE(sr_vals); i++) { @@ -2654,13 +2561,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S16_LE: break; case SNDRV_PCM_FORMAT_S20_3LE: - aif0 |= 0x40; + aif0 |= 0x4; break; case SNDRV_PCM_FORMAT_S24_LE: - aif0 |= 0x80; + aif0 |= 0x8; break; case SNDRV_PCM_FORMAT_S32_LE: - aif0 |= 0xc0; + aif0 |= 0xc; break; default: return -EINVAL; @@ -2672,7 +2579,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, WM8962_SAMPLE_RATE_INT_MODE | WM8962_SAMPLE_RATE_MASK, adctl3); - wm8962_configure_bclk(codec); + if (codec->dapm.bias_level == SND_SOC_BIAS_ON) + wm8962_configure_bclk(codec); return 0; } @@ -2702,6 +2610,8 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, wm8962->sysclk_rate = freq; + wm8962_configure_bclk(codec); + return 0; } @@ -2880,8 +2790,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct _fll_div fll_div; unsigned long timeout; int ret; - int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; - int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA; + int fll1 = 0; /* Any change? */ if (source == wm8962->fll_src && Fref == wm8962->fll_fref && @@ -2897,6 +2806,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); + pm_runtime_put(codec->dev); + return 0; } @@ -2904,6 +2815,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (ret != 0) return ret; + /* Parameters good, disable so we can reprogram */ + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); + switch (fll_id) { case WM8962_FLL_MCLK: case WM8962_FLL_BCLK: @@ -2942,12 +2856,11 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, try_wait_for_completion(&wm8962->fll_lock); - if (sysclk) - fll1 |= WM8962_FLL_ENA; + pm_runtime_get_sync(codec->dev); snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | - WM8962_FLL_ENA, fll1); + WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA); dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); @@ -3008,14 +2921,14 @@ static struct snd_soc_dai_driver wm8962_dai = { .name = "wm8962", .playback = { .stream_name = "Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8962_RATES, .formats = WM8962_FORMATS, }, .capture = { .stream_name = "Capture", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8962_RATES, .formats = WM8962_FORMATS, @@ -3056,54 +2969,73 @@ static void wm8962_mic_work(struct work_struct *work) static irqreturn_t wm8962_irq(int irq, void *data) { - struct snd_soc_codec *codec = data; - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - int mask; - int active; - int reg; + struct device *dev = data; + struct wm8962_priv *wm8962 = dev_get_drvdata(dev); + unsigned int mask; + unsigned int active; + int reg, ret; - mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); + ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK, + &mask); + if (ret != 0) { + dev_err(dev, "Failed to read interrupt mask: %d\n", + ret); + return IRQ_NONE; + } + + ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active); + if (ret != 0) { + dev_err(dev, "Failed to read interrupt: %d\n", ret); + return IRQ_NONE; + } - active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); active &= ~mask; if (!active) return IRQ_NONE; /* Acknowledge the interrupts */ - snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); + ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active); + if (ret != 0) + dev_warn(dev, "Failed to ack interrupt: %d\n", ret); if (active & WM8962_FLL_LOCK_EINT) { - dev_dbg(codec->dev, "FLL locked\n"); + dev_dbg(dev, "FLL locked\n"); complete(&wm8962->fll_lock); } if (active & WM8962_FIFOS_ERR_EINT) - dev_err(codec->dev, "FIFO error\n"); + dev_err(dev, "FIFO error\n"); if (active & WM8962_TEMP_SHUT_EINT) { - dev_crit(codec->dev, "Thermal shutdown\n"); + dev_crit(dev, "Thermal shutdown\n"); - reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS); + ret = regmap_read(wm8962->regmap, + WM8962_THERMAL_SHUTDOWN_STATUS, ®); + if (ret != 0) { + dev_warn(dev, "Failed to read thermal status: %d\n", + ret); + reg = 0; + } if (reg & WM8962_TEMP_ERR_HP) - dev_crit(codec->dev, "Headphone thermal error\n"); + dev_crit(dev, "Headphone thermal error\n"); if (reg & WM8962_TEMP_WARN_HP) - dev_crit(codec->dev, "Headphone thermal warning\n"); + dev_crit(dev, "Headphone thermal warning\n"); if (reg & WM8962_TEMP_ERR_SPK) - dev_crit(codec->dev, "Speaker thermal error\n"); + dev_crit(dev, "Speaker thermal error\n"); if (reg & WM8962_TEMP_WARN_SPK) - dev_crit(codec->dev, "Speaker thermal warning\n"); + dev_crit(dev, "Speaker thermal warning\n"); } if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { - dev_dbg(codec->dev, "Microphone event detected\n"); + dev_dbg(dev, "Microphone event detected\n"); #ifndef CONFIG_SND_SOC_WM8962_MODULE - trace_snd_soc_jack_irq(dev_name(codec->dev)); + trace_snd_soc_jack_irq(dev_name(dev)); #endif - pm_wakeup_event(codec->dev, 300); + pm_wakeup_event(dev, 300); schedule_delayed_work(&wm8962->mic_work, msecs_to_jiffies(250)); @@ -3584,7 +3516,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, trigger | IRQF_ONESHOT, - "wm8962", codec); + "wm8962", codec->dev); if (ret != 0) { dev_err(codec->dev, "Failed to request IRQ %d: %d\n", wm8962->irq, ret); @@ -3622,20 +3554,19 @@ static int wm8962_remove(struct snd_soc_codec *codec) return 0; } -static int wm8962_soc_volatile(struct snd_soc_codec *codec, - unsigned int reg) -{ - return true; -} - - static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { .probe = wm8962_probe, .remove = wm8962_remove, .set_bias_level = wm8962_set_bias_level, .set_pll = wm8962_set_fll, - .reg_cache_size = WM8962_MAX_REGISTER, - .volatile_register = wm8962_soc_volatile, + .idle_bias_off = true, +}; + +/* Improve power consumption for IN4 DC measurement mode */ +static const struct reg_default wm8962_dc_measure[] = { + { 0xfd, 0x1 }, + { 0xcc, 0x40 }, + { 0xfd, 0 }, }; static const struct regmap_config wm8962_regmap = { @@ -3653,6 +3584,7 @@ static const struct regmap_config wm8962_regmap = { static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm8962_priv *wm8962; unsigned int reg; int ret, i; @@ -3706,7 +3638,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, } if (reg != 0x6243) { dev_err(&i2c->dev, - "Device is not a WM8962, ID %x != 0x6243\n", ret); + "Device is not a WM8962, ID %x != 0x6243\n", reg); ret = -EINVAL; goto err_regmap; } @@ -3731,7 +3663,19 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, goto err_regmap; } - regcache_cache_only(wm8962->regmap, true); + if (pdata && pdata->in4_dc_measure) { + ret = regmap_register_patch(wm8962->regmap, + wm8962_dc_measure, + ARRAY_SIZE(wm8962_dc_measure)); + if (ret != 0) + dev_err(&i2c->dev, + "Failed to configure for DC mesurement: %d\n", + ret); + } + + pm_runtime_set_active(&i2c->dev); + pm_runtime_enable(&i2c->dev); + pm_request_idle(&i2c->dev); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8962, &wm8962_dai, 1); @@ -3763,6 +3707,65 @@ static __devexit int wm8962_i2c_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM_RUNTIME +static int wm8962_runtime_resume(struct device *dev) +{ + struct wm8962_priv *wm8962 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), + wm8962->supplies); + if (ret != 0) { + dev_err(dev, + "Failed to enable supplies: %d\n", ret); + return ret; + } + + regcache_cache_only(wm8962->regmap, false); + regcache_sync(wm8962->regmap); + + regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, + WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA, + WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA); + + /* Bias enable at 2*50k for ramp */ + regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, + WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, + WM8962_BIAS_ENA | 0x180); + + msleep(5); + + /* VMID back to 2x250k for standby */ + regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, + WM8962_VMID_SEL_MASK, 0x100); + + return 0; +} + +static int wm8962_runtime_suspend(struct device *dev) +{ + struct wm8962_priv *wm8962 = dev_get_drvdata(dev); + + regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, + WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0); + + regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, + WM8962_STARTUP_BIAS_ENA | + WM8962_VMID_BUF_ENA, 0); + + regcache_cache_only(wm8962->regmap, true); + + regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), + wm8962->supplies); + + return 0; +} +#endif + +static struct dev_pm_ops wm8962_pm = { + SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL) +}; + static const struct i2c_device_id wm8962_i2c_id[] = { { "wm8962", 0 }, { } @@ -3773,23 +3776,14 @@ static struct i2c_driver wm8962_i2c_driver = { .driver = { .name = "wm8962", .owner = THIS_MODULE, + .pm = &wm8962_pm, }, .probe = wm8962_i2c_probe, .remove = __devexit_p(wm8962_i2c_remove), .id_table = wm8962_i2c_id, }; -static int __init wm8962_modinit(void) -{ - return i2c_add_driver(&wm8962_i2c_driver); -} -module_init(wm8962_modinit); - -static void __exit wm8962_exit(void) -{ - i2c_del_driver(&wm8962_i2c_driver); -} -module_exit(wm8962_exit); +module_i2c_driver(wm8962_i2c_driver); MODULE_DESCRIPTION("ASoC WM8962 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 4ef9d4cb7d7c..6cdf6a2bc283 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -33,24 +33,89 @@ * We can't read the WM8988 register space when we * are using 2 wire for device control, so we cache them instead. */ -static const u16 wm8988_reg[] = { - 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ - 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ - 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ - 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ - 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ - 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ - 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ - 0x0079, 0x0079, 0x0079, /* 40 */ +static const struct reg_default wm8988_reg_defaults[] = { + { 0, 0x0097 }, + { 1, 0x0097 }, + { 2, 0x0079 }, + { 3, 0x0079 }, + { 5, 0x0008 }, + { 7, 0x000a }, + { 8, 0x0000 }, + { 10, 0x00ff }, + { 11, 0x00ff }, + { 12, 0x000f }, + { 13, 0x000f }, + { 16, 0x0000 }, + { 17, 0x007b }, + { 18, 0x0000 }, + { 19, 0x0032 }, + { 20, 0x0000 }, + { 21, 0x00c3 }, + { 22, 0x00c3 }, + { 23, 0x00c0 }, + { 24, 0x0000 }, + { 25, 0x0000 }, + { 26, 0x0000 }, + { 27, 0x0000 }, + { 31, 0x0000 }, + { 32, 0x0000 }, + { 33, 0x0000 }, + { 34, 0x0050 }, + { 35, 0x0050 }, + { 36, 0x0050 }, + { 37, 0x0050 }, + { 40, 0x0079 }, + { 41, 0x0079 }, + { 42, 0x0079 }, }; +static bool wm8988_writeable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8988_LINVOL: + case WM8988_RINVOL: + case WM8988_LOUT1V: + case WM8988_ROUT1V: + case WM8988_ADCDAC: + case WM8988_IFACE: + case WM8988_SRATE: + case WM8988_LDAC: + case WM8988_RDAC: + case WM8988_BASS: + case WM8988_TREBLE: + case WM8988_RESET: + case WM8988_3D: + case WM8988_ALC1: + case WM8988_ALC2: + case WM8988_ALC3: + case WM8988_NGATE: + case WM8988_LADC: + case WM8988_RADC: + case WM8988_ADCTL1: + case WM8988_ADCTL2: + case WM8988_PWR1: + case WM8988_PWR2: + case WM8988_ADCTL3: + case WM8988_ADCIN: + case WM8988_LADCIN: + case WM8988_RADCIN: + case WM8988_LOUTM1: + case WM8988_LOUTM2: + case WM8988_ROUTM1: + case WM8988_ROUTM2: + case WM8988_LOUT2V: + case WM8988_ROUT2V: + case WM8988_LPPB: + return true; + default: + return false; + } +} + /* codec private data */ struct wm8988_priv { + struct regmap *regmap; unsigned int sysclk; - enum snd_soc_control_type control_type; struct snd_pcm_hw_constraint_list *sysclk_constraints; }; @@ -661,6 +726,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) { + struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; switch (level) { @@ -674,7 +740,7 @@ 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) { - snd_soc_cache_sync(codec); + regcache_sync(wm8988->regmap); /* VREF, VMID=2x5k */ snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); @@ -730,7 +796,10 @@ static struct snd_soc_dai_driver wm8988_dai = { static int wm8988_suspend(struct snd_soc_codec *codec) { + struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); + wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); + regcache_mark_dirty(wm8988->regmap); return 0; } @@ -745,7 +814,8 @@ static int wm8988_probe(struct snd_soc_codec *codec) struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); int ret = 0; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); + codec->control_data = wm8988->regmap; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -781,9 +851,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { .suspend = wm8988_suspend, .resume = wm8988_resume, .set_bias_level = wm8988_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8988_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8988_reg, .controls = wm8988_snd_controls, .num_controls = ARRAY_SIZE(wm8988_snd_controls), @@ -793,6 +860,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), }; +static struct regmap_config wm8988_regmap = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8988_LPPB, + .writeable_reg = wm8988_writeable, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8988_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults), +}; + #if defined(CONFIG_SPI_MASTER) static int __devinit wm8988_spi_probe(struct spi_device *spi) { @@ -804,18 +883,28 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) if (wm8988 == NULL) return -ENOMEM; - wm8988->control_type = SND_SOC_SPI; + wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap); + if (IS_ERR(wm8988->regmap)) { + ret = PTR_ERR(wm8988->regmap); + dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); + return ret; + } + spi_set_drvdata(spi, wm8988); ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8988, &wm8988_dai, 1); + if (ret != 0) + regmap_exit(wm8988->regmap); return ret; } static int __devexit wm8988_spi_remove(struct spi_device *spi) { + struct wm8988_priv *wm8988 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); + regmap_exit(wm8988->regmap); return 0; } @@ -842,16 +931,27 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, wm8988); - wm8988->control_type = SND_SOC_I2C; + + wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap); + if (IS_ERR(wm8988->regmap)) { + ret = PTR_ERR(wm8988->regmap); + dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); + return ret; + } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8988, &wm8988_dai, 1); + if (ret != 0) + regmap_exit(wm8988->regmap); + return ret; } static __devexit int wm8988_i2c_remove(struct i2c_client *client) { + struct wm8988_priv *wm8988 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); + regmap_exit(wm8988->regmap); return 0; } @@ -863,7 +963,7 @@ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); static struct i2c_driver wm8988_i2c_driver = { .driver = { - .name = "wm8988-codec", + .name = "wm8988", .owner = THIS_MODULE, }, .probe = wm8988_i2c_probe, diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index e538edaae1f0..9d242351e6e8 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1356,7 +1356,7 @@ static int wm8990_probe(struct snd_soc_codec *codec) snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - snd_soc_add_controls(codec, wm8990_snd_controls, + snd_soc_add_codec_controls(codec, wm8990_snd_controls, ARRAY_SIZE(wm8990_snd_controls)); wm8990_add_widgets(codec); diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 7ee40da8dbb5..9ac31ba9b82e 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1297,7 +1297,7 @@ static int wm8991_probe(struct snd_soc_codec *codec) snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - snd_soc_add_controls(codec, wm8991_snd_controls, + snd_soc_add_codec_controls(codec, wm8991_snd_controls, ARRAY_SIZE(wm8991_snd_controls)); snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets, diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index dd687c3a84f9..d256a9340644 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -61,8 +61,9 @@ static struct reg_default wm8993_reg_defaults[] = { { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ { 19, 0x0010 }, /* R19 - GPIO1 */ { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */ - { 21, 0x8000 }, /* R22 - GPIOCTRL 2 */ - { 22, 0x0800 }, /* R23 - GPIO_POL */ + { 21, 0x0000 }, /* R21 - Inputs Clamp */ + { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */ + { 23, 0x0800 }, /* R23 - GPIO_POL */ { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ @@ -1057,6 +1058,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); int ret; + wm_hubs_set_bias_level(codec, level); + switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: @@ -1077,10 +1080,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, regcache_cache_only(wm8993->regmap, false); regcache_sync(wm8993->regmap); - /* Tune DC servo configuration */ - snd_soc_write(codec, 0x44, 3); - snd_soc_write(codec, 0x56, 3); - snd_soc_write(codec, 0x44, 0); + wm_hubs_vmid_ena(codec); /* Bring up VMID with fast soft start */ snd_soc_update_bits(codec, WM8993_ANTIPOP2, @@ -1609,13 +1609,13 @@ static int wm8993_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; - snd_soc_add_controls(codec, wm8993_snd_controls, + snd_soc_add_codec_controls(codec, wm8993_snd_controls, ARRAY_SIZE(wm8993_snd_controls)); if (wm8993->pdata.num_retune_configs != 0) { dev_dbg(codec->dev, "Using ReTune Mobile\n"); } else { dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); - snd_soc_add_controls(codec, wm8993_eq_controls, + snd_soc_add_codec_controls(codec, wm8993_eq_controls, ARRAY_SIZE(wm8993_eq_controls)); } @@ -1627,6 +1627,12 @@ static int wm8993_probe(struct snd_soc_codec *codec) wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, wm8993->pdata.lineout2_diff); + /* If the line outputs are differential then we aren't presenting + * VMID as an output and can disable it. + */ + if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff) + codec->dapm.idle_bias_off = 1; + return 0; } @@ -1691,6 +1697,13 @@ static int wm8993_resume(struct snd_soc_codec *codec) #define wm8993_resume NULL #endif +/* Tune DC servo configuration */ +static struct reg_default wm8993_regmap_patch[] = { + { 0x44, 3 }, + { 0x56, 3 }, + { 0x44, 0 }, +}; + static const struct regmap_config wm8993_regmap = { .reg_bits = 8, .val_bits = 16, @@ -1769,6 +1782,12 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, if (ret != 0) goto err_enable; + ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch, + ARRAY_SIZE(wm8993_regmap_patch)); + if (ret != 0) + dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n", + ret); + if (i2c->irq) { /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */ ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1, @@ -1840,24 +1859,7 @@ static struct i2c_driver wm8993_i2c_driver = { .id_table = wm8993_i2c_id, }; -static int __init wm8993_modinit(void) -{ - int ret = 0; - ret = i2c_add_driver(&wm8993_i2c_driver); - if (ret != 0) { - pr_err("WM8993: Unable to register I2C driver: %d\n", - ret); - } - return ret; -} -module_init(wm8993_modinit); - -static void __exit wm8993_exit(void) -{ - i2c_del_driver(&wm8993_i2c_driver); -} -module_exit(wm8993_exit); - +module_i2c_driver(wm8993_i2c_driver); MODULE_DESCRIPTION("ASoC WM8993 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h index 2184617b9611..4478b40c86e3 100644 --- a/sound/soc/codecs/wm8993.h +++ b/sound/soc/codecs/wm8993.h @@ -31,6 +31,7 @@ #define WM8993_GPIO_CTRL_1 0x12 #define WM8993_GPIO1 0x13 #define WM8993_IRQ_DEBOUNCE 0x14 +#define WM8993_INPUTS_CLAMP_REG 0x15 #define WM8993_GPIOCTRL_2 0x16 #define WM8993_GPIO_POL 0x17 #define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18 @@ -656,6 +657,14 @@ #define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */ /* + * R21 (0x15) - Inputs Clamp + */ +#define WM8993_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */ +#define WM8993_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */ +#define WM8993_INPUTS_CLAMP_SHIFT 7 /* INPUTS_CLAMP */ +#define WM8993_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */ + +/* * R22 (0x16) - GPIOCTRL 2 */ #define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b047bfada709..2417ef9316ed 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -685,15 +685,37 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0, static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + u16 old = snd_soc_read(codec, WM8994_ANTIPOP_2) + & WM1811_JACKDET_MODE_MASK; + + if (!wm8994->jackdet || !wm8994->jack_cb) + return; if (wm8994->active_refcount) mode = WM1811_JACKDET_MODE_AUDIO; + if (mode == old) + return; + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, mode); - if (mode == WM1811_JACKDET_MODE_MIC) - msleep(2); + switch (mode) { + case WM1811_JACKDET_MODE_MIC: + case WM1811_JACKDET_MODE_AUDIO: + switch (old) { + case WM1811_JACKDET_MODE_MIC: + case WM1811_JACKDET_MODE_AUDIO: + break; + default: + msleep(2); + break; + } + + default: + break; + } + } static void active_reference(struct snd_soc_codec *codec) @@ -707,15 +729,8 @@ static void active_reference(struct snd_soc_codec *codec) dev_dbg(codec->dev, "Active refcount incremented, now %d\n", wm8994->active_refcount); - if (wm8994->active_refcount == 1) { - /* If we're using jack detection go into audio mode */ - if (wm8994->jackdet && wm8994->jack_cb) { - snd_soc_update_bits(codec, WM8994_ANTIPOP_2, - WM1811_JACKDET_MODE_MASK, - WM1811_JACKDET_MODE_AUDIO); - msleep(2); - } - } + /* If we're using jack detection go into audio mode */ + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_AUDIO); mutex_unlock(&wm8994->accdet_lock); } @@ -734,16 +749,12 @@ static void active_dereference(struct snd_soc_codec *codec) if (wm8994->active_refcount == 0) { /* Go into appropriate detection only mode */ - if (wm8994->jackdet && wm8994->jack_cb) { - if (wm8994->jack_mic || wm8994->mic_detecting) - mode = WM1811_JACKDET_MODE_MIC; - else - mode = WM1811_JACKDET_MODE_JACK; + if (wm8994->jack_mic || wm8994->mic_detecting) + mode = WM1811_JACKDET_MODE_MIC; + else + mode = WM1811_JACKDET_MODE_JACK; - snd_soc_update_bits(codec, WM8994_ANTIPOP_2, - WM1811_JACKDET_MODE_MASK, - mode); - } + wm1811_jackdet_set_mode(codec, mode); } mutex_unlock(&wm8994->accdet_lock); @@ -770,20 +781,33 @@ static void vmid_reference(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + pm_runtime_get_sync(codec->dev); + wm8994->vmid_refcount++; dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", wm8994->vmid_refcount); if (wm8994->vmid_refcount == 1) { + snd_soc_update_bits(codec, WM8994_ANTIPOP_1, + WM8994_LINEOUT_VMID_BUF_ENA | + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH, + WM8994_LINEOUT_VMID_BUF_ENA); + + wm_hubs_vmid_ena(codec); + /* Startup bias, VMID ramp & buffer */ snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_BIAS_SRC | + WM8994_VMID_DISCH | WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA | WM8994_VMID_RAMP_MASK, + WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA | - (0x11 << WM8994_VMID_RAMP_SHIFT)); + (0x2 << WM8994_VMID_RAMP_SHIFT)); /* Main bias enable, VMID=2x40k */ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, @@ -791,7 +815,11 @@ static void vmid_reference(struct snd_soc_codec *codec) WM8994_VMID_SEL_MASK, WM8994_BIAS_ENA | 0x2); - msleep(20); + msleep(50); + + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_VMID_RAMP_MASK | WM8994_BIAS_SRC, + 0); } } @@ -821,6 +849,10 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); + /* Discharge VMID */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_VMID_DISCH, WM8994_VMID_DISCH); + /* Discharge line */ snd_soc_update_bits(codec, WM8994_ANTIPOP_1, WM8994_LINEOUT1_DISCH | @@ -837,6 +869,8 @@ static void vmid_dereference(struct snd_soc_codec *codec) WM8994_VMID_BUF_ENA | WM8994_VMID_RAMP_MASK, 0); } + + pm_runtime_put(codec->dev); } static int vmid_event(struct snd_soc_dapm_widget *w, @@ -1450,17 +1484,17 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIF2DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), -SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIF3DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), @@ -1575,6 +1609,14 @@ static const struct snd_soc_dapm_route intercon[] = { { "TOCLK", NULL, "CLK_SYS" }, + { "AIF1DACDAT", NULL, "AIF1 Playback" }, + { "AIF2DACDAT", NULL, "AIF2 Playback" }, + { "AIF3DACDAT", NULL, "AIF3 Playback" }, + + { "AIF1 Capture", NULL, "AIF1ADCDAT" }, + { "AIF2 Capture", NULL, "AIF2ADCDAT" }, + { "AIF3 Capture", NULL, "AIF3ADCDAT" }, + /* AIF1 outputs */ { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, @@ -1887,7 +1929,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, WM8994_FLL1_OUTDIV_MASK | WM8994_FLL1_FRATIO_MASK, reg); - snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k); + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset, + WM8994_FLL1_K_MASK, fll.k); snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, WM8994_FLL1_N_MASK, @@ -2065,6 +2108,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; + wm_hubs_set_bias_level(codec, level); + switch (level) { case SND_SOC_BIAS_ON: break; @@ -2159,6 +2204,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, wm8994->cur_fw = NULL; break; } + codec->dapm.bias_level = level; return 0; @@ -2759,13 +2805,6 @@ static int wm8994_resume(struct snd_soc_codec *codec) codec->cache_only = 0; } - /* Restore the registers */ - ret = snd_soc_cache_sync(codec); - if (ret != 0) - dev_err(codec->dev, "Failed to sync cache: %d\n", ret); - - wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { if (!wm8994->fll_suspend[i].out) continue; @@ -2867,7 +2906,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; - ret = snd_soc_add_controls(wm8994->codec, controls, + ret = snd_soc_add_codec_controls(wm8994->codec, controls, ARRAY_SIZE(controls)); if (ret != 0) dev_err(wm8994->codec->dev, @@ -2920,7 +2959,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) wm8994->drc_enum.max = pdata->num_drc_cfgs; wm8994->drc_enum.texts = wm8994->drc_texts; - ret = snd_soc_add_controls(wm8994->codec, controls, + ret = snd_soc_add_codec_controls(wm8994->codec, controls, ARRAY_SIZE(controls)); if (ret != 0) dev_err(wm8994->codec->dev, @@ -2936,7 +2975,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) if (pdata->num_retune_mobile_cfgs) wm8994_handle_retune_mobile_pdata(wm8994); else - snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, + snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls, ARRAY_SIZE(wm8994_eq_controls)); for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { @@ -2953,8 +2992,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) * @codec: WM8994 codec * @jack: jack to report detection events on * @micbias: microphone bias to detect on - * @det: value to report for presence detection - * @shrt: value to report for short detection * * Enable microphone detection via IRQ on the WM8994. If GPIOs are * being used to bring out signals to the processor then only platform @@ -2965,43 +3002,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) * and micbias2_lvl platform data members. */ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, - int micbias, int det, int shrt) + int micbias) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_micdet *micdet; struct wm8994 *control = wm8994->wm8994; - int reg; + int reg, ret; - if (control->type != WM8994) + if (control->type != WM8994) { + dev_warn(codec->dev, "Not a WM8994\n"); return -EINVAL; + } switch (micbias) { case 1: micdet = &wm8994->micdet[0]; + if (jack) + ret = snd_soc_dapm_force_enable_pin(&codec->dapm, + "MICBIAS1"); + else + ret = snd_soc_dapm_disable_pin(&codec->dapm, + "MICBIAS1"); break; case 2: micdet = &wm8994->micdet[1]; + if (jack) + ret = snd_soc_dapm_force_enable_pin(&codec->dapm, + "MICBIAS1"); + else + ret = snd_soc_dapm_disable_pin(&codec->dapm, + "MICBIAS1"); break; default: + dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias); return -EINVAL; - } + } + + if (ret != 0) + dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n", + micbias, ret); - dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", - micbias, det, shrt); + dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n", + micbias, jack); /* Store the configuration */ micdet->jack = jack; - micdet->det = det; - micdet->shrt = shrt; + micdet->detecting = true; /* If either of the jacks is set up then enable detection */ if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) reg = WM8994_MICD_ENA; - else + else reg = 0; snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); + snd_soc_dapm_sync(&codec->dapm); + return 0; } EXPORT_SYMBOL_GPL(wm8994_mic_detect); @@ -3027,20 +3084,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) dev_dbg(codec->dev, "Microphone status: %x\n", reg); report = 0; - if (reg & WM8994_MIC1_DET_STS) - report |= priv->micdet[0].det; - if (reg & WM8994_MIC1_SHRT_STS) - report |= priv->micdet[0].shrt; + if (reg & WM8994_MIC1_DET_STS) { + if (priv->micdet[0].detecting) + report = SND_JACK_HEADSET; + } + if (reg & WM8994_MIC1_SHRT_STS) { + if (priv->micdet[0].detecting) + report = SND_JACK_HEADPHONE; + else + report |= SND_JACK_BTN_0; + } + if (report) + priv->micdet[0].detecting = false; + else + priv->micdet[0].detecting = true; + snd_soc_jack_report(priv->micdet[0].jack, report, - priv->micdet[0].det | priv->micdet[0].shrt); + SND_JACK_HEADSET | SND_JACK_BTN_0); report = 0; - if (reg & WM8994_MIC2_DET_STS) - report |= priv->micdet[1].det; - if (reg & WM8994_MIC2_SHRT_STS) - report |= priv->micdet[1].shrt; + if (reg & WM8994_MIC2_DET_STS) { + if (priv->micdet[1].detecting) + report = SND_JACK_HEADSET; + } + if (reg & WM8994_MIC2_SHRT_STS) { + if (priv->micdet[1].detecting) + report = SND_JACK_HEADPHONE; + else + report |= SND_JACK_BTN_0; + } + if (report) + priv->micdet[1].detecting = false; + else + priv->micdet[1].detecting = true; + snd_soc_jack_report(priv->micdet[1].jack, report, - priv->micdet[1].det | priv->micdet[1].shrt); + SND_JACK_HEADSET | SND_JACK_BTN_0); return IRQ_HANDLED; } @@ -3089,7 +3168,7 @@ static void wm8958_default_micdet(u16 status, void *data) } - if (wm8994->mic_detecting && status & 0x4) { + if (wm8994->mic_detecting && status & 0xfc) { dev_dbg(codec->dev, "Detected headphone\n"); wm8994->mic_detecting = false; @@ -3103,6 +3182,14 @@ static void wm8958_default_micdet(u16 status, void *data) snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); + if (wm8994->pdata->jd_ext_cap) { + mutex_lock(&codec->mutex); + snd_soc_dapm_disable_pin(&codec->dapm, + "MICBIAS2"); + snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); + } + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); } @@ -3157,21 +3244,52 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); + snd_soc_update_bits(codec, WM8958_MICBIAS2, + WM8958_MICB2_DISCH, 0); + + /* Disable debounce while inserted */ + snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, + WM1811_JACKDET_DB, 0); + /* * Start off measument of microphone impedence to find * out what's actually there. */ wm8994->mic_detecting = true; wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); + + /* If required for an external cap force MICBIAS on */ + if (wm8994->pdata->jd_ext_cap) { + mutex_lock(&codec->mutex); + snd_soc_dapm_force_enable_pin(&codec->dapm, + "MICBIAS2"); + snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); + } } else { dev_dbg(codec->dev, "Jack not detected\n"); + snd_soc_update_bits(codec, WM8958_MICBIAS2, + WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); + + if (wm8994->pdata->jd_ext_cap) { + mutex_lock(&codec->mutex); + snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); + snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); + } + snd_soc_jack_report(wm8994->micdet[0].jack, 0, SND_JACK_MECHANICAL | SND_JACK_HEADSET | wm8994->btn_mask); + /* Enable debounce while removed */ + snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, + WM1811_JACKDET_DB, WM1811_JACKDET_DB); + wm8994->mic_detecting = false; wm8994->jack_mic = false; snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, @@ -3223,6 +3341,7 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, } snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); + snd_soc_dapm_sync(&codec->dapm); wm8994->micdet[0].jack = jack; wm8994->jack_cb = cb; @@ -3253,6 +3372,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, * otherwise jump straight to microphone detection. */ if (wm8994->jackdet) { + snd_soc_update_bits(codec, WM8958_MICBIAS2, + WM8958_MICB2_DISCH, + WM8958_MICB2_DISCH); snd_soc_update_bits(codec, WM8994_LDO_1, WM8994_LDO1_DISCH, 0); wm1811_jackdet_set_mode(codec, @@ -3265,7 +3387,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, } else { snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE); snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); + snd_soc_dapm_sync(&codec->dapm); } return 0; @@ -3363,23 +3487,16 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data) static int wm8994_codec_probe(struct snd_soc_codec *codec) { struct wm8994 *control = dev_get_drvdata(codec->dev->parent); - struct wm8994_priv *wm8994; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm = &codec->dapm; unsigned int reg; int ret, i; + wm8994->codec = codec; codec->control_data = control->regmap; - wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv), - GFP_KERNEL); - if (wm8994 == NULL) - return -ENOMEM; - snd_soc_codec_set_drvdata(codec, wm8994); - snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); - wm8994->wm8994 = dev_get_drvdata(codec->dev->parent); - wm8994->pdata = dev_get_platdata(codec->dev->parent); wm8994->codec = codec; mutex_init(&wm8994->accdet_lock); @@ -3394,12 +3511,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) WM8994_IRQ_MIC1_DET; pm_runtime_enable(codec->dev); - pm_runtime_resume(codec->dev); + pm_runtime_idle(codec->dev); + + /* By default use idle_bias_off, will override for WM8994 */ + codec->dapm.idle_bias_off = 1; /* Set revision-specific configuration */ wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); switch (control->type) { case WM8994: + /* Single ended line outputs should have VMID on. */ + if (!wm8994->pdata->lineout1_diff || + !wm8994->pdata->lineout2_diff) + codec->dapm.idle_bias_off = 0; + switch (wm8994->revision) { case 2: case 3: @@ -3417,11 +3542,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) case WM8958: wm8994->hubs.dcs_readback_mode = 1; + wm8994->hubs.hp_startup_mode = 1; break; case WM1811: wm8994->hubs.dcs_readback_mode = 2; wm8994->hubs.no_series_update = 1; + wm8994->hubs.hp_startup_mode = 1; + wm8994->hubs.no_cache_class_w = true; switch (wm8994->revision) { case 0: @@ -3538,6 +3666,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->fll_locked_irq = false; } + /* Make sure we can read from the GPIOs if they're inputs */ + pm_runtime_get_sync(codec->dev); + /* Remember if AIFnLRCLK is configured as a GPIO. This should be * configured on init - if a system wants to do this dynamically * at runtime we can deal with that then. @@ -3566,7 +3697,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->lrclk_shared[1] = 0; } - wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + pm_runtime_put(codec->dev); /* Latch volume updates (right only; we always do left then right). */ snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, @@ -3644,7 +3775,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994_handle_pdata(wm8994); wm_hubs_add_analogue_controls(codec); - snd_soc_add_controls(codec, wm8994_snd_controls, + snd_soc_add_codec_controls(codec, wm8994_snd_controls, ARRAY_SIZE(wm8994_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, ARRAY_SIZE(wm8994_dapm_widgets)); @@ -3670,7 +3801,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) } break; case WM8958: - snd_soc_add_controls(codec, wm8958_snd_controls, + snd_soc_add_codec_controls(codec, wm8958_snd_controls, ARRAY_SIZE(wm8958_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, ARRAY_SIZE(wm8958_dapm_widgets)); @@ -3692,7 +3823,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) break; case WM1811: - snd_soc_add_controls(codec, wm8958_snd_controls, + snd_soc_add_codec_controls(codec, wm8958_snd_controls, ARRAY_SIZE(wm8958_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, ARRAY_SIZE(wm8958_dapm_widgets)); @@ -3821,24 +3952,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) return 0; } -static int wm8994_soc_volatile(struct snd_soc_codec *codec, - unsigned int reg) -{ - return true; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .probe = wm8994_codec_probe, .remove = wm8994_codec_remove, .suspend = wm8994_suspend, .resume = wm8994_resume, .set_bias_level = wm8994_set_bias_level, - .reg_cache_size = WM8994_MAX_REGISTER, - .volatile_register = wm8994_soc_volatile, }; static int __devinit wm8994_probe(struct platform_device *pdev) { + struct wm8994_priv *wm8994; + + wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv), + GFP_KERNEL); + if (wm8994 == NULL) + return -ENOMEM; + platform_set_drvdata(pdev, wm8994); + + wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); + wm8994->pdata = dev_get_platdata(pdev->dev.parent); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, wm8994_dai, ARRAY_SIZE(wm8994_dai)); } diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index c3a42474ab19..f996d14766d9 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -35,7 +35,7 @@ typedef void (*wm8958_micdet_cb)(u16 status, void *data); int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, - int micbias, int det, int shrt); + int micbias); int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, wm8958_micdet_cb cb, void *cb_data); @@ -46,8 +46,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec); struct wm8994_micdet { struct snd_soc_jack *jack; - int det; - int shrt; + bool detecting; }; /* codec private data */ diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index c8aada597d70..28c89b094c6e 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2047,7 +2047,6 @@ static int wm8995_probe(struct snd_soc_codec *codec) int i; int ret; - codec->dapm.idle_bias_off = 1; wm8995 = snd_soc_codec_get_drvdata(codec); wm8995->codec = codec; @@ -2137,7 +2136,7 @@ static int wm8995_probe(struct snd_soc_codec *codec) wm8995_update_class_w(codec); - snd_soc_add_controls(codec, wm8995_snd_controls, + snd_soc_add_codec_controls(codec, wm8995_snd_controls, ARRAY_SIZE(wm8995_snd_controls)); snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets, ARRAY_SIZE(wm8995_dapm_widgets)); @@ -2241,6 +2240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { .suspend = wm8995_suspend, .resume = wm8995_resume, .set_bias_level = wm8995_set_bias_level, + .idle_bias_off = true, }; static struct regmap_config wm8995_regmap = { diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 8e8f8d1fef91..9376b19941b6 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -73,7 +73,6 @@ struct wm8996_priv { struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; - struct regulator *cpvdd; int bg_ena; struct wm8996_pdata pdata; @@ -90,6 +89,7 @@ struct wm8996_priv { struct snd_soc_jack *jack; bool detecting; bool jack_mic; + int jack_flips; wm8996_polarity_fn polarity_cb; #ifdef CONFIG_GPIOLIB @@ -108,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - regcache_cache_only(wm8996->regmap, true); \ + regcache_mark_dirty(wm8996->regmap); \ } \ return 0; \ } @@ -716,10 +716,16 @@ SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0), SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0), SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0), +SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5, + WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA | + WM8996_DSP1TXR_DRC_ENA), SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0), SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0), SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0), +SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5, + WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA | + WM8996_DSP2TXR_DRC_ENA), }; static const struct snd_kcontrol_new wm8996_eq_controls[] = { @@ -792,29 +798,18 @@ static int bg_event(struct snd_soc_dapm_widget *w, static int cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); int ret = 0; switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = regulator_enable(wm8996->cpvdd); - if (ret != 0) - dev_err(codec->dev, "Failed to enable CPVDD: %d\n", - ret); - break; case SND_SOC_DAPM_POST_PMU: msleep(5); break; - case SND_SOC_DAPM_POST_PMD: - regulator_disable_deferred(wm8996->cpvdd, 20); - break; default: BUG(); ret = -EINVAL; } - return ret; + return 0; } static int rmv_short_event(struct snd_soc_dapm_widget *w, @@ -1116,11 +1111,12 @@ SND_SOC_DAPM_INPUT("IN2RP"), SND_SOC_DAPM_INPUT("DMIC1DAT"), SND_SOC_DAPM_INPUT("DMIC2DAT"), +SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), @@ -1179,41 +1175,25 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0), SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), -SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0, - WM8996_POWER_MANAGEMENT_4, 9, 0), -SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1, - WM8996_POWER_MANAGEMENT_4, 8, 0), - -SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0, - WM8996_POWER_MANAGEMENT_6, 9, 0), -SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1, - WM8996_POWER_MANAGEMENT_6, 8, 0), - -SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, - WM8996_POWER_MANAGEMENT_4, 5, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, - WM8996_POWER_MANAGEMENT_4, 4, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, - WM8996_POWER_MANAGEMENT_4, 3, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, - WM8996_POWER_MANAGEMENT_4, 2, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, - WM8996_POWER_MANAGEMENT_4, 1, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0, - WM8996_POWER_MANAGEMENT_4, 0, 0), - -SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5, - WM8996_POWER_MANAGEMENT_6, 5, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4, - WM8996_POWER_MANAGEMENT_6, 4, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3, - WM8996_POWER_MANAGEMENT_6, 3, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2, - WM8996_POWER_MANAGEMENT_6, 2, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1, - WM8996_POWER_MANAGEMENT_6, 1, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0, - WM8996_POWER_MANAGEMENT_6, 0, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, WM8996_POWER_MANAGEMENT_4, 9, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX0", NULL, 1, WM8996_POWER_MANAGEMENT_4, 8, 0), + +SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, WM8996_POWER_MANAGEMENT_6, 9, 0), +SND_SOC_DAPM_AIF_OUT("AIF2TX0", NULL, 1, WM8996_POWER_MANAGEMENT_6, 8, 0), + +SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 5, WM8996_POWER_MANAGEMENT_4, 5, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 4, WM8996_POWER_MANAGEMENT_4, 4, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 3, WM8996_POWER_MANAGEMENT_4, 3, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 2, WM8996_POWER_MANAGEMENT_4, 2, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 1, WM8996_POWER_MANAGEMENT_4, 1, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX0", NULL, 0, WM8996_POWER_MANAGEMENT_4, 0, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 5, WM8996_POWER_MANAGEMENT_6, 5, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 4, WM8996_POWER_MANAGEMENT_6, 4, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 3, WM8996_POWER_MANAGEMENT_6, 3, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 2, WM8996_POWER_MANAGEMENT_6, 2, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 1, WM8996_POWER_MANAGEMENT_6, 1, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX0", NULL, 0, WM8996_POWER_MANAGEMENT_6, 0, 0), /* We route as stereo pairs so define some dummy widgets to squash * things down for now. RXA = 0,1, RXB = 2,3 and so on */ @@ -1279,6 +1259,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { { "AIFCLK", NULL, "SYSCLK" }, { "SYSDSPCLK", NULL, "SYSCLK" }, { "Charge Pump", NULL, "SYSCLK" }, + { "Charge Pump", NULL, "CPVDD" }, { "MICB1", NULL, "LDO2" }, { "MICB1", NULL, "MICB1 Audio" }, @@ -1287,6 +1268,26 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { { "MICB2", NULL, "MICB2 Audio" }, { "MICB2", NULL, "Bandgap" }, + { "AIF1RX0", NULL, "AIF1 Playback" }, + { "AIF1RX1", NULL, "AIF1 Playback" }, + { "AIF1RX2", NULL, "AIF1 Playback" }, + { "AIF1RX3", NULL, "AIF1 Playback" }, + { "AIF1RX4", NULL, "AIF1 Playback" }, + { "AIF1RX5", NULL, "AIF1 Playback" }, + + { "AIF2RX0", NULL, "AIF2 Playback" }, + { "AIF2RX1", NULL, "AIF2 Playback" }, + + { "AIF1 Capture", NULL, "AIF1TX0" }, + { "AIF1 Capture", NULL, "AIF1TX1" }, + { "AIF1 Capture", NULL, "AIF1TX2" }, + { "AIF1 Capture", NULL, "AIF1TX3" }, + { "AIF1 Capture", NULL, "AIF1TX4" }, + { "AIF1 Capture", NULL, "AIF1TX5" }, + + { "AIF2 Capture", NULL, "AIF2TX0" }, + { "AIF2 Capture", NULL, "AIF2TX1" }, + { "IN1L PGA", NULL, "IN2LN" }, { "IN1L PGA", NULL, "IN2LP" }, { "IN1L PGA", NULL, "IN1LN" }, @@ -1719,6 +1720,7 @@ static int wm8996_reset(struct wm8996_priv *wm8996) { if (wm8996->pdata.ldo_ena > 0) { gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); + gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); return 0; } else { return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, @@ -2437,6 +2439,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, wm8996->jack = jack; wm8996->detecting = true; wm8996->polarity_cb = polarity_cb; + wm8996->jack_flips = 0; if (wm8996->polarity_cb) wm8996->polarity_cb(codec, 0); @@ -2552,6 +2555,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec) WM8996_HP_POLL, WM8996_HP_POLL); } +static void wm8996_report_headphone(struct snd_soc_codec *codec) +{ + dev_dbg(codec->dev, "Headphone detected\n"); + wm8996_hpdet_start(codec); + + /* Increase the detection rate a bit for responsiveness. */ + snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, + WM8996_MICD_RATE_MASK | + WM8996_MICD_BIAS_STARTTIME_MASK, + 7 << WM8996_MICD_RATE_SHIFT | + 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); +} + static void wm8996_micd(struct snd_soc_codec *codec) { struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); @@ -2571,6 +2587,7 @@ static void wm8996_micd(struct snd_soc_codec *codec) dev_dbg(codec->dev, "Jack removal detected\n"); wm8996->jack_mic = false; wm8996->detecting = true; + wm8996->jack_flips = 0; snd_soc_jack_report(wm8996->jack, 0, SND_JACK_LINEOUT | SND_JACK_HEADSET | SND_JACK_BTN_0); @@ -2611,9 +2628,17 @@ static void wm8996_micd(struct snd_soc_codec *codec) /* If we detected a lower impedence during initial startup * then we probably have the wrong polarity, flip it. Don't * do this for the lowest impedences to speed up detection of - * plain headphones. + * plain headphones. If both polarities report a low + * impedence then give up and report headphones. */ if (wm8996->detecting && (val & 0x3f0)) { + wm8996->jack_flips++; + + if (wm8996->jack_flips > 1) { + wm8996_report_headphone(codec); + return; + } + reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | WM8996_MICD_BIAS_SRC; @@ -2640,17 +2665,7 @@ static void wm8996_micd(struct snd_soc_codec *codec) snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, SND_JACK_BTN_0); } else if (wm8996->detecting) { - dev_dbg(codec->dev, "Headphone detected\n"); - wm8996_hpdet_start(codec); - - /* Increase the detection rate a bit for - * responsiveness. - */ - snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK | - WM8996_MICD_BIAS_STARTTIME_MASK, - 7 << WM8996_MICD_RATE_SHIFT | - 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); + wm8996_report_headphone(codec); } } } @@ -2767,7 +2782,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; - ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); + ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); if (ret != 0) dev_err(codec->dev, "Failed to add ReTune Mobile controls: %d\n", ret); @@ -2790,7 +2805,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) int ret; struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); struct i2c_client *i2c = to_i2c_client(codec->dev); - struct snd_soc_dapm_context *dapm = &codec->dapm; int i, irq_flags; wm8996->codec = codec; @@ -2798,8 +2812,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) init_completion(&wm8996->dcs_done); init_completion(&wm8996->fll_lock); - dapm->idle_bias_off = true; - codec->control_data = wm8996->regmap; ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); @@ -2965,7 +2977,7 @@ static int wm8996_probe(struct snd_soc_codec *codec) if (wm8996->pdata.num_retune_mobile_cfgs) wm8996_retune_mobile_pdata(codec); else - snd_soc_add_controls(codec, wm8996_eq_controls, + snd_soc_add_codec_controls(codec, wm8996_eq_controls, ARRAY_SIZE(wm8996_eq_controls)); /* If the TX LRCLK pins are not in LRCLK mode configure the @@ -3037,22 +3049,16 @@ static int wm8996_remove(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) regulator_unregister_notifier(wm8996->supplies[i].consumer, &wm8996->disable_nb[i]); - regulator_put(wm8996->cpvdd); regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); return 0; } -static int wm8996_soc_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - return true; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { .probe = wm8996_probe, .remove = wm8996_remove, .set_bias_level = wm8996_set_bias_level, + .idle_bias_off = true, .seq_notifier = wm8996_seq_notifier, .controls = wm8996_snd_controls, .num_controls = ARRAY_SIZE(wm8996_snd_controls), @@ -3061,8 +3067,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { .dapm_routes = wm8996_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), .set_pll = wm8996_set_fll, - .reg_cache_size = WM8996_MAX_REGISTER, - .volatile_register = wm8996_soc_volatile_register, }; #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ @@ -3152,25 +3156,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) wm8996->supplies[i].supply = wm8996_supply_names[i]; - ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); + ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), + wm8996->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); goto err_gpio; } - wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); - if (IS_ERR(wm8996->cpvdd)) { - ret = PTR_ERR(wm8996->cpvdd); - dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); - goto err_get; - } - ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); - goto err_cpvdd; + goto err_gpio; } if (wm8996->pdata.ldo_ena > 0) { @@ -3191,7 +3188,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, goto err_regmap; } if (reg != 0x8915) { - dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); + dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg); ret = -EINVAL; goto err_regmap; } @@ -3232,10 +3229,6 @@ err_enable: if (wm8996->pdata.ldo_ena > 0) gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); -err_cpvdd: - regulator_put(wm8996->cpvdd); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); err_gpio: if (wm8996->pdata.ldo_ena > 0) gpio_free(wm8996->pdata.ldo_ena); @@ -3250,8 +3243,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); wm8996_free_gpio(wm8996); - regulator_put(wm8996->cpvdd); - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); regmap_exit(wm8996->regmap); if (wm8996->pdata.ldo_ena > 0) { gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); @@ -3276,25 +3267,7 @@ static struct i2c_driver wm8996_i2c_driver = { .id_table = wm8996_i2c_id, }; -static int __init wm8996_modinit(void) -{ - int ret; - - ret = i2c_add_driver(&wm8996_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8996 I2C driver: %d\n", - ret); - } - - return ret; -} -module_init(wm8996_modinit); - -static void __exit wm8996_exit(void) -{ - i2c_del_driver(&wm8996_i2c_driver); -} -module_exit(wm8996_exit); +module_i2c_driver(wm8996_i2c_driver); MODULE_DESCRIPTION("ASoC WM8996 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index a6bab392700e..076c126ed9b1 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -824,6 +824,8 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { static int wm9081_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); + switch (level) { case SND_SOC_BIAS_ON: break; @@ -841,6 +843,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: /* Initial cold start */ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + regcache_cache_only(wm9081->regmap, false); + regcache_sync(wm9081->regmap); + /* Disable LINEOUT discharge */ snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, WM9081_LINEOUT_DISCH, 0); @@ -892,6 +897,8 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, WM9081_LINEOUT_DISCH, WM9081_LINEOUT_DISCH); + + regcache_cache_only(wm9081->regmap, true); break; } @@ -1258,7 +1265,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) { struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); int ret; - u16 reg; codec->control_data = wm9081->regmap; @@ -1268,16 +1274,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) return ret; } - reg = 0; - if (wm9081->pdata.irq_high) - reg |= WM9081_IRQ_POL; - if (!wm9081->pdata.irq_cmos) - reg |= WM9081_IRQ_OP_CTRL; - snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL, - WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg); - - wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* Enable zero cross by default */ snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, WM9081_LINEOUTZC, WM9081_LINEOUTZC); @@ -1287,7 +1283,7 @@ static int wm9081_probe(struct snd_soc_codec *codec) if (!wm9081->pdata.num_retune_configs) { dev_dbg(codec->dev, "No ReTune Mobile data, using normal EQ\n"); - snd_soc_add_controls(codec, wm9081_eq_controls, + snd_soc_add_codec_controls(codec, wm9081_eq_controls, ARRAY_SIZE(wm9081_eq_controls)); } @@ -1300,38 +1296,15 @@ static int wm9081_remove(struct snd_soc_codec *codec) return 0; } -#ifdef CONFIG_PM -static int wm9081_suspend(struct snd_soc_codec *codec) -{ - wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm9081_resume(struct snd_soc_codec *codec) -{ - struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); - - regcache_sync(wm9081->regmap); - - wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define wm9081_suspend NULL -#define wm9081_resume NULL -#endif - static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { .probe = wm9081_probe, .remove = wm9081_remove, - .suspend = wm9081_suspend, - .resume = wm9081_resume, .set_sysclk = wm9081_set_sysclk, .set_bias_level = wm9081_set_bias_level, + .idle_bias_off = true, + .controls = wm9081_snd_controls, .num_controls = ARRAY_SIZE(wm9081_snd_controls), .dapm_widgets = wm9081_dapm_widgets, @@ -1395,6 +1368,16 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), sizeof(wm9081->pdata)); + reg = 0; + if (wm9081->pdata.irq_high) + reg |= WM9081_IRQ_POL; + if (!wm9081->pdata.irq_cmos) + reg |= WM9081_IRQ_OP_CTRL; + regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL, + WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg); + + regcache_cache_only(wm9081->regmap, true); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9081, &wm9081_dai, 1); if (ret < 0) @@ -1435,28 +1418,7 @@ static struct i2c_driver wm9081_i2c_driver = { }; #endif -static int __init wm9081_modinit(void) -{ - int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm9081_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", - ret); - } -#endif - return ret; -} -module_init(wm9081_modinit); - -static void __exit wm9081_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm9081_i2c_driver); -#endif -} -module_exit(wm9081_exit); - +module_i2c_driver(wm9081_i2c_driver); MODULE_DESCRIPTION("ASoC WM9081 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index a2b9208a08f0..4b263b6edf13 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -433,7 +433,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_add_controls(codec, wm9090_controls, + snd_soc_add_codec_controls(codec, wm9090_controls, ARRAY_SIZE(wm9090_controls)); if (wm9090->pdata.lin1_diff) { @@ -442,7 +442,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) } else { snd_soc_dapm_add_routes(dapm, audio_map_in1_se, ARRAY_SIZE(audio_map_in1_se)); - snd_soc_add_controls(codec, wm9090_in1_se_controls, + snd_soc_add_codec_controls(codec, wm9090_in1_se_controls, ARRAY_SIZE(wm9090_in1_se_controls)); } @@ -452,7 +452,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) } else { snd_soc_dapm_add_routes(dapm, audio_map_in2_se, ARRAY_SIZE(audio_map_in2_se)); - snd_soc_add_controls(codec, wm9090_in2_se_controls, + snd_soc_add_codec_controls(codec, wm9090_in2_se_controls, ARRAY_SIZE(wm9090_in2_se_controls)); } @@ -639,7 +639,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, if (ret < 0) goto err; if (reg != 0x9093) { - dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret); + dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg); ret = -ENODEV; goto err; } diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 40c92ead85a3..cacc6a86b46f 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -351,7 +351,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) if (ret) goto reset_err; - snd_soc_add_controls(codec, wm9705_snd_ac97_controls, + snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls, ARRAY_SIZE(wm9705_snd_ac97_controls)); return 0; diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index b7b31f84c10b..b342ae50bcd6 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -20,10 +20,9 @@ #include <sound/ac97_codec.h> #include <sound/initval.h> #include <sound/soc.h> +#include <sound/tlv.h> #include "wm9712.h" -#define WM9712_VERSION "0.4" - static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg); static int ac97_write(struct snd_soc_codec *codec, @@ -71,6 +70,9 @@ static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer", static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; static const char *wm9712_diff_sel[] = {"Mic", "Line"}; +static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0); +static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0); + static const struct soc_enum wm9712_enum[] = { SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), @@ -149,9 +151,9 @@ SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), -SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), -SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), -SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), +SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), +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 @@ -619,8 +621,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) { int ret = 0; - printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); if (ret < 0) { printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); @@ -637,7 +637,7 @@ 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_controls(codec, wm9712_snd_ac97_controls, + snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls, ARRAY_SIZE(wm9712_snd_ac97_controls)); return 0; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 2b8479bfcd93..2d22cc70d536 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1216,7 +1216,7 @@ 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_controls(codec, wm9713_snd_ac97_controls, + snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls, ARRAY_SIZE(wm9713_snd_ac97_controls)); return 0; diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 2a61094075f8..c08d1c2f346f 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -172,7 +172,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) break; default: WARN(1, "Unknown DCS readback method\n"); - break; + return; } dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); @@ -207,7 +207,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) /* Save the callibrated offset if we're in class W mode and * therefore don't have any analogue signal mixed in. */ - if (hubs->class_w) + if (hubs->class_w && !hubs->no_cache_class_w) hubs->class_w_dcs = dcs_cfg; } @@ -500,6 +500,36 @@ static int earpiece_event(struct snd_soc_dapm_widget *w, return 0; } +static int lineout_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *control, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); + bool *flag; + + switch (w->shift) { + case WM8993_LINEOUT1N_ENA_SHIFT: + flag = &hubs->lineout1n_ena; + break; + case WM8993_LINEOUT1P_ENA_SHIFT: + flag = &hubs->lineout1p_ena; + break; + case WM8993_LINEOUT2N_ENA_SHIFT: + flag = &hubs->lineout2n_ena; + break; + case WM8993_LINEOUT2P_ENA_SHIFT: + flag = &hubs->lineout2p_ena; + break; + default: + WARN(1, "Unknown line output"); + return -EINVAL; + } + + *flag = SND_SOC_DAPM_EVENT_ON(event); + + return 0; +} + static const struct snd_kcontrol_new in1l_pga[] = { SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), @@ -586,14 +616,14 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0), }; static const struct snd_kcontrol_new line2_mix[] = { -SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0), -SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0), +SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0), +SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0), SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), }; static const struct snd_kcontrol_new line2n_mix[] = { -SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), -SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), +SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), +SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), }; static const struct snd_kcontrol_new line2p_mix[] = { @@ -613,6 +643,8 @@ SND_SOC_DAPM_INPUT("IN2RP:VXRP"), SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("LINEOUT_VMID_BUF", WM8993_ANTIPOP1, 7, 0, NULL, 0), + SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, in1l_pga, ARRAY_SIZE(in1l_pga)), SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0, @@ -638,9 +670,8 @@ SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, - NULL, 0, - hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, earpiece_mixer, ARRAY_SIZE(earpiece_mixer)), @@ -654,10 +685,10 @@ SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0, right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), -SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, - NULL, 0), -SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, - NULL, 0), +SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, + NULL, 0), +SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, + NULL, 0), SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, line1_mix, ARRAY_SIZE(line1_mix)), @@ -673,14 +704,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, line2p_mix, ARRAY_SIZE(line2p_mix)), -SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, - NULL, 0), -SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, - NULL, 0), -SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, - NULL, 0), -SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, - NULL, 0), +SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, + NULL, 0, lineout_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, + NULL, 0, lineout_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, + NULL, 0, lineout_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, + NULL, 0, lineout_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_OUTPUT("SPKOUTLP"), SND_SOC_DAPM_OUTPUT("SPKOUTLN"), @@ -834,9 +869,11 @@ static const struct snd_soc_dapm_route lineout1_diff_routes[] = { }; static const struct snd_soc_dapm_route lineout1_se_routes[] = { + { "LINEOUT1N Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, + { "LINEOUT1P Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, @@ -844,8 +881,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { }; static const struct snd_soc_dapm_route lineout2_diff_routes[] = { - { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, - { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, + { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" }, + { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" }, { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, @@ -853,9 +890,11 @@ static const struct snd_soc_dapm_route lineout2_diff_routes[] = { }; static const struct snd_soc_dapm_route lineout2_se_routes[] = { + { "LINEOUT2N Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, + { "LINEOUT2P Mixer", NULL, "LINEOUT_VMID_BUF" }, { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, @@ -895,7 +934,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); - snd_soc_add_controls(codec, analogue_snd_controls, + snd_soc_add_codec_controls(codec, analogue_snd_controls, ARRAY_SIZE(analogue_snd_controls)); snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, @@ -943,6 +982,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, int jd_scthr, int jd_thr, int micbias1_lvl, int micbias2_lvl) { + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); + + hubs->lineout1_se = !lineout1_diff; + hubs->lineout2_se = !lineout2_diff; + if (!lineout1_diff) snd_soc_update_bits(codec, WM8993_LINE_MIXER1, WM8993_LINEOUT1_MODE, @@ -952,12 +996,6 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, WM8993_LINEOUT2_MODE, WM8993_LINEOUT2_MODE); - /* If the line outputs are differential then we aren't presenting - * VMID as an output and can disable it. - */ - if (lineout1_diff && lineout2_diff) - codec->dapm.idle_bias_off = 1; - if (lineout1fb) snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB); @@ -978,6 +1016,74 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); +void wm_hubs_vmid_ena(struct snd_soc_codec *codec) +{ + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); + int val = 0; + + if (hubs->lineout1_se) + val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA; + + if (hubs->lineout2_se) + val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA; + + /* Enable the line outputs while we power up */ + snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val); +} +EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena); + +void wm_hubs_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); + int val; + + switch (level) { + case SND_SOC_BIAS_STANDBY: + /* Clamp the inputs to VMID while we ramp to charge caps */ + snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, + WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP); + break; + + case SND_SOC_BIAS_ON: + /* Turn off any unneded single ended outputs */ + val = 0; + + if (hubs->lineout1_se && hubs->lineout1n_ena) + val |= WM8993_LINEOUT1N_ENA; + + if (hubs->lineout1_se && hubs->lineout1p_ena) + val |= WM8993_LINEOUT1P_ENA; + + if (hubs->lineout2_se && hubs->lineout2n_ena) + val |= WM8993_LINEOUT2N_ENA; + + if (hubs->lineout2_se && hubs->lineout2p_ena) + val |= WM8993_LINEOUT2P_ENA; + + snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, + WM8993_LINEOUT1N_ENA | + WM8993_LINEOUT1P_ENA | + WM8993_LINEOUT2N_ENA | + WM8993_LINEOUT2P_ENA, + val); + + if (!hubs->lineout1n_ena && !hubs->lineout1p_ena && + !hubs->lineout2n_ena && !hubs->lineout2p_ena) + snd_soc_update_bits(codec, WM8993_ANTIPOP1, + WM8993_LINEOUT_VMID_BUF_ENA, 0); + + /* Remove the input clamps */ + snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, + WM8993_INPUTS_CLAMP, 0); + break; + + default: + break; + } +} +EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level); + MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index c674c7a502a6..5705276f4943 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -30,9 +30,18 @@ struct wm_hubs_data { int series_startup; int no_series_update; + bool no_cache_class_w; bool class_w; u16 class_w_dcs; + bool lineout1_se; + bool lineout1n_ena; + bool lineout1p_ena; + + bool lineout2_se; + bool lineout2n_ena; + bool lineout2p_ena; + bool dcs_done_irq; struct completion dcs_done; }; @@ -46,5 +55,8 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, int micbias1_lvl, int micbias2_lvl); extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); +extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec); +extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level); #endif |