summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/fabrics/layout.c2
-rw-r--r--sound/core/pcm_compat.c2
-rw-r--r--sound/core/pcm_lib.c13
-rw-r--r--sound/core/rtctimer.c2
-rw-r--r--sound/core/timer.c5
-rw-r--r--sound/i2c/other/tea575x-tuner.c143
-rw-r--r--sound/isa/msnd/msnd.h2
-rw-r--r--sound/oss/ad1848.c6
-rw-r--r--sound/oss/pas2_pcm.c8
-rw-r--r--sound/oss/pss.c6
-rw-r--r--sound/oss/sb_mixer.c6
-rw-r--r--sound/pci/Kconfig10
-rw-r--r--sound/pci/ac97/ac97_patch.c1
-rw-r--r--sound/pci/asihpi/asihpi.c21
-rw-r--r--sound/pci/asihpi/hpicmn.c5
-rw-r--r--sound/pci/asihpi/hpidspcd.c9
-rw-r--r--sound/pci/asihpi/hpioctl.c28
-rw-r--r--sound/pci/azt3328.c11
-rw-r--r--sound/pci/echoaudio/darla20.c2
-rw-r--r--sound/pci/echoaudio/darla24.c2
-rw-r--r--sound/pci/echoaudio/echo3g.c2
-rw-r--r--sound/pci/echoaudio/gina20.c2
-rw-r--r--sound/pci/echoaudio/gina24.c2
-rw-r--r--sound/pci/echoaudio/indigo.c2
-rw-r--r--sound/pci/echoaudio/indigodj.c2
-rw-r--r--sound/pci/echoaudio/indigodjx.c2
-rw-r--r--sound/pci/echoaudio/indigoio.c2
-rw-r--r--sound/pci/echoaudio/indigoiox.c2
-rw-r--r--sound/pci/echoaudio/layla20.c2
-rw-r--r--sound/pci/echoaudio/layla24.c2
-rw-r--r--sound/pci/echoaudio/mia.c2
-rw-r--r--sound/pci/echoaudio/mona.c2
-rw-r--r--sound/pci/hda/Kconfig1
-rw-r--r--sound/pci/hda/alc268_quirks.c36
-rw-r--r--sound/pci/hda/alc269_quirks.c7
-rw-r--r--sound/pci/hda/hda_codec.c114
-rw-r--r--sound/pci/hda/hda_codec.h15
-rw-r--r--sound/pci/hda/hda_eld.c31
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/patch_analog.c4
-rw-r--r--sound/pci/hda/patch_cirrus.c741
-rw-r--r--sound/pci/hda/patch_conexant.c71
-rw-r--r--sound/pci/hda/patch_realtek.c100
-rw-r--r--sound/pci/hda/patch_sigmatel.c289
-rw-r--r--sound/pci/hda/patch_via.c6
-rw-r--r--sound/pci/lx6464es/lx6464es.h2
-rw-r--r--sound/pci/rme9652/hdspm.c128
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c2
-rw-r--r--sound/soc/codecs/Kconfig11
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/ad193x.c11
-rw-r--r--sound/soc/codecs/ad193x.h5
-rw-r--r--sound/soc/codecs/sgtl5000.c198
-rw-r--r--sound/soc/codecs/sta32x.c1
-rw-r--r--sound/soc/codecs/twl4030.c22
-rw-r--r--sound/soc/codecs/twl6040.c733
-rw-r--r--sound/soc/codecs/twl6040.h119
-rw-r--r--sound/soc/codecs/wm8750.c8
-rw-r--r--sound/soc/codecs/wm8903.c5
-rw-r--r--sound/soc/codecs/wm8915.c2995
-rw-r--r--sound/soc/codecs/wm8915.h3717
-rw-r--r--sound/soc/codecs/wm8962.c18
-rw-r--r--sound/soc/codecs/wm8994.c1
-rw-r--r--sound/soc/codecs/wm8996.c3002
-rw-r--r--sound/soc/codecs/wm8996.h3717
-rw-r--r--sound/soc/codecs/wm_hubs.c3
-rw-r--r--sound/soc/davinci/davinci-vcif.c9
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c5
-rw-r--r--sound/soc/fsl/fsl_dma.c2
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c18
-rw-r--r--sound/soc/fsl/p1022_ds.c4
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c2
-rw-r--r--sound/soc/omap/ams-delta.c6
-rw-r--r--sound/soc/omap/n810.c4
-rw-r--r--sound/soc/omap/omap-mcbsp.c4
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/omap-pcm.c4
-rw-r--r--sound/soc/omap/omap-pcm.h2
-rw-r--r--sound/soc/omap/rx51.c2
-rw-r--r--sound/soc/omap/sdp3430.c2
-rw-r--r--sound/soc/omap/sdp4430.c52
-rw-r--r--sound/soc/omap/zoom2.c2
-rw-r--r--sound/soc/samsung/Kconfig3
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/h1940_uda1380.c1
-rw-r--r--sound/soc/samsung/i2s.c7
-rw-r--r--sound/soc/samsung/idma.c453
-rw-r--r--sound/soc/samsung/idma.h26
-rw-r--r--sound/soc/samsung/jive_wm8750.c2
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c1
-rw-r--r--sound/soc/samsung/speyside.c32
-rw-r--r--sound/soc/samsung/speyside_wm8962.c8
-rw-r--r--sound/soc/soc-core.c7
-rw-r--r--sound/soc/soc-dapm.c30
-rw-r--r--sound/soc/soc-io.c23
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-pcm.c3
-rw-r--r--sound/soc/tegra/tegra_pcm.c9
-rw-r--r--sound/soc/tegra/tegra_wm8903.c19
-rw-r--r--sound/soc/txx9/txx9aclc.c1
-rw-r--r--sound/sparc/dbri.c2
-rw-r--r--sound/usb/caiaq/audio.c37
-rw-r--r--sound/usb/caiaq/device.h1
-rw-r--r--sound/usb/caiaq/input.c2
-rw-r--r--sound/usb/endpoint.c2
-rw-r--r--sound/usb/mixer.c28
-rw-r--r--sound/usb/mixer.h1
-rw-r--r--sound/usb/quirks-table.h40
-rw-r--r--sound/usb/quirks.c2
109 files changed, 9320 insertions, 7971 deletions
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 3fd1a7e2492..552b97afbca 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -1073,10 +1073,10 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
sdev->pcmid = -1;
list_del(&ldev->list);
layouts_list_items--;
+ kfree(ldev);
outnodev:
of_node_put(sound);
layout_device = NULL;
- kfree(ldev);
return -ENODEV;
}
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 5fb2e28e796..91cdf9435fe 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -342,7 +342,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
kfree(bufs);
return -EFAULT;
}
- bufs[ch] = compat_ptr(ptr);
+ bufs[i] = compat_ptr(ptr);
bufptr++;
}
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index f1341308bed..86d0caf91b3 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -128,7 +128,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
}
}
-static void pcm_debug_name(struct snd_pcm_substream *substream,
+#ifdef CONFIG_SND_DEBUG
+void snd_pcm_debug_name(struct snd_pcm_substream *substream,
char *name, size_t len)
{
snprintf(name, len, "pcmC%dD%d%c:%d",
@@ -137,6 +138,8 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
substream->stream ? 'c' : 'p',
substream->number);
}
+EXPORT_SYMBOL(snd_pcm_debug_name);
+#endif
#define XRUN_DEBUG_BASIC (1<<0)
#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
@@ -168,7 +171,7 @@ static void xrun(struct snd_pcm_substream *substream)
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
char name[16];
- pcm_debug_name(substream, name, sizeof(name));
+ snd_pcm_debug_name(substream, name, sizeof(name));
snd_printd(KERN_DEBUG "XRUN: %s\n", name);
dump_stack_on_xrun(substream);
}
@@ -243,7 +246,7 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
return;
if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
return;
- pcm_debug_name(substream, name, sizeof(name));
+ snd_pcm_debug_name(substream, name, sizeof(name));
for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
entry = &log->entries[idx];
if (entry->period_size == 0)
@@ -319,7 +322,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
if (pos >= runtime->buffer_size) {
if (printk_ratelimit()) {
char name[16];
- pcm_debug_name(substream, name, sizeof(name));
+ snd_pcm_debug_name(substream, name, sizeof(name));
xrun_log_show(substream);
snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
"buffer size = %ld, period size = %ld\n",
@@ -364,7 +367,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
if (xrun_debug(substream, in_interrupt ?
XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
char name[16];
- pcm_debug_name(substream, name, sizeof(name));
+ snd_pcm_debug_name(substream, name, sizeof(name));
snd_printd("%s_update: %s: pos=%u/%u/%u, "
"hwptr=%ld/%ld/%ld/%ld\n",
in_interrupt ? "period" : "hwptr",
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 0851cd13e30..e85e72baff9 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -22,7 +22,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
#include <linux/log2.h>
#include <sound/core.h>
#include <sound/timer.h>
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 7c1cbf0a0dc..67ebf1c21c0 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -328,6 +328,8 @@ int snd_timer_close(struct snd_timer_instance *timeri)
mutex_unlock(&register_mutex);
} else {
timer = timeri->timer;
+ if (snd_BUG_ON(!timer))
+ goto out;
/* wait, until the active callback is finished */
spin_lock_irq(&timer->lock);
while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
@@ -353,6 +355,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
}
mutex_unlock(&register_mutex);
}
+ out:
if (timeri->private_free)
timeri->private_free(timeri);
kfree(timeri->owner);
@@ -531,6 +534,8 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
if (err < 0)
return err;
timer = timeri->timer;
+ if (!timer)
+ return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
timeri->cticks = timeri->ticks;
timeri->pticks = 0;
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 4831800239d..484a35b3715 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -22,11 +22,11 @@
#include <asm/io.h>
#include <linux/delay.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/version.h>
-#include <sound/core.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
#include <sound/tea575x-tuner.h>
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -62,17 +62,6 @@ module_param(radio_nr, int, 0);
#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
#define TEA575X_BIT_FREQ_MASK 0x7fff
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
-
/*
* lowlevel part
*/
@@ -266,83 +255,23 @@ static int vidioc_s_audio(struct file *file, void *priv,
return 0;
}
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
{
- struct snd_tea575x *tea = video_drvdata(file);
+ struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = tea->mute;
+ tea->mute = ctrl->val;
+ snd_tea575x_set_freq(tea);
return 0;
}
- return -EINVAL;
-}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (tea->mute != ctrl->value) {
- tea->mute = ctrl->value;
- snd_tea575x_set_freq(tea);
- }
- return 0;
- }
return -EINVAL;
}
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
- return 0;
-}
-
-static int snd_tea575x_exclusive_open(struct file *file)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
-}
-
-static int snd_tea575x_exclusive_release(struct file *file)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- clear_bit(0, &tea->in_use);
- return 0;
-}
-
static const struct v4l2_file_operations tea575x_fops = {
.owner = THIS_MODULE,
- .open = snd_tea575x_exclusive_open,
- .release = snd_tea575x_exclusive_release,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
@@ -351,20 +280,19 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
};
static struct video_device tea575x_radio = {
.name = "tea575x-tuner",
.fops = &tea575x_fops,
.ioctl_ops = &tea575x_ioctl_ops,
- .release = video_device_release,
+ .release = video_device_release_empty,
+};
+
+static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
+ .s_ctrl = tea575x_s_ctrl,
};
/*
@@ -373,7 +301,6 @@ static struct video_device tea575x_radio = {
int snd_tea575x_init(struct snd_tea575x *tea)
{
int retval;
- struct video_device *tea575x_radio_inst;
tea->mute = 1;
@@ -381,43 +308,49 @@ int snd_tea575x_init(struct snd_tea575x *tea)
if (snd_tea575x_read(tea) != 0x55AA)
return -ENODEV;
- tea->in_use = 0;
tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
tea->freq = 90500 * 16; /* 90.5Mhz default */
+ snd_tea575x_set_freq(tea);
- tea575x_radio_inst = video_device_alloc();
- if (tea575x_radio_inst == NULL) {
- printk(KERN_ERR "tea575x-tuner: not enough memory\n");
- return -ENOMEM;
- }
+ tea->vd = tea575x_radio;
+ video_set_drvdata(&tea->vd, tea);
+ mutex_init(&tea->mutex);
+ tea->vd.lock = &tea->mutex;
- memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio));
+ v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
+ tea->vd.ctrl_handler = &tea->ctrl_handler;
+ v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+ retval = tea->ctrl_handler.error;
+ if (retval) {
+ printk(KERN_ERR "tea575x-tuner: can't initialize controls\n");
+ v4l2_ctrl_handler_free(&tea->ctrl_handler);
+ return retval;
+ }
- strcpy(tea575x_radio.name, tea->tea5759 ?
- "TEA5759 radio" : "TEA5757 radio");
+ if (tea->ext_init) {
+ retval = tea->ext_init(tea);
+ if (retval) {
+ v4l2_ctrl_handler_free(&tea->ctrl_handler);
+ return retval;
+ }
+ }
- video_set_drvdata(tea575x_radio_inst, tea);
+ v4l2_ctrl_handler_setup(&tea->ctrl_handler);
- retval = video_register_device(tea575x_radio_inst,
- VFL_TYPE_RADIO, radio_nr);
+ retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr);
if (retval) {
printk(KERN_ERR "tea575x-tuner: can't register video device!\n");
- kfree(tea575x_radio_inst);
+ v4l2_ctrl_handler_free(&tea->ctrl_handler);
return retval;
}
- snd_tea575x_set_freq(tea);
- tea->vd = tea575x_radio_inst;
-
return 0;
}
void snd_tea575x_exit(struct snd_tea575x *tea)
{
- if (tea->vd) {
- video_unregister_device(tea->vd);
- tea->vd = NULL;
- }
+ video_unregister_device(&tea->vd);
+ v4l2_ctrl_handler_free(&tea->ctrl_handler);
}
static int __init alsa_tea575x_module_init(void)
diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h
index 3773e242b58..a168ba3313a 100644
--- a/sound/isa/msnd/msnd.h
+++ b/sound/isa/msnd/msnd.h
@@ -249,7 +249,7 @@ struct snd_msnd {
/* State variables */
enum { msndClassic, msndPinnacle } type;
- mode_t mode;
+ fmode_t mode;
unsigned long flags;
#define F_RESETTING 0
#define F_HAVEDIGITAL 1
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 4d2a6ae978f..8a197fd3c57 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -458,7 +458,7 @@ static int ad1848_set_recmask(ad1848_info * devc, int mask)
return mask;
}
-static void change_bits(ad1848_info * devc, unsigned char *regval,
+static void oss_change_bits(ad1848_info *devc, unsigned char *regval,
unsigned char *muteval, int dev, int chn, int newval)
{
unsigned char mask;
@@ -516,10 +516,10 @@ static void ad1848_mixer_set_channel(ad1848_info *devc, int dev, int value, int
if (muteregoffs != regoffs) {
muteval = ad_read(devc, muteregoffs);
- change_bits(devc, &val, &muteval, dev, channel, value);
+ oss_change_bits(devc, &val, &muteval, dev, channel, value);
}
else
- change_bits(devc, &val, &val, dev, channel, value);
+ oss_change_bits(devc, &val, &val, dev, channel, value);
spin_lock_irqsave(&devc->lock,flags);
ad_write(devc, regoffs, val);
diff --git a/sound/oss/pas2_pcm.c b/sound/oss/pas2_pcm.c
index 8f7d175767a..6f13ab4afc6 100644
--- a/sound/oss/pas2_pcm.c
+++ b/sound/oss/pas2_pcm.c
@@ -63,13 +63,13 @@ static int pcm_set_speed(int arg)
if (pcm_channels & 2)
{
- foo = ((CLOCK_TICK_RATE / 2) + (arg / 2)) / arg;
- arg = ((CLOCK_TICK_RATE / 2) + (foo / 2)) / foo;
+ foo = ((PIT_TICK_RATE / 2) + (arg / 2)) / arg;
+ arg = ((PIT_TICK_RATE / 2) + (foo / 2)) / foo;
}
else
{
- foo = (CLOCK_TICK_RATE + (arg / 2)) / arg;
- arg = (CLOCK_TICK_RATE + (foo / 2)) / foo;
+ foo = (PIT_TICK_RATE + (arg / 2)) / arg;
+ arg = (PIT_TICK_RATE + (foo / 2)) / foo;
}
pcm_speed = arg;
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 9b800ce5100..2fc0624024b 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -673,7 +673,8 @@ static void configure_nonsound_components(void)
if (pss_cdrom_port == -1) { /* If cdrom port enablation wasn't requested */
printk(KERN_INFO "PSS: CDROM port not enabled.\n");
- } else if (check_region(pss_cdrom_port, 2)) {
+ } else if (!request_region(pss_cdrom_port, 2, "PSS CDROM")) {
+ pss_cdrom_port = -1;
printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
} else {
set_io_base(devc, CONF_CDROM, pss_cdrom_port);
@@ -1232,7 +1233,8 @@ static void __exit cleanup_pss(void)
if(pssmpu)
unload_pss_mpu(&cfg_mpu);
unload_pss(&cfg);
- }
+ } else if (pss_cdrom_port != -1)
+ release_region(pss_cdrom_port, 2);
if(!pss_keep_settings) /* Keep hardware settings if asked */
{
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index 2039d31b7e2..f8f3b7a66b7 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -232,7 +232,7 @@ static int detect_mixer(sb_devc * devc)
return 1;
}
-static void change_bits(sb_devc * devc, unsigned char *regval, int dev, int chn, int newval)
+static void oss_change_bits(sb_devc *devc, unsigned char *regval, int dev, int chn, int newval)
{
unsigned char mask;
int shift;
@@ -284,7 +284,7 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right)
return -EINVAL;
val = sb_getmixer(devc, regoffs);
- change_bits(devc, &val, dev, LEFT_CHN, left);
+ oss_change_bits(devc, &val, dev, LEFT_CHN, left);
if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /*
* Change register
@@ -304,7 +304,7 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right)
* Read the new one
*/
}
- change_bits(devc, &val, dev, RIGHT_CHN, right);
+ oss_change_bits(devc, &val, dev, RIGHT_CHN, right);
sb_setmixer(devc, regoffs, val);
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e90d103e177..88168044375 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,5 +1,10 @@
# ALSA PCI drivers
+config SND_TEA575X
+ tristate
+ depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2
+ default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2
+
menuconfig SND_PCI
bool "PCI sound devices"
depends on PCI
@@ -563,11 +568,6 @@ config SND_FM801_TEA575X_BOOL
FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
SF64-PCR) into the snd-fm801 driver.
-config SND_TEA575X
- tristate
- depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
- default SND_FM801 || SND_ES1968
-
source "sound/pci/hda/Kconfig"
config SND_HDSP
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 200c9a1d48b..a872d0a8297 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1909,6 +1909,7 @@ static unsigned int ad1981_jacks_whitelist[] = {
0x103c0944, /* HP nc6220 */
0x103c0934, /* HP nc8220 */
0x103c006d, /* HP nx9105 */
+ 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */
0x17340088, /* FSC Scenic-W */
0 /* end */
};
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index b941d2541dd..eae62ebbd29 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -41,31 +41,10 @@
#include <sound/tlv.h>
#include <sound/hwdep.h>
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
-#if defined CONFIG_SND_DEBUG
-/* copied from pcm_lib.c, hope later patch will make that version public
-and this copy can be removed */
-static inline void
-snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
-{
- snprintf(buf, size, "pcmC%dD%d%c:%d",
- substream->pcm->card->number,
- substream->pcm->device,
- substream->stream ? 'c' : 'p',
- substream->number);
-}
-#else
-static inline void
-snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
-{
- *buf = 0;
-}
-#endif
-
#if defined CONFIG_SND_DEBUG_VERBOSE
/**
* snd_printddd - very verbose debug printk
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index 65b7ca13115..bd47521b24e 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -631,13 +631,12 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
if (!p_cache)
return NULL;
- p_cache->p_info =
- kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
+ p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count,
+ GFP_KERNEL);
if (!p_cache->p_info) {
kfree(p_cache);
return NULL;
}
- memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
p_cache->cache_size_in_bytes = size_in_bytes;
p_cache->control_count = control_count;
p_cache->p_cache = p_dsp_control_buffer;
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 3a7afa31c1d..71d32c868c9 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -43,6 +43,7 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
struct pci_dev *dev = os_data;
struct code_header header;
char fw_name[20];
+ short err_ret = HPI_ERROR_DSP_FILE_NOT_FOUND;
int err;
sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
@@ -85,8 +86,10 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
- if (!dsp_code->pvt)
- return HPI_ERROR_MEMORY_ALLOC;
+ if (!dsp_code->pvt) {
+ err_ret = HPI_ERROR_MEMORY_ALLOC;
+ goto error2;
+ }
dsp_code->pvt->dev = dev;
dsp_code->pvt->firmware = firmware;
@@ -99,7 +102,7 @@ error2:
release_firmware(firmware);
error1:
dsp_code->block_length = 0;
- return HPI_ERROR_DSP_FILE_NOT_FOUND;
+ return err_ret;
}
/*-------------------------------------------------------------------*/
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 65fcf477073..a32502e796d 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -107,7 +107,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
union hpi_response_buffer_v1 *hr;
u16 res_max_size;
u32 uncopied_bytes;
- struct hpi_adapter *pa = NULL;
int err = 0;
if (cmd != HPI_IOCTL_LINUX)
@@ -178,15 +177,21 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} else {
u16 __user *ptr = NULL;
u32 size = 0;
-
+ u32 adapter_present;
/* -1=no data 0=read from user mem, 1=write to user mem */
int wrflag = -1;
- u32 adapter = hm->h.adapter_index;
+ struct hpi_adapter *pa;
+
+ if (hm->h.adapter_index < HPI_MAX_ADAPTERS) {
+ pa = &adapters[hm->h.adapter_index];
+ adapter_present = pa->type;
+ } else {
+ adapter_present = 0;
+ }
- if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
- hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_OPEN,
- HPI_ERROR_BAD_ADAPTER_NUMBER);
+ if (!adapter_present) {
+ hpi_init_response(&hr->r0, hm->h.object,
+ hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER);
uncopied_bytes =
copy_to_user(puhr, hr, sizeof(hr->h));
@@ -197,9 +202,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
goto out;
}
- pa = &adapters[adapter];
-
- if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
+ if (mutex_lock_interruptible(&pa->mutex)) {
err = -EINTR;
goto out;
}
@@ -235,8 +238,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
"stream buffer size %d\n",
size);
- mutex_unlock(&adapters
- [adapter].mutex);
+ mutex_unlock(&pa->mutex);
err = -EINVAL;
goto out;
}
@@ -277,7 +279,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
uncopied_bytes, size);
}
- mutex_unlock(&adapters[adapter].mutex);
+ mutex_unlock(&pa->mutex);
}
/* on return response size must be set */
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index e4d76a270c9..579fc0dce12 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2625,16 +2625,19 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
int err;
snd_azf3328_dbgcallenter();
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
+ if (dev >= SNDRV_CARDS) {
+ err = -ENODEV;
+ goto out;
+ }
if (!enable[dev]) {
dev++;
- return -ENOENT;
+ err = -ENOENT;
+ goto out;
}
err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
if (err < 0)
- return err;
+ goto out;
strcpy(card->driver, "AZF3328");
strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index fe7ad64dccd..43c7e12bc05 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -52,7 +52,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/darla20_dsp.fw");
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index d1fd34b1a8e..95b03306e02 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -56,7 +56,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/darla24_dsp.fw");
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index 1dffdc54416..8723c40183e 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -64,7 +64,7 @@
#include <sound/initval.h>
#include <sound/rawmidi.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index 050e54aa693..0058c67115d 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -56,7 +56,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/gina20_dsp.fw");
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index 5748fc6d29d..14e4925e76c 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -62,7 +62,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 4ae5e35cb5f..f416b154f14 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -54,7 +54,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 3550715bab1..e594a3b2766 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -54,7 +54,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index 19b191fd012..f0d00bfceee 100644
--- a/sound/pci/echoaudio/indigodjx.c
+++ b/sound/pci/echoaudio/indigodjx.c
@@ -54,7 +54,7 @@
#include <sound/pcm_params.h>
#include <sound/asoundef.h>
#include <sound/initval.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index a9fcedf317a..1af0037304c 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -55,7 +55,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index bcdfac63212..0b51163452b 100644
--- a/sound/pci/echoaudio/indigoiox.c
+++ b/sound/pci/echoaudio/indigoiox.c
@@ -55,7 +55,7 @@
#include <sound/pcm_params.h>
#include <sound/asoundef.h>
#include <sound/initval.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index d3a98c5dac8..3f63ab8dfff 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -62,7 +62,7 @@
#include <sound/initval.h>
#include <sound/rawmidi.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/layla20_dsp.fw");
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index 2a1dca6dce1..28313724447 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -64,7 +64,7 @@
#include <sound/initval.h>
#include <sound/rawmidi.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index 9cdf14cfdd7..eddaeb4da50 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -63,7 +63,7 @@
#include <sound/initval.h>
#include <sound/rawmidi.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index 1047be405eb..0364011c237 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -60,7 +60,7 @@
#include <sound/asoundef.h>
#include <sound/initval.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "echoaudio.h"
MODULE_FIRMWARE("ea/loader_dsp.fw");
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 7489b460855..bb7e102d672 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -243,6 +243,7 @@ config SND_HDA_GENERIC
config SND_HDA_POWER_SAVE
bool "Aggressive power-saving on HD-audio"
+ depends on PM
help
Say Y here to enable more aggressive power-saving mode on
HD-audio driver. The power-saving timeout can be configured
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c
index be58bf2f3ae..2e5876ce71f 100644
--- a/sound/pci/hda/alc268_quirks.c
+++ b/sound/pci/hda/alc268_quirks.c
@@ -476,8 +476,8 @@ static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
static const struct alc_config_preset alc268_presets[] = {
[ALC267_QUANTA_IL1] = {
- .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
- alc268_capture_nosrc_mixer },
+ .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
+ .cap_mixer = alc268_capture_nosrc_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc267_quanta_il1_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -492,8 +492,8 @@ static const struct alc_config_preset alc268_presets[] = {
.init_hook = alc_inithook,
},
[ALC268_3ST] = {
- .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
- alc268_beep_mixer },
+ .mixers = { alc268_base_mixer, alc268_beep_mixer },
+ .cap_mixer = alc268_capture_alt_mixer,
.init_verbs = { alc268_base_init_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
.dac_nids = alc268_dac_nids,
@@ -507,8 +507,8 @@ static const struct alc_config_preset alc268_presets[] = {
.input_mux = &alc268_capture_source,
},
[ALC268_TOSHIBA] = {
- .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
- alc268_beep_mixer },
+ .mixers = { alc268_toshiba_mixer, alc268_beep_mixer },
+ .cap_mixer = alc268_capture_alt_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_toshiba_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -525,8 +525,8 @@ static const struct alc_config_preset alc268_presets[] = {
.init_hook = alc_inithook,
},
[ALC268_ACER] = {
- .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
- alc268_beep_mixer },
+ .mixers = { alc268_acer_mixer, alc268_beep_mixer },
+ .cap_mixer = alc268_capture_alt_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_acer_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -543,8 +543,8 @@ static const struct alc_config_preset alc268_presets[] = {
.init_hook = alc_inithook,
},
[ALC268_ACER_DMIC] = {
- .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
- alc268_beep_mixer },
+ .mixers = { alc268_acer_dmic_mixer, alc268_beep_mixer },
+ .cap_mixer = alc268_capture_alt_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_acer_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -561,9 +561,8 @@ static const struct alc_config_preset alc268_presets[] = {
.init_hook = alc_inithook,
},
[ALC268_ACER_ASPIRE_ONE] = {
- .mixers = { alc268_acer_aspire_one_mixer,
- alc268_beep_mixer,
- alc268_capture_nosrc_mixer },
+ .mixers = { alc268_acer_aspire_one_mixer, alc268_beep_mixer},
+ .cap_mixer = alc268_capture_nosrc_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_acer_aspire_one_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -579,8 +578,8 @@ static const struct alc_config_preset alc268_presets[] = {
.init_hook = alc_inithook,
},
[ALC268_DELL] = {
- .mixers = { alc268_dell_mixer, alc268_beep_mixer,
- alc268_capture_nosrc_mixer },
+ .mixers = { alc268_dell_mixer, alc268_beep_mixer},
+ .cap_mixer = alc268_capture_nosrc_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_dell_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -596,8 +595,8 @@ static const struct alc_config_preset alc268_presets[] = {
.init_hook = alc_inithook,
},
[ALC268_ZEPTO] = {
- .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
- alc268_beep_mixer },
+ .mixers = { alc268_base_mixer, alc268_beep_mixer },
+ .cap_mixer = alc268_capture_alt_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_toshiba_verbs },
.num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -616,7 +615,8 @@ static const struct alc_config_preset alc268_presets[] = {
},
#ifdef CONFIG_SND_DEBUG
[ALC268_TEST] = {
- .mixers = { alc268_test_mixer, alc268_capture_mixer },
+ .mixers = { alc268_test_mixer },
+ .cap_mixer = alc268_capture_mixer,
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_volume_init_verbs,
alc268_beep_init_verbs },
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c
index 14fdcf29b15..5ac0e2162a4 100644
--- a/sound/pci/hda/alc269_quirks.c
+++ b/sound/pci/hda/alc269_quirks.c
@@ -531,17 +531,10 @@ static const struct snd_pci_quirk alc269_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
- SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
- SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
- ALC269_DMIC),
- SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
- ALC269_DMIC),
- SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
- SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 9c27a3a4c4d..3e7850c238c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -91,8 +91,10 @@ EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
#ifdef CONFIG_SND_HDA_POWER_SAVE
static void hda_power_work(struct work_struct *work);
static void hda_keep_power_on(struct hda_codec *codec);
+#define hda_codec_is_power_on(codec) ((codec)->power_on)
#else
static inline void hda_keep_power_on(struct hda_codec *codec) {}
+#define hda_codec_is_power_on(codec) 1
#endif
/**
@@ -1101,7 +1103,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec)
}
EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
static void restore_shutup_pins(struct hda_codec *codec)
{
@@ -1499,7 +1501,7 @@ static void purify_inactive_streams(struct hda_codec *codec)
}
}
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
/* clean up all streams; called from suspend */
static void hda_cleanup_all_streams(struct hda_codec *codec)
{
@@ -1838,7 +1840,7 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
}
EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
/**
* snd_hda_codec_resume_amp - Resume all AMP commands from the cache
* @codec: HD-audio codec
@@ -1868,7 +1870,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
}
}
EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
-#endif /* SND_HDA_NEEDS_RESUME */
+#endif /* CONFIG_PM */
static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
unsigned int ofs)
@@ -3082,7 +3084,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
}
EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
/*
* command cache
*/
@@ -3199,53 +3201,32 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
seq->param);
}
EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
-#endif /* SND_HDA_NEEDS_RESUME */
+#endif /* CONFIG_PM */
-/*
- * set power state of the codec
- */
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state)
+void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state,
+ bool eapd_workaround)
{
- hda_nid_t nid;
+ hda_nid_t nid = codec->start_nid;
int i;
- /* this delay seems necessary to avoid click noise at power-down */
- if (power_state == AC_PWRST_D3)
- msleep(100);
- snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
- power_state);
- /* partial workaround for "azx_get_response timeout" */
- if (power_state == AC_PWRST_D0 &&
- (codec->vendor_id & 0xffff0000) == 0x14f10000)
- msleep(10);
-
- nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) {
unsigned int wcaps = get_wcaps(codec, nid);
- if (wcaps & AC_WCAP_POWER) {
- unsigned int wid_type = get_wcaps_type(wcaps);
- if (power_state == AC_PWRST_D3 &&
- wid_type == AC_WID_PIN) {
- unsigned int pincap;
- /*
- * don't power down the widget if it controls
- * eapd and EAPD_BTLENABLE is set.
- */
- pincap = snd_hda_query_pin_caps(codec, nid);
- if (pincap & AC_PINCAP_EAPD) {
- int eapd = snd_hda_codec_read(codec,
- nid, 0,
+ if (!(wcaps & AC_WCAP_POWER))
+ continue;
+ /* don't power down the widget if it controls eapd and
+ * EAPD_BTLENABLE is set.
+ */
+ if (eapd_workaround && power_state == AC_PWRST_D3 &&
+ get_wcaps_type(wcaps) == AC_WID_PIN &&
+ (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
+ int eapd = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_EAPD_BTLENABLE, 0);
- eapd &= 0x02;
- if (eapd)
- continue;
- }
- }
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_POWER_STATE,
- power_state);
+ if (eapd & 0x02)
+ continue;
}
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
+ power_state);
}
if (power_state == AC_PWRST_D0) {
@@ -3262,6 +3243,26 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
} while (time_after_eq(end_time, jiffies));
}
}
+EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
+
+/*
+ * set power state of the codec
+ */
+static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state)
+{
+ if (codec->patch_ops.set_power_state) {
+ codec->patch_ops.set_power_state(codec, fg, power_state);
+ return;
+ }
+
+ /* this delay seems necessary to avoid click noise at power-down */
+ if (power_state == AC_PWRST_D3)
+ msleep(100);
+ snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+ power_state);
+ snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
+}
#ifdef CONFIG_SND_HDA_HWDEP
/* execute additional init verbs */
@@ -3274,7 +3275,7 @@ static void hda_exec_init_verbs(struct hda_codec *codec)
static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
#endif
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
/*
* call suspend and power-down; used both from PM and power-save
*/
@@ -3315,7 +3316,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
snd_hda_codec_resume_cache(codec);
}
}
-#endif /* SND_HDA_NEEDS_RESUME */
+#endif /* CONFIG_PM */
/**
@@ -4071,9 +4072,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state);
-
static void hda_power_work(struct work_struct *work)
{
struct hda_codec *codec =
@@ -4376,11 +4374,8 @@ void snd_hda_bus_reboot_notify(struct hda_bus *bus)
if (!bus)
return;
list_for_each_entry(codec, &bus->codec_list, list) {
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- if (!codec->power_on)
- continue;
-#endif
- if (codec->patch_ops.reboot_notify)
+ if (hda_codec_is_power_on(codec) &&
+ codec->patch_ops.reboot_notify)
codec->patch_ops.reboot_notify(codec);
}
}
@@ -5079,11 +5074,10 @@ int snd_hda_suspend(struct hda_bus *bus)
struct hda_codec *codec;
list_for_each_entry(codec, &bus->codec_list, list) {
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- if (!codec->power_on)
- continue;
-#endif
- hda_call_codec_suspend(codec);
+ if (hda_codec_is_power_on(codec))
+ hda_call_codec_suspend(codec);
+ if (codec->patch_ops.post_suspend)
+ codec->patch_ops.post_suspend(codec);
}
return 0;
}
@@ -5103,6 +5097,8 @@ int snd_hda_resume(struct hda_bus *bus)
struct hda_codec *codec;
list_for_each_entry(codec, &bus->codec_list, list) {
+ if (codec->patch_ops.pre_resume)
+ codec->patch_ops.pre_resume(codec);
if (snd_hda_codec_needs_resume(codec))
hda_call_codec_resume(codec);
}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f465e07a487..755f2b0f9d8 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -26,10 +26,6 @@
#include <sound/pcm.h>
#include <sound/hwdep.h>
-#if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE)
-#define SND_HDA_NEEDS_RESUME /* resume control code is required */
-#endif
-
/*
* nodes
*/
@@ -704,8 +700,12 @@ struct hda_codec_ops {
int (*init)(struct hda_codec *codec);
void (*free)(struct hda_codec *codec);
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
-#ifdef SND_HDA_NEEDS_RESUME
+ void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state);
+#ifdef CONFIG_PM
int (*suspend)(struct hda_codec *codec, pm_message_t state);
+ int (*post_suspend)(struct hda_codec *codec);
+ int (*pre_resume)(struct hda_codec *codec);
int (*resume)(struct hda_codec *codec);
#endif
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -927,7 +927,7 @@ void snd_hda_sequence_write(struct hda_codec *codec,
int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
/* cached write */
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
int direct, unsigned int verb, unsigned int parm);
void snd_hda_sequence_write_cache(struct hda_codec *codec,
@@ -1008,6 +1008,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
*/
void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
void snd_hda_bus_reboot_notify(struct hda_bus *bus);
+void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state,
+ bool eapd_workaround);
/*
* power management
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 28ce17d09c3..c34f730f481 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -144,25 +144,17 @@ static int cea_sampling_frequencies[8] = {
SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
};
-static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
+static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
int byte_index)
{
unsigned int val;
val = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_HDMI_ELDD, byte_index);
-
#ifdef BE_PARANOID
printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
#endif
-
- if ((val & AC_ELDD_ELD_VALID) == 0) {
- snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
- byte_index);
- val = 0;
- }
-
- return val & AC_ELDD_ELD_DATA;
+ return val;
}
#define GRAB_BITS(buf, byte, lowbit, bits) \
@@ -344,11 +336,26 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
if (!buf)
return -ENOMEM;
- for (i = 0; i < size; i++)
- buf[i] = hdmi_get_eld_byte(codec, nid, i);
+ for (i = 0; i < size; i++) {
+ unsigned int val = hdmi_get_eld_data(codec, nid, i);
+ if (!(val & AC_ELDD_ELD_VALID)) {
+ if (!i) {
+ snd_printd(KERN_INFO
+ "HDMI: invalid ELD data\n");
+ ret = -EINVAL;
+ goto error;
+ }
+ snd_printd(KERN_INFO
+ "HDMI: invalid ELD data byte %d\n", i);
+ val = 0;
+ } else
+ val &= AC_ELDD_ELD_DATA;
+ buf[i] = val;
+ }
ret = hdmi_update_eld(eld, buf, size);
+error:
kfree(buf);
return ret;
}
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 88b277e9740..2e7ac31afa8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -131,7 +131,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int idx, int mask, int val);
int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
int dir, int idx, int mask, int val);
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
void snd_hda_codec_resume_amp(struct hda_codec *codec);
#endif
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 1362c8ba4d1..8648917acff 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -563,7 +563,7 @@ static void ad198x_free(struct hda_codec *codec)
snd_hda_detach_beep_device(codec);
}
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
{
ad198x_shutup(codec);
@@ -579,7 +579,7 @@ static const struct hda_codec_ops ad198x_patch_ops = {
#ifdef CONFIG_SND_HDA_POWER_SAVE
.check_power_status = ad198x_check_power_status,
#endif
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
.suspend = ad198x_suspend,
#endif
.reboot_notify = ad198x_shutup,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 7f93739b1e3..d6c93d92b55 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -25,6 +25,7 @@
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_local.h"
+#include <sound/tlv.h>
/*
*/
@@ -61,9 +62,15 @@ struct cs_spec {
unsigned int hp_detect:1;
unsigned int mic_detect:1;
+ /* CS421x */
+ unsigned int spdif_detect:1;
+ unsigned int sense_b:1;
+ hda_nid_t vendor_nid;
+ struct hda_input_mux input_mux;
+ unsigned int last_input;
};
-/* available models */
+/* available models with CS420x */
enum {
CS420X_MBP53,
CS420X_MBP55,
@@ -72,6 +79,12 @@ enum {
CS420X_MODELS
};
+/* CS421x boards */
+enum {
+ CS421X_CDB4210,
+ CS421X_MODELS
+};
+
/* Vendor-specific processing widget */
#define CS420X_VENDOR_NID 0x11
#define CS_DIG_OUT1_PIN_NID 0x10
@@ -111,21 +124,42 @@ enum {
/* 0x0009 - 0x0014 -> 12 test regs */
/* 0x0015 - visibility reg */
+/*
+ * Cirrus Logic CS4210
+ *
+ * 1 DAC => HP(sense) / Speakers,
+ * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
+ * 1 SPDIF OUT => SPDIF Trasmitter(sense)
+*/
+#define CS4210_DAC_NID 0x02
+#define CS4210_ADC_NID 0x03
+#define CS421X_VENDOR_NID 0x0B
+#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
+#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
+
+#define CS421X_IDX_DEV_CFG 0x01
+#define CS421X_IDX_ADC_CFG 0x02
+#define CS421X_IDX_DAC_CFG 0x03
+#define CS421X_IDX_SPK_CTL 0x04
+
+#define SPDIF_EVENT 0x04
static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
{
- snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
+ struct cs_spec *spec = codec->spec;
+ snd_hda_codec_write(codec, spec->vendor_nid, 0,
AC_VERB_SET_COEF_INDEX, idx);
- return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0,
+ return snd_hda_codec_read(codec, spec->vendor_nid, 0,
AC_VERB_GET_PROC_COEF, 0);
}
static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
unsigned int coef)
{
- snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
+ struct cs_spec *spec = codec->spec;
+ snd_hda_codec_write(codec, spec->vendor_nid, 0,
AC_VERB_SET_COEF_INDEX, idx);
- snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
+ snd_hda_codec_write(codec, spec->vendor_nid, 0,
AC_VERB_SET_PROC_COEF, coef);
}
@@ -341,17 +375,16 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
unsigned int *idxp)
{
- int i;
+ int i, idx;
hda_nid_t nid;
nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) {
unsigned int type;
- int idx;
type = get_wcaps_type(get_wcaps(codec, nid));
if (type != AC_WID_AUD_IN)
continue;
- idx = snd_hda_get_conn_index(codec, nid, pin, 0);
+ idx = snd_hda_get_conn_index(codec, nid, pin, false);
if (idx >= 0) {
*idxp = idx;
return nid;
@@ -835,6 +868,8 @@ static int build_digital_input(struct hda_codec *codec)
/*
* auto-mute and auto-mic switching
+ * CS421x auto-output redirecting
+ * HP/SPK/SPDIF
*/
static void cs_automute(struct hda_codec *codec)
@@ -842,9 +877,25 @@ static void cs_automute(struct hda_codec *codec)
struct cs_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
unsigned int hp_present;
+ unsigned int spdif_present;
hda_nid_t nid;
int i;
+ spdif_present = 0;
+ if (cfg->dig_outs) {
+ nid = cfg->dig_out_pins[0];
+ if (is_jack_detectable(codec, nid)) {
+ /*
+ TODO: SPDIF output redirect when SENSE_B is enabled.
+ Shared (SENSE_A) jack (e.g HP/mini-TOSLINK)
+ assumed.
+ */
+ if (snd_hda_jack_detect(codec, nid)
+ /* && spec->sense_b */)
+ spdif_present = 1;
+ }
+ }
+
hp_present = 0;
for (i = 0; i < cfg->hp_outs; i++) {
nid = cfg->hp_pins[i];
@@ -854,11 +905,19 @@ static void cs_automute(struct hda_codec *codec)
if (hp_present)
break;
}
+
+ /* mute speakers if spdif or hp jack is plugged in */
for (i = 0; i < cfg->speaker_outs; i++) {
nid = cfg->speaker_pins[i];
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
hp_present ? 0 : PIN_OUT);
+ /* detect on spdif is specific to CS421x */
+ if (spec->vendor_nid == CS421X_VENDOR_NID) {
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ spdif_present ? 0 : PIN_OUT);
+ }
}
if (spec->board_config == CS420X_MBP53 ||
spec->board_config == CS420X_MBP55 ||
@@ -867,21 +926,62 @@ static void cs_automute(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x01, 0,
AC_VERB_SET_GPIO_DATA, gpio);
}
+
+ /* specific to CS421x */
+ if (spec->vendor_nid == CS421X_VENDOR_NID) {
+ /* mute HPs if spdif jack (SENSE_B) is present */
+ for (i = 0; i < cfg->hp_outs; i++) {
+ nid = cfg->hp_pins[i];
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ (spdif_present && spec->sense_b) ? 0 : PIN_HP);
+ }
+
+ /* SPDIF TX on/off */
+ if (cfg->dig_outs) {
+ nid = cfg->dig_out_pins[0];
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ spdif_present ? PIN_OUT : 0);
+
+ }
+ /* Update board GPIOs if neccessary ... */
+ }
}
+/*
+ * Auto-input redirect for CS421x
+ * Switch max 3 inputs of a single ADC (nid 3)
+*/
+
static void cs_automic(struct hda_codec *codec)
{
struct cs_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
hda_nid_t nid;
unsigned int present;
-
+
nid = cfg->inputs[spec->automic_idx].pin;
present = snd_hda_jack_detect(codec, nid);
- if (present)
- change_cur_input(codec, spec->automic_idx, 0);
- else
- change_cur_input(codec, !spec->automic_idx, 0);
+
+ /* specific to CS421x, single ADC */
+ if (spec->vendor_nid == CS421X_VENDOR_NID) {
+ if (present) {
+ spec->last_input = spec->cur_input;
+ spec->cur_input = spec->automic_idx;
+ } else {
+ spec->cur_input = spec->last_input;
+ }
+
+ snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ spec->adc_idx[spec->cur_input]);
+ } else {
+ if (present)
+ change_cur_input(codec, spec->automic_idx, 0);
+ else
+ change_cur_input(codec, !spec->automic_idx, 0);
+ }
}
/*
@@ -911,23 +1011,28 @@ static void init_output(struct hda_codec *codec)
for (i = 0; i < cfg->line_outs; i++)
snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+ /* HP */
for (i = 0; i < cfg->hp_outs; i++) {
hda_nid_t nid = cfg->hp_pins[i];
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
if (!cfg->speaker_outs)
continue;
- if (is_jack_detectable(codec, nid)) {
+ if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | HP_EVENT);
spec->hp_detect = 1;
}
}
+
+ /* Speaker */
for (i = 0; i < cfg->speaker_outs; i++)
snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
- if (spec->hp_detect)
+
+ /* SPDIF is enabled on presence detect for CS421x */
+ if (spec->hp_detect || spec->spdif_detect)
cs_automute(codec);
}
@@ -961,19 +1066,31 @@ static void init_input(struct hda_codec *codec)
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | MIC_EVENT);
}
- change_cur_input(codec, spec->cur_input, 1);
- if (spec->mic_detect)
- cs_automic(codec);
-
- coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
- if (is_active_pin(codec, CS_DMIC2_PIN_NID))
- coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */
- if (is_active_pin(codec, CS_DMIC1_PIN_NID))
- coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0
- * No effect if SPDIF_OUT2 is selected in
- * IDX_SPDIF_CTL.
- */
- cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
+ /* specific to CS421x */
+ if (spec->vendor_nid == CS421X_VENDOR_NID) {
+ if (spec->mic_detect)
+ cs_automic(codec);
+ else {
+ spec->cur_adc = spec->adc_nid[spec->cur_input];
+ snd_hda_codec_write(codec, spec->cur_adc, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ spec->adc_idx[spec->cur_input]);
+ }
+ } else {
+ change_cur_input(codec, spec->cur_input, 1);
+ if (spec->mic_detect)
+ cs_automic(codec);
+
+ coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
+ if (is_active_pin(codec, CS_DMIC2_PIN_NID))
+ coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
+ if (is_active_pin(codec, CS_DMIC1_PIN_NID))
+ coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
+ * No effect if SPDIF_OUT2 is
+ * selected in IDX_SPDIF_CTL.
+ */
+ cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
+ }
}
static const struct hda_verb cs_coef_init_verbs[] = {
@@ -1221,16 +1338,16 @@ static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
[CS420X_IMAC27] = imac27_pincfgs,
};
-static void fix_pincfg(struct hda_codec *codec, int model)
+static void fix_pincfg(struct hda_codec *codec, int model,
+ const struct cs_pincfg **pin_configs)
{
- const struct cs_pincfg *cfg = cs_pincfgs[model];
+ const struct cs_pincfg *cfg = pin_configs[model];
if (!cfg)
return;
for (; cfg->nid; cfg++)
snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
}
-
static int patch_cs420x(struct hda_codec *codec)
{
struct cs_spec *spec;
@@ -1241,11 +1358,13 @@ static int patch_cs420x(struct hda_codec *codec)
return -ENOMEM;
codec->spec = spec;
+ spec->vendor_nid = CS420X_VENDOR_NID;
+
spec->board_config =
snd_hda_check_board_config(codec, CS420X_MODELS,
cs420x_models, cs420x_cfg_tbl);
if (spec->board_config >= 0)
- fix_pincfg(codec, spec->board_config);
+ fix_pincfg(codec, spec->board_config, cs_pincfgs);
switch (spec->board_config) {
case CS420X_IMAC27:
@@ -1272,6 +1391,562 @@ static int patch_cs420x(struct hda_codec *codec)
return err;
}
+/*
+ * Cirrus Logic CS4210
+ *
+ * 1 DAC => HP(sense) / Speakers,
+ * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
+ * 1 SPDIF OUT => SPDIF Trasmitter(sense)
+*/
+
+/* CS4210 board names */
+static const char *cs421x_models[CS421X_MODELS] = {
+ [CS421X_CDB4210] = "cdb4210",
+};
+
+static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
+ /* Test Intel board + CDB2410 */
+ SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
+ {} /* terminator */
+};
+
+/* CS4210 board pinconfigs */
+/* Default CS4210 (CDB4210)*/
+static const struct cs_pincfg cdb4210_pincfgs[] = {
+ { 0x05, 0x0321401f },
+ { 0x06, 0x90170010 },
+ { 0x07, 0x03813031 },
+ { 0x08, 0xb7a70037 },
+ { 0x09, 0xb7a6003e },
+ { 0x0a, 0x034510f0 },
+ {} /* terminator */
+};
+
+static const struct cs_pincfg *cs421x_pincfgs[CS421X_MODELS] = {
+ [CS421X_CDB4210] = cdb4210_pincfgs,
+};
+
+static const struct hda_verb cs421x_coef_init_verbs[] = {
+ {0x0B, AC_VERB_SET_PROC_STATE, 1},
+ {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG},
+ /*
+ Disable Coefficient Index Auto-Increment(DAI)=1,
+ PDREF=0
+ */
+ {0x0B, AC_VERB_SET_PROC_COEF, 0x0001 },
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG},
+ /* ADC SZCMode = Digital Soft Ramp */
+ {0x0B, AC_VERB_SET_PROC_COEF, 0x0002 },
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DAC_CFG},
+ {0x0B, AC_VERB_SET_PROC_COEF,
+ (0x0002 /* DAC SZCMode = Digital Soft Ramp */
+ | 0x0004 /* Mute DAC on FIFO error */
+ | 0x0008 /* Enable DAC High Pass Filter */
+ )},
+ {} /* terminator */
+};
+
+/* Errata: CS4210 rev A1 Silicon
+ *
+ * http://www.cirrus.com/en/pubs/errata/
+ *
+ * Description:
+ * 1. Performance degredation is present in the ADC.
+ * 2. Speaker output is not completely muted upon HP detect.
+ * 3. Noise is present when clipping occurs on the amplified
+ * speaker outputs.
+ *
+ * Workaround:
+ * The following verb sequence written to the registers during
+ * initialization will correct the issues listed above.
+ */
+
+static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = {
+ {0x0B, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, 0x0006},
+ {0x0B, AC_VERB_SET_PROC_COEF, 0x9999}, /* Test mode: on */
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, 0x000A},
+ {0x0B, AC_VERB_SET_PROC_COEF, 0x14CB}, /* Chop double */
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, 0x0011},
+ {0x0B, AC_VERB_SET_PROC_COEF, 0xA2D0}, /* Increase ADC current */
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, 0x001A},
+ {0x0B, AC_VERB_SET_PROC_COEF, 0x02A9}, /* Mute speaker */
+
+ {0x0B, AC_VERB_SET_COEF_INDEX, 0x001B},
+ {0x0B, AC_VERB_SET_PROC_COEF, 0X1006}, /* Remove noise */
+
+ {} /* terminator */
+};
+
+/* Speaker Amp Gain is controlled by the vendor widget's coef 4 */
+static const DECLARE_TLV_DB_SCALE(cs421x_speaker_boost_db_scale, 900, 300, 0);
+
+static int cs421x_boost_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 3;
+ return 0;
+}
+
+static int cs421x_boost_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.integer.value[0] =
+ cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL) & 0x0003;
+ return 0;
+}
+
+static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ unsigned int vol = ucontrol->value.integer.value[0];
+ unsigned int coef =
+ cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL);
+ unsigned int original_coef = coef;
+
+ coef &= ~0x0003;
+ coef |= (vol & 0x0003);
+ if (original_coef == coef)
+ return 0;
+ else {
+ cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef);
+ return 1;
+ }
+}
+
+static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = {
+
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Speaker Boost Playback Volume",
+ .info = cs421x_boost_vol_info,
+ .get = cs421x_boost_vol_get,
+ .put = cs421x_boost_vol_put,
+ .tlv = { .p = cs421x_speaker_boost_db_scale },
+};
+
+static void cs421x_pinmux_init(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+ unsigned int def_conf, coef;
+
+ /* GPIO, DMIC_SCL, DMIC_SDA and SENSE_B are multiplexed */
+ coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
+
+ if (spec->gpio_mask)
+ coef |= 0x0008; /* B1,B2 are GPIOs */
+ else
+ coef &= ~0x0008;
+
+ if (spec->sense_b)
+ coef |= 0x0010; /* B2 is SENSE_B, not inverted */
+ else
+ coef &= ~0x0010;
+
+ cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
+
+ if ((spec->gpio_mask || spec->sense_b) &&
+ is_active_pin(codec, CS421X_DMIC_PIN_NID)) {
+
+ /*
+ GPIO or SENSE_B forced - disconnect the DMIC pin.
+ */
+ def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID);
+ def_conf &= ~AC_DEFCFG_PORT_CONN;
+ def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT);
+ snd_hda_codec_set_pincfg(codec, CS421X_DMIC_PIN_NID, def_conf);
+ }
+}
+
+static void init_cs421x_digital(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ int i;
+
+
+ for (i = 0; i < cfg->dig_outs; i++) {
+ hda_nid_t nid = cfg->dig_out_pins[i];
+ if (!cfg->speaker_outs)
+ continue;
+ if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
+
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | SPDIF_EVENT);
+ spec->spdif_detect = 1;
+ }
+ }
+}
+
+static int cs421x_init(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+
+ snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
+ snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
+
+ cs421x_pinmux_init(codec);
+
+ if (spec->gpio_mask) {
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
+ spec->gpio_mask);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
+ spec->gpio_dir);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+ spec->gpio_data);
+ }
+
+ init_output(codec);
+ init_input(codec);
+ init_cs421x_digital(codec);
+
+ return 0;
+}
+
+/*
+ * CS4210 Input MUX (1 ADC)
+ */
+static int cs421x_mux_enum_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct cs_spec *spec = codec->spec;
+
+ return snd_hda_input_mux_info(&spec->input_mux, uinfo);
+}
+
+static int cs421x_mux_enum_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct cs_spec *spec = codec->spec;
+
+ ucontrol->value.enumerated.item[0] = spec->cur_input;
+ return 0;
+}
+
+static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct cs_spec *spec = codec->spec;
+
+ return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
+ spec->adc_nid[0], &spec->cur_input);
+
+}
+
+static struct snd_kcontrol_new cs421x_capture_source = {
+
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = cs421x_mux_enum_info,
+ .get = cs421x_mux_enum_get,
+ .put = cs421x_mux_enum_put,
+};
+
+static int cs421x_add_input_volume_control(struct hda_codec *codec, int item)
+{
+ struct cs_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ const struct hda_input_mux *imux = &spec->input_mux;
+ hda_nid_t pin = cfg->inputs[item].pin;
+ struct snd_kcontrol *kctl;
+ u32 caps;
+
+ if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
+ return 0;
+
+ caps = query_amp_caps(codec, pin, HDA_INPUT);
+ caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
+ if (caps <= 1)
+ return 0;
+
+ return add_volume(codec, imux->items[item].label, 0,
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
+}
+
+/* add a (input-boost) volume control to the given input pin */
+static int build_cs421x_input(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ struct hda_input_mux *imux = &spec->input_mux;
+ int i, err, type_idx;
+ const char *label;
+
+ if (!spec->num_inputs)
+ return 0;
+
+ /* make bind-capture */
+ spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
+ spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
+ for (i = 0; i < 2; i++) {
+ struct snd_kcontrol *kctl;
+ int n;
+ if (!spec->capture_bind[i])
+ return -ENOMEM;
+ kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
+ if (!kctl)
+ return -ENOMEM;
+ kctl->private_value = (long)spec->capture_bind[i];
+ err = snd_hda_ctl_add(codec, 0, kctl);
+ if (err < 0)
+ return err;
+ for (n = 0; n < AUTO_PIN_LAST; n++) {
+ if (!spec->adc_nid[n])
+ continue;
+ err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
+ if (err < 0)
+ return err;
+ }
+ }
+
+ /* Add Input MUX Items + Capture Volume/Switch */
+ for (i = 0; i < spec->num_inputs; i++) {
+ label = hda_get_autocfg_input_label(codec, cfg, i);
+ snd_hda_add_imux_item(imux, label, spec->adc_idx[i], &type_idx);
+
+ err = cs421x_add_input_volume_control(codec, i);
+ if (err < 0)
+ return err;
+ }
+
+ /*
+ Add 'Capture Source' Switch if
+ * 2 inputs and no mic detec
+ * 3 inputs
+ */
+ if ((spec->num_inputs == 2 && !spec->mic_detect) ||
+ (spec->num_inputs == 3)) {
+
+ err = snd_hda_ctl_add(codec, spec->adc_nid[0],
+ snd_ctl_new1(&cs421x_capture_source, codec));
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+/* Single DAC (Mute/Gain) */
+static int build_cs421x_output(struct hda_codec *codec)
+{
+ hda_nid_t dac = CS4210_DAC_NID;
+ struct cs_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ struct snd_kcontrol *kctl;
+ int err;
+ char *name = "HP/Speakers";
+
+ fix_volume_caps(codec, dac);
+ if (!spec->vmaster_sw) {
+ err = add_vmaster(codec, dac);
+ if (err < 0)
+ return err;
+ }
+
+ err = add_mute(codec, name, 0,
+ HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
+ if (err < 0)
+ return err;
+ err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
+ if (err < 0)
+ return err;
+
+ err = add_volume(codec, name, 0,
+ HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
+ if (err < 0)
+ return err;
+ err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
+ if (err < 0)
+ return err;
+
+ if (cfg->speaker_outs) {
+ err = snd_hda_ctl_add(codec, 0,
+ snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
+ if (err < 0)
+ return err;
+ }
+ return err;
+}
+
+static int cs421x_build_controls(struct hda_codec *codec)
+{
+ int err;
+
+ err = build_cs421x_output(codec);
+ if (err < 0)
+ return err;
+ err = build_cs421x_input(codec);
+ if (err < 0)
+ return err;
+ err = build_digital_output(codec);
+ if (err < 0)
+ return err;
+ return cs421x_init(codec);
+}
+
+static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ switch ((res >> 26) & 0x3f) {
+ case HP_EVENT:
+ case SPDIF_EVENT:
+ cs_automute(codec);
+ break;
+
+ case MIC_EVENT:
+ cs_automic(codec);
+ break;
+ }
+}
+
+static int parse_cs421x_input(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+ struct auto_pin_cfg *cfg = &spec->autocfg;
+ int i;
+
+ for (i = 0; i < cfg->num_inputs; i++) {
+ hda_nid_t pin = cfg->inputs[i].pin;
+ spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
+ spec->cur_input = spec->last_input = i;
+ spec->num_inputs++;
+
+ /* check whether the automatic mic switch is available */
+ if (is_ext_mic(codec, i) && cfg->num_inputs >= 2) {
+ spec->mic_detect = 1;
+ spec->automic_idx = i;
+ }
+ }
+ return 0;
+}
+
+static int cs421x_parse_auto_config(struct hda_codec *codec)
+{
+ struct cs_spec *spec = codec->spec;
+ int err;
+
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
+ if (err < 0)
+ return err;
+ err = parse_output(codec);
+ if (err < 0)
+ return err;
+ err = parse_cs421x_input(codec);
+ if (err < 0)
+ return err;
+ err = parse_digital_output(codec);
+ if (err < 0)
+ return err;
+ return 0;
+}
+
+#ifdef CONFIG_PM
+/*
+ Manage PDREF, when transitioning to D3hot
+ (DAC,ADC) -> D3, PDREF=1, AFG->D3
+*/
+static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
+{
+ unsigned int coef;
+
+ snd_hda_shutup_pins(codec);
+
+ snd_hda_codec_write(codec, CS4210_DAC_NID, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+ snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+
+ coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
+ coef |= 0x0004; /* PDREF */
+ cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
+
+ return 0;
+}
+#endif
+
+static struct hda_codec_ops cs4210_patch_ops = {
+ .build_controls = cs421x_build_controls,
+ .build_pcms = cs_build_pcms,
+ .init = cs421x_init,
+ .free = cs_free,
+ .unsol_event = cs421x_unsol_event,
+#ifdef CONFIG_PM
+ .suspend = cs421x_suspend,
+#endif
+};
+
+static int patch_cs421x(struct hda_codec *codec)
+{
+ struct cs_spec *spec;
+ int err;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec)
+ return -ENOMEM;
+ codec->spec = spec;
+
+ spec->vendor_nid = CS421X_VENDOR_NID;
+
+ spec->board_config =
+ snd_hda_check_board_config(codec, CS421X_MODELS,
+ cs421x_models, cs421x_cfg_tbl);
+ if (spec->board_config >= 0)
+ fix_pincfg(codec, spec->board_config, cs421x_pincfgs);
+ /*
+ Setup GPIO/SENSE for each board (if used)
+ */
+ switch (spec->board_config) {
+ case CS421X_CDB4210:
+ snd_printd("CS4210 board: %s\n",
+ cs421x_models[spec->board_config]);
+/* spec->gpio_mask = 3;
+ spec->gpio_dir = 3;
+ spec->gpio_data = 3;
+*/
+ spec->sense_b = 1;
+
+ break;
+ }
+
+ /*
+ Update the GPIO/DMIC/SENSE_B pinmux before the configuration
+ is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
+ is disabled.
+ */
+ cs421x_pinmux_init(codec);
+
+ err = cs421x_parse_auto_config(codec);
+ if (err < 0)
+ goto error;
+
+ codec->patch_ops = cs4210_patch_ops;
+
+ return 0;
+
+ error:
+ kfree(codec->spec);
+ codec->spec = NULL;
+ return err;
+}
+
/*
* patch entries
@@ -1279,11 +1954,13 @@ static int patch_cs420x(struct hda_codec *codec)
static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
{ .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
{ .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
+ { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x },
{} /* terminator */
};
MODULE_ALIAS("snd-hda-codec-id:10134206");
MODULE_ALIAS("snd-hda-codec-id:10134207");
+MODULE_ALIAS("snd-hda-codec-id:10134210");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 884f67b8f4e..7696d05b935 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -446,6 +446,19 @@ static int conexant_init_jacks(struct hda_codec *codec)
return 0;
}
+static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state)
+{
+ if (power_state == AC_PWRST_D3)
+ msleep(100);
+ snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+ power_state);
+ /* partial workaround for "azx_get_response timeout" */
+ if (power_state == AC_PWRST_D0)
+ msleep(10);
+ snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
+}
+
static int conexant_init(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
@@ -588,6 +601,7 @@ static const struct hda_codec_ops conexant_patch_ops = {
.build_pcms = conexant_build_pcms,
.init = conexant_init,
.free = conexant_free,
+ .set_power_state = conexant_set_power,
#ifdef CONFIG_SND_HDA_POWER_SAVE
.suspend = conexant_suspend,
#endif
@@ -3334,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
#define MAX_AUTO_DACS 5
+#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */
+
/* fill analog DAC list from the widget tree */
static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
{
@@ -3356,16 +3372,26 @@ static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
/* fill pin_dac_pair list from the pin and dac list */
static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
int num_pins, hda_nid_t *dacs, int *rest,
- struct pin_dac_pair *filled, int type)
+ struct pin_dac_pair *filled, int nums,
+ int type)
{
- int i, nums;
+ int i, start = nums;
- nums = 0;
- for (i = 0; i < num_pins; i++) {
+ for (i = 0; i < num_pins; i++, nums++) {
filled[nums].pin = pins[i];
filled[nums].type = type;
filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
- nums++;
+ if (filled[nums].dac)
+ continue;
+ if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) {
+ filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG;
+ continue;
+ }
+ if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) {
+ filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
+ continue;
+ }
+ snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]);
}
return nums;
}
@@ -3381,19 +3407,19 @@ static void cx_auto_parse_output(struct hda_codec *codec)
rest = fill_cx_auto_dacs(codec, dacs);
/* parse all analog output pins */
nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
- dacs, &rest, spec->dac_info,
- AUTO_PIN_LINE_OUT);
- nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
- dacs, &rest, spec->dac_info + nums,
- AUTO_PIN_HP_OUT);
- nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
- dacs, &rest, spec->dac_info + nums,
- AUTO_PIN_SPEAKER_OUT);
+ dacs, &rest, spec->dac_info, 0,
+ AUTO_PIN_LINE_OUT);
+ nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
+ dacs, &rest, spec->dac_info, nums,
+ AUTO_PIN_HP_OUT);
+ nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
+ dacs, &rest, spec->dac_info, nums,
+ AUTO_PIN_SPEAKER_OUT);
spec->dac_info_filled = nums;
/* fill multiout struct */
for (i = 0; i < nums; i++) {
hda_nid_t dac = spec->dac_info[i].dac;
- if (!dac)
+ if (!dac || (dac & DAC_SLAVE_FLAG))
continue;
switch (spec->dac_info[i].type) {
case AUTO_PIN_LINE_OUT:
@@ -3848,7 +3874,7 @@ static void cx_auto_parse_input(struct hda_codec *codec)
}
if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
cx_auto_check_auto_mic(codec);
- if (imux->num_items > 1 && !spec->auto_mic) {
+ if (imux->num_items > 1) {
for (i = 1; i < imux->num_items; i++) {
if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
spec->adc_switching = 1;
@@ -4021,6 +4047,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
nid = spec->dac_info[i].dac;
if (!nid)
nid = spec->multiout.dac_nids[0];
+ else if (nid & DAC_SLAVE_FLAG)
+ nid &= ~DAC_SLAVE_FLAG;
select_connection(codec, spec->dac_info[i].pin, nid);
}
if (spec->auto_mute) {
@@ -4153,9 +4181,11 @@ static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
hda_nid_t pin, const char *name, int idx)
{
unsigned int caps;
- caps = query_amp_caps(codec, dac, HDA_OUTPUT);
- if (caps & AC_AMPCAP_NUM_STEPS)
- return cx_auto_add_pb_volume(codec, dac, name, idx);
+ if (dac && !(dac & DAC_SLAVE_FLAG)) {
+ caps = query_amp_caps(codec, dac, HDA_OUTPUT);
+ if (caps & AC_AMPCAP_NUM_STEPS)
+ return cx_auto_add_pb_volume(codec, dac, name, idx);
+ }
caps = query_amp_caps(codec, pin, HDA_OUTPUT);
if (caps & AC_AMPCAP_NUM_STEPS)
return cx_auto_add_pb_volume(codec, pin, name, idx);
@@ -4177,8 +4207,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
for (i = 0; i < spec->dac_info_filled; i++) {
const char *label;
int idx, type;
- if (!spec->dac_info[i].dac)
- continue;
+ hda_nid_t dac = spec->dac_info[i].dac;
type = spec->dac_info[i].type;
if (type == AUTO_PIN_LINE_OUT)
type = spec->autocfg.line_out_type;
@@ -4197,7 +4226,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
idx = num_spk++;
break;
}
- err = try_add_pb_volume(codec, spec->dac_info[i].dac,
+ err = try_add_pb_volume(codec, dac,
spec->dac_info[i].pin,
label, idx);
if (err < 0)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 52ce07534e5..7cabd731716 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -565,11 +565,11 @@ static void alc_hp_automute(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- if (!spec->automute)
- return;
spec->jack_present =
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
spec->autocfg.hp_pins);
+ if (!spec->automute)
+ return;
update_speakers(codec);
}
@@ -578,11 +578,11 @@ static void alc_line_automute(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- if (!spec->automute || !spec->detect_line)
- return;
spec->line_jack_present =
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
spec->autocfg.line_out_pins);
+ if (!spec->automute || !spec->detect_line)
+ return;
update_speakers(codec);
}
@@ -895,13 +895,15 @@ static void alc_init_auto_hp(struct hda_codec *codec)
if (present == 3)
spec->automute_hp_lo = 1; /* both HP and LO automute */
- if (!cfg->speaker_pins[0]) {
+ if (!cfg->speaker_pins[0] &&
+ cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
memcpy(cfg->speaker_pins, cfg->line_out_pins,
sizeof(cfg->speaker_pins));
cfg->speaker_outs = cfg->line_outs;
}
- if (!cfg->hp_pins[0]) {
+ if (!cfg->hp_pins[0] &&
+ cfg->line_out_type == AUTO_PIN_HP_OUT) {
memcpy(cfg->hp_pins, cfg->line_out_pins,
sizeof(cfg->hp_pins));
cfg->hp_outs = cfg->line_outs;
@@ -920,6 +922,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
spec->automute_mode = ALC_AUTOMUTE_PIN;
}
if (spec->automute && cfg->line_out_pins[0] &&
+ cfg->speaker_pins[0] &&
cfg->line_out_pins[0] != cfg->hp_pins[0] &&
cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
for (i = 0; i < cfg->line_outs; i++) {
@@ -1781,6 +1784,7 @@ static const char * const alc_slave_vols[] = {
"Speaker Playback Volume",
"Mono Playback Volume",
"Line-Out Playback Volume",
+ "PCM Playback Volume",
NULL,
};
@@ -1795,6 +1799,7 @@ static const char * const alc_slave_sws[] = {
"Mono Playback Switch",
"IEC958 Playback Switch",
"Line-Out Playback Switch",
+ "PCM Playback Switch",
NULL,
};
@@ -1911,7 +1916,7 @@ static int alc_build_controls(struct hda_codec *codec)
return err;
}
}
- if (spec->cap_mixer) {
+ if (spec->cap_mixer && spec->adc_nids) {
const char *kname = kctl ? kctl->id.name : NULL;
for (knew = spec->cap_mixer; knew->name; knew++) {
if (kname && strcmp(knew->name, kname) == 0)
@@ -2386,7 +2391,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
}
#endif
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
static int alc_resume(struct hda_codec *codec)
{
msleep(150); /* to avoid pop noise */
@@ -2406,7 +2411,7 @@ static const struct hda_codec_ops alc_patch_ops = {
.init = alc_init,
.free = alc_free,
.unsol_event = alc_unsol_event,
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
.resume = alc_resume,
#endif
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -2801,7 +2806,8 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
int i;
again:
- spec->multiout.num_dacs = 0;
+ /* set num_dacs once to full for alc_auto_look_for_dac() */
+ spec->multiout.num_dacs = cfg->line_outs;
spec->multiout.hp_nid = 0;
spec->multiout.extra_out_nid[0] = 0;
memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
@@ -2834,6 +2840,8 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
}
}
+ /* re-count num_dacs and squash invalid entries */
+ spec->multiout.num_dacs = 0;
for (i = 0; i < cfg->line_outs; i++) {
if (spec->private_dac_nids[i])
spec->multiout.num_dacs++;
@@ -3075,16 +3083,22 @@ static void alc_auto_init_multi_out(struct hda_codec *codec)
static void alc_auto_init_extra_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- hda_nid_t pin;
+ hda_nid_t pin, dac;
pin = spec->autocfg.hp_pins[0];
- if (pin)
- alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
- spec->multiout.hp_nid);
+ if (pin) {
+ dac = spec->multiout.hp_nid;
+ if (!dac)
+ dac = spec->multiout.dac_nids[0];
+ alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
+ }
pin = spec->autocfg.speaker_pins[0];
- if (pin)
- alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
- spec->multiout.extra_out_nid[0]);
+ if (pin) {
+ dac = spec->multiout.extra_out_nid[0];
+ if (!dac)
+ dac = spec->multiout.dac_nids[0];
+ alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
+ }
}
/*
@@ -3674,7 +3688,7 @@ static int patch_alc880(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc880_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -3801,7 +3815,7 @@ static int patch_alc260(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc260_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -3980,7 +3994,7 @@ static int patch_alc882(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc882_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -4134,7 +4148,7 @@ static int patch_alc262(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc262_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -4290,7 +4304,7 @@ static int patch_alc268(struct hda_codec *codec)
(0 << AC_AMPCAP_MUTE_SHIFT));
}
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -4410,7 +4424,7 @@ static void alc269_shutup(struct hda_codec *codec)
}
}
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
static int alc269_resume(struct hda_codec *codec)
{
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
@@ -4433,7 +4447,7 @@ static int alc269_resume(struct hda_codec *codec)
hda_call_check_power_status(codec, 0x01);
return 0;
}
-#endif /* SND_HDA_NEEDS_RESUME */
+#endif /* CONFIG_PM */
static void alc269_fixup_hweq(struct hda_codec *codec,
const struct alc_fixup *fix, int action)
@@ -4478,6 +4492,22 @@ static void alc269_fixup_pcm_44k(struct hda_codec *codec,
spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
}
+static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
+ const struct alc_fixup *fix, int action)
+{
+ int coef;
+
+ if (action != ALC_FIXUP_ACT_INIT)
+ return;
+ /* The digital-mic unit sends PDM (differential signal) instead of
+ * the standard PCM, thus you can't record a valid mono stream as is.
+ * Below is a workaround specific to ALC269 to control the dmic
+ * signal source as mono.
+ */
+ coef = alc_read_coef_idx(codec, 0x07);
+ alc_write_coef_idx(codec, 0x07, coef | 0x80);
+}
+
enum {
ALC269_FIXUP_SONY_VAIO,
ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -4488,6 +4518,7 @@ enum {
ALC275_FIXUP_SONY_HWEQ,
ALC271_FIXUP_DMIC,
ALC269_FIXUP_PCM_44K,
+ ALC269_FIXUP_STEREO_DMIC,
};
static const struct alc_fixup alc269_fixups[] = {
@@ -4550,10 +4581,19 @@ static const struct alc_fixup alc269_fixups[] = {
.type = ALC_FIXUP_FUNC,
.v.func = alc269_fixup_pcm_44k,
},
+ [ALC269_FIXUP_STEREO_DMIC] = {
+ .type = ALC_FIXUP_FUNC,
+ .v.func = alc269_fixup_stereo_dmic,
+ },
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
+ SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
@@ -4702,7 +4742,7 @@ static int patch_alc269(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc269_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -4725,7 +4765,7 @@ static int patch_alc269(struct hda_codec *codec)
spec->vmaster_nid = 0x02;
codec->patch_ops = alc_patch_ops;
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
codec->patch_ops.resume = alc269_resume;
#endif
if (board_config == ALC_MODEL_AUTO)
@@ -4840,7 +4880,7 @@ static int patch_alc861(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc861_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -4981,7 +5021,7 @@ static int patch_alc861vd(struct hda_codec *codec)
add_verb(spec, alc660vd_eapd_verbs);
}
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -5197,7 +5237,7 @@ static int patch_alc662(struct hda_codec *codec)
if (board_config != ALC_MODEL_AUTO)
setup_preset(codec, &alc662_presets[board_config]);
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
@@ -5333,7 +5373,7 @@ static int patch_alc680(struct hda_codec *codec)
#endif
}
- if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
+ if (!spec->no_analog && !spec->adc_nids) {
alc_auto_fill_adc_caps(codec);
alc_rebuild_imux_for_auto_mic(codec);
alc_remove_invalid_adc_nids(codec);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 56425a53cf1..5145b663ef6 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -95,6 +95,7 @@ enum {
STAC_92HD83XXX_PWR_REF,
STAC_DELL_S14,
STAC_92HD83XXX_HP,
+ STAC_92HD83XXX_HP_cNB11_INTQUAD,
STAC_HP_DV7_4000,
STAC_92HD83XXX_MODELS
};
@@ -212,6 +213,7 @@ struct sigmatel_spec {
unsigned int gpio_mute;
unsigned int gpio_led;
unsigned int gpio_led_polarity;
+ unsigned int vref_led;
/* stream */
unsigned int stream_delay;
@@ -671,6 +673,32 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int stac_vrefout_set(struct hda_codec *codec,
+ hda_nid_t nid, unsigned int new_vref)
+{
+ int error, pinctl;
+
+ snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
+ pinctl = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+
+ if (pinctl < 0)
+ return pinctl;
+
+ pinctl &= 0xff;
+ pinctl &= ~AC_PINCTL_VREFEN;
+ pinctl |= (new_vref & AC_PINCTL_VREFEN);
+
+ error = snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
+ if (error < 0)
+ return error;
+
+ return 1;
+}
+#endif
+
static unsigned int stac92xx_vref_set(struct hda_codec *codec,
hda_nid_t nid, unsigned int new_vref)
{
@@ -1636,10 +1664,17 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
0x40f000f0, 0x40f000f0,
};
+static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
+ 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
+ 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
+ 0x40f000f0, 0x40f000f0,
+};
+
static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
[STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
[STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
[STAC_DELL_S14] = dell_s14_pin_configs,
+ [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
[STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
};
@@ -1649,6 +1684,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
[STAC_92HD83XXX_PWR_REF] = "mic-ref",
[STAC_DELL_S14] = "dell-s14",
[STAC_92HD83XXX_HP] = "hp",
+ [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
[STAC_HP_DV7_4000] = "hp-dv7-4000",
};
@@ -1661,7 +1697,47 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
"unknown Dell", STAC_DELL_S14),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
- "HP", STAC_92HD83XXX_HP),
+ "HP", STAC_92HD83XXX_HP),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
{} /* terminator */
};
@@ -4020,6 +4096,8 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
{
unsigned int gpiostate, gpiomask, gpiodir;
+ snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
+
gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
AC_VERB_GET_GPIO_DATA, 0);
gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
@@ -4209,10 +4287,12 @@ static void stac_store_hints(struct hda_codec *codec)
spec->eapd_switch = val;
get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- if (spec->gpio_led_polarity)
- spec->gpio_data |= spec->gpio_led;
+ if (spec->gpio_led <= 8) {
+ spec->gpio_mask |= spec->gpio_led;
+ spec->gpio_dir |= spec->gpio_led;
+ if (spec->gpio_led_polarity)
+ spec->gpio_data |= spec->gpio_led;
+ }
}
}
@@ -4382,11 +4462,26 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
snd_array_free(&spec->kctls);
}
+static void stac92xx_shutup_pins(struct hda_codec *codec)
+{
+ unsigned int i, def_conf;
+
+ if (codec->bus->shutdown)
+ return;
+ for (i = 0; i < codec->init_pins.used; i++) {
+ struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
+ def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
+ if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
+ snd_hda_codec_write(codec, pin->nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+ }
+}
+
static void stac92xx_shutup(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
- snd_hda_shutup_pins(codec);
+ stac92xx_shutup_pins(codec);
if (spec->eapd_mask)
stac_gpio_set(codec, spec->gpio_mask,
@@ -4784,10 +4879,11 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
NULL, dev))) {
- if (sscanf(dev->name, "HP_Mute_LED_%d_%d",
+ if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
&spec->gpio_led_polarity,
&spec->gpio_led) == 2) {
- spec->gpio_led = 1 << spec->gpio_led;
+ if (spec->gpio_led < 4)
+ spec->gpio_led = 1 << spec->gpio_led;
return 1;
}
if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -4885,7 +4981,7 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
#define stac927x_proc_hook NULL
#endif
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
static int stac92xx_resume(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
@@ -4901,29 +4997,81 @@ static int stac92xx_resume(struct hda_codec *codec)
stac_issue_unsol_event(codec,
spec->autocfg.line_out_pins[0]);
}
+ return 0;
+}
+
+static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
+{
+ stac92xx_shutup(codec);
+ return 0;
+}
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int stac92xx_pre_resume(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+
/* sync mute LED */
- if (spec->gpio_led)
- hda_call_check_power_status(codec, 0x01);
+ if (spec->gpio_led) {
+ if (spec->gpio_led <= 8) {
+ stac_gpio_set(codec, spec->gpio_mask,
+ spec->gpio_dir, spec->gpio_data);
+ } else {
+ stac_vrefout_set(codec,
+ spec->gpio_led, spec->vref_led);
+ }
+ }
return 0;
}
+static int stac92xx_post_suspend(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ if (spec->gpio_led > 8) {
+ /* with vref-out pin used for mute led control
+ * codec AFG is prevented from D3 state, but on
+ * system suspend it can (and should) be used
+ */
+ snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+ }
+ return 0;
+}
+
+static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state)
+{
+ unsigned int afg_power_state = power_state;
+ struct sigmatel_spec *spec = codec->spec;
+
+ if (power_state == AC_PWRST_D3) {
+ if (spec->gpio_led > 8) {
+ /* with vref-out pin used for mute led control
+ * codec AFG is prevented from D3 state
+ */
+ afg_power_state = AC_PWRST_D1;
+ }
+ /* this delay seems necessary to avoid click noise at power-down */
+ msleep(100);
+ }
+ snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+ afg_power_state);
+ snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
+}
+
/*
- * using power check for controlling mute led of HP notebooks
- * check for mute state only on Speakers (nid = 0x10)
- *
- * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
- * the LED is NOT working properly !
- *
- * Changed name to reflect that it now works for any designated
- * model, not just HP HDX.
+ * For this feature CONFIG_SND_HDA_POWER_SAVE is needed
+ * as mute LED state is updated in check_power_status hook
*/
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int stac92xx_hp_check_power_status(struct hda_codec *codec,
- hda_nid_t nid)
+static int stac92xx_update_led_status(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
- int i, muted = 1;
+ int i, num_ext_dacs, muted = 1;
+ unsigned int muted_lvl, notmtd_lvl;
+ hda_nid_t nid;
+
+ if (!spec->gpio_led)
+ return 0;
for (i = 0; i < spec->multiout.num_dacs; i++) {
nid = spec->multiout.dac_nids[i];
@@ -4933,27 +5081,58 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
break;
}
}
- if (muted)
- spec->gpio_data &= ~spec->gpio_led; /* orange */
- else
- spec->gpio_data |= spec->gpio_led; /* white */
-
- if (!spec->gpio_led_polarity) {
- /* LED state is inverted on these systems */
- spec->gpio_data ^= spec->gpio_led;
+ if (muted && spec->multiout.hp_nid)
+ if (!(snd_hda_codec_amp_read(codec,
+ spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
+ HDA_AMP_MUTE)) {
+ muted = 0; /* HP is not muted */
+ }
+ num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
+ for (i = 0; muted && i < num_ext_dacs; i++) {
+ nid = spec->multiout.extra_out_nid[i];
+ if (nid == 0)
+ break;
+ if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
+ HDA_AMP_MUTE)) {
+ muted = 0; /* extra output is not muted */
+ }
}
+ /*polarity defines *not* muted state level*/
+ if (spec->gpio_led <= 8) {
+ if (muted)
+ spec->gpio_data &= ~spec->gpio_led; /* orange */
+ else
+ spec->gpio_data |= spec->gpio_led; /* white */
- stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
+ if (!spec->gpio_led_polarity) {
+ /* LED state is inverted on these systems */
+ spec->gpio_data ^= spec->gpio_led;
+ }
+ stac_gpio_set(codec, spec->gpio_mask,
+ spec->gpio_dir, spec->gpio_data);
+ } else {
+ notmtd_lvl = spec->gpio_led_polarity ?
+ AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
+ muted_lvl = spec->gpio_led_polarity ?
+ AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
+ spec->vref_led = muted ? muted_lvl : notmtd_lvl;
+ stac_vrefout_set(codec, spec->gpio_led, spec->vref_led);
+ }
return 0;
}
-#endif
-static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
+/*
+ * use power check for controlling mute led of HP notebooks
+ */
+static int stac92xx_check_power_status(struct hda_codec *codec,
+ hda_nid_t nid)
{
- stac92xx_shutup(codec);
+ stac92xx_update_led_status(codec);
+
return 0;
}
-#endif
+#endif /* CONFIG_SND_HDA_POWER_SAVE */
+#endif /* CONFIG_PM */
static const struct hda_codec_ops stac92xx_patch_ops = {
.build_controls = stac92xx_build_controls,
@@ -4961,7 +5140,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
.init = stac92xx_init,
.free = stac92xx_free,
.unsol_event = stac92xx_unsol_event,
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
.suspend = stac92xx_suspend,
.resume = stac92xx_resume,
#endif
@@ -5477,12 +5656,19 @@ again:
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- spec->gpio_data |= spec->gpio_led;
- /* register check_power_status callback. */
+ if (spec->gpio_led <= 8) {
+ spec->gpio_mask |= spec->gpio_led;
+ spec->gpio_dir |= spec->gpio_led;
+ spec->gpio_data |= spec->gpio_led;
+ } else {
+ codec->patch_ops.set_power_state =
+ stac92xx_set_power_state;
+ codec->patch_ops.post_suspend =
+ stac92xx_post_suspend;
+ }
+ codec->patch_ops.pre_resume = stac92xx_pre_resume;
codec->patch_ops.check_power_status =
- stac92xx_hp_check_power_status;
+ stac92xx_check_power_status;
}
#endif
@@ -5805,12 +5991,19 @@ again:
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- spec->gpio_data |= spec->gpio_led;
- /* register check_power_status callback. */
+ if (spec->gpio_led <= 8) {
+ spec->gpio_mask |= spec->gpio_led;
+ spec->gpio_dir |= spec->gpio_led;
+ spec->gpio_data |= spec->gpio_led;
+ } else {
+ codec->patch_ops.set_power_state =
+ stac92xx_set_power_state;
+ codec->patch_ops.post_suspend =
+ stac92xx_post_suspend;
+ }
+ codec->patch_ops.pre_resume = stac92xx_pre_resume;
codec->patch_ops.check_power_status =
- stac92xx_hp_check_power_status;
+ stac92xx_check_power_status;
}
#endif
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index f38160b00e1..4ebfbd874c9 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1708,7 +1708,7 @@ static void via_unsol_event(struct hda_codec *codec,
via_gpio_control(codec);
}
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
static int via_suspend(struct hda_codec *codec, pm_message_t state)
{
struct via_spec *spec = codec->spec;
@@ -1736,7 +1736,7 @@ static const struct hda_codec_ops via_patch_ops = {
.init = via_init,
.free = via_free,
.unsol_event = via_unsol_event,
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
.suspend = via_suspend,
#endif
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -2084,7 +2084,7 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec)
struct via_spec *spec = codec->spec;
struct nid_path *path;
bool check_dac;
- hda_nid_t pin, dac;
+ hda_nid_t pin, dac = 0;
int err;
pin = spec->autocfg.speaker_pins[0];
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index e2a124ae27e..6792eda9c9a 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -26,7 +26,7 @@
#define LX6464ES_H
#include <linux/spinlock.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index af130ee0c45..493e3946756 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -521,6 +521,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
/* revisions >= 230 indicate AES32 card */
+#define HDSPM_MADI_ANCIENT_REV 204
#define HDSPM_MADI_OLD_REV 207
#define HDSPM_MADI_REV 210
#define HDSPM_RAYDAT_REV 211
@@ -1217,6 +1218,22 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
rate = 0;
break;
}
+
+ /* QS and DS rates normally can not be detected
+ * automatically by the card. Only exception is MADI
+ * in 96k frame mode.
+ *
+ * So if we read SS values (32 .. 48k), check for
+ * user-provided DS/QS bits in the control register
+ * and multiply the base frequency accordingly.
+ */
+ if (rate <= 48000) {
+ if (hdspm->control_register & HDSPM_QuadSpeed)
+ rate *= 4;
+ else if (hdspm->control_register &
+ HDSPM_DoubleSpeed)
+ rate *= 2;
+ }
}
break;
}
@@ -1322,6 +1339,10 @@ static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period)
break;
case MADIface:
freq_const = 131072000000000ULL;
+ break;
+ default:
+ snd_BUG();
+ return 0;
}
return div_u64(freq_const, period);
@@ -1339,16 +1360,19 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
switch (hdspm->io_type) {
case MADIface:
- n = 131072000000000ULL; /* 125 MHz */
- break;
+ n = 131072000000000ULL; /* 125 MHz */
+ break;
case MADI:
case AES32:
- n = 110069313433624ULL; /* 105 MHz */
- break;
+ n = 110069313433624ULL; /* 105 MHz */
+ break;
case RayDAT:
case AIO:
- n = 104857600000000ULL; /* 100 MHz */
- break;
+ n = 104857600000000ULL; /* 100 MHz */
+ break;
+ default:
+ snd_BUG();
+ return;
}
n = div_u64(n, rate);
@@ -3415,6 +3439,91 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
return change;
}
+#define HDSPM_MADI_SPEEDMODE(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = xindex, \
+ .info = snd_hdspm_info_madi_speedmode, \
+ .get = snd_hdspm_get_madi_speedmode, \
+ .put = snd_hdspm_put_madi_speedmode \
+}
+
+static int hdspm_madi_speedmode(struct hdspm *hdspm)
+{
+ if (hdspm->control_register & HDSPM_QuadSpeed)
+ return 2;
+ if (hdspm->control_register & HDSPM_DoubleSpeed)
+ return 1;
+ return 0;
+}
+
+static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
+{
+ hdspm->control_register &= ~(HDSPM_DoubleSpeed | HDSPM_QuadSpeed);
+ switch (mode) {
+ case 0:
+ break;
+ case 1:
+ hdspm->control_register |= HDSPM_DoubleSpeed;
+ break;
+ case 2:
+ hdspm->control_register |= HDSPM_QuadSpeed;
+ break;
+ }
+ hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+ return 0;
+}
+
+static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[] = { "Single", "Double", "Quad" };
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 3;
+
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item =
+ uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name,
+ texts[uinfo->value.enumerated.item]);
+
+ return 0;
+}
+
+static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+
+ spin_lock_irq(&hdspm->lock);
+ ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm);
+ spin_unlock_irq(&hdspm->lock);
+ return 0;
+}
+
+static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+ int change;
+ int val;
+
+ if (!snd_hdspm_use_is_exclusive(hdspm))
+ return -EBUSY;
+ val = ucontrol->value.integer.value[0];
+ if (val < 0)
+ val = 0;
+ if (val > 2)
+ val = 2;
+ spin_lock_irq(&hdspm->lock);
+ change = val != hdspm_madi_speedmode(hdspm);
+ hdspm_set_madi_speedmode(hdspm, val);
+ spin_unlock_irq(&hdspm->lock);
+ return change;
+}
#define HDSPM_MIXER(xname, xindex) \
{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
@@ -4289,7 +4398,8 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
HDSPM_TX_64("TX 64 channels mode", 0),
HDSPM_C_TMS("Clear Track Marker", 0),
HDSPM_SAFE_MODE("Safe Mode", 0),
- HDSPM_INPUT_SELECT("Input Select", 0)
+ HDSPM_INPUT_SELECT("Input Select", 0),
+ HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
};
@@ -4302,7 +4412,8 @@ static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = {
HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
HDSPM_TX_64("TX 64 channels mode", 0),
HDSPM_C_TMS("Clear Track Marker", 0),
- HDSPM_SAFE_MODE("Safe Mode", 0)
+ HDSPM_SAFE_MODE("Safe Mode", 0),
+ HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
};
static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
@@ -6381,6 +6492,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
switch (hdspm->firmware_rev) {
case HDSPM_MADI_REV:
case HDSPM_MADI_OLD_REV:
+ case HDSPM_MADI_ANCIENT_REV:
hdspm->io_type = MADI;
hdspm->card_name = "RME MADI";
hdspm->midiPorts = 3;
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index d6651c033cb..a118a0fb9d8 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -56,7 +56,7 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
switch (params_rate(params)) {
case 48000:
- clk = 12288000;
+ clk = 24576000;
break;
}
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 36a030f1d1f..665d9240c4a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -78,7 +78,6 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8900 if I2C
select SND_SOC_WM8903 if I2C
select SND_SOC_WM8904 if I2C
- select SND_SOC_WM8915 if I2C
select SND_SOC_WM8940 if I2C
select SND_SOC_WM8955 if I2C
select SND_SOC_WM8960 if I2C
@@ -95,6 +94,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8993 if I2C
select SND_SOC_WM8994 if MFD_WM8994
select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
+ select SND_SOC_WM8996 if I2C
select SND_SOC_WM9081 if I2C
select SND_SOC_WM9090 if I2C
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -250,10 +250,11 @@ config SND_SOC_TLV320DAC33
tristate
config SND_SOC_TWL4030
- select TWL4030_CODEC
+ select MFD_TWL4030_AUDIO
tristate
config SND_SOC_TWL6040
+ select TWL6040_CORE
tristate
config SND_SOC_UDA134X
@@ -328,9 +329,6 @@ config SND_SOC_WM8903
config SND_SOC_WM8904
tristate
-config SND_SOC_WM8915
- tristate
-
config SND_SOC_WM8940
tristate
@@ -379,6 +377,9 @@ config SND_SOC_WM8994
config SND_SOC_WM8995
tristate
+config SND_SOC_WM8996
+ tristate
+
config SND_SOC_WM9081
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index da9990fb856..5119a7e2c1a 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -63,7 +63,7 @@ snd-soc-wm8804-objs := wm8804.o
snd-soc-wm8900-objs := wm8900.o
snd-soc-wm8903-objs := wm8903.o
snd-soc-wm8904-objs := wm8904.o
-snd-soc-wm8915-objs := wm8915.o
+snd-soc-wm8996-objs := wm8996.o
snd-soc-wm8940-objs := wm8940.o
snd-soc-wm8955-objs := wm8955.o
snd-soc-wm8960-objs := wm8960.o
@@ -160,7 +160,7 @@ obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
-obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o
+obj-$(CONFIG_SND_SOC_WM8996) += snd-soc-wm8996.o
obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 2374ca5ffe6..eedb6f5e582 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -27,11 +27,6 @@ struct ad193x_priv {
int sysclk;
};
-/* ad193x register cache & default register settings */
-static const u8 ad193x_reg[AD193X_NUM_REGS] = {
- 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
-};
-
/*
* AD193X volume/mute/de-emphasis etc. controls
*/
@@ -307,7 +302,8 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
- reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
+ reg = (reg & (~AD193X_DAC_WORD_LEN_MASK))
+ | (word_len << AD193X_DAC_WORD_LEN_SHFT);
snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
reg = snd_soc_read(codec, AD193X_ADC_CTRL1);
@@ -389,9 +385,6 @@ static int ad193x_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
.probe = ad193x_probe,
- .reg_cache_default = ad193x_reg,
- .reg_cache_size = AD193X_NUM_REGS,
- .reg_word_size = sizeof(u16),
};
#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 9747b549787..cccc2e8e5fb 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -34,7 +34,8 @@
#define AD193X_DAC_LEFT_HIGH (1 << 3)
#define AD193X_DAC_BCLK_INV (1 << 7)
#define AD193X_DAC_CTRL2 0x804
-#define AD193X_DAC_WORD_LEN_MASK 0xC
+#define AD193X_DAC_WORD_LEN_SHFT 3
+#define AD193X_DAC_WORD_LEN_MASK 0x18
#define AD193X_DAC_MASTER_MUTE 1
#define AD193X_DAC_CHNL_MUTE 0x805
#define AD193X_DACL1_MUTE 0
@@ -63,7 +64,7 @@
#define AD193X_ADC_CTRL1 0x80f
#define AD193X_ADC_SERFMT_MASK 0x60
#define AD193X_ADC_SERFMT_STEREO (0 << 5)
-#define AD193X_ADC_SERFMT_TDM (1 << 2)
+#define AD193X_ADC_SERFMT_TDM (1 << 5)
#define AD193X_ADC_SERFMT_AUX (2 << 5)
#define AD193X_ADC_WORD_LEN_MASK 0x3
#define AD193X_ADC_CTRL2 0x810
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index ff29380c9ed..7e4066e131e 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -33,73 +33,31 @@
#define SGTL5000_DAP_REG_OFFSET 0x0100
#define SGTL5000_MAX_REG_OFFSET 0x013A
-/* default value of sgtl5000 registers except DAP */
-static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = {
- 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */
- 0x0000, /* 0x0002, CHIP_DIG_POWER. */
- 0x0008, /* 0x0004, CHIP_CKL_CTRL */
- 0x0010, /* 0x0006, CHIP_I2S_CTRL */
- 0x0000, /* 0x0008, reserved */
- 0x0008, /* 0x000A, CHIP_SSS_CTRL */
- 0x0000, /* 0x000C, reserved */
- 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */
- 0x3c3c, /* 0x0010, CHIP_DAC_VOL */
- 0x0000, /* 0x0012, reserved */
- 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */
- 0x0000, /* 0x0016, reserved */
- 0x0000, /* 0x0018, reserved */
- 0x0000, /* 0x001A, reserved */
- 0x0000, /* 0x001E, reserved */
- 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */
- 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */
- 0x0111, /* 0x0024, CHIP_ANN_CTRL */
- 0x0000, /* 0x0026, CHIP_LINREG_CTRL */
- 0x0000, /* 0x0028, CHIP_REF_CTRL */
- 0x0000, /* 0x002A, CHIP_MIC_CTRL */
- 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */
- 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */
- 0x7060, /* 0x0030, CHIP_ANA_POWER */
- 0x5000, /* 0x0032, CHIP_PLL_CTRL */
- 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */
- 0x0000, /* 0x0036, CHIP_ANA_STATUS */
- 0x0000, /* 0x0038, reserved */
- 0x0000, /* 0x003A, CHIP_ANA_TEST2 */
- 0x0000, /* 0x003C, CHIP_SHORT_CTRL */
- 0x0000, /* reserved */
-};
-
-/* default value of dap registers */
-static const u16 sgtl5000_dap_regs[] = {
- 0x0000, /* 0x0100, DAP_CONTROL */
- 0x0000, /* 0x0102, DAP_PEQ */
- 0x0040, /* 0x0104, DAP_BASS_ENHANCE */
- 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */
- 0x0000, /* 0x0108, DAP_AUDIO_EQ */
- 0x0040, /* 0x010A, DAP_SGTL_SURROUND */
- 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */
- 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */
- 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */
- 0x0000, /* 0x0112, reserved */
- 0x0000, /* 0x0114, reserved */
- 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */
- 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */
- 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */
- 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */
- 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */
- 0x8000, /* 0x0120, DAP_MAIN_CHAN */
- 0x0000, /* 0x0122, DAP_MIX_CHAN */
- 0x0510, /* 0x0124, DAP_AVC_CTRL */
- 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */
- 0x0028, /* 0x0128, DAP_AVC_ATTACK */
- 0x0050, /* 0x012A, DAP_AVC_DECAY */
- 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */
- 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */
- 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */
- 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */
- 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */
- 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */
- 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */
- 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */
+/* default value of sgtl5000 registers */
+static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = {
+ [SGTL5000_CHIP_CLK_CTRL] = 0x0008,
+ [SGTL5000_CHIP_I2S_CTRL] = 0x0010,
+ [SGTL5000_CHIP_SSS_CTRL] = 0x0008,
+ [SGTL5000_CHIP_DAC_VOL] = 0x3c3c,
+ [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f,
+ [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818,
+ [SGTL5000_CHIP_ANA_CTRL] = 0x0111,
+ [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404,
+ [SGTL5000_CHIP_ANA_POWER] = 0x7060,
+ [SGTL5000_CHIP_PLL_CTRL] = 0x5000,
+ [SGTL5000_DAP_BASS_ENHANCE] = 0x0040,
+ [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f,
+ [SGTL5000_DAP_SURROUND] = 0x0040,
+ [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f,
+ [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f,
+ [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f,
+ [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f,
+ [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f,
+ [SGTL5000_DAP_MAIN_CHAN] = 0x8000,
+ [SGTL5000_DAP_AVC_CTRL] = 0x0510,
+ [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473,
+ [SGTL5000_DAP_AVC_ATTACK] = 0x0028,
+ [SGTL5000_DAP_AVC_DECAY] = 0x0050,
};
/* regulator supplies for sgtl5000, VDDD is an optional external supply */
@@ -907,6 +865,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
struct regulator_init_data *init_data,
int voltage)
{
+ dev_err(codec->dev, "this setup needs regulator support in the kernel\n");
return -EINVAL;
}
@@ -1022,12 +981,10 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state)
static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
{
u16 *cache = codec->reg_cache;
- int i;
- int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1;
+ u16 reg;
/* restore regular registers */
- for (i = 0; i < regular_regs; i++) {
- int reg = i << 1;
+ for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) {
/* this regs depends on the others */
if (reg == SGTL5000_CHIP_ANA_POWER ||
@@ -1037,35 +994,31 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
reg == SGTL5000_CHIP_CLK_CTRL)
continue;
- snd_soc_write(codec, reg, cache[i]);
+ snd_soc_write(codec, reg, cache[reg]);
}
/* restore dap registers */
- for (i = SGTL5000_DAP_REG_OFFSET >> 1;
- i < SGTL5000_MAX_REG_OFFSET >> 1; i++) {
- int reg = i << 1;
-
- snd_soc_write(codec, reg, cache[i]);
- }
+ for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2)
+ snd_soc_write(codec, reg, cache[reg]);
/*
* restore power and other regs according
* to set_power() and set_clock()
*/
snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
- cache[SGTL5000_CHIP_LINREG_CTRL >> 1]);
+ cache[SGTL5000_CHIP_LINREG_CTRL]);
snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
- cache[SGTL5000_CHIP_ANA_POWER >> 1]);
+ cache[SGTL5000_CHIP_ANA_POWER]);
snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
- cache[SGTL5000_CHIP_CLK_CTRL >> 1]);
+ cache[SGTL5000_CHIP_CLK_CTRL]);
snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
- cache[SGTL5000_CHIP_REF_CTRL >> 1]);
+ cache[SGTL5000_CHIP_REF_CTRL]);
snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
- cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]);
+ cache[SGTL5000_CHIP_LINE_OUT_CTRL]);
return 0;
}
@@ -1218,6 +1171,34 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
return 0;
}
+static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec)
+{
+ struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ /* set internal ldo to 1.2v */
+ ret = ldo_regulator_register(codec, &ldo_init_data, LDO_VOLTAGE);
+ if (ret) {
+ dev_err(codec->dev,
+ "Failed to register vddd internal supplies: %d\n", ret);
+ return ret;
+ }
+
+ sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
+ sgtl5000->supplies);
+
+ if (ret) {
+ ldo_regulator_remove(codec);
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(codec->dev, "Using internal LDO instead of VDDD\n");
+ return 0;
+}
+
static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
{
u16 reg;
@@ -1235,30 +1216,9 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
if (!ret)
external_vddd = 1;
else {
- /* set internal ldo to 1.2v */
- int voltage = LDO_VOLTAGE;
-
- ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
- if (ret) {
- dev_err(codec->dev,
- "Failed to register vddd internal supplies: %d\n",
- ret);
- return ret;
- }
-
- sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
-
- ret = regulator_bulk_get(codec->dev,
- ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
-
- if (ret) {
- ldo_regulator_remove(codec);
- dev_err(codec->dev,
- "Failed to request supplies: %d\n", ret);
-
+ ret = sgtl5000_replace_vddd_with_ldo(codec);
+ if (ret)
return ret;
- }
}
ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
@@ -1287,7 +1247,6 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
* roll back to use internal LDO
*/
if (external_vddd && rev >= 0x11) {
- int voltage = LDO_VOLTAGE;
/* disable all regulator first */
regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
@@ -1295,23 +1254,10 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
- ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
+ ret = sgtl5000_replace_vddd_with_ldo(codec);
if (ret)
return ret;
- sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
-
- ret = regulator_bulk_get(codec->dev,
- ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- if (ret) {
- ldo_regulator_remove(codec);
- dev_err(codec->dev,
- "Failed to request supplies: %d\n", ret);
-
- return ret;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
if (ret)
@@ -1460,16 +1406,6 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
if (!sgtl5000)
return -ENOMEM;
- /*
- * copy DAP default values to default value array.
- * sgtl5000 register space has a big hole, merge it
- * at init phase makes life easy.
- * FIXME: should we drop 'const' of sgtl5000_regs?
- */
- memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)),
- sgtl5000_dap_regs,
- SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET);
-
i2c_set_clientdata(client, sgtl5000);
ret = snd_soc_register_codec(&client->dev,
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 409d89d1f34..fbd7eb9e61c 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -857,6 +857,7 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
+ kfree(sta32x);
return ret;
}
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index bec788b1261..71674bec960 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -36,7 +36,7 @@
#include <sound/tlv.h>
/* Register descriptions are here */
-#include <linux/mfd/twl4030-codec.h>
+#include <linux/mfd/twl4030-audio.h>
/* Shadow register used by the audio driver */
#define TWL4030_REG_SW_SHADOW 0x4A
@@ -251,9 +251,9 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
return;
if (enable)
- mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
+ mode = twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
else
- mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
+ mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
if (mode >= 0) {
twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
@@ -297,7 +297,7 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
static void twl4030_init_chip(struct snd_soc_codec *codec)
{
- struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev);
+ struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 reg, byte;
int i = 0;
@@ -375,13 +375,13 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
if (enable) {
twl4030->apll_enabled++;
if (twl4030->apll_enabled == 1)
- status = twl4030_codec_enable_resource(
- TWL4030_CODEC_RES_APLL);
+ status = twl4030_audio_enable_resource(
+ TWL4030_AUDIO_RES_APLL);
} else {
twl4030->apll_enabled--;
if (!twl4030->apll_enabled)
- status = twl4030_codec_disable_resource(
- TWL4030_CODEC_RES_APLL);
+ status = twl4030_audio_disable_resource(
+ TWL4030_AUDIO_RES_APLL);
}
if (status >= 0)
@@ -732,7 +732,7 @@ static int aif_event(struct snd_soc_dapm_widget *w,
static void headset_ramp(struct snd_soc_codec *codec, int ramp)
{
- struct twl4030_codec_audio_data *pdata = codec->dev->platform_data;
+ struct twl4030_codec_data *pdata = codec->dev->platform_data;
unsigned char hs_gain, hs_pop;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
/* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -2260,7 +2260,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
}
snd_soc_codec_set_drvdata(codec, twl4030);
/* Set the defaults, and power up the codec */
- twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
+ twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
codec->dapm.idle_bias_off = 1;
twl4030_init_chip(codec);
@@ -2297,7 +2297,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
static int __devinit twl4030_codec_probe(struct platform_device *pdev)
{
- struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
+ struct twl4030_codec_data *pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "platform_data is missing\n");
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index cd63bba623d..443032b3b32 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -24,11 +24,10 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -77,14 +76,19 @@ struct twl6040_jack_data {
/* codec private data */
struct twl6040_data {
- int audpwron;
- int naudint;
+ int plug_irq;
int codec_powered;
int pll;
int non_lp;
+ int pll_power_mode;
+ int hs_power_mode;
+ int hs_power_mode_locked;
+ unsigned int clk_in;
unsigned int sysclk;
- struct snd_pcm_hw_constraint_list *sysclk_constraints;
- struct completion ready;
+ u16 hs_left_step;
+ u16 hs_right_step;
+ u16 hf_left_step;
+ u16 hf_right_step;
struct twl6040_jack_data hs_jack;
struct snd_soc_codec *codec;
struct workqueue_struct *workqueue;
@@ -206,6 +210,32 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
TWL6040_REG_DLB,
};
+/* set of rates for each pll: low-power and high-performance */
+static unsigned int lp_rates[] = {
+ 8000,
+ 11250,
+ 16000,
+ 22500,
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+};
+
+static unsigned int hp_rates[] = {
+ 8000,
+ 16000,
+ 32000,
+ 48000,
+ 96000,
+};
+
+static struct snd_pcm_hw_constraint_list sysclk_constraints[] = {
+ { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, },
+ { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, },
+};
+
/*
* read twl6040 register cache
*/
@@ -239,12 +269,13 @@ static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
unsigned int reg)
{
+ struct twl6040 *twl6040 = codec->control_data;
u8 value;
if (reg >= TWL6040_CACHEREGNUM)
return -EIO;
- twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg);
+ value = twl6040_reg_read(twl6040, reg);
twl6040_write_reg_cache(codec, reg, value);
return value;
@@ -256,11 +287,13 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
static int twl6040_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value)
{
+ struct twl6040 *twl6040 = codec->control_data;
+
if (reg >= TWL6040_CACHEREGNUM)
return -EIO;
twl6040_write_reg_cache(codec, reg, value);
- return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg);
+ return twl6040_reg_write(twl6040, reg, value);
}
static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
@@ -268,15 +301,21 @@ static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
u8 *cache = codec->reg_cache;
int reg, i;
- /* allow registers to be accessed by i2c */
- twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]);
-
for (i = 0; i < TWL6040_VIOREGNUM; i++) {
reg = twl6040_vio_reg[i];
- /* skip read-only registers (ASICID, ASICREV, STATUS) */
+ /*
+ * skip read-only registers (ASICID, ASICREV, STATUS)
+ * and registers shared among MFD children
+ */
switch (reg) {
case TWL6040_REG_ASICID:
case TWL6040_REG_ASICREV:
+ case TWL6040_REG_INTID:
+ case TWL6040_REG_INTMR:
+ case TWL6040_REG_NCPCTL:
+ case TWL6040_REG_LDOCTL:
+ case TWL6040_REG_GPOCTL:
+ case TWL6040_REG_ACCCTL:
case TWL6040_REG_STATUS:
continue;
default:
@@ -293,6 +332,20 @@ static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
for (i = 0; i < TWL6040_VDDREGNUM; i++) {
reg = twl6040_vdd_reg[i];
+ /* skip vibra and PLL registers */
+ switch (reg) {
+ case TWL6040_REG_VIBCTLL:
+ case TWL6040_REG_VIBDATL:
+ case TWL6040_REG_VIBCTLR:
+ case TWL6040_REG_VIBDATR:
+ case TWL6040_REG_HPPLLCTL:
+ case TWL6040_REG_LPPLLCTL:
+ case TWL6040_REG_LPPLLDIV:
+ continue;
+ default:
+ break;
+ }
+
twl6040_write(codec, reg, cache[reg]);
}
}
@@ -317,7 +370,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
if (headset->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < headset->left_vol) {
- val += left_step;
+ if (val + left_step > headset->left_vol)
+ val = headset->left_vol;
+ else
+ val += left_step;
+
reg &= ~TWL6040_HSL_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN,
(reg | (~val & TWL6040_HSL_VOL_MASK)));
@@ -327,7 +384,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
} else if (headset->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0x0) {
- val -= left_step;
+ if ((int)val - (int)left_step < 0)
+ val = 0;
+ else
+ val -= left_step;
+
reg &= ~TWL6040_HSL_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
(~val & TWL6040_HSL_VOL_MASK));
@@ -344,7 +405,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
if (headset->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < headset->right_vol) {
- val += right_step;
+ if (val + right_step > headset->right_vol)
+ val = headset->right_vol;
+ else
+ val += right_step;
+
reg &= ~TWL6040_HSR_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN,
(reg | (~val << TWL6040_HSR_VOL_SHIFT)));
@@ -354,7 +419,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
} else if (headset->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0x0) {
- val -= right_step;
+ if ((int)val - (int)right_step < 0)
+ val = 0;
+ else
+ val -= right_step;
+
reg &= ~TWL6040_HSR_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN,
reg | (~val << TWL6040_HSR_VOL_SHIFT));
@@ -385,7 +454,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
if (handsfree->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < handsfree->left_vol) {
- val += left_step;
+ if (val + left_step > handsfree->left_vol)
+ val = handsfree->left_vol;
+ else
+ val += left_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFLGAIN,
reg | (0x1D - val));
@@ -395,7 +468,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
} else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0) {
- val -= left_step;
+ if ((int)val - (int)left_step < 0)
+ val = 0;
+ else
+ val -= left_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFLGAIN,
reg | (0x1D - val));
@@ -412,7 +489,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
if (handsfree->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < handsfree->right_vol) {
- val += right_step;
+ if (val + right_step > handsfree->right_vol)
+ val = handsfree->right_vol;
+ else
+ val += right_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFRGAIN,
reg | (0x1D - val));
@@ -422,7 +503,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
} else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0) {
- val -= right_step;
+ if ((int)val - (int)right_step < 0)
+ val = 0;
+ else
+ val -= right_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFRGAIN,
reg | (0x1D - val));
@@ -451,11 +536,9 @@ static void twl6040_pga_hs_work(struct work_struct *work)
/* HS PGA volumes have 4 bits of resolution to ramp */
for (i = 0; i <= 16; i++) {
- headset_complete = 1;
- if (headset->ramp != TWL6040_RAMP_NONE)
- headset_complete = twl6040_hs_ramp_step(codec,
- headset->left_step,
- headset->right_step);
+ headset_complete = twl6040_hs_ramp_step(codec,
+ headset->left_step,
+ headset->right_step);
/* ramp finished ? */
if (headset_complete)
@@ -496,11 +579,9 @@ static void twl6040_pga_hf_work(struct work_struct *work)
/* HF PGA volumes have 5 bits of resolution to ramp */
for (i = 0; i <= 32; i++) {
- handsfree_complete = 1;
- if (handsfree->ramp != TWL6040_RAMP_NONE)
- handsfree_complete = twl6040_hf_ramp_step(codec,
- handsfree->left_step,
- handsfree->right_step);
+ handsfree_complete = twl6040_hf_ramp_step(codec,
+ handsfree->left_step,
+ handsfree->right_step);
/* ramp finished ? */
if (handsfree_complete)
@@ -541,12 +622,16 @@ static int pga_event(struct snd_soc_dapm_widget *w,
out = &priv->headset;
work = &priv->hs_delayed_work;
queue = priv->hs_workqueue;
+ out->left_step = priv->hs_left_step;
+ out->right_step = priv->hs_right_step;
out->step_delay = 5; /* 5 ms between volume ramp steps */
break;
case 4:
out = &priv->handsfree;
work = &priv->hf_delayed_work;
queue = priv->hf_workqueue;
+ out->left_step = priv->hf_left_step;
+ out->right_step = priv->hf_right_step;
out->step_delay = 5; /* 5 ms between volume ramp steps */
if (SND_SOC_DAPM_EVENT_ON(event))
priv->non_lp++;
@@ -579,8 +664,6 @@ static int pga_event(struct snd_soc_dapm_widget *w,
if (!delayed_work_pending(work)) {
/* use volume ramp for power-down */
- out->left_step = 1;
- out->right_step = 1;
out->ramp = TWL6040_RAMP_DOWN;
INIT_COMPLETION(out->ramp_done);
@@ -596,88 +679,6 @@ static int pga_event(struct snd_soc_dapm_widget *w,
return 0;
}
-/* twl6040 codec manual power-up sequence */
-static void twl6040_power_up(struct snd_soc_codec *codec)
-{
- u8 ncpctl, ldoctl, lppllctl, accctl;
-
- ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
- ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
- lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
- accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
-
- /* enable reference system */
- ldoctl |= TWL6040_REFENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- msleep(10);
- /* enable internal oscillator */
- ldoctl |= TWL6040_OSCENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- udelay(10);
- /* enable high-side ldo */
- ldoctl |= TWL6040_HSLDOENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- udelay(244);
- /* enable negative charge pump */
- ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN;
- twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
- udelay(488);
- /* enable low-side ldo */
- ldoctl |= TWL6040_LSLDOENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- udelay(244);
- /* enable low-power pll */
- lppllctl |= TWL6040_LPLLENA;
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
- /* reset state machine */
- accctl |= TWL6040_RESETSPLIT;
- twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
- mdelay(5);
- accctl &= ~TWL6040_RESETSPLIT;
- twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
- /* disable internal oscillator */
- ldoctl &= ~TWL6040_OSCENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
-}
-
-/* twl6040 codec manual power-down sequence */
-static void twl6040_power_down(struct snd_soc_codec *codec)
-{
- u8 ncpctl, ldoctl, lppllctl, accctl;
-
- ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
- ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
- lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
- accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
-
- /* enable internal oscillator */
- ldoctl |= TWL6040_OSCENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- udelay(10);
- /* disable low-power pll */
- lppllctl &= ~TWL6040_LPLLENA;
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
- /* disable low-side ldo */
- ldoctl &= ~TWL6040_LSLDOENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- udelay(244);
- /* disable negative charge pump */
- ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN);
- twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
- udelay(488);
- /* disable high-side ldo */
- ldoctl &= ~TWL6040_HSLDOENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- udelay(244);
- /* disable internal oscillator */
- ldoctl &= ~TWL6040_OSCENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- /* disable reference system */
- ldoctl &= ~TWL6040_REFENA;
- twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
- msleep(10);
-}
-
/* set headset dac and driver power mode */
static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
{
@@ -713,15 +714,26 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = w->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
- if (SND_SOC_DAPM_EVENT_ON(event))
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
priv->non_lp++;
- else
+ if (!strcmp(w->name, "Earphone Driver")) {
+ /* Earphone doesn't support low power mode */
+ priv->hs_power_mode_locked = 1;
+ ret = headset_power_mode(codec, 1);
+ }
+ } else {
priv->non_lp--;
+ if (!strcmp(w->name, "Earphone Driver")) {
+ priv->hs_power_mode_locked = 0;
+ ret = headset_power_mode(codec, priv->hs_power_mode);
+ }
+ }
msleep(1);
- return 0;
+ return ret;
}
static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
@@ -766,33 +778,19 @@ static void twl6040_accessory_work(struct work_struct *work)
}
/* audio interrupt handler */
-static irqreturn_t twl6040_naudint_handler(int irq, void *data)
+static irqreturn_t twl6040_audio_handler(int irq, void *data)
{
struct snd_soc_codec *codec = data;
+ struct twl6040 *twl6040 = codec->control_data;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
u8 intid;
- twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
-
- if (intid & TWL6040_THINT)
- dev_alert(codec->dev, "die temp over-limit detection\n");
+ intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT))
queue_delayed_work(priv->workqueue, &priv->delayed_work,
msecs_to_jiffies(200));
- if (intid & TWL6040_HOOKINT)
- dev_info(codec->dev, "hook detection\n");
-
- if (intid & TWL6040_HFINT)
- dev_alert(codec->dev, "hf drivers over current detection\n");
-
- if (intid & TWL6040_VIBINT)
- dev_alert(codec->dev, "vib drivers over current detection\n");
-
- if (intid & TWL6040_READYINT)
- complete(&priv->ready);
-
return IRQ_HANDLED;
}
@@ -1040,6 +1038,73 @@ static const struct snd_kcontrol_new hfr_mux_controls =
static const struct snd_kcontrol_new ep_driver_switch_controls =
SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
+/* Headset power mode */
+static const char *twl6040_power_mode_texts[] = {
+ "Low-Power", "High-Perfomance",
+};
+
+static const struct soc_enum twl6040_power_mode_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_power_mode_texts),
+ twl6040_power_mode_texts);
+
+static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
+
+ return 0;
+}
+
+static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ int high_perf = ucontrol->value.enumerated.item[0];
+ int ret = 0;
+
+ if (!priv->hs_power_mode_locked)
+ ret = headset_power_mode(codec, high_perf);
+
+ if (!ret)
+ priv->hs_power_mode = high_perf;
+
+ return ret;
+}
+
+static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] = priv->pll_power_mode;
+
+ return 0;
+}
+
+static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+
+ priv->pll_power_mode = ucontrol->value.enumerated.item[0];
+
+ return 0;
+}
+
+int twl6040_get_clk_id(struct snd_soc_codec *codec)
+{
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+
+ return priv->pll_power_mode;
+}
+EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
+
static const struct snd_kcontrol_new twl6040_snd_controls[] = {
/* Capture gains */
SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -1058,6 +1123,13 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
SOC_SINGLE_TLV("Earphone Playback Volume",
TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
+
+ SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum,
+ twl6040_headset_power_get_enum,
+ twl6040_headset_power_put_enum),
+
+ SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum,
+ twl6040_pll_get_enum, twl6040_pll_put_enum),
};
static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
@@ -1231,36 +1303,11 @@ static int twl6040_add_widgets(struct snd_soc_codec *codec)
return 0;
}
-static int twl6040_power_up_completion(struct snd_soc_codec *codec,
- int naudint)
-{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int time_left;
- u8 intid;
-
- time_left = wait_for_completion_timeout(&priv->ready,
- msecs_to_jiffies(144));
-
- if (!time_left) {
- twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid,
- TWL6040_REG_INTID);
- if (!(intid & TWL6040_READYINT)) {
- dev_err(codec->dev, "timeout waiting for READYINT\n");
- return -ETIMEDOUT;
- }
- }
-
- priv->codec_powered = 1;
-
- return 0;
-}
-
static int twl6040_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct twl6040 *twl6040 = codec->control_data;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int audpwron = priv->audpwron;
- int naudint = priv->naudint;
int ret;
switch (level) {
@@ -1272,58 +1319,23 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
if (priv->codec_powered)
break;
- if (gpio_is_valid(audpwron)) {
- /* use AUDPWRON line */
- gpio_set_value(audpwron, 1);
+ ret = twl6040_power(twl6040, 1);
+ if (ret)
+ return ret;
- /* wait for power-up completion */
- ret = twl6040_power_up_completion(codec, naudint);
- if (ret)
- return ret;
-
- /* sync registers updated during power-up sequence */
- twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
- twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
- twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL);
- } else {
- /* use manual power-up sequence */
- twl6040_power_up(codec);
- priv->codec_powered = 1;
- }
+ priv->codec_powered = 1;
/* initialize vdd/vss registers with reg_cache */
twl6040_init_vdd_regs(codec);
/* Set external boost GPO */
twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
-
- /* Set initial minimal gain values */
- twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF);
- twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E);
- twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D);
- twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D);
break;
case SND_SOC_BIAS_OFF:
if (!priv->codec_powered)
break;
- if (gpio_is_valid(audpwron)) {
- /* use AUDPWRON line */
- gpio_set_value(audpwron, 0);
-
- /* power-down sequence latency */
- udelay(500);
-
- /* sync registers updated during power-down sequence */
- twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
- twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
- twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL,
- 0x00);
- } else {
- /* use manual power-down sequence */
- twl6040_power_down(codec);
- }
-
+ twl6040_power(twl6040, 0);
priv->codec_powered = 0;
break;
}
@@ -1333,27 +1345,6 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-/* set of rates for each pll: low-power and high-performance */
-
-static unsigned int lp_rates[] = {
- 88200,
- 96000,
-};
-
-static struct snd_pcm_hw_constraint_list lp_constraints = {
- .count = ARRAY_SIZE(lp_rates),
- .list = lp_rates,
-};
-
-static unsigned int hp_rates[] = {
- 96000,
-};
-
-static struct snd_pcm_hw_constraint_list hp_constraints = {
- .count = ARRAY_SIZE(hp_rates),
- .list = hp_rates,
-};
-
static int twl6040_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -1363,7 +1354,7 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
- priv->sysclk_constraints);
+ &sysclk_constraints[priv->pll_power_mode]);
return 0;
}
@@ -1375,22 +1366,27 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- u8 lppllctl;
int rate;
- /* nothing to do for high-perf pll, it supports only 48 kHz */
- if (priv->pll == TWL6040_HPPLL_ID)
- return 0;
-
- lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
-
rate = params_rate(params);
switch (rate) {
case 11250:
case 22500:
case 44100:
case 88200:
- lppllctl |= TWL6040_LPLLFIN;
+ /* These rates are not supported when HPPLL is in use */
+ if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) {
+ dev_err(codec->dev, "HPPLL does not support rate %d\n",
+ rate);
+ return -EINVAL;
+ }
+ /* Capture is not supported with 17.64MHz sysclk */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ dev_err(codec->dev,
+ "capture mode is not supported at %dHz\n",
+ rate);
+ return -EINVAL;
+ }
priv->sysclk = 17640000;
break;
case 8000:
@@ -1398,7 +1394,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
case 32000:
case 48000:
case 96000:
- lppllctl &= ~TWL6040_LPLLFIN;
priv->sysclk = 19200000;
break;
default:
@@ -1406,8 +1401,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
-
return 0;
}
@@ -1416,7 +1409,9 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
+ struct twl6040 *twl6040 = codec->control_data;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+ int ret;
if (!priv->sysclk) {
dev_err(codec->dev,
@@ -1424,24 +1419,19 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
return -EINVAL;
}
- /*
- * capture is not supported at 17.64 MHz,
- * it's reserved for headset low-power playback scenario
- */
- if ((priv->sysclk == 17640000) &&
- substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- dev_err(codec->dev,
- "capture mode is not supported at %dHz\n",
- priv->sysclk);
- return -EINVAL;
- }
-
if ((priv->sysclk == 17640000) && priv->non_lp) {
dev_err(codec->dev,
"some enabled paths aren't supported at %dHz\n",
priv->sysclk);
return -EPERM;
}
+
+ ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
+ if (ret) {
+ dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
+ return -EPERM;
+ }
+
return 0;
}
@@ -1450,99 +1440,12 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_codec *codec = codec_dai->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- u8 hppllctl, lppllctl;
-
- hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL);
- lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
switch (clk_id) {
case TWL6040_SYSCLK_SEL_LPPLL:
- switch (freq) {
- case 32768:
- /* headset dac and driver must be in low-power mode */
- headset_power_mode(codec, 0);
-
- /* clk32k input requires low-power pll */
- lppllctl |= TWL6040_LPLLENA;
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
- mdelay(5);
- lppllctl &= ~TWL6040_HPLLSEL;
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
- hppllctl &= ~TWL6040_HPLLENA;
- twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
- break;
- default:
- dev_err(codec->dev, "unknown mclk freq %d\n", freq);
- return -EINVAL;
- }
-
- /* lppll divider */
- switch (priv->sysclk) {
- case 17640000:
- lppllctl |= TWL6040_LPLLFIN;
- break;
- case 19200000:
- lppllctl &= ~TWL6040_LPLLFIN;
- break;
- default:
- /* sysclk not yet configured */
- lppllctl &= ~TWL6040_LPLLFIN;
- priv->sysclk = 19200000;
- break;
- }
-
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
-
- priv->pll = TWL6040_LPPLL_ID;
- priv->sysclk_constraints = &lp_constraints;
- break;
case TWL6040_SYSCLK_SEL_HPPLL:
- hppllctl &= ~TWL6040_MCLK_MSK;
-
- switch (freq) {
- case 12000000:
- /* mclk input, pll enabled */
- hppllctl |= TWL6040_MCLK_12000KHZ |
- TWL6040_HPLLSQRBP |
- TWL6040_HPLLENA;
- break;
- case 19200000:
- /* mclk input, pll disabled */
- hppllctl |= TWL6040_MCLK_19200KHZ |
- TWL6040_HPLLSQRENA |
- TWL6040_HPLLBP;
- break;
- case 26000000:
- /* mclk input, pll enabled */
- hppllctl |= TWL6040_MCLK_26000KHZ |
- TWL6040_HPLLSQRBP |
- TWL6040_HPLLENA;
- break;
- case 38400000:
- /* clk slicer, pll disabled */
- hppllctl |= TWL6040_MCLK_38400KHZ |
- TWL6040_HPLLSQRENA |
- TWL6040_HPLLBP;
- break;
- default:
- dev_err(codec->dev, "unknown mclk freq %d\n", freq);
- return -EINVAL;
- }
-
- /* headset dac and driver must be in high-performance mode */
- headset_power_mode(codec, 1);
-
- twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
- udelay(500);
- lppllctl |= TWL6040_HPLLSEL;
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
- lppllctl &= ~TWL6040_LPLLENA;
- twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
-
- /* high-performance pll can provide only 19.2 MHz */
- priv->pll = TWL6040_HPPLL_ID;
- priv->sysclk = 19200000;
- priv->sysclk_constraints = &hp_constraints;
+ priv->pll = clk_id;
+ priv->clk_in = freq;
break;
default:
dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
@@ -1559,15 +1462,27 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
.set_sysclk = twl6040_set_dai_sysclk,
};
-static struct snd_soc_dai_driver twl6040_dai = {
+static struct snd_soc_dai_driver twl6040_dai[] = {
+{
.name = "twl6040-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
- .channels_max = 4,
+ .channels_max = 2,
+ .rates = TWL6040_RATES,
+ .formats = TWL6040_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
.rates = TWL6040_RATES,
.formats = TWL6040_FORMATS,
},
+ .ops = &twl6040_dai_ops,
+},
+{
+ .name = "twl6040-ul",
.capture = {
.stream_name = "Capture",
.channels_min = 1,
@@ -1576,6 +1491,40 @@ static struct snd_soc_dai_driver twl6040_dai = {
.formats = TWL6040_FORMATS,
},
.ops = &twl6040_dai_ops,
+},
+{
+ .name = "twl6040-dl1",
+ .playback = {
+ .stream_name = "Headset Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = TWL6040_RATES,
+ .formats = TWL6040_FORMATS,
+ },
+ .ops = &twl6040_dai_ops,
+},
+{
+ .name = "twl6040-dl2",
+ .playback = {
+ .stream_name = "Handsfree Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = TWL6040_RATES,
+ .formats = TWL6040_FORMATS,
+ },
+ .ops = &twl6040_dai_ops,
+},
+{
+ .name = "twl6040-vib",
+ .playback = {
+ .stream_name = "Vibra Playback",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .formats = TWL6040_FORMATS,
+ },
+ .ops = &twl6040_dai_ops,
+},
};
#ifdef CONFIG_PM
@@ -1600,11 +1549,11 @@ static int twl6040_resume(struct snd_soc_codec *codec)
static int twl6040_probe(struct snd_soc_codec *codec)
{
- struct twl4030_codec_data *twl_codec = codec->dev->platform_data;
struct twl6040_data *priv;
- int audpwron, naudint;
+ struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+ struct platform_device *pdev = container_of(codec->dev,
+ struct platform_device, dev);
int ret = 0;
- u8 icrev, intmr = TWL6040_ALLINT_MSK;
priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
if (priv == NULL)
@@ -1612,23 +1561,32 @@ static int twl6040_probe(struct snd_soc_codec *codec)
snd_soc_codec_set_drvdata(codec, priv);
priv->codec = codec;
+ codec->control_data = dev_get_drvdata(codec->dev->parent);
- twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV);
+ if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
+ priv->hs_left_step = pdata->hs_left_step;
+ priv->hs_right_step = pdata->hs_right_step;
+ } else {
+ priv->hs_left_step = 1;
+ priv->hs_right_step = 1;
+ }
- if (twl_codec && (icrev > 0))
- audpwron = twl_codec->audpwron_gpio;
- else
- audpwron = -EINVAL;
+ if (pdata && pdata->hf_left_step && pdata->hf_right_step) {
+ priv->hf_left_step = pdata->hf_left_step;
+ priv->hf_right_step = pdata->hf_right_step;
+ } else {
+ priv->hf_left_step = 1;
+ priv->hf_right_step = 1;
+ }
- if (twl_codec)
- naudint = twl_codec->naudint_irq;
- else
- naudint = 0;
+ priv->plug_irq = platform_get_irq(pdev, 0);
+ if (priv->plug_irq < 0) {
+ dev_err(codec->dev, "invalid irq\n");
+ ret = -EINVAL;
+ goto work_err;
+ }
- priv->audpwron = audpwron;
- priv->naudint = naudint;
priv->workqueue = create_singlethread_workqueue("twl6040-codec");
-
if (!priv->workqueue) {
ret = -ENOMEM;
goto work_err;
@@ -1638,56 +1596,33 @@ static int twl6040_probe(struct snd_soc_codec *codec)
mutex_init(&priv->mutex);
- init_completion(&priv->ready);
init_completion(&priv->headset.ramp_done);
init_completion(&priv->handsfree.ramp_done);
- if (gpio_is_valid(audpwron)) {
- ret = gpio_request(audpwron, "audpwron");
- if (ret)
- goto gpio1_err;
-
- ret = gpio_direction_output(audpwron, 0);
- if (ret)
- goto gpio2_err;
-
- priv->codec_powered = 0;
-
- /* enable only codec ready interrupt */
- intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK);
-
- /* reset interrupt status to allow correct power up sequence */
- twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
- }
- twl6040_write(codec, TWL6040_REG_INTMR, intmr);
-
- if (naudint) {
- /* audio interrupt */
- ret = request_threaded_irq(naudint, NULL,
- twl6040_naudint_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "twl6040_codec", codec);
- if (ret)
- goto gpio2_err;
- }
-
- /* init vio registers */
- twl6040_init_vio_regs(codec);
-
priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
if (priv->hf_workqueue == NULL) {
ret = -ENOMEM;
- goto irq_err;
+ goto hfwq_err;
}
priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
if (priv->hs_workqueue == NULL) {
ret = -ENOMEM;
- goto wq_err;
+ goto hswq_err;
}
INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
+ ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
+ 0, "twl6040_irq_plug", codec);
+ if (ret) {
+ dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
+ goto plugirq_err;
+ }
+
+ /* init vio registers */
+ twl6040_init_vio_regs(codec);
+
/* power on device */
ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
if (ret)
@@ -1700,16 +1635,12 @@ static int twl6040_probe(struct snd_soc_codec *codec)
return 0;
bias_err:
+ free_irq(priv->plug_irq, codec);
+plugirq_err:
destroy_workqueue(priv->hs_workqueue);
-wq_err:
+hswq_err:
destroy_workqueue(priv->hf_workqueue);
-irq_err:
- if (naudint)
- free_irq(naudint, codec);
-gpio2_err:
- if (gpio_is_valid(audpwron))
- gpio_free(audpwron);
-gpio1_err:
+hfwq_err:
destroy_workqueue(priv->workqueue);
work_err:
kfree(priv);
@@ -1719,17 +1650,9 @@ work_err:
static int twl6040_remove(struct snd_soc_codec *codec)
{
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int audpwron = priv->audpwron;
- int naudint = priv->naudint;
twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- if (gpio_is_valid(audpwron))
- gpio_free(audpwron);
-
- if (naudint)
- free_irq(naudint, codec);
-
+ free_irq(priv->plug_irq, codec);
destroy_workqueue(priv->workqueue);
destroy_workqueue(priv->hf_workqueue);
destroy_workqueue(priv->hs_workqueue);
@@ -1753,8 +1676,8 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
static int __devinit twl6040_codec_probe(struct platform_device *pdev)
{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_twl6040, &twl6040_dai, 1);
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
+ twl6040_dai, ARRAY_SIZE(twl6040_dai));
}
static int __devexit twl6040_codec_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index 23aeed0963e..d8de67869dd 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -22,125 +22,8 @@
#ifndef __TWL6040_H__
#define __TWL6040_H__
-#define TWL6040_REG_ASICID 0x01
-#define TWL6040_REG_ASICREV 0x02
-#define TWL6040_REG_INTID 0x03
-#define TWL6040_REG_INTMR 0x04
-#define TWL6040_REG_NCPCTL 0x05
-#define TWL6040_REG_LDOCTL 0x06
-#define TWL6040_REG_HPPLLCTL 0x07
-#define TWL6040_REG_LPPLLCTL 0x08
-#define TWL6040_REG_LPPLLDIV 0x09
-#define TWL6040_REG_AMICBCTL 0x0A
-#define TWL6040_REG_DMICBCTL 0x0B
-#define TWL6040_REG_MICLCTL 0x0C
-#define TWL6040_REG_MICRCTL 0x0D
-#define TWL6040_REG_MICGAIN 0x0E
-#define TWL6040_REG_LINEGAIN 0x0F
-#define TWL6040_REG_HSLCTL 0x10
-#define TWL6040_REG_HSRCTL 0x11
-#define TWL6040_REG_HSGAIN 0x12
-#define TWL6040_REG_EARCTL 0x13
-#define TWL6040_REG_HFLCTL 0x14
-#define TWL6040_REG_HFLGAIN 0x15
-#define TWL6040_REG_HFRCTL 0x16
-#define TWL6040_REG_HFRGAIN 0x17
-#define TWL6040_REG_VIBCTLL 0x18
-#define TWL6040_REG_VIBDATL 0x19
-#define TWL6040_REG_VIBCTLR 0x1A
-#define TWL6040_REG_VIBDATR 0x1B
-#define TWL6040_REG_HKCTL1 0x1C
-#define TWL6040_REG_HKCTL2 0x1D
-#define TWL6040_REG_GPOCTL 0x1E
-#define TWL6040_REG_ALB 0x1F
-#define TWL6040_REG_DLB 0x20
-#define TWL6040_REG_TRIM1 0x28
-#define TWL6040_REG_TRIM2 0x29
-#define TWL6040_REG_TRIM3 0x2A
-#define TWL6040_REG_HSOTRIM 0x2B
-#define TWL6040_REG_HFOTRIM 0x2C
-#define TWL6040_REG_ACCCTL 0x2D
-#define TWL6040_REG_STATUS 0x2E
-
-#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
-
-#define TWL6040_VIOREGNUM 18
-#define TWL6040_VDDREGNUM 21
-
-/* INTID (0x03) fields */
-
-#define TWL6040_THINT 0x01
-#define TWL6040_PLUGINT 0x02
-#define TWL6040_UNPLUGINT 0x04
-#define TWL6040_HOOKINT 0x08
-#define TWL6040_HFINT 0x10
-#define TWL6040_VIBINT 0x20
-#define TWL6040_READYINT 0x40
-
-/* INTMR (0x04) fields */
-
-#define TWL6040_PLUGMSK 0x02
-#define TWL6040_READYMSK 0x40
-#define TWL6040_ALLINT_MSK 0x7B
-
-/* NCPCTL (0x05) fields */
-
-#define TWL6040_NCPENA 0x01
-#define TWL6040_NCPOPEN 0x40
-
-/* LDOCTL (0x06) fields */
-
-#define TWL6040_LSLDOENA 0x01
-#define TWL6040_HSLDOENA 0x04
-#define TWL6040_REFENA 0x40
-#define TWL6040_OSCENA 0x80
-
-/* HPPLLCTL (0x07) fields */
-
-#define TWL6040_HPLLENA 0x01
-#define TWL6040_HPLLRST 0x02
-#define TWL6040_HPLLBP 0x04
-#define TWL6040_HPLLSQRENA 0x08
-#define TWL6040_HPLLSQRBP 0x10
-#define TWL6040_MCLK_12000KHZ (0 << 5)
-#define TWL6040_MCLK_19200KHZ (1 << 5)
-#define TWL6040_MCLK_26000KHZ (2 << 5)
-#define TWL6040_MCLK_38400KHZ (3 << 5)
-#define TWL6040_MCLK_MSK 0x60
-
-/* LPPLLCTL (0x08) fields */
-
-#define TWL6040_LPLLENA 0x01
-#define TWL6040_LPLLRST 0x02
-#define TWL6040_LPLLSEL 0x04
-#define TWL6040_LPLLFIN 0x08
-#define TWL6040_HPLLSEL 0x10
-
-/* HSLCTL (0x10) fields */
-
-#define TWL6040_HSDACMODEL 0x02
-#define TWL6040_HSDRVMODEL 0x08
-
-/* HSRCTL (0x11) fields */
-
-#define TWL6040_HSDACMODER 0x02
-#define TWL6040_HSDRVMODER 0x08
-
-/* ACCCTL (0x2D) fields */
-
-#define TWL6040_RESETSPLIT 0x04
-
-#define TWL6040_SYSCLK_SEL_LPPLL 1
-#define TWL6040_SYSCLK_SEL_HPPLL 2
-
-#define TWL6040_HPPLL_ID 1
-#define TWL6040_LPPLL_ID 2
-
-/* STATUS (0x2E) fields */
-
-#define TWL6040_PLUGCOMP 0x02
-
void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *jack, int report);
+int twl6040_get_clk_id(struct snd_soc_codec *codec);
#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 38f38fddd19..d0003cc3bcd 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -778,11 +778,19 @@ static int __devexit wm8750_spi_remove(struct spi_device *spi)
return 0;
}
+static const struct spi_device_id wm8750_spi_ids[] = {
+ { "wm8750", 0 },
+ { "wm8987", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
+
static struct spi_driver wm8750_spi_driver = {
.driver = {
.name = "wm8750-codec",
.owner = THIS_MODULE,
},
+ .id_table = wm8750_spi_ids,
.probe = wm8750_spi_probe,
.remove = __devexit_p(wm8750_spi_remove),
};
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 43e3d760766..4ad8ebd290e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2046,8 +2046,13 @@ static int wm8903_probe(struct snd_soc_codec *codec)
/* power down chip */
static int wm8903_remove(struct snd_soc_codec *codec)
{
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
+
wm8903_free_gpio(codec);
wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ if (wm8903->irq)
+ free_irq(wm8903->irq, codec);
+
return 0;
}
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c
deleted file mode 100644
index 423baa9be24..00000000000
--- a/sound/soc/codecs/wm8915.c
+++ /dev/null
@@ -1,2995 +0,0 @@
-/*
- * wm8915.c - WM8915 audio codec interface
- *
- * Copyright 2011 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.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/gcd.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-
-#include <sound/wm8915.h>
-#include "wm8915.h"
-
-#define WM8915_AIFS 2
-
-#define HPOUT1L 1
-#define HPOUT1R 2
-#define HPOUT2L 4
-#define HPOUT2R 8
-
-#define WM8915_NUM_SUPPLIES 4
-static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
- "DBVDD",
- "AVDD1",
- "AVDD2",
- "CPVDD",
-};
-
-struct wm8915_priv {
- struct snd_soc_codec *codec;
-
- int ldo1ena;
-
- int sysclk;
- int sysclk_src;
-
- int fll_src;
- int fll_fref;
- int fll_fout;
-
- struct completion fll_lock;
-
- u16 dcs_pending;
- struct completion dcs_done;
-
- u16 hpout_ena;
- u16 hpout_pending;
-
- struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES];
- struct notifier_block disable_nb[WM8915_NUM_SUPPLIES];
-
- struct wm8915_pdata pdata;
-
- int rx_rate[WM8915_AIFS];
- int bclk_rate[WM8915_AIFS];
-
- /* Platform dependant ReTune mobile configuration */
- int num_retune_mobile_texts;
- const char **retune_mobile_texts;
- int retune_mobile_cfg[2];
- struct soc_enum retune_mobile_enum;
-
- struct snd_soc_jack *jack;
- bool detecting;
- bool jack_mic;
- wm8915_polarity_fn polarity_cb;
-
-#ifdef CONFIG_GPIOLIB
- struct gpio_chip gpio_chip;
-#endif
-};
-
-/* We can't use the same notifier block for more than one supply and
- * there's no way I can see to get from a callback to the caller
- * except container_of().
- */
-#define WM8915_REGULATOR_EVENT(n) \
-static int wm8915_regulator_event_##n(struct notifier_block *nb, \
- unsigned long event, void *data) \
-{ \
- struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \
- disable_nb[n]); \
- if (event & REGULATOR_EVENT_DISABLE) { \
- wm8915->codec->cache_sync = 1; \
- } \
- return 0; \
-}
-
-WM8915_REGULATOR_EVENT(0)
-WM8915_REGULATOR_EVENT(1)
-WM8915_REGULATOR_EVENT(2)
-WM8915_REGULATOR_EVENT(3)
-
-static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
- [WM8915_SOFTWARE_RESET] = 0x8915,
- [WM8915_POWER_MANAGEMENT_7] = 0x10,
- [WM8915_DAC1_HPOUT1_VOLUME] = 0x88,
- [WM8915_DAC2_HPOUT2_VOLUME] = 0x88,
- [WM8915_DAC1_LEFT_VOLUME] = 0x2c0,
- [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0,
- [WM8915_DAC2_LEFT_VOLUME] = 0x2c0,
- [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0,
- [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80,
- [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80,
- [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80,
- [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80,
- [WM8915_MICBIAS_1] = 0x39,
- [WM8915_MICBIAS_2] = 0x39,
- [WM8915_LDO_1] = 0x3,
- [WM8915_LDO_2] = 0x13,
- [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4,
- [WM8915_HEADPHONE_DETECT_1] = 0x20,
- [WM8915_MIC_DETECT_1] = 0x7600,
- [WM8915_MIC_DETECT_2] = 0xbf,
- [WM8915_CHARGE_PUMP_1] = 0x1f25,
- [WM8915_CHARGE_PUMP_2] = 0xab19,
- [WM8915_DC_SERVO_5] = 0x2a2a,
- [WM8915_CONTROL_INTERFACE_1] = 0x8004,
- [WM8915_CLOCKING_1] = 0x10,
- [WM8915_AIF_RATE] = 0x83,
- [WM8915_FLL_CONTROL_4] = 0x5dc0,
- [WM8915_FLL_CONTROL_5] = 0xc84,
- [WM8915_FLL_EFS_2] = 0x2,
- [WM8915_AIF1_TX_LRCLK_1] = 0x80,
- [WM8915_AIF1_TX_LRCLK_2] = 0x8,
- [WM8915_AIF1_RX_LRCLK_1] = 0x80,
- [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
- [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818,
- [WM8915_AIF1TX_TEST] = 0x7,
- [WM8915_AIF2_TX_LRCLK_1] = 0x80,
- [WM8915_AIF2_TX_LRCLK_2] = 0x8,
- [WM8915_AIF2_RX_LRCLK_1] = 0x80,
- [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
- [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818,
- [WM8915_AIF2TX_TEST] = 0x1,
- [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0,
- [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0,
- [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0,
- [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0,
- [WM8915_DSP1_TX_FILTERS] = 0x2000,
- [WM8915_DSP1_RX_FILTERS_1] = 0x200,
- [WM8915_DSP1_RX_FILTERS_2] = 0x10,
- [WM8915_DSP1_DRC_1] = 0x98,
- [WM8915_DSP1_DRC_2] = 0x845,
- [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318,
- [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300,
- [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca,
- [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400,
- [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
- [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
- [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145,
- [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75,
- [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
- [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
- [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373,
- [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54,
- [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558,
- [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e,
- [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829,
- [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
- [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
- [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564,
- [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559,
- [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
- [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0,
- [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0,
- [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0,
- [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0,
- [WM8915_DSP2_TX_FILTERS] = 0x2000,
- [WM8915_DSP2_RX_FILTERS_1] = 0x200,
- [WM8915_DSP2_RX_FILTERS_2] = 0x10,
- [WM8915_DSP2_DRC_1] = 0x98,
- [WM8915_DSP2_DRC_2] = 0x845,
- [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318,
- [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300,
- [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca,
- [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400,
- [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
- [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
- [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145,
- [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75,
- [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
- [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
- [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373,
- [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54,
- [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558,
- [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e,
- [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829,
- [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
- [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
- [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564,
- [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559,
- [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
- [WM8915_OVERSAMPLING] = 0xd,
- [WM8915_SIDETONE] = 0x1040,
- [WM8915_GPIO_1] = 0xa101,
- [WM8915_GPIO_2] = 0xa101,
- [WM8915_GPIO_3] = 0xa101,
- [WM8915_GPIO_4] = 0xa101,
- [WM8915_GPIO_5] = 0xa101,
- [WM8915_PULL_CONTROL_2] = 0x140,
- [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f,
- [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
- [WM8915_RIGHT_PDM_SPEAKER] = 0x1,
- [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
- [WM8915_PDM_SPEAKER_VOLUME] = 0x66,
- [WM8915_WRITE_SEQUENCER_0] = 0x1,
- [WM8915_WRITE_SEQUENCER_1] = 0x1,
- [WM8915_WRITE_SEQUENCER_3] = 0x6,
- [WM8915_WRITE_SEQUENCER_4] = 0x40,
- [WM8915_WRITE_SEQUENCER_5] = 0x1,
- [WM8915_WRITE_SEQUENCER_6] = 0xf,
- [WM8915_WRITE_SEQUENCER_7] = 0x6,
- [WM8915_WRITE_SEQUENCER_8] = 0x1,
- [WM8915_WRITE_SEQUENCER_9] = 0x3,
- [WM8915_WRITE_SEQUENCER_10] = 0x104,
- [WM8915_WRITE_SEQUENCER_12] = 0x60,
- [WM8915_WRITE_SEQUENCER_13] = 0x11,
- [WM8915_WRITE_SEQUENCER_14] = 0x401,
- [WM8915_WRITE_SEQUENCER_16] = 0x50,
- [WM8915_WRITE_SEQUENCER_17] = 0x3,
- [WM8915_WRITE_SEQUENCER_18] = 0x100,
- [WM8915_WRITE_SEQUENCER_20] = 0x51,
- [WM8915_WRITE_SEQUENCER_21] = 0x3,
- [WM8915_WRITE_SEQUENCER_22] = 0x104,
- [WM8915_WRITE_SEQUENCER_23] = 0xa,
- [WM8915_WRITE_SEQUENCER_24] = 0x60,
- [WM8915_WRITE_SEQUENCER_25] = 0x3b,
- [WM8915_WRITE_SEQUENCER_26] = 0x502,
- [WM8915_WRITE_SEQUENCER_27] = 0x100,
- [WM8915_WRITE_SEQUENCER_28] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_32] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_36] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_40] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_44] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_48] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_52] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_56] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_60] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_64] = 0x1,
- [WM8915_WRITE_SEQUENCER_65] = 0x1,
- [WM8915_WRITE_SEQUENCER_67] = 0x6,
- [WM8915_WRITE_SEQUENCER_68] = 0x40,
- [WM8915_WRITE_SEQUENCER_69] = 0x1,
- [WM8915_WRITE_SEQUENCER_70] = 0xf,
- [WM8915_WRITE_SEQUENCER_71] = 0x6,
- [WM8915_WRITE_SEQUENCER_72] = 0x1,
- [WM8915_WRITE_SEQUENCER_73] = 0x3,
- [WM8915_WRITE_SEQUENCER_74] = 0x104,
- [WM8915_WRITE_SEQUENCER_76] = 0x60,
- [WM8915_WRITE_SEQUENCER_77] = 0x11,
- [WM8915_WRITE_SEQUENCER_78] = 0x401,
- [WM8915_WRITE_SEQUENCER_80] = 0x50,
- [WM8915_WRITE_SEQUENCER_81] = 0x3,
- [WM8915_WRITE_SEQUENCER_82] = 0x100,
- [WM8915_WRITE_SEQUENCER_84] = 0x60,
- [WM8915_WRITE_SEQUENCER_85] = 0x3b,
- [WM8915_WRITE_SEQUENCER_86] = 0x502,
- [WM8915_WRITE_SEQUENCER_87] = 0x100,
- [WM8915_WRITE_SEQUENCER_88] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_92] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_96] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_100] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_104] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_108] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_112] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_116] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_120] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_124] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_128] = 0x1,
- [WM8915_WRITE_SEQUENCER_129] = 0x1,
- [WM8915_WRITE_SEQUENCER_131] = 0x6,
- [WM8915_WRITE_SEQUENCER_132] = 0x40,
- [WM8915_WRITE_SEQUENCER_133] = 0x1,
- [WM8915_WRITE_SEQUENCER_134] = 0xf,
- [WM8915_WRITE_SEQUENCER_135] = 0x6,
- [WM8915_WRITE_SEQUENCER_136] = 0x1,
- [WM8915_WRITE_SEQUENCER_137] = 0x3,
- [WM8915_WRITE_SEQUENCER_138] = 0x106,
- [WM8915_WRITE_SEQUENCER_140] = 0x61,
- [WM8915_WRITE_SEQUENCER_141] = 0x11,
- [WM8915_WRITE_SEQUENCER_142] = 0x401,
- [WM8915_WRITE_SEQUENCER_144] = 0x50,
- [WM8915_WRITE_SEQUENCER_145] = 0x3,
- [WM8915_WRITE_SEQUENCER_146] = 0x102,
- [WM8915_WRITE_SEQUENCER_148] = 0x51,
- [WM8915_WRITE_SEQUENCER_149] = 0x3,
- [WM8915_WRITE_SEQUENCER_150] = 0x106,
- [WM8915_WRITE_SEQUENCER_151] = 0xa,
- [WM8915_WRITE_SEQUENCER_152] = 0x61,
- [WM8915_WRITE_SEQUENCER_153] = 0x3b,
- [WM8915_WRITE_SEQUENCER_154] = 0x502,
- [WM8915_WRITE_SEQUENCER_155] = 0x100,
- [WM8915_WRITE_SEQUENCER_156] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_160] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_164] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_168] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_172] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_176] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_180] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_184] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_188] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_192] = 0x1,
- [WM8915_WRITE_SEQUENCER_193] = 0x1,
- [WM8915_WRITE_SEQUENCER_195] = 0x6,
- [WM8915_WRITE_SEQUENCER_196] = 0x40,
- [WM8915_WRITE_SEQUENCER_197] = 0x1,
- [WM8915_WRITE_SEQUENCER_198] = 0xf,
- [WM8915_WRITE_SEQUENCER_199] = 0x6,
- [WM8915_WRITE_SEQUENCER_200] = 0x1,
- [WM8915_WRITE_SEQUENCER_201] = 0x3,
- [WM8915_WRITE_SEQUENCER_202] = 0x106,
- [WM8915_WRITE_SEQUENCER_204] = 0x61,
- [WM8915_WRITE_SEQUENCER_205] = 0x11,
- [WM8915_WRITE_SEQUENCER_206] = 0x401,
- [WM8915_WRITE_SEQUENCER_208] = 0x50,
- [WM8915_WRITE_SEQUENCER_209] = 0x3,
- [WM8915_WRITE_SEQUENCER_210] = 0x102,
- [WM8915_WRITE_SEQUENCER_212] = 0x61,
- [WM8915_WRITE_SEQUENCER_213] = 0x3b,
- [WM8915_WRITE_SEQUENCER_214] = 0x502,
- [WM8915_WRITE_SEQUENCER_215] = 0x100,
- [WM8915_WRITE_SEQUENCER_216] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_220] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_224] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_228] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_232] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_236] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_240] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_244] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_248] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_252] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_256] = 0x60,
- [WM8915_WRITE_SEQUENCER_258] = 0x601,
- [WM8915_WRITE_SEQUENCER_260] = 0x50,
- [WM8915_WRITE_SEQUENCER_262] = 0x100,
- [WM8915_WRITE_SEQUENCER_264] = 0x1,
- [WM8915_WRITE_SEQUENCER_266] = 0x104,
- [WM8915_WRITE_SEQUENCER_267] = 0x100,
- [WM8915_WRITE_SEQUENCER_268] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_272] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_276] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_280] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_284] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_288] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_292] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_296] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_300] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_304] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_308] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_312] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_316] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_320] = 0x61,
- [WM8915_WRITE_SEQUENCER_322] = 0x601,
- [WM8915_WRITE_SEQUENCER_324] = 0x50,
- [WM8915_WRITE_SEQUENCER_326] = 0x102,
- [WM8915_WRITE_SEQUENCER_328] = 0x1,
- [WM8915_WRITE_SEQUENCER_330] = 0x106,
- [WM8915_WRITE_SEQUENCER_331] = 0x100,
- [WM8915_WRITE_SEQUENCER_332] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_336] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_340] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_344] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_348] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_352] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_356] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_360] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_364] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_368] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_372] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_376] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_380] = 0x2fff,
- [WM8915_WRITE_SEQUENCER_384] = 0x60,
- [WM8915_WRITE_SEQUENCER_386] = 0x601,
- [WM8915_WRITE_SEQUENCER_388] = 0x61,
- [WM8915_WRITE_SEQUENCER_390] = 0x601,
- [WM8915_WRITE_SEQUENCER_392] = 0x50,
- [WM8915_WRITE_SEQUENCER_394] = 0x300,
- [WM8915_WRITE_SEQUENCER_396] = 0x1,
- [WM8915_WRITE_SEQUENCER_398] = 0x304,
- [WM8915_WRITE_SEQUENCER_400] = 0x40,
- [WM8915_WRITE_SEQUENCER_402] = 0xf,
- [WM8915_WRITE_SEQUENCER_404] = 0x1,
- [WM8915_WRITE_SEQUENCER_407] = 0x100,
-};
-
-static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
-static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-
-static const char *sidetone_hpf_text[] = {
- "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
-};
-
-static const struct soc_enum sidetone_hpf =
- SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text);
-
-static const char *hpf_mode_text[] = {
- "HiFi", "Custom", "Voice"
-};
-
-static const struct soc_enum dsp1tx_hpf_mode =
- SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
-
-static const struct soc_enum dsp2tx_hpf_mode =
- SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
-
-static const char *hpf_cutoff_text[] = {
- "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
-};
-
-static const struct soc_enum dsp1tx_hpf_cutoff =
- SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
-
-static const struct soc_enum dsp2tx_hpf_cutoff =
- SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
-
-static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- struct wm8915_pdata *pdata = &wm8915->pdata;
- int base, best, best_val, save, i, cfg, iface;
-
- if (!wm8915->num_retune_mobile_texts)
- return;
-
- switch (block) {
- case 0:
- base = WM8915_DSP1_RX_EQ_GAINS_1;
- if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
- WM8915_DSP1RX_SRC)
- iface = 1;
- else
- iface = 0;
- break;
- case 1:
- base = WM8915_DSP1_RX_EQ_GAINS_2;
- if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
- WM8915_DSP2RX_SRC)
- iface = 1;
- else
- iface = 0;
- break;
- default:
- return;
- }
-
- /* Find the version of the currently selected configuration
- * with the nearest sample rate. */
- cfg = wm8915->retune_mobile_cfg[block];
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8915->retune_mobile_texts[cfg]) == 0 &&
- abs(pdata->retune_mobile_cfgs[i].rate
- - wm8915->rx_rate[iface]) < best_val) {
- best = i;
- best_val = abs(pdata->retune_mobile_cfgs[i].rate
- - wm8915->rx_rate[iface]);
- }
- }
-
- dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
- block,
- pdata->retune_mobile_cfgs[best].name,
- pdata->retune_mobile_cfgs[best].rate,
- wm8915->rx_rate[iface]);
-
- /* The EQ will be disabled while reconfiguring it, remember the
- * current configuration.
- */
- save = snd_soc_read(codec, base);
- save &= WM8915_DSP1RX_EQ_ENA;
-
- for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
- snd_soc_update_bits(codec, base + i, 0xffff,
- pdata->retune_mobile_cfgs[best].regs[i]);
-
- snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save);
-}
-
-/* Icky as hell but saves code duplication */
-static int wm8915_get_retune_mobile_block(const char *name)
-{
- if (strcmp(name, "DSP1 EQ Mode") == 0)
- return 0;
- if (strcmp(name, "DSP2 EQ Mode") == 0)
- return 1;
- return -EINVAL;
-}
-
-static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- struct wm8915_pdata *pdata = &wm8915->pdata;
- int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
- int value = ucontrol->value.integer.value[0];
-
- if (block < 0)
- return block;
-
- if (value >= pdata->num_retune_mobile_cfgs)
- return -EINVAL;
-
- wm8915->retune_mobile_cfg[block] = value;
-
- wm8915_set_retune_mobile(codec, block);
-
- return 0;
-}
-
-static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
-
- ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block];
-
- return 0;
-}
-
-static const struct snd_kcontrol_new wm8915_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME,
- WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
-SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME,
- WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
-
-SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES,
- 0, 5, 24, 0, sidetone_tlv),
-SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES,
- 0, 5, 24, 0, sidetone_tlv),
-SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0),
-SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
-SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0),
-
-SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME,
- WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME,
- WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-
-SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS,
- 13, 1, 0),
-SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0),
-SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
-SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
-
-SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS,
- 13, 1, 0),
-SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0),
-SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
-SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
-
-SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME,
- WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME,
- WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME,
- WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME,
- WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME,
- WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME,
- WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1),
-
-SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0),
-SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0),
-SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0),
-SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0),
-
-SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0),
-SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0),
-
-SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4,
- 8, 0, out_digital_tlv),
-SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4,
- 8, 0, out_digital_tlv),
-
-SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME,
- WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
-SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME,
- WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME,
- WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
-SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME,
- WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
-
-SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
- spk_tlv),
-SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER,
- WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1),
-SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER,
- WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0),
-
-SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
-SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8915_eq_controls[] = {
-SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-
-SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-};
-
-static int cp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- msleep(5);
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rmv_short_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
-
- /* Record which outputs we enabled */
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- wm8915->hpout_pending &= ~w->shift;
- break;
- case SND_SOC_DAPM_PRE_PMU:
- wm8915->hpout_pending |= w->shift;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
-{
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
- unsigned long timeout = 200;
-
- snd_soc_write(codec, WM8915_DC_SERVO_2, mask);
-
- /* Use the interrupt if possible */
- do {
- if (i2c->irq) {
- timeout = wait_for_completion_timeout(&wm8915->dcs_done,
- msecs_to_jiffies(200));
- if (timeout == 0)
- dev_err(codec->dev, "DC servo timed out\n");
-
- } else {
- msleep(1);
- if (--i) {
- timeout = 0;
- break;
- }
- }
-
- ret = snd_soc_read(codec, WM8915_DC_SERVO_2);
- dev_dbg(codec->dev, "DC servo state: %x\n", ret);
- } while (ret & mask);
-
- if (timeout == 0)
- dev_err(codec->dev, "DC servo timed out for %x\n", mask);
- else
- dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
-}
-
-static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm,
- enum snd_soc_dapm_type event, int subseq)
-{
- struct snd_soc_codec *codec = container_of(dapm,
- struct snd_soc_codec, dapm);
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- u16 val, mask;
-
- /* Complete any pending DC servo starts */
- if (wm8915->dcs_pending) {
- dev_dbg(codec->dev, "Starting DC servo for %x\n",
- wm8915->dcs_pending);
-
- /* Trigger a startup sequence */
- wait_for_dc_servo(codec, wm8915->dcs_pending
- << WM8915_DCS_TRIG_STARTUP_0_SHIFT);
-
- wm8915->dcs_pending = 0;
- }
-
- if (wm8915->hpout_pending != wm8915->hpout_ena) {
- dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
- wm8915->hpout_ena, wm8915->hpout_pending);
-
- val = 0;
- mask = 0;
- if (wm8915->hpout_pending & HPOUT1L) {
- val |= WM8915_HPOUT1L_RMV_SHORT;
- mask |= WM8915_HPOUT1L_RMV_SHORT;
- } else {
- mask |= WM8915_HPOUT1L_RMV_SHORT |
- WM8915_HPOUT1L_OUTP |
- WM8915_HPOUT1L_DLY;
- }
-
- if (wm8915->hpout_pending & HPOUT1R) {
- val |= WM8915_HPOUT1R_RMV_SHORT;
- mask |= WM8915_HPOUT1R_RMV_SHORT;
- } else {
- mask |= WM8915_HPOUT1R_RMV_SHORT |
- WM8915_HPOUT1R_OUTP |
- WM8915_HPOUT1R_DLY;
- }
-
- snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val);
-
- val = 0;
- mask = 0;
- if (wm8915->hpout_pending & HPOUT2L) {
- val |= WM8915_HPOUT2L_RMV_SHORT;
- mask |= WM8915_HPOUT2L_RMV_SHORT;
- } else {
- mask |= WM8915_HPOUT2L_RMV_SHORT |
- WM8915_HPOUT2L_OUTP |
- WM8915_HPOUT2L_DLY;
- }
-
- if (wm8915->hpout_pending & HPOUT2R) {
- val |= WM8915_HPOUT2R_RMV_SHORT;
- mask |= WM8915_HPOUT2R_RMV_SHORT;
- } else {
- mask |= WM8915_HPOUT2R_RMV_SHORT |
- WM8915_HPOUT2R_OUTP |
- WM8915_HPOUT2R_DLY;
- }
-
- snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val);
-
- wm8915->hpout_ena = wm8915->hpout_pending;
- }
-}
-
-static int dcs_start(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- wm8915->dcs_pending |= 1 << w->shift;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const char *sidetone_text[] = {
- "IN1", "IN2",
-};
-
-static const struct soc_enum left_sidetone_enum =
- SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text);
-
-static const struct snd_kcontrol_new left_sidetone =
- SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
-
-static const struct soc_enum right_sidetone_enum =
- SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text);
-
-static const struct snd_kcontrol_new right_sidetone =
- SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
-
-static const char *spk_text[] = {
- "DAC1L", "DAC1R", "DAC2L", "DAC2R"
-};
-
-static const struct soc_enum spkl_enum =
- SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text);
-
-static const struct snd_kcontrol_new spkl_mux =
- SOC_DAPM_ENUM("SPKL", spkl_enum);
-
-static const struct soc_enum spkr_enum =
- SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
-
-static const struct snd_kcontrol_new spkr_mux =
- SOC_DAPM_ENUM("SPKR", spkr_enum);
-
-static const char *dsp1rx_text[] = {
- "AIF1", "AIF2"
-};
-
-static const struct soc_enum dsp1rx_enum =
- SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
-
-static const struct snd_kcontrol_new dsp1rx =
- SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
-
-static const char *dsp2rx_text[] = {
- "AIF2", "AIF1"
-};
-
-static const struct soc_enum dsp2rx_enum =
- SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
-
-static const struct snd_kcontrol_new dsp2rx =
- SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
-
-static const char *aif2tx_text[] = {
- "DSP2", "DSP1", "AIF1"
-};
-
-static const struct soc_enum aif2tx_enum =
- SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
-
-static const struct snd_kcontrol_new aif2tx =
- SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
-
-static const char *inmux_text[] = {
- "ADC", "DMIC1", "DMIC2"
-};
-
-static const struct soc_enum in1_enum =
- SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text);
-
-static const struct snd_kcontrol_new in1_mux =
- SOC_DAPM_ENUM("IN1 Mux", in1_enum);
-
-static const struct soc_enum in2_enum =
- SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text);
-
-static const struct snd_kcontrol_new in2_mux =
- SOC_DAPM_ENUM("IN2 Mux", in2_enum);
-
-static const struct snd_kcontrol_new dac2r_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac2l_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1r_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1l_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp1txl[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp1txr[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp2txl[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp2txr[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-
-static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1LN"),
-SND_SOC_DAPM_INPUT("IN1LP"),
-SND_SOC_DAPM_INPUT("IN1RN"),
-SND_SOC_DAPM_INPUT("IN1RP"),
-
-SND_SOC_DAPM_INPUT("IN2LN"),
-SND_SOC_DAPM_INPUT("IN2LP"),
-SND_SOC_DAPM_INPUT("IN2RN"),
-SND_SOC_DAPM_INPUT("IN2RP"),
-
-SND_SOC_DAPM_INPUT("DMIC1DAT"),
-SND_SOC_DAPM_INPUT("DMIC2DAT"),
-
-SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event,
- SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
-SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0),
-SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0),
-
-SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
-SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
-SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
-SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
-
-SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0),
-SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0),
-SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0),
-SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0),
-
-SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0),
-
-SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
-SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
-
-SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0),
-SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0),
-SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0),
-SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0),
-
-SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0,
- dsp2txl, ARRAY_SIZE(dsp2txl)),
-SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0,
- dsp2txr, ARRAY_SIZE(dsp2txr)),
-SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0,
- dsp1txl, ARRAY_SIZE(dsp1txl)),
-SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0,
- dsp1txr, ARRAY_SIZE(dsp1txr)),
-
-SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
- dac2l_mix, ARRAY_SIZE(dac2l_mix)),
-SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
- dac2r_mix, ARRAY_SIZE(dac2r_mix)),
-SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
- dac1l_mix, ARRAY_SIZE(dac1l_mix)),
-SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
- dac1r_mix, ARRAY_SIZE(dac1r_mix)),
-
-SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0),
-SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0),
-SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0),
-SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1,
- WM8915_POWER_MANAGEMENT_4, 9, 0),
-SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2,
- WM8915_POWER_MANAGEMENT_4, 8, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1,
- WM8915_POWER_MANAGEMENT_6, 9, 0),
-SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2,
- WM8915_POWER_MANAGEMENT_6, 8, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
- WM8915_POWER_MANAGEMENT_4, 5, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4,
- WM8915_POWER_MANAGEMENT_4, 4, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3,
- WM8915_POWER_MANAGEMENT_4, 3, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2,
- WM8915_POWER_MANAGEMENT_4, 2, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1,
- WM8915_POWER_MANAGEMENT_4, 1, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
- WM8915_POWER_MANAGEMENT_4, 0, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
- WM8915_POWER_MANAGEMENT_6, 5, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
- WM8915_POWER_MANAGEMENT_6, 4, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
- WM8915_POWER_MANAGEMENT_6, 3, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
- WM8915_POWER_MANAGEMENT_6, 2, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
- WM8915_POWER_MANAGEMENT_6, 1, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
- WM8915_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 */
-SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
-SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
-SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
-
-SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
-SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
-SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_OUTPUT("HPOUT1L"),
-SND_SOC_DAPM_OUTPUT("HPOUT1R"),
-SND_SOC_DAPM_OUTPUT("HPOUT2L"),
-SND_SOC_DAPM_OUTPUT("HPOUT2R"),
-SND_SOC_DAPM_OUTPUT("SPKDAT"),
-};
-
-static const struct snd_soc_dapm_route wm8915_dapm_routes[] = {
- { "AIFCLK", NULL, "SYSCLK" },
- { "SYSDSPCLK", NULL, "SYSCLK" },
- { "Charge Pump", NULL, "SYSCLK" },
-
- { "MICB1", NULL, "LDO2" },
- { "MICB2", NULL, "LDO2" },
-
- { "IN1L PGA", NULL, "IN2LN" },
- { "IN1L PGA", NULL, "IN2LP" },
- { "IN1L PGA", NULL, "IN1LN" },
- { "IN1L PGA", NULL, "IN1LP" },
-
- { "IN1R PGA", NULL, "IN2RN" },
- { "IN1R PGA", NULL, "IN2RP" },
- { "IN1R PGA", NULL, "IN1RN" },
- { "IN1R PGA", NULL, "IN1RP" },
-
- { "ADCL", NULL, "IN1L PGA" },
-
- { "ADCR", NULL, "IN1R PGA" },
-
- { "DMIC1L", NULL, "DMIC1DAT" },
- { "DMIC1R", NULL, "DMIC1DAT" },
- { "DMIC2L", NULL, "DMIC2DAT" },
- { "DMIC2R", NULL, "DMIC2DAT" },
-
- { "DMIC2L", NULL, "DMIC2" },
- { "DMIC2R", NULL, "DMIC2" },
- { "DMIC1L", NULL, "DMIC1" },
- { "DMIC1R", NULL, "DMIC1" },
-
- { "IN1L Mux", "ADC", "ADCL" },
- { "IN1L Mux", "DMIC1", "DMIC1L" },
- { "IN1L Mux", "DMIC2", "DMIC2L" },
-
- { "IN1R Mux", "ADC", "ADCR" },
- { "IN1R Mux", "DMIC1", "DMIC1R" },
- { "IN1R Mux", "DMIC2", "DMIC2R" },
-
- { "IN2L Mux", "ADC", "ADCL" },
- { "IN2L Mux", "DMIC1", "DMIC1L" },
- { "IN2L Mux", "DMIC2", "DMIC2L" },
-
- { "IN2R Mux", "ADC", "ADCR" },
- { "IN2R Mux", "DMIC1", "DMIC1R" },
- { "IN2R Mux", "DMIC2", "DMIC2R" },
-
- { "Left Sidetone", "IN1", "IN1L Mux" },
- { "Left Sidetone", "IN2", "IN2L Mux" },
-
- { "Right Sidetone", "IN1", "IN1R Mux" },
- { "Right Sidetone", "IN2", "IN2R Mux" },
-
- { "DSP1TXL", "IN1 Switch", "IN1L Mux" },
- { "DSP1TXR", "IN1 Switch", "IN1R Mux" },
-
- { "DSP2TXL", "IN1 Switch", "IN2L Mux" },
- { "DSP2TXR", "IN1 Switch", "IN2R Mux" },
-
- { "AIF1TX0", NULL, "DSP1TXL" },
- { "AIF1TX1", NULL, "DSP1TXR" },
- { "AIF1TX2", NULL, "DSP2TXL" },
- { "AIF1TX3", NULL, "DSP2TXR" },
- { "AIF1TX4", NULL, "AIF2RX0" },
- { "AIF1TX5", NULL, "AIF2RX1" },
-
- { "AIF1RX0", NULL, "AIFCLK" },
- { "AIF1RX1", NULL, "AIFCLK" },
- { "AIF1RX2", NULL, "AIFCLK" },
- { "AIF1RX3", NULL, "AIFCLK" },
- { "AIF1RX4", NULL, "AIFCLK" },
- { "AIF1RX5", NULL, "AIFCLK" },
-
- { "AIF2RX0", NULL, "AIFCLK" },
- { "AIF2RX1", NULL, "AIFCLK" },
-
- { "DSP1RXL", NULL, "SYSDSPCLK" },
- { "DSP1RXR", NULL, "SYSDSPCLK" },
- { "DSP2RXL", NULL, "SYSDSPCLK" },
- { "DSP2RXR", NULL, "SYSDSPCLK" },
- { "DSP1TXL", NULL, "SYSDSPCLK" },
- { "DSP1TXR", NULL, "SYSDSPCLK" },
- { "DSP2TXL", NULL, "SYSDSPCLK" },
- { "DSP2TXR", NULL, "SYSDSPCLK" },
-
- { "AIF1RXA", NULL, "AIF1RX0" },
- { "AIF1RXA", NULL, "AIF1RX1" },
- { "AIF1RXB", NULL, "AIF1RX2" },
- { "AIF1RXB", NULL, "AIF1RX3" },
- { "AIF1RXC", NULL, "AIF1RX4" },
- { "AIF1RXC", NULL, "AIF1RX5" },
-
- { "AIF2RX", NULL, "AIF2RX0" },
- { "AIF2RX", NULL, "AIF2RX1" },
-
- { "AIF2TX", "DSP2", "DSP2TX" },
- { "AIF2TX", "DSP1", "DSP1RX" },
- { "AIF2TX", "AIF1", "AIF1RXC" },
-
- { "DSP1RXL", NULL, "DSP1RX" },
- { "DSP1RXR", NULL, "DSP1RX" },
- { "DSP2RXL", NULL, "DSP2RX" },
- { "DSP2RXR", NULL, "DSP2RX" },
-
- { "DSP2TX", NULL, "DSP2TXL" },
- { "DSP2TX", NULL, "DSP2TXR" },
-
- { "DSP1RX", "AIF1", "AIF1RXA" },
- { "DSP1RX", "AIF2", "AIF2RX" },
-
- { "DSP2RX", "AIF1", "AIF1RXB" },
- { "DSP2RX", "AIF2", "AIF2RX" },
-
- { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
- { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
- { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
- { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
- { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
- { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
- { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
- { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
- { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC1L", NULL, "DAC1L Mixer" },
- { "DAC1R", NULL, "DAC1R Mixer" },
- { "DAC2L", NULL, "DAC2L Mixer" },
- { "DAC2R", NULL, "DAC2R Mixer" },
-
- { "HPOUT2L PGA", NULL, "Charge Pump" },
- { "HPOUT2L PGA", NULL, "DAC2L" },
- { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
- { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
- { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" },
- { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
-
- { "HPOUT2R PGA", NULL, "Charge Pump" },
- { "HPOUT2R PGA", NULL, "DAC2R" },
- { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
- { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
- { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" },
- { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
-
- { "HPOUT1L PGA", NULL, "Charge Pump" },
- { "HPOUT1L PGA", NULL, "DAC1L" },
- { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
- { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
- { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" },
- { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
-
- { "HPOUT1R PGA", NULL, "Charge Pump" },
- { "HPOUT1R PGA", NULL, "DAC1R" },
- { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
- { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
- { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" },
- { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
-
- { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
- { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
- { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
- { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
-
- { "SPKL", "DAC1L", "DAC1L" },
- { "SPKL", "DAC1R", "DAC1R" },
- { "SPKL", "DAC2L", "DAC2L" },
- { "SPKL", "DAC2R", "DAC2R" },
-
- { "SPKR", "DAC1L", "DAC1L" },
- { "SPKR", "DAC1R", "DAC1R" },
- { "SPKR", "DAC2L", "DAC2L" },
- { "SPKR", "DAC2R", "DAC2R" },
-
- { "SPKL PGA", NULL, "SPKL" },
- { "SPKR PGA", NULL, "SPKR" },
-
- { "SPKDAT", NULL, "SPKL PGA" },
- { "SPKDAT", NULL, "SPKR PGA" },
-};
-
-static int wm8915_readable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- /* Due to the sparseness of the register map the compiler
- * output from an explicit switch statement ends up being much
- * more efficient than a table.
- */
- switch (reg) {
- case WM8915_SOFTWARE_RESET:
- case WM8915_POWER_MANAGEMENT_1:
- case WM8915_POWER_MANAGEMENT_2:
- case WM8915_POWER_MANAGEMENT_3:
- case WM8915_POWER_MANAGEMENT_4:
- case WM8915_POWER_MANAGEMENT_5:
- case WM8915_POWER_MANAGEMENT_6:
- case WM8915_POWER_MANAGEMENT_7:
- case WM8915_POWER_MANAGEMENT_8:
- case WM8915_LEFT_LINE_INPUT_VOLUME:
- case WM8915_RIGHT_LINE_INPUT_VOLUME:
- case WM8915_LINE_INPUT_CONTROL:
- case WM8915_DAC1_HPOUT1_VOLUME:
- case WM8915_DAC2_HPOUT2_VOLUME:
- case WM8915_DAC1_LEFT_VOLUME:
- case WM8915_DAC1_RIGHT_VOLUME:
- case WM8915_DAC2_LEFT_VOLUME:
- case WM8915_DAC2_RIGHT_VOLUME:
- case WM8915_OUTPUT1_LEFT_VOLUME:
- case WM8915_OUTPUT1_RIGHT_VOLUME:
- case WM8915_OUTPUT2_LEFT_VOLUME:
- case WM8915_OUTPUT2_RIGHT_VOLUME:
- case WM8915_MICBIAS_1:
- case WM8915_MICBIAS_2:
- case WM8915_LDO_1:
- case WM8915_LDO_2:
- case WM8915_ACCESSORY_DETECT_MODE_1:
- case WM8915_ACCESSORY_DETECT_MODE_2:
- case WM8915_HEADPHONE_DETECT_1:
- case WM8915_HEADPHONE_DETECT_2:
- case WM8915_MIC_DETECT_1:
- case WM8915_MIC_DETECT_2:
- case WM8915_MIC_DETECT_3:
- case WM8915_CHARGE_PUMP_1:
- case WM8915_CHARGE_PUMP_2:
- case WM8915_DC_SERVO_1:
- case WM8915_DC_SERVO_2:
- case WM8915_DC_SERVO_3:
- case WM8915_DC_SERVO_5:
- case WM8915_DC_SERVO_6:
- case WM8915_DC_SERVO_7:
- case WM8915_DC_SERVO_READBACK_0:
- case WM8915_ANALOGUE_HP_1:
- case WM8915_ANALOGUE_HP_2:
- case WM8915_CHIP_REVISION:
- case WM8915_CONTROL_INTERFACE_1:
- case WM8915_WRITE_SEQUENCER_CTRL_1:
- case WM8915_WRITE_SEQUENCER_CTRL_2:
- case WM8915_AIF_CLOCKING_1:
- case WM8915_AIF_CLOCKING_2:
- case WM8915_CLOCKING_1:
- case WM8915_CLOCKING_2:
- case WM8915_AIF_RATE:
- case WM8915_FLL_CONTROL_1:
- case WM8915_FLL_CONTROL_2:
- case WM8915_FLL_CONTROL_3:
- case WM8915_FLL_CONTROL_4:
- case WM8915_FLL_CONTROL_5:
- case WM8915_FLL_CONTROL_6:
- case WM8915_FLL_EFS_1:
- case WM8915_FLL_EFS_2:
- case WM8915_AIF1_CONTROL:
- case WM8915_AIF1_BCLK:
- case WM8915_AIF1_TX_LRCLK_1:
- case WM8915_AIF1_TX_LRCLK_2:
- case WM8915_AIF1_RX_LRCLK_1:
- case WM8915_AIF1_RX_LRCLK_2:
- case WM8915_AIF1TX_DATA_CONFIGURATION_1:
- case WM8915_AIF1TX_DATA_CONFIGURATION_2:
- case WM8915_AIF1RX_DATA_CONFIGURATION:
- case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION:
- case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION:
- case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION:
- case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION:
- case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION:
- case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION:
- case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION:
- case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION:
- case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION:
- case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION:
- case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION:
- case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION:
- case WM8915_AIF1RX_MONO_CONFIGURATION:
- case WM8915_AIF1TX_TEST:
- case WM8915_AIF2_CONTROL:
- case WM8915_AIF2_BCLK:
- case WM8915_AIF2_TX_LRCLK_1:
- case WM8915_AIF2_TX_LRCLK_2:
- case WM8915_AIF2_RX_LRCLK_1:
- case WM8915_AIF2_RX_LRCLK_2:
- case WM8915_AIF2TX_DATA_CONFIGURATION_1:
- case WM8915_AIF2TX_DATA_CONFIGURATION_2:
- case WM8915_AIF2RX_DATA_CONFIGURATION:
- case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION:
- case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION:
- case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION:
- case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION:
- case WM8915_AIF2RX_MONO_CONFIGURATION:
- case WM8915_AIF2TX_TEST:
- case WM8915_DSP1_TX_LEFT_VOLUME:
- case WM8915_DSP1_TX_RIGHT_VOLUME:
- case WM8915_DSP1_RX_LEFT_VOLUME:
- case WM8915_DSP1_RX_RIGHT_VOLUME:
- case WM8915_DSP1_TX_FILTERS:
- case WM8915_DSP1_RX_FILTERS_1:
- case WM8915_DSP1_RX_FILTERS_2:
- case WM8915_DSP1_DRC_1:
- case WM8915_DSP1_DRC_2:
- case WM8915_DSP1_DRC_3:
- case WM8915_DSP1_DRC_4:
- case WM8915_DSP1_DRC_5:
- case WM8915_DSP1_RX_EQ_GAINS_1:
- case WM8915_DSP1_RX_EQ_GAINS_2:
- case WM8915_DSP1_RX_EQ_BAND_1_A:
- case WM8915_DSP1_RX_EQ_BAND_1_B:
- case WM8915_DSP1_RX_EQ_BAND_1_PG:
- case WM8915_DSP1_RX_EQ_BAND_2_A:
- case WM8915_DSP1_RX_EQ_BAND_2_B:
- case WM8915_DSP1_RX_EQ_BAND_2_C:
- case WM8915_DSP1_RX_EQ_BAND_2_PG:
- case WM8915_DSP1_RX_EQ_BAND_3_A:
- case WM8915_DSP1_RX_EQ_BAND_3_B:
- case WM8915_DSP1_RX_EQ_BAND_3_C:
- case WM8915_DSP1_RX_EQ_BAND_3_PG:
- case WM8915_DSP1_RX_EQ_BAND_4_A:
- case WM8915_DSP1_RX_EQ_BAND_4_B:
- case WM8915_DSP1_RX_EQ_BAND_4_C:
- case WM8915_DSP1_RX_EQ_BAND_4_PG:
- case WM8915_DSP1_RX_EQ_BAND_5_A:
- case WM8915_DSP1_RX_EQ_BAND_5_B:
- case WM8915_DSP1_RX_EQ_BAND_5_PG:
- case WM8915_DSP2_TX_LEFT_VOLUME:
- case WM8915_DSP2_TX_RIGHT_VOLUME:
- case WM8915_DSP2_RX_LEFT_VOLUME:
- case WM8915_DSP2_RX_RIGHT_VOLUME:
- case WM8915_DSP2_TX_FILTERS:
- case WM8915_DSP2_RX_FILTERS_1:
- case WM8915_DSP2_RX_FILTERS_2:
- case WM8915_DSP2_DRC_1:
- case WM8915_DSP2_DRC_2:
- case WM8915_DSP2_DRC_3:
- case WM8915_DSP2_DRC_4:
- case WM8915_DSP2_DRC_5:
- case WM8915_DSP2_RX_EQ_GAINS_1:
- case WM8915_DSP2_RX_EQ_GAINS_2:
- case WM8915_DSP2_RX_EQ_BAND_1_A:
- case WM8915_DSP2_RX_EQ_BAND_1_B:
- case WM8915_DSP2_RX_EQ_BAND_1_PG:
- case WM8915_DSP2_RX_EQ_BAND_2_A:
- case WM8915_DSP2_RX_EQ_BAND_2_B:
- case WM8915_DSP2_RX_EQ_BAND_2_C:
- case WM8915_DSP2_RX_EQ_BAND_2_PG:
- case WM8915_DSP2_RX_EQ_BAND_3_A:
- case WM8915_DSP2_RX_EQ_BAND_3_B:
- case WM8915_DSP2_RX_EQ_BAND_3_C:
- case WM8915_DSP2_RX_EQ_BAND_3_PG:
- case WM8915_DSP2_RX_EQ_BAND_4_A:
- case WM8915_DSP2_RX_EQ_BAND_4_B:
- case WM8915_DSP2_RX_EQ_BAND_4_C:
- case WM8915_DSP2_RX_EQ_BAND_4_PG:
- case WM8915_DSP2_RX_EQ_BAND_5_A:
- case WM8915_DSP2_RX_EQ_BAND_5_B:
- case WM8915_DSP2_RX_EQ_BAND_5_PG:
- case WM8915_DAC1_MIXER_VOLUMES:
- case WM8915_DAC1_LEFT_MIXER_ROUTING:
- case WM8915_DAC1_RIGHT_MIXER_ROUTING:
- case WM8915_DAC2_MIXER_VOLUMES:
- case WM8915_DAC2_LEFT_MIXER_ROUTING:
- case WM8915_DAC2_RIGHT_MIXER_ROUTING:
- case WM8915_DSP1_TX_LEFT_MIXER_ROUTING:
- case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING:
- case WM8915_DSP2_TX_LEFT_MIXER_ROUTING:
- case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING:
- case WM8915_DSP_TX_MIXER_SELECT:
- case WM8915_DAC_SOFTMUTE:
- case WM8915_OVERSAMPLING:
- case WM8915_SIDETONE:
- case WM8915_GPIO_1:
- case WM8915_GPIO_2:
- case WM8915_GPIO_3:
- case WM8915_GPIO_4:
- case WM8915_GPIO_5:
- case WM8915_PULL_CONTROL_1:
- case WM8915_PULL_CONTROL_2:
- case WM8915_INTERRUPT_STATUS_1:
- case WM8915_INTERRUPT_STATUS_2:
- case WM8915_INTERRUPT_RAW_STATUS_2:
- case WM8915_INTERRUPT_STATUS_1_MASK:
- case WM8915_INTERRUPT_STATUS_2_MASK:
- case WM8915_INTERRUPT_CONTROL:
- case WM8915_LEFT_PDM_SPEAKER:
- case WM8915_RIGHT_PDM_SPEAKER:
- case WM8915_PDM_SPEAKER_MUTE_SEQUENCE:
- case WM8915_PDM_SPEAKER_VOLUME:
- return 1;
- default:
- return 0;
- }
-}
-
-static int wm8915_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case WM8915_SOFTWARE_RESET:
- case WM8915_CHIP_REVISION:
- case WM8915_LDO_1:
- case WM8915_LDO_2:
- case WM8915_INTERRUPT_STATUS_1:
- case WM8915_INTERRUPT_STATUS_2:
- case WM8915_INTERRUPT_RAW_STATUS_2:
- case WM8915_DC_SERVO_READBACK_0:
- case WM8915_DC_SERVO_2:
- case WM8915_DC_SERVO_6:
- case WM8915_DC_SERVO_7:
- case WM8915_FLL_CONTROL_6:
- case WM8915_MIC_DETECT_3:
- case WM8915_HEADPHONE_DETECT_1:
- case WM8915_HEADPHONE_DETECT_2:
- return 1;
- default:
- return 0;
- }
-}
-
-static int wm8915_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
-}
-
-static const int bclk_divs[] = {
- 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
-};
-
-static void wm8915_update_bclk(struct snd_soc_codec *codec)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int aif, best, cur_val, bclk_rate, bclk_reg, i;
-
- /* Don't bother if we're in a low frequency idle mode that
- * can't support audio.
- */
- if (wm8915->sysclk < 64000)
- return;
-
- for (aif = 0; aif < WM8915_AIFS; aif++) {
- switch (aif) {
- case 0:
- bclk_reg = WM8915_AIF1_BCLK;
- break;
- case 1:
- bclk_reg = WM8915_AIF2_BCLK;
- break;
- }
-
- bclk_rate = wm8915->bclk_rate[aif];
-
- /* Pick a divisor for BCLK as close as we can get to ideal */
- best = 0;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
- if (cur_val < 0) /* BCLK table is sorted */
- break;
- best = i;
- }
- bclk_rate = wm8915->sysclk / bclk_divs[best];
- dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
- bclk_divs[best], bclk_rate);
-
- snd_soc_update_bits(codec, bclk_reg,
- WM8915_AIF1_BCLK_DIV_MASK, best);
- }
-}
-
-static int wm8915_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
- snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
- WM8915_BG_ENA, WM8915_BG_ENA);
- msleep(2);
- }
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
- wm8915->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- if (wm8915->pdata.ldo_ena >= 0) {
- gpio_set_value_cansleep(wm8915->pdata.ldo_ena,
- 1);
- msleep(5);
- }
-
- codec->cache_only = false;
- snd_soc_cache_sync(codec);
- }
-
- snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
- WM8915_BG_ENA, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- codec->cache_only = true;
- if (wm8915->pdata.ldo_ena >= 0)
- gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
- regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies),
- wm8915->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- int aifctrl = 0;
- int bclk = 0;
- int lrclk_tx = 0;
- int lrclk_rx = 0;
- int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
-
- switch (dai->id) {
- case 0:
- aifctrl_reg = WM8915_AIF1_CONTROL;
- bclk_reg = WM8915_AIF1_BCLK;
- lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2;
- lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2;
- break;
- case 1:
- aifctrl_reg = WM8915_AIF2_CONTROL;
- bclk_reg = WM8915_AIF2_BCLK;
- lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2;
- lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bclk |= WM8915_AIF1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
- lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bclk |= WM8915_AIF1_BCLK_INV;
- lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
- lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
- lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- bclk |= WM8915_AIF1_BCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- bclk |= WM8915_AIF1_BCLK_MSTR;
- lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
- lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- break;
- case SND_SOC_DAIFMT_DSP_B:
- aifctrl |= 1;
- break;
- case SND_SOC_DAIFMT_I2S:
- aifctrl |= 2;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aifctrl |= 3;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl);
- snd_soc_update_bits(codec, bclk_reg,
- WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR,
- bclk);
- snd_soc_update_bits(codec, lrclk_tx_reg,
- WM8915_AIF1TX_LRCLK_INV |
- WM8915_AIF1TX_LRCLK_MSTR,
- lrclk_tx);
- snd_soc_update_bits(codec, lrclk_rx_reg,
- WM8915_AIF1RX_LRCLK_INV |
- WM8915_AIF1RX_LRCLK_MSTR,
- lrclk_rx);
-
- return 0;
-}
-
-static const int dsp_divs[] = {
- 48000, 32000, 16000, 8000
-};
-
-static int wm8915_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 wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int bits, i, bclk_rate;
- int aifdata = 0;
- int lrclk = 0;
- int dsp = 0;
- int aifdata_reg, lrclk_reg, dsp_shift;
-
- switch (dai->id) {
- case 0:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) {
- aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION;
- lrclk_reg = WM8915_AIF1_RX_LRCLK_1;
- } else {
- aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
- lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
- }
- dsp_shift = 0;
- break;
- case 1:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) {
- aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION;
- lrclk_reg = WM8915_AIF2_RX_LRCLK_1;
- } else {
- aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
- lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
- }
- dsp_shift = WM8915_DSP2_DIV_SHIFT;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- bclk_rate = snd_soc_params_to_bclk(params);
- if (bclk_rate < 0) {
- dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
- return bclk_rate;
- }
-
- wm8915->bclk_rate[dai->id] = bclk_rate;
- wm8915->rx_rate[dai->id] = params_rate(params);
-
- /* Needs looking at for TDM */
- bits = snd_pcm_format_width(params_format(params));
- if (bits < 0)
- return bits;
- aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits;
-
- for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
- if (dsp_divs[i] == params_rate(params))
- break;
- }
- if (i == ARRAY_SIZE(dsp_divs)) {
- dev_err(codec->dev, "Unsupported sample rate %dHz\n",
- params_rate(params));
- return -EINVAL;
- }
- dsp |= i << dsp_shift;
-
- wm8915_update_bclk(codec);
-
- lrclk = bclk_rate / params_rate(params);
- dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
- lrclk, bclk_rate / lrclk);
-
- snd_soc_update_bits(codec, aifdata_reg,
- WM8915_AIF1TX_WL_MASK |
- WM8915_AIF1TX_SLOT_LEN_MASK,
- aifdata);
- snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
- lrclk);
- snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
- WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
-
- return 0;
-}
-
-static int wm8915_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int lfclk = 0;
- int ratediv = 0;
- int src;
- int old;
-
- if (freq == wm8915->sysclk && clk_id == wm8915->sysclk_src)
- return 0;
-
- /* Disable SYSCLK while we reconfigure */
- old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1) & WM8915_SYSCLK_ENA;
- snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
- WM8915_SYSCLK_ENA, 0);
-
- switch (clk_id) {
- case WM8915_SYSCLK_MCLK1:
- wm8915->sysclk = freq;
- src = 0;
- break;
- case WM8915_SYSCLK_MCLK2:
- wm8915->sysclk = freq;
- src = 1;
- break;
- case WM8915_SYSCLK_FLL:
- wm8915->sysclk = freq;
- src = 2;
- break;
- default:
- dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
- return -EINVAL;
- }
-
- switch (wm8915->sysclk) {
- case 6144000:
- snd_soc_update_bits(codec, WM8915_AIF_RATE,
- WM8915_SYSCLK_RATE, 0);
- break;
- case 24576000:
- ratediv = WM8915_SYSCLK_DIV;
- case 12288000:
- snd_soc_update_bits(codec, WM8915_AIF_RATE,
- WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE);
- break;
- case 32000:
- case 32768:
- lfclk = WM8915_LFCLK_ENA;
- break;
- default:
- dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
- wm8915->sysclk);
- return -EINVAL;
- }
-
- wm8915_update_bclk(codec);
-
- snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
- WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
- src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
- snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk);
- snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
- WM8915_SYSCLK_ENA, old);
-
- wm8915->sysclk_src = clk_id;
-
- return 0;
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_refclk_div;
- u16 fll_loop_gain;
- u16 fll_ref_freq;
- 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;
-
- if (Fref >= 3000000)
- fll_div->fll_loop_gain = 5;
- else
- fll_div->fll_loop_gain = 0;
-
- if (Fref >= 48000)
- fll_div->fll_ref_freq = 0;
- else
- fll_div->fll_ref_freq = 1;
-
- /* 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 FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
- fll_div->fll_fratio, fll_div->fll_outdiv,
- fll_div->fll_refclk_div);
-
- return 0;
-}
-
-static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct _fll_div fll_div;
- unsigned long timeout;
- int ret, reg;
-
- /* Any change? */
- if (source == wm8915->fll_src && Fref == wm8915->fll_fref &&
- Fout == wm8915->fll_fout)
- return 0;
-
- if (Fout == 0) {
- dev_dbg(codec->dev, "FLL disabled\n");
-
- wm8915->fll_fref = 0;
- wm8915->fll_fout = 0;
-
- snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
- WM8915_FLL_ENA, 0);
-
- return 0;
- }
-
- ret = fll_factors(&fll_div, Fref, Fout);
- if (ret != 0)
- return ret;
-
- switch (source) {
- case WM8915_FLL_MCLK1:
- reg = 0;
- break;
- case WM8915_FLL_MCLK2:
- reg = 1;
- break;
- case WM8915_FLL_DACLRCLK1:
- reg = 2;
- break;
- case WM8915_FLL_BCLK1:
- reg = 3;
- break;
- default:
- dev_err(codec->dev, "Unknown FLL source %d\n", ret);
- return -EINVAL;
- }
-
- reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT;
- reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT;
-
- snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5,
- WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ |
- WM8915_FLL_REFCLK_SRC_MASK, reg);
-
- reg = 0;
- if (fll_div.theta || fll_div.lambda)
- reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT);
- else
- reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT;
- snd_soc_write(codec, WM8915_FLL_EFS_2, reg);
-
- snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2,
- WM8915_FLL_OUTDIV_MASK |
- WM8915_FLL_FRATIO_MASK,
- (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) |
- (fll_div.fll_fratio));
-
- snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta);
-
- snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4,
- WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK,
- (fll_div.n << WM8915_FLL_N_SHIFT) |
- fll_div.fll_loop_gain);
-
- snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda);
-
- snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
- WM8915_FLL_ENA, WM8915_FLL_ENA);
-
- /* The FLL supports live reconfiguration - kick that in case we were
- * already enabled.
- */
- snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK);
-
- /* Wait for the FLL to lock, using the interrupt if possible */
- if (Fref > 1000000)
- timeout = usecs_to_jiffies(300);
- else
- timeout = msecs_to_jiffies(2);
-
- /* Allow substantially longer if we've actually got the IRQ */
- if (i2c->irq)
- timeout *= 1000;
-
- ret = wait_for_completion_timeout(&wm8915->fll_lock, timeout);
-
- if (ret == 0 && i2c->irq) {
- dev_err(codec->dev, "Timed out waiting for FLL\n");
- ret = -ETIMEDOUT;
- } else {
- ret = 0;
- }
-
- dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
-
- wm8915->fll_fref = Fref;
- wm8915->fll_fout = Fout;
- wm8915->fll_src = source;
-
- return ret;
-}
-
-#ifdef CONFIG_GPIOLIB
-static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip)
-{
- return container_of(chip, struct wm8915_priv, gpio_chip);
-}
-
-static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
- struct snd_soc_codec *codec = wm8915->codec;
-
- snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
- WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT);
-}
-
-static int wm8915_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
- struct snd_soc_codec *codec = wm8915->codec;
- int val;
-
- val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT);
-
- return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
- WM8915_GP1_FN_MASK | WM8915_GP1_DIR |
- WM8915_GP1_LVL, val);
-}
-
-static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
- struct snd_soc_codec *codec = wm8915->codec;
- int ret;
-
- ret = snd_soc_read(codec, WM8915_GPIO_1 + offset);
- if (ret < 0)
- return ret;
-
- return (ret & WM8915_GP1_LVL) != 0;
-}
-
-static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
- struct snd_soc_codec *codec = wm8915->codec;
-
- return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
- WM8915_GP1_FN_MASK | WM8915_GP1_DIR,
- (1 << WM8915_GP1_FN_SHIFT) |
- (1 << WM8915_GP1_DIR_SHIFT));
-}
-
-static struct gpio_chip wm8915_template_chip = {
- .label = "wm8915",
- .owner = THIS_MODULE,
- .direction_output = wm8915_gpio_direction_out,
- .set = wm8915_gpio_set,
- .direction_input = wm8915_gpio_direction_in,
- .get = wm8915_gpio_get,
- .can_sleep = 1,
-};
-
-static void wm8915_init_gpio(struct snd_soc_codec *codec)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- wm8915->gpio_chip = wm8915_template_chip;
- wm8915->gpio_chip.ngpio = 5;
- wm8915->gpio_chip.dev = codec->dev;
-
- if (wm8915->pdata.gpio_base)
- wm8915->gpio_chip.base = wm8915->pdata.gpio_base;
- else
- wm8915->gpio_chip.base = -1;
-
- ret = gpiochip_add(&wm8915->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
-}
-
-static void wm8915_free_gpio(struct snd_soc_codec *codec)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = gpiochip_remove(&wm8915->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
-}
-#else
-static void wm8915_init_gpio(struct snd_soc_codec *codec)
-{
-}
-
-static void wm8915_free_gpio(struct snd_soc_codec *codec)
-{
-}
-#endif
-
-/**
- * wm8915_detect - Enable default WM8915 jack detection
- *
- * The WM8915 has advanced accessory detection support for headsets.
- * This function provides a default implementation which integrates
- * the majority of this functionality with minimal user configuration.
- *
- * This will detect headset, headphone and short circuit button and
- * will also detect inverted microphone ground connections and update
- * the polarity of the connections.
- */
-int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8915_polarity_fn polarity_cb)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
-
- wm8915->jack = jack;
- wm8915->detecting = true;
- wm8915->polarity_cb = polarity_cb;
-
- if (wm8915->polarity_cb)
- wm8915->polarity_cb(codec, 0);
-
- /* Clear discarge to avoid noise during detection */
- snd_soc_update_bits(codec, WM8915_MICBIAS_1,
- WM8915_MICB1_DISCH, 0);
- snd_soc_update_bits(codec, WM8915_MICBIAS_2,
- WM8915_MICB2_DISCH, 0);
-
- /* LDO2 powers the microphones, SYSCLK clocks detection */
- snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
- snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
-
- /* We start off just enabling microphone detection - even a
- * plain headphone will trigger detection.
- */
- snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
- WM8915_MICD_ENA, WM8915_MICD_ENA);
-
- /* Slowest detection rate, gives debounce for initial detection */
- snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
- WM8915_MICD_RATE_MASK,
- WM8915_MICD_RATE_MASK);
-
- /* Enable interrupts and we're off */
- snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK,
- WM8915_IM_MICD_EINT, 0);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8915_detect);
-
-static void wm8915_micd(struct snd_soc_codec *codec)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int val, reg;
-
- val = snd_soc_read(codec, WM8915_MIC_DETECT_3);
-
- dev_dbg(codec->dev, "Microphone event: %x\n", val);
-
- if (!(val & WM8915_MICD_VALID)) {
- dev_warn(codec->dev, "Microphone detection state invalid\n");
- return;
- }
-
- /* No accessory, reset everything and report removal */
- if (!(val & WM8915_MICD_STS)) {
- dev_dbg(codec->dev, "Jack removal detected\n");
- wm8915->jack_mic = false;
- wm8915->detecting = true;
- snd_soc_jack_report(wm8915->jack, 0,
- SND_JACK_HEADSET | SND_JACK_BTN_0);
- snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
- WM8915_MICD_RATE_MASK,
- WM8915_MICD_RATE_MASK);
- return;
- }
-
- /* If the measurement is very high we've got a microphone but
- * do a little debounce to account for mechanical issues.
- */
- if (val & 0x400) {
- dev_dbg(codec->dev, "Microphone detected\n");
- snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET,
- SND_JACK_HEADSET | SND_JACK_BTN_0);
- wm8915->jack_mic = true;
- wm8915->detecting = false;
-
- /* Increase poll rate to give better responsiveness
- * for buttons */
- snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
- WM8915_MICD_RATE_MASK,
- 5 << WM8915_MICD_RATE_SHIFT);
- }
-
- /* 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.
- */
- if (wm8915->detecting && (val & 0x3f0)) {
- reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2);
- reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
- WM8915_MICD_BIAS_SRC;
- snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
- WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
- WM8915_MICD_BIAS_SRC, reg);
-
- if (wm8915->polarity_cb)
- wm8915->polarity_cb(codec,
- (reg & WM8915_MICD_SRC) != 0);
-
- dev_dbg(codec->dev, "Set microphone polarity to %d\n",
- (reg & WM8915_MICD_SRC) != 0);
-
- return;
- }
-
- /* Don't distinguish between buttons, just report any low
- * impedence as BTN_0.
- */
- if (val & 0x3fc) {
- if (wm8915->jack_mic) {
- dev_dbg(codec->dev, "Mic button detected\n");
- snd_soc_jack_report(wm8915->jack,
- SND_JACK_HEADSET | SND_JACK_BTN_0,
- SND_JACK_HEADSET | SND_JACK_BTN_0);
- } else {
- dev_dbg(codec->dev, "Headphone detected\n");
- snd_soc_jack_report(wm8915->jack,
- SND_JACK_HEADPHONE,
- SND_JACK_HEADSET |
- SND_JACK_BTN_0);
-
- /* Increase the detection rate a bit for
- * responsiveness.
- */
- snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
- WM8915_MICD_RATE_MASK,
- 7 << WM8915_MICD_RATE_SHIFT);
-
- wm8915->detecting = false;
- }
- }
-}
-
-static irqreturn_t wm8915_irq(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- int irq_val;
-
- irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2);
- if (irq_val < 0) {
- dev_err(codec->dev, "Failed to read IRQ status: %d\n",
- irq_val);
- return IRQ_NONE;
- }
- irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK);
-
- if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) {
- dev_dbg(codec->dev, "DC servo IRQ\n");
- complete(&wm8915->dcs_done);
- }
-
- if (irq_val & WM8915_FIFOS_ERR_EINT)
- dev_err(codec->dev, "Digital core FIFO error\n");
-
- if (irq_val & WM8915_FLL_LOCK_EINT) {
- dev_dbg(codec->dev, "FLL locked\n");
- complete(&wm8915->fll_lock);
- }
-
- if (irq_val & WM8915_MICD_EINT)
- wm8915_micd(codec);
-
- if (irq_val) {
- snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val);
-
- return IRQ_HANDLED;
- } else {
- return IRQ_NONE;
- }
-}
-
-static irqreturn_t wm8915_edge_irq(int irq, void *data)
-{
- irqreturn_t ret = IRQ_NONE;
- irqreturn_t val;
-
- do {
- val = wm8915_irq(irq, data);
- if (val != IRQ_NONE)
- ret = val;
- } while (val != IRQ_NONE);
-
- return ret;
-}
-
-static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- struct wm8915_pdata *pdata = &wm8915->pdata;
-
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT("DSP1 EQ Mode",
- wm8915->retune_mobile_enum,
- wm8915_get_retune_mobile_enum,
- wm8915_put_retune_mobile_enum),
- SOC_ENUM_EXT("DSP2 EQ Mode",
- wm8915->retune_mobile_enum,
- wm8915_get_retune_mobile_enum,
- wm8915_put_retune_mobile_enum),
- };
- int ret, i, j;
- const char **t;
-
- /* We need an array of texts for the enum API but the number
- * of texts is likely to be less than the number of
- * configurations due to the sample rate dependency of the
- * configurations. */
- wm8915->num_retune_mobile_texts = 0;
- wm8915->retune_mobile_texts = NULL;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- for (j = 0; j < wm8915->num_retune_mobile_texts; j++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8915->retune_mobile_texts[j]) == 0)
- break;
- }
-
- if (j != wm8915->num_retune_mobile_texts)
- continue;
-
- /* Expand the array... */
- t = krealloc(wm8915->retune_mobile_texts,
- sizeof(char *) *
- (wm8915->num_retune_mobile_texts + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* ...store the new entry... */
- t[wm8915->num_retune_mobile_texts] =
- pdata->retune_mobile_cfgs[i].name;
-
- /* ...and remember the new version. */
- wm8915->num_retune_mobile_texts++;
- wm8915->retune_mobile_texts = t;
- }
-
- dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
- wm8915->num_retune_mobile_texts);
-
- wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts;
- wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts;
-
- ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(codec->dev,
- "Failed to add ReTune Mobile controls: %d\n", ret);
-}
-
-static int wm8915_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct wm8915_priv *wm8915 = 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;
-
- wm8915->codec = codec;
-
- init_completion(&wm8915->dcs_done);
- init_completion(&wm8915->fll_lock);
-
- dapm->idle_bias_off = true;
- dapm->bias_level = SND_SOC_BIAS_OFF;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
- wm8915->supplies[i].supply = wm8915_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies),
- wm8915->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
- wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0;
- wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
- wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
- wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
-
- /* This should really be moved into the regulator core */
- for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
- ret = regulator_register_notifier(wm8915->supplies[i].consumer,
- &wm8915->disable_nb[i]);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to register regulator notifier: %d\n",
- ret);
- }
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
- wm8915->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- if (wm8915->pdata.ldo_ena >= 0) {
- gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1);
- msleep(5);
- }
-
- ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
- goto err_enable;
- }
- if (ret != 0x8915) {
- dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_read(codec, WM8915_CHIP_REVISION);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_enable;
- }
-
- dev_info(codec->dev, "revision %c\n",
- (ret & WM8915_CHIP_REV_MASK) + 'A');
-
- if (wm8915->pdata.ldo_ena >= 0) {
- gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
- } else {
- ret = wm8915_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
- }
-
- codec->cache_only = true;
-
- /* Apply platform data settings */
- snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL,
- WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK,
- wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT |
- wm8915->pdata.inr_mode);
-
- for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) {
- if (!wm8915->pdata.gpio_default[i])
- continue;
-
- snd_soc_write(codec, WM8915_GPIO_1 + i,
- wm8915->pdata.gpio_default[i] & 0xffff);
- }
-
- if (wm8915->pdata.spkmute_seq)
- snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE,
- WM8915_SPK_MUTE_ENDIAN |
- WM8915_SPK_MUTE_SEQ1_MASK,
- wm8915->pdata.spkmute_seq);
-
- snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
- WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC |
- WM8915_MICD_SRC, wm8915->pdata.micdet_def);
-
- /* Latch volume update bits */
- snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME,
- WM8915_IN1_VU, WM8915_IN1_VU);
- snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME,
- WM8915_IN1_VU, WM8915_IN1_VU);
-
- snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME,
- WM8915_DAC1_VU, WM8915_DAC1_VU);
- snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME,
- WM8915_DAC1_VU, WM8915_DAC1_VU);
- snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME,
- WM8915_DAC2_VU, WM8915_DAC2_VU);
- snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME,
- WM8915_DAC2_VU, WM8915_DAC2_VU);
-
- snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME,
- WM8915_DAC1_VU, WM8915_DAC1_VU);
- snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME,
- WM8915_DAC1_VU, WM8915_DAC1_VU);
- snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME,
- WM8915_DAC2_VU, WM8915_DAC2_VU);
- snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME,
- WM8915_DAC2_VU, WM8915_DAC2_VU);
-
- snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME,
- WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
- snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME,
- WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
- snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME,
- WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
- snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME,
- WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
-
- snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME,
- WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
- snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME,
- WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
- snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME,
- WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
- snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME,
- WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
-
- /* No support currently for the underclocked TDM modes and
- * pick a default TDM layout with each channel pair working with
- * slots 0 and 1. */
- snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION,
- WM8915_AIF1RX_CHAN0_SLOTS_MASK |
- WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION,
- WM8915_AIF1RX_CHAN1_SLOTS_MASK |
- WM8915_AIF1RX_CHAN1_START_SLOT_MASK,
- 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION,
- WM8915_AIF1RX_CHAN2_SLOTS_MASK |
- WM8915_AIF1RX_CHAN2_START_SLOT_MASK,
- 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION,
- WM8915_AIF1RX_CHAN3_SLOTS_MASK |
- WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION,
- WM8915_AIF1RX_CHAN4_SLOTS_MASK |
- WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION,
- WM8915_AIF1RX_CHAN5_SLOTS_MASK |
- WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
-
- snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION,
- WM8915_AIF2RX_CHAN0_SLOTS_MASK |
- WM8915_AIF2RX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION,
- WM8915_AIF2RX_CHAN1_SLOTS_MASK |
- WM8915_AIF2RX_CHAN1_START_SLOT_MASK,
- 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
-
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION,
- WM8915_AIF1TX_CHAN0_SLOTS_MASK |
- WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
- WM8915_AIF1TX_CHAN1_SLOTS_MASK |
- WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION,
- WM8915_AIF1TX_CHAN2_SLOTS_MASK |
- WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION,
- WM8915_AIF1TX_CHAN3_SLOTS_MASK |
- WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION,
- WM8915_AIF1TX_CHAN4_SLOTS_MASK |
- WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION,
- WM8915_AIF1TX_CHAN5_SLOTS_MASK |
- WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
-
- snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION,
- WM8915_AIF2TX_CHAN0_SLOTS_MASK |
- WM8915_AIF2TX_CHAN0_START_SLOT_MASK,
- 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
- WM8915_AIF2TX_CHAN1_SLOTS_MASK |
- WM8915_AIF2TX_CHAN1_START_SLOT_MASK,
- 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
-
- if (wm8915->pdata.num_retune_mobile_cfgs)
- wm8915_retune_mobile_pdata(codec);
- else
- snd_soc_add_controls(codec, wm8915_eq_controls,
- ARRAY_SIZE(wm8915_eq_controls));
-
- /* If the TX LRCLK pins are not in LRCLK mode configure the
- * AIFs to source their clocks from the RX LRCLKs.
- */
- if ((snd_soc_read(codec, WM8915_GPIO_1)))
- snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2,
- WM8915_AIF1TX_LRCLK_MODE,
- WM8915_AIF1TX_LRCLK_MODE);
-
- if ((snd_soc_read(codec, WM8915_GPIO_2)))
- snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2,
- WM8915_AIF2TX_LRCLK_MODE,
- WM8915_AIF2TX_LRCLK_MODE);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
-
- wm8915_init_gpio(codec);
-
- if (i2c->irq) {
- if (wm8915->pdata.irq_flags)
- irq_flags = wm8915->pdata.irq_flags;
- else
- irq_flags = IRQF_TRIGGER_LOW;
-
- irq_flags |= IRQF_ONESHOT;
-
- if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
- ret = request_threaded_irq(i2c->irq, NULL,
- wm8915_edge_irq,
- irq_flags, "wm8915", codec);
- else
- ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
- irq_flags, "wm8915", codec);
-
- if (ret == 0) {
- /* Unmask the interrupt */
- snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
- WM8915_IM_IRQ, 0);
-
- /* Enable error reporting and DC servo status */
- snd_soc_update_bits(codec,
- WM8915_INTERRUPT_STATUS_2_MASK,
- WM8915_IM_DCS_DONE_23_EINT |
- WM8915_IM_DCS_DONE_01_EINT |
- WM8915_IM_FLL_LOCK_EINT |
- WM8915_IM_FIFOS_ERR_EINT,
- 0);
- } else {
- dev_err(codec->dev, "Failed to request IRQ: %d\n",
- ret);
- }
- }
-
- return 0;
-
-err_enable:
- if (wm8915->pdata.ldo_ena >= 0)
- gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
-err:
- return ret;
-}
-
-static int wm8915_remove(struct snd_soc_codec *codec)
-{
- struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- int i;
-
- snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
- WM8915_IM_IRQ, WM8915_IM_IRQ);
-
- if (i2c->irq)
- free_irq(i2c->irq, codec);
-
- wm8915_free_gpio(codec);
-
- for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
- regulator_unregister_notifier(wm8915->supplies[i].consumer,
- &wm8915->disable_nb[i]);
- regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8915 = {
- .probe = wm8915_probe,
- .remove = wm8915_remove,
- .set_bias_level = wm8915_set_bias_level,
- .seq_notifier = wm8915_seq_notifier,
- .reg_cache_size = WM8915_MAX_REGISTER + 1,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8915_reg,
- .volatile_register = wm8915_volatile_register,
- .readable_register = wm8915_readable_register,
- .compress_type = SND_SOC_RBTREE_COMPRESSION,
- .controls = wm8915_snd_controls,
- .num_controls = ARRAY_SIZE(wm8915_snd_controls),
- .dapm_widgets = wm8915_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets),
- .dapm_routes = wm8915_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes),
- .set_pll = wm8915_set_fll,
-};
-
-#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
-#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | 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_ops wm8915_dai_ops = {
- .set_fmt = wm8915_set_fmt,
- .hw_params = wm8915_hw_params,
- .set_sysclk = wm8915_set_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8915_dai[] = {
- {
- .name = "wm8915-aif1",
- .playback = {
- .stream_name = "AIF1 Playback",
- .channels_min = 1,
- .channels_max = 6,
- .rates = WM8915_RATES,
- .formats = WM8915_FORMATS,
- },
- .capture = {
- .stream_name = "AIF1 Capture",
- .channels_min = 1,
- .channels_max = 6,
- .rates = WM8915_RATES,
- .formats = WM8915_FORMATS,
- },
- .ops = &wm8915_dai_ops,
- },
- {
- .name = "wm8915-aif2",
- .playback = {
- .stream_name = "AIF2 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8915_RATES,
- .formats = WM8915_FORMATS,
- },
- .capture = {
- .stream_name = "AIF2 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8915_RATES,
- .formats = WM8915_FORMATS,
- },
- .ops = &wm8915_dai_ops,
- },
-};
-
-static __devinit int wm8915_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8915_priv *wm8915;
- int ret;
-
- wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL);
- if (wm8915 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8915);
-
- if (dev_get_platdata(&i2c->dev))
- memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev),
- sizeof(wm8915->pdata));
-
- if (wm8915->pdata.ldo_ena > 0) {
- ret = gpio_request_one(wm8915->pdata.ldo_ena,
- GPIOF_OUT_INIT_LOW, "WM8915 ENA");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
- wm8915->pdata.ldo_ena, ret);
- goto err;
- }
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8915, wm8915_dai,
- ARRAY_SIZE(wm8915_dai));
- if (ret < 0)
- goto err_gpio;
-
- return ret;
-
-err_gpio:
- if (wm8915->pdata.ldo_ena > 0)
- gpio_free(wm8915->pdata.ldo_ena);
-err:
- kfree(wm8915);
-
- return ret;
-}
-
-static __devexit int wm8915_i2c_remove(struct i2c_client *client)
-{
- struct wm8915_priv *wm8915 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- if (wm8915->pdata.ldo_ena > 0)
- gpio_free(wm8915->pdata.ldo_ena);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8915_i2c_id[] = {
- { "wm8915", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id);
-
-static struct i2c_driver wm8915_i2c_driver = {
- .driver = {
- .name = "wm8915",
- .owner = THIS_MODULE,
- },
- .probe = wm8915_i2c_probe,
- .remove = __devexit_p(wm8915_i2c_remove),
- .id_table = wm8915_i2c_id,
-};
-
-static int __init wm8915_modinit(void)
-{
- int ret;
-
- ret = i2c_add_driver(&wm8915_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n",
- ret);
- }
-
- return ret;
-}
-module_init(wm8915_modinit);
-
-static void __exit wm8915_exit(void)
-{
- i2c_del_driver(&wm8915_i2c_driver);
-}
-module_exit(wm8915_exit);
-
-MODULE_DESCRIPTION("ASoC WM8915 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8915.h b/sound/soc/codecs/wm8915.h
deleted file mode 100644
index 200ffd7bf95..00000000000
--- a/sound/soc/codecs/wm8915.h
+++ /dev/null
@@ -1,3717 +0,0 @@
-/*
- * wm8915.h - WM8915 audio codec interface
- *
- * Copyright 2011 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 _WM8915_H
-#define _WM8915_H
-
-#define WM8915_SYSCLK_MCLK1 1
-#define WM8915_SYSCLK_MCLK2 2
-#define WM8915_SYSCLK_FLL 3
-
-#define WM8915_FLL_MCLK1 1
-#define WM8915_FLL_MCLK2 2
-#define WM8915_FLL_DACLRCLK1 3
-#define WM8915_FLL_BCLK1 4
-
-typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity);
-
-int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8915_polarity_fn polarity_cb);
-
-/*
- * Register values.
- */
-#define WM8915_SOFTWARE_RESET 0x00
-#define WM8915_POWER_MANAGEMENT_1 0x01
-#define WM8915_POWER_MANAGEMENT_2 0x02
-#define WM8915_POWER_MANAGEMENT_3 0x03
-#define WM8915_POWER_MANAGEMENT_4 0x04
-#define WM8915_POWER_MANAGEMENT_5 0x05
-#define WM8915_POWER_MANAGEMENT_6 0x06
-#define WM8915_POWER_MANAGEMENT_7 0x07
-#define WM8915_POWER_MANAGEMENT_8 0x08
-#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10
-#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11
-#define WM8915_LINE_INPUT_CONTROL 0x12
-#define WM8915_DAC1_HPOUT1_VOLUME 0x15
-#define WM8915_DAC2_HPOUT2_VOLUME 0x16
-#define WM8915_DAC1_LEFT_VOLUME 0x18
-#define WM8915_DAC1_RIGHT_VOLUME 0x19
-#define WM8915_DAC2_LEFT_VOLUME 0x1A
-#define WM8915_DAC2_RIGHT_VOLUME 0x1B
-#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C
-#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D
-#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E
-#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F
-#define WM8915_MICBIAS_1 0x20
-#define WM8915_MICBIAS_2 0x21
-#define WM8915_LDO_1 0x28
-#define WM8915_LDO_2 0x29
-#define WM8915_ACCESSORY_DETECT_MODE_1 0x30
-#define WM8915_ACCESSORY_DETECT_MODE_2 0x31
-#define WM8915_HEADPHONE_DETECT_1 0x34
-#define WM8915_HEADPHONE_DETECT_2 0x35
-#define WM8915_MIC_DETECT_1 0x38
-#define WM8915_MIC_DETECT_2 0x39
-#define WM8915_MIC_DETECT_3 0x3A
-#define WM8915_CHARGE_PUMP_1 0x40
-#define WM8915_CHARGE_PUMP_2 0x41
-#define WM8915_DC_SERVO_1 0x50
-#define WM8915_DC_SERVO_2 0x51
-#define WM8915_DC_SERVO_3 0x52
-#define WM8915_DC_SERVO_5 0x54
-#define WM8915_DC_SERVO_6 0x55
-#define WM8915_DC_SERVO_7 0x56
-#define WM8915_DC_SERVO_READBACK_0 0x57
-#define WM8915_ANALOGUE_HP_1 0x60
-#define WM8915_ANALOGUE_HP_2 0x61
-#define WM8915_CHIP_REVISION 0x100
-#define WM8915_CONTROL_INTERFACE_1 0x101
-#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110
-#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111
-#define WM8915_AIF_CLOCKING_1 0x200
-#define WM8915_AIF_CLOCKING_2 0x201
-#define WM8915_CLOCKING_1 0x208
-#define WM8915_CLOCKING_2 0x209
-#define WM8915_AIF_RATE 0x210
-#define WM8915_FLL_CONTROL_1 0x220
-#define WM8915_FLL_CONTROL_2 0x221
-#define WM8915_FLL_CONTROL_3 0x222
-#define WM8915_FLL_CONTROL_4 0x223
-#define WM8915_FLL_CONTROL_5 0x224
-#define WM8915_FLL_CONTROL_6 0x225
-#define WM8915_FLL_EFS_1 0x226
-#define WM8915_FLL_EFS_2 0x227
-#define WM8915_AIF1_CONTROL 0x300
-#define WM8915_AIF1_BCLK 0x301
-#define WM8915_AIF1_TX_LRCLK_1 0x302
-#define WM8915_AIF1_TX_LRCLK_2 0x303
-#define WM8915_AIF1_RX_LRCLK_1 0x304
-#define WM8915_AIF1_RX_LRCLK_2 0x305
-#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306
-#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307
-#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308
-#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
-#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
-#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
-#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
-#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
-#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
-#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
-#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
-#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
-#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
-#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
-#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
-#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315
-#define WM8915_AIF1TX_TEST 0x31A
-#define WM8915_AIF2_CONTROL 0x320
-#define WM8915_AIF2_BCLK 0x321
-#define WM8915_AIF2_TX_LRCLK_1 0x322
-#define WM8915_AIF2_TX_LRCLK_2 0x323
-#define WM8915_AIF2_RX_LRCLK_1 0x324
-#define WM8915_AIF2_RX_LRCLK_2 0x325
-#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326
-#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327
-#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328
-#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
-#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
-#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
-#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
-#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D
-#define WM8915_AIF2TX_TEST 0x32F
-#define WM8915_DSP1_TX_LEFT_VOLUME 0x400
-#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401
-#define WM8915_DSP1_RX_LEFT_VOLUME 0x402
-#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403
-#define WM8915_DSP1_TX_FILTERS 0x410
-#define WM8915_DSP1_RX_FILTERS_1 0x420
-#define WM8915_DSP1_RX_FILTERS_2 0x421
-#define WM8915_DSP1_DRC_1 0x440
-#define WM8915_DSP1_DRC_2 0x441
-#define WM8915_DSP1_DRC_3 0x442
-#define WM8915_DSP1_DRC_4 0x443
-#define WM8915_DSP1_DRC_5 0x444
-#define WM8915_DSP1_RX_EQ_GAINS_1 0x480
-#define WM8915_DSP1_RX_EQ_GAINS_2 0x481
-#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482
-#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483
-#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484
-#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485
-#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486
-#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487
-#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488
-#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489
-#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A
-#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B
-#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C
-#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D
-#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E
-#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F
-#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490
-#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491
-#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492
-#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493
-#define WM8915_DSP2_TX_LEFT_VOLUME 0x500
-#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501
-#define WM8915_DSP2_RX_LEFT_VOLUME 0x502
-#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503
-#define WM8915_DSP2_TX_FILTERS 0x510
-#define WM8915_DSP2_RX_FILTERS_1 0x520
-#define WM8915_DSP2_RX_FILTERS_2 0x521
-#define WM8915_DSP2_DRC_1 0x540
-#define WM8915_DSP2_DRC_2 0x541
-#define WM8915_DSP2_DRC_3 0x542
-#define WM8915_DSP2_DRC_4 0x543
-#define WM8915_DSP2_DRC_5 0x544
-#define WM8915_DSP2_RX_EQ_GAINS_1 0x580
-#define WM8915_DSP2_RX_EQ_GAINS_2 0x581
-#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582
-#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583
-#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584
-#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585
-#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586
-#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587
-#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588
-#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589
-#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A
-#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B
-#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C
-#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D
-#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E
-#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F
-#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590
-#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591
-#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592
-#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593
-#define WM8915_DAC1_MIXER_VOLUMES 0x600
-#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601
-#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602
-#define WM8915_DAC2_MIXER_VOLUMES 0x603
-#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604
-#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605
-#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606
-#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
-#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608
-#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
-#define WM8915_DSP_TX_MIXER_SELECT 0x60A
-#define WM8915_DAC_SOFTMUTE 0x610
-#define WM8915_OVERSAMPLING 0x620
-#define WM8915_SIDETONE 0x621
-#define WM8915_GPIO_1 0x700
-#define WM8915_GPIO_2 0x701
-#define WM8915_GPIO_3 0x702
-#define WM8915_GPIO_4 0x703
-#define WM8915_GPIO_5 0x704
-#define WM8915_PULL_CONTROL_1 0x720
-#define WM8915_PULL_CONTROL_2 0x721
-#define WM8915_INTERRUPT_STATUS_1 0x730
-#define WM8915_INTERRUPT_STATUS_2 0x731
-#define WM8915_INTERRUPT_RAW_STATUS_2 0x732
-#define WM8915_INTERRUPT_STATUS_1_MASK 0x738
-#define WM8915_INTERRUPT_STATUS_2_MASK 0x739
-#define WM8915_INTERRUPT_CONTROL 0x740
-#define WM8915_LEFT_PDM_SPEAKER 0x800
-#define WM8915_RIGHT_PDM_SPEAKER 0x801
-#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802
-#define WM8915_PDM_SPEAKER_VOLUME 0x803
-#define WM8915_WRITE_SEQUENCER_0 0x3000
-#define WM8915_WRITE_SEQUENCER_1 0x3001
-#define WM8915_WRITE_SEQUENCER_2 0x3002
-#define WM8915_WRITE_SEQUENCER_3 0x3003
-#define WM8915_WRITE_SEQUENCER_4 0x3004
-#define WM8915_WRITE_SEQUENCER_5 0x3005
-#define WM8915_WRITE_SEQUENCER_6 0x3006
-#define WM8915_WRITE_SEQUENCER_7 0x3007
-#define WM8915_WRITE_SEQUENCER_8 0x3008
-#define WM8915_WRITE_SEQUENCER_9 0x3009
-#define WM8915_WRITE_SEQUENCER_10 0x300A
-#define WM8915_WRITE_SEQUENCER_11 0x300B
-#define WM8915_WRITE_SEQUENCER_12 0x300C
-#define WM8915_WRITE_SEQUENCER_13 0x300D
-#define WM8915_WRITE_SEQUENCER_14 0x300E
-#define WM8915_WRITE_SEQUENCER_15 0x300F
-#define WM8915_WRITE_SEQUENCER_16 0x3010
-#define WM8915_WRITE_SEQUENCER_17 0x3011
-#define WM8915_WRITE_SEQUENCER_18 0x3012
-#define WM8915_WRITE_SEQUENCER_19 0x3013
-#define WM8915_WRITE_SEQUENCER_20 0x3014
-#define WM8915_WRITE_SEQUENCER_21 0x3015
-#define WM8915_WRITE_SEQUENCER_22 0x3016
-#define WM8915_WRITE_SEQUENCER_23 0x3017
-#define WM8915_WRITE_SEQUENCER_24 0x3018
-#define WM8915_WRITE_SEQUENCER_25 0x3019
-#define WM8915_WRITE_SEQUENCER_26 0x301A
-#define WM8915_WRITE_SEQUENCER_27 0x301B
-#define WM8915_WRITE_SEQUENCER_28 0x301C
-#define WM8915_WRITE_SEQUENCER_29 0x301D
-#define WM8915_WRITE_SEQUENCER_30 0x301E
-#define WM8915_WRITE_SEQUENCER_31 0x301F
-#define WM8915_WRITE_SEQUENCER_32 0x3020
-#define WM8915_WRITE_SEQUENCER_33 0x3021
-#define WM8915_WRITE_SEQUENCER_34 0x3022
-#define WM8915_WRITE_SEQUENCER_35 0x3023
-#define WM8915_WRITE_SEQUENCER_36 0x3024
-#define WM8915_WRITE_SEQUENCER_37 0x3025
-#define WM8915_WRITE_SEQUENCER_38 0x3026
-#define WM8915_WRITE_SEQUENCER_39 0x3027
-#define WM8915_WRITE_SEQUENCER_40 0x3028
-#define WM8915_WRITE_SEQUENCER_41 0x3029
-#define WM8915_WRITE_SEQUENCER_42 0x302A
-#define WM8915_WRITE_SEQUENCER_43 0x302B
-#define WM8915_WRITE_SEQUENCER_44 0x302C
-#define WM8915_WRITE_SEQUENCER_45 0x302D
-#define WM8915_WRITE_SEQUENCER_46 0x302E
-#define WM8915_WRITE_SEQUENCER_47 0x302F
-#define WM8915_WRITE_SEQUENCER_48 0x3030
-#define WM8915_WRITE_SEQUENCER_49 0x3031
-#define WM8915_WRITE_SEQUENCER_50 0x3032
-#define WM8915_WRITE_SEQUENCER_51 0x3033
-#define WM8915_WRITE_SEQUENCER_52 0x3034
-#define WM8915_WRITE_SEQUENCER_53 0x3035
-#define WM8915_WRITE_SEQUENCER_54 0x3036
-#define WM8915_WRITE_SEQUENCER_55 0x3037
-#define WM8915_WRITE_SEQUENCER_56 0x3038
-#define WM8915_WRITE_SEQUENCER_57 0x3039
-#define WM8915_WRITE_SEQUENCER_58 0x303A
-#define WM8915_WRITE_SEQUENCER_59 0x303B
-#define WM8915_WRITE_SEQUENCER_60 0x303C
-#define WM8915_WRITE_SEQUENCER_61 0x303D
-#define WM8915_WRITE_SEQUENCER_62 0x303E
-#define WM8915_WRITE_SEQUENCER_63 0x303F
-#define WM8915_WRITE_SEQUENCER_64 0x3040
-#define WM8915_WRITE_SEQUENCER_65 0x3041
-#define WM8915_WRITE_SEQUENCER_66 0x3042
-#define WM8915_WRITE_SEQUENCER_67 0x3043
-#define WM8915_WRITE_SEQUENCER_68 0x3044
-#define WM8915_WRITE_SEQUENCER_69 0x3045
-#define WM8915_WRITE_SEQUENCER_70 0x3046
-#define WM8915_WRITE_SEQUENCER_71 0x3047
-#define WM8915_WRITE_SEQUENCER_72 0x3048
-#define WM8915_WRITE_SEQUENCER_73 0x3049
-#define WM8915_WRITE_SEQUENCER_74 0x304A
-#define WM8915_WRITE_SEQUENCER_75 0x304B
-#define WM8915_WRITE_SEQUENCER_76 0x304C
-#define WM8915_WRITE_SEQUENCER_77 0x304D
-#define WM8915_WRITE_SEQUENCER_78 0x304E
-#define WM8915_WRITE_SEQUENCER_79 0x304F
-#define WM8915_WRITE_SEQUENCER_80 0x3050
-#define WM8915_WRITE_SEQUENCER_81 0x3051
-#define WM8915_WRITE_SEQUENCER_82 0x3052
-#define WM8915_WRITE_SEQUENCER_83 0x3053
-#define WM8915_WRITE_SEQUENCER_84 0x3054
-#define WM8915_WRITE_SEQUENCER_85 0x3055
-#define WM8915_WRITE_SEQUENCER_86 0x3056
-#define WM8915_WRITE_SEQUENCER_87 0x3057
-#define WM8915_WRITE_SEQUENCER_88 0x3058
-#define WM8915_WRITE_SEQUENCER_89 0x3059
-#define WM8915_WRITE_SEQUENCER_90 0x305A
-#define WM8915_WRITE_SEQUENCER_91 0x305B
-#define WM8915_WRITE_SEQUENCER_92 0x305C
-#define WM8915_WRITE_SEQUENCER_93 0x305D
-#define WM8915_WRITE_SEQUENCER_94 0x305E
-#define WM8915_WRITE_SEQUENCER_95 0x305F
-#define WM8915_WRITE_SEQUENCER_96 0x3060
-#define WM8915_WRITE_SEQUENCER_97 0x3061
-#define WM8915_WRITE_SEQUENCER_98 0x3062
-#define WM8915_WRITE_SEQUENCER_99 0x3063
-#define WM8915_WRITE_SEQUENCER_100 0x3064
-#define WM8915_WRITE_SEQUENCER_101 0x3065
-#define WM8915_WRITE_SEQUENCER_102 0x3066
-#define WM8915_WRITE_SEQUENCER_103 0x3067
-#define WM8915_WRITE_SEQUENCER_104 0x3068
-#define WM8915_WRITE_SEQUENCER_105 0x3069
-#define WM8915_WRITE_SEQUENCER_106 0x306A
-#define WM8915_WRITE_SEQUENCER_107 0x306B
-#define WM8915_WRITE_SEQUENCER_108 0x306C
-#define WM8915_WRITE_SEQUENCER_109 0x306D
-#define WM8915_WRITE_SEQUENCER_110 0x306E
-#define WM8915_WRITE_SEQUENCER_111 0x306F
-#define WM8915_WRITE_SEQUENCER_112 0x3070
-#define WM8915_WRITE_SEQUENCER_113 0x3071
-#define WM8915_WRITE_SEQUENCER_114 0x3072
-#define WM8915_WRITE_SEQUENCER_115 0x3073
-#define WM8915_WRITE_SEQUENCER_116 0x3074
-#define WM8915_WRITE_SEQUENCER_117 0x3075
-#define WM8915_WRITE_SEQUENCER_118 0x3076
-#define WM8915_WRITE_SEQUENCER_119 0x3077
-#define WM8915_WRITE_SEQUENCER_120 0x3078
-#define WM8915_WRITE_SEQUENCER_121 0x3079
-#define WM8915_WRITE_SEQUENCER_122 0x307A
-#define WM8915_WRITE_SEQUENCER_123 0x307B
-#define WM8915_WRITE_SEQUENCER_124 0x307C
-#define WM8915_WRITE_SEQUENCER_125 0x307D
-#define WM8915_WRITE_SEQUENCER_126 0x307E
-#define WM8915_WRITE_SEQUENCER_127 0x307F
-#define WM8915_WRITE_SEQUENCER_128 0x3080
-#define WM8915_WRITE_SEQUENCER_129 0x3081
-#define WM8915_WRITE_SEQUENCER_130 0x3082
-#define WM8915_WRITE_SEQUENCER_131 0x3083
-#define WM8915_WRITE_SEQUENCER_132 0x3084
-#define WM8915_WRITE_SEQUENCER_133 0x3085
-#define WM8915_WRITE_SEQUENCER_134 0x3086
-#define WM8915_WRITE_SEQUENCER_135 0x3087
-#define WM8915_WRITE_SEQUENCER_136 0x3088
-#define WM8915_WRITE_SEQUENCER_137 0x3089
-#define WM8915_WRITE_SEQUENCER_138 0x308A
-#define WM8915_WRITE_SEQUENCER_139 0x308B
-#define WM8915_WRITE_SEQUENCER_140 0x308C
-#define WM8915_WRITE_SEQUENCER_141 0x308D
-#define WM8915_WRITE_SEQUENCER_142 0x308E
-#define WM8915_WRITE_SEQUENCER_143 0x308F
-#define WM8915_WRITE_SEQUENCER_144 0x3090
-#define WM8915_WRITE_SEQUENCER_145 0x3091
-#define WM8915_WRITE_SEQUENCER_146 0x3092
-#define WM8915_WRITE_SEQUENCER_147 0x3093
-#define WM8915_WRITE_SEQUENCER_148 0x3094
-#define WM8915_WRITE_SEQUENCER_149 0x3095
-#define WM8915_WRITE_SEQUENCER_150 0x3096
-#define WM8915_WRITE_SEQUENCER_151 0x3097
-#define WM8915_WRITE_SEQUENCER_152 0x3098
-#define WM8915_WRITE_SEQUENCER_153 0x3099
-#define WM8915_WRITE_SEQUENCER_154 0x309A
-#define WM8915_WRITE_SEQUENCER_155 0x309B
-#define WM8915_WRITE_SEQUENCER_156 0x309C
-#define WM8915_WRITE_SEQUENCER_157 0x309D
-#define WM8915_WRITE_SEQUENCER_158 0x309E
-#define WM8915_WRITE_SEQUENCER_159 0x309F
-#define WM8915_WRITE_SEQUENCER_160 0x30A0
-#define WM8915_WRITE_SEQUENCER_161 0x30A1
-#define WM8915_WRITE_SEQUENCER_162 0x30A2
-#define WM8915_WRITE_SEQUENCER_163 0x30A3
-#define WM8915_WRITE_SEQUENCER_164 0x30A4
-#define WM8915_WRITE_SEQUENCER_165 0x30A5
-#define WM8915_WRITE_SEQUENCER_166 0x30A6
-#define WM8915_WRITE_SEQUENCER_167 0x30A7
-#define WM8915_WRITE_SEQUENCER_168 0x30A8
-#define WM8915_WRITE_SEQUENCER_169 0x30A9
-#define WM8915_WRITE_SEQUENCER_170 0x30AA
-#define WM8915_WRITE_SEQUENCER_171 0x30AB
-#define WM8915_WRITE_SEQUENCER_172 0x30AC
-#define WM8915_WRITE_SEQUENCER_173 0x30AD
-#define WM8915_WRITE_SEQUENCER_174 0x30AE
-#define WM8915_WRITE_SEQUENCER_175 0x30AF
-#define WM8915_WRITE_SEQUENCER_176 0x30B0
-#define WM8915_WRITE_SEQUENCER_177 0x30B1
-#define WM8915_WRITE_SEQUENCER_178 0x30B2
-#define WM8915_WRITE_SEQUENCER_179 0x30B3
-#define WM8915_WRITE_SEQUENCER_180 0x30B4
-#define WM8915_WRITE_SEQUENCER_181 0x30B5
-#define WM8915_WRITE_SEQUENCER_182 0x30B6
-#define WM8915_WRITE_SEQUENCER_183 0x30B7
-#define WM8915_WRITE_SEQUENCER_184 0x30B8
-#define WM8915_WRITE_SEQUENCER_185 0x30B9
-#define WM8915_WRITE_SEQUENCER_186 0x30BA
-#define WM8915_WRITE_SEQUENCER_187 0x30BB
-#define WM8915_WRITE_SEQUENCER_188 0x30BC
-#define WM8915_WRITE_SEQUENCER_189 0x30BD
-#define WM8915_WRITE_SEQUENCER_190 0x30BE
-#define WM8915_WRITE_SEQUENCER_191 0x30BF
-#define WM8915_WRITE_SEQUENCER_192 0x30C0
-#define WM8915_WRITE_SEQUENCER_193 0x30C1
-#define WM8915_WRITE_SEQUENCER_194 0x30C2
-#define WM8915_WRITE_SEQUENCER_195 0x30C3
-#define WM8915_WRITE_SEQUENCER_196 0x30C4
-#define WM8915_WRITE_SEQUENCER_197 0x30C5
-#define WM8915_WRITE_SEQUENCER_198 0x30C6
-#define WM8915_WRITE_SEQUENCER_199 0x30C7
-#define WM8915_WRITE_SEQUENCER_200 0x30C8
-#define WM8915_WRITE_SEQUENCER_201 0x30C9
-#define WM8915_WRITE_SEQUENCER_202 0x30CA
-#define WM8915_WRITE_SEQUENCER_203 0x30CB
-#define WM8915_WRITE_SEQUENCER_204 0x30CC
-#define WM8915_WRITE_SEQUENCER_205 0x30CD
-#define WM8915_WRITE_SEQUENCER_206 0x30CE
-#define WM8915_WRITE_SEQUENCER_207 0x30CF
-#define WM8915_WRITE_SEQUENCER_208 0x30D0
-#define WM8915_WRITE_SEQUENCER_209 0x30D1
-#define WM8915_WRITE_SEQUENCER_210 0x30D2
-#define WM8915_WRITE_SEQUENCER_211 0x30D3
-#define WM8915_WRITE_SEQUENCER_212 0x30D4
-#define WM8915_WRITE_SEQUENCER_213 0x30D5
-#define WM8915_WRITE_SEQUENCER_214 0x30D6
-#define WM8915_WRITE_SEQUENCER_215 0x30D7
-#define WM8915_WRITE_SEQUENCER_216 0x30D8
-#define WM8915_WRITE_SEQUENCER_217 0x30D9
-#define WM8915_WRITE_SEQUENCER_218 0x30DA
-#define WM8915_WRITE_SEQUENCER_219 0x30DB
-#define WM8915_WRITE_SEQUENCER_220 0x30DC
-#define WM8915_WRITE_SEQUENCER_221 0x30DD
-#define WM8915_WRITE_SEQUENCER_222 0x30DE
-#define WM8915_WRITE_SEQUENCER_223 0x30DF
-#define WM8915_WRITE_SEQUENCER_224 0x30E0
-#define WM8915_WRITE_SEQUENCER_225 0x30E1
-#define WM8915_WRITE_SEQUENCER_226 0x30E2
-#define WM8915_WRITE_SEQUENCER_227 0x30E3
-#define WM8915_WRITE_SEQUENCER_228 0x30E4
-#define WM8915_WRITE_SEQUENCER_229 0x30E5
-#define WM8915_WRITE_SEQUENCER_230 0x30E6
-#define WM8915_WRITE_SEQUENCER_231 0x30E7
-#define WM8915_WRITE_SEQUENCER_232 0x30E8
-#define WM8915_WRITE_SEQUENCER_233 0x30E9
-#define WM8915_WRITE_SEQUENCER_234 0x30EA
-#define WM8915_WRITE_SEQUENCER_235 0x30EB
-#define WM8915_WRITE_SEQUENCER_236 0x30EC
-#define WM8915_WRITE_SEQUENCER_237 0x30ED
-#define WM8915_WRITE_SEQUENCER_238 0x30EE
-#define WM8915_WRITE_SEQUENCER_239 0x30EF
-#define WM8915_WRITE_SEQUENCER_240 0x30F0
-#define WM8915_WRITE_SEQUENCER_241 0x30F1
-#define WM8915_WRITE_SEQUENCER_242 0x30F2
-#define WM8915_WRITE_SEQUENCER_243 0x30F3
-#define WM8915_WRITE_SEQUENCER_244 0x30F4
-#define WM8915_WRITE_SEQUENCER_245 0x30F5
-#define WM8915_WRITE_SEQUENCER_246 0x30F6
-#define WM8915_WRITE_SEQUENCER_247 0x30F7
-#define WM8915_WRITE_SEQUENCER_248 0x30F8
-#define WM8915_WRITE_SEQUENCER_249 0x30F9
-#define WM8915_WRITE_SEQUENCER_250 0x30FA
-#define WM8915_WRITE_SEQUENCER_251 0x30FB
-#define WM8915_WRITE_SEQUENCER_252 0x30FC
-#define WM8915_WRITE_SEQUENCER_253 0x30FD
-#define WM8915_WRITE_SEQUENCER_254 0x30FE
-#define WM8915_WRITE_SEQUENCER_255 0x30FF
-#define WM8915_WRITE_SEQUENCER_256 0x3100
-#define WM8915_WRITE_SEQUENCER_257 0x3101
-#define WM8915_WRITE_SEQUENCER_258 0x3102
-#define WM8915_WRITE_SEQUENCER_259 0x3103
-#define WM8915_WRITE_SEQUENCER_260 0x3104
-#define WM8915_WRITE_SEQUENCER_261 0x3105
-#define WM8915_WRITE_SEQUENCER_262 0x3106
-#define WM8915_WRITE_SEQUENCER_263 0x3107
-#define WM8915_WRITE_SEQUENCER_264 0x3108
-#define WM8915_WRITE_SEQUENCER_265 0x3109
-#define WM8915_WRITE_SEQUENCER_266 0x310A
-#define WM8915_WRITE_SEQUENCER_267 0x310B
-#define WM8915_WRITE_SEQUENCER_268 0x310C
-#define WM8915_WRITE_SEQUENCER_269 0x310D
-#define WM8915_WRITE_SEQUENCER_270 0x310E
-#define WM8915_WRITE_SEQUENCER_271 0x310F
-#define WM8915_WRITE_SEQUENCER_272 0x3110
-#define WM8915_WRITE_SEQUENCER_273 0x3111
-#define WM8915_WRITE_SEQUENCER_274 0x3112
-#define WM8915_WRITE_SEQUENCER_275 0x3113
-#define WM8915_WRITE_SEQUENCER_276 0x3114
-#define WM8915_WRITE_SEQUENCER_277 0x3115
-#define WM8915_WRITE_SEQUENCER_278 0x3116
-#define WM8915_WRITE_SEQUENCER_279 0x3117
-#define WM8915_WRITE_SEQUENCER_280 0x3118
-#define WM8915_WRITE_SEQUENCER_281 0x3119
-#define WM8915_WRITE_SEQUENCER_282 0x311A
-#define WM8915_WRITE_SEQUENCER_283 0x311B
-#define WM8915_WRITE_SEQUENCER_284 0x311C
-#define WM8915_WRITE_SEQUENCER_285 0x311D
-#define WM8915_WRITE_SEQUENCER_286 0x311E
-#define WM8915_WRITE_SEQUENCER_287 0x311F
-#define WM8915_WRITE_SEQUENCER_288 0x3120
-#define WM8915_WRITE_SEQUENCER_289 0x3121
-#define WM8915_WRITE_SEQUENCER_290 0x3122
-#define WM8915_WRITE_SEQUENCER_291 0x3123
-#define WM8915_WRITE_SEQUENCER_292 0x3124
-#define WM8915_WRITE_SEQUENCER_293 0x3125
-#define WM8915_WRITE_SEQUENCER_294 0x3126
-#define WM8915_WRITE_SEQUENCER_295 0x3127
-#define WM8915_WRITE_SEQUENCER_296 0x3128
-#define WM8915_WRITE_SEQUENCER_297 0x3129
-#define WM8915_WRITE_SEQUENCER_298 0x312A
-#define WM8915_WRITE_SEQUENCER_299 0x312B
-#define WM8915_WRITE_SEQUENCER_300 0x312C
-#define WM8915_WRITE_SEQUENCER_301 0x312D
-#define WM8915_WRITE_SEQUENCER_302 0x312E
-#define WM8915_WRITE_SEQUENCER_303 0x312F
-#define WM8915_WRITE_SEQUENCER_304 0x3130
-#define WM8915_WRITE_SEQUENCER_305 0x3131
-#define WM8915_WRITE_SEQUENCER_306 0x3132
-#define WM8915_WRITE_SEQUENCER_307 0x3133
-#define WM8915_WRITE_SEQUENCER_308 0x3134
-#define WM8915_WRITE_SEQUENCER_309 0x3135
-#define WM8915_WRITE_SEQUENCER_310 0x3136
-#define WM8915_WRITE_SEQUENCER_311 0x3137
-#define WM8915_WRITE_SEQUENCER_312 0x3138
-#define WM8915_WRITE_SEQUENCER_313 0x3139
-#define WM8915_WRITE_SEQUENCER_314 0x313A
-#define WM8915_WRITE_SEQUENCER_315 0x313B
-#define WM8915_WRITE_SEQUENCER_316 0x313C
-#define WM8915_WRITE_SEQUENCER_317 0x313D
-#define WM8915_WRITE_SEQUENCER_318 0x313E
-#define WM8915_WRITE_SEQUENCER_319 0x313F
-#define WM8915_WRITE_SEQUENCER_320 0x3140
-#define WM8915_WRITE_SEQUENCER_321 0x3141
-#define WM8915_WRITE_SEQUENCER_322 0x3142
-#define WM8915_WRITE_SEQUENCER_323 0x3143
-#define WM8915_WRITE_SEQUENCER_324 0x3144
-#define WM8915_WRITE_SEQUENCER_325 0x3145
-#define WM8915_WRITE_SEQUENCER_326 0x3146
-#define WM8915_WRITE_SEQUENCER_327 0x3147
-#define WM8915_WRITE_SEQUENCER_328 0x3148
-#define WM8915_WRITE_SEQUENCER_329 0x3149
-#define WM8915_WRITE_SEQUENCER_330 0x314A
-#define WM8915_WRITE_SEQUENCER_331 0x314B
-#define WM8915_WRITE_SEQUENCER_332 0x314C
-#define WM8915_WRITE_SEQUENCER_333 0x314D
-#define WM8915_WRITE_SEQUENCER_334 0x314E
-#define WM8915_WRITE_SEQUENCER_335 0x314F
-#define WM8915_WRITE_SEQUENCER_336 0x3150
-#define WM8915_WRITE_SEQUENCER_337 0x3151
-#define WM8915_WRITE_SEQUENCER_338 0x3152
-#define WM8915_WRITE_SEQUENCER_339 0x3153
-#define WM8915_WRITE_SEQUENCER_340 0x3154
-#define WM8915_WRITE_SEQUENCER_341 0x3155
-#define WM8915_WRITE_SEQUENCER_342 0x3156
-#define WM8915_WRITE_SEQUENCER_343 0x3157
-#define WM8915_WRITE_SEQUENCER_344 0x3158
-#define WM8915_WRITE_SEQUENCER_345 0x3159
-#define WM8915_WRITE_SEQUENCER_346 0x315A
-#define WM8915_WRITE_SEQUENCER_347 0x315B
-#define WM8915_WRITE_SEQUENCER_348 0x315C
-#define WM8915_WRITE_SEQUENCER_349 0x315D
-#define WM8915_WRITE_SEQUENCER_350 0x315E
-#define WM8915_WRITE_SEQUENCER_351 0x315F
-#define WM8915_WRITE_SEQUENCER_352 0x3160
-#define WM8915_WRITE_SEQUENCER_353 0x3161
-#define WM8915_WRITE_SEQUENCER_354 0x3162
-#define WM8915_WRITE_SEQUENCER_355 0x3163
-#define WM8915_WRITE_SEQUENCER_356 0x3164
-#define WM8915_WRITE_SEQUENCER_357 0x3165
-#define WM8915_WRITE_SEQUENCER_358 0x3166
-#define WM8915_WRITE_SEQUENCER_359 0x3167
-#define WM8915_WRITE_SEQUENCER_360 0x3168
-#define WM8915_WRITE_SEQUENCER_361 0x3169
-#define WM8915_WRITE_SEQUENCER_362 0x316A
-#define WM8915_WRITE_SEQUENCER_363 0x316B
-#define WM8915_WRITE_SEQUENCER_364 0x316C
-#define WM8915_WRITE_SEQUENCER_365 0x316D
-#define WM8915_WRITE_SEQUENCER_366 0x316E
-#define WM8915_WRITE_SEQUENCER_367 0x316F
-#define WM8915_WRITE_SEQUENCER_368 0x3170
-#define WM8915_WRITE_SEQUENCER_369 0x3171
-#define WM8915_WRITE_SEQUENCER_370 0x3172
-#define WM8915_WRITE_SEQUENCER_371 0x3173
-#define WM8915_WRITE_SEQUENCER_372 0x3174
-#define WM8915_WRITE_SEQUENCER_373 0x3175
-#define WM8915_WRITE_SEQUENCER_374 0x3176
-#define WM8915_WRITE_SEQUENCER_375 0x3177
-#define WM8915_WRITE_SEQUENCER_376 0x3178
-#define WM8915_WRITE_SEQUENCER_377 0x3179
-#define WM8915_WRITE_SEQUENCER_378 0x317A
-#define WM8915_WRITE_SEQUENCER_379 0x317B
-#define WM8915_WRITE_SEQUENCER_380 0x317C
-#define WM8915_WRITE_SEQUENCER_381 0x317D
-#define WM8915_WRITE_SEQUENCER_382 0x317E
-#define WM8915_WRITE_SEQUENCER_383 0x317F
-#define WM8915_WRITE_SEQUENCER_384 0x3180
-#define WM8915_WRITE_SEQUENCER_385 0x3181
-#define WM8915_WRITE_SEQUENCER_386 0x3182
-#define WM8915_WRITE_SEQUENCER_387 0x3183
-#define WM8915_WRITE_SEQUENCER_388 0x3184
-#define WM8915_WRITE_SEQUENCER_389 0x3185
-#define WM8915_WRITE_SEQUENCER_390 0x3186
-#define WM8915_WRITE_SEQUENCER_391 0x3187
-#define WM8915_WRITE_SEQUENCER_392 0x3188
-#define WM8915_WRITE_SEQUENCER_393 0x3189
-#define WM8915_WRITE_SEQUENCER_394 0x318A
-#define WM8915_WRITE_SEQUENCER_395 0x318B
-#define WM8915_WRITE_SEQUENCER_396 0x318C
-#define WM8915_WRITE_SEQUENCER_397 0x318D
-#define WM8915_WRITE_SEQUENCER_398 0x318E
-#define WM8915_WRITE_SEQUENCER_399 0x318F
-#define WM8915_WRITE_SEQUENCER_400 0x3190
-#define WM8915_WRITE_SEQUENCER_401 0x3191
-#define WM8915_WRITE_SEQUENCER_402 0x3192
-#define WM8915_WRITE_SEQUENCER_403 0x3193
-#define WM8915_WRITE_SEQUENCER_404 0x3194
-#define WM8915_WRITE_SEQUENCER_405 0x3195
-#define WM8915_WRITE_SEQUENCER_406 0x3196
-#define WM8915_WRITE_SEQUENCER_407 0x3197
-#define WM8915_WRITE_SEQUENCER_408 0x3198
-#define WM8915_WRITE_SEQUENCER_409 0x3199
-#define WM8915_WRITE_SEQUENCER_410 0x319A
-#define WM8915_WRITE_SEQUENCER_411 0x319B
-#define WM8915_WRITE_SEQUENCER_412 0x319C
-#define WM8915_WRITE_SEQUENCER_413 0x319D
-#define WM8915_WRITE_SEQUENCER_414 0x319E
-#define WM8915_WRITE_SEQUENCER_415 0x319F
-#define WM8915_WRITE_SEQUENCER_416 0x31A0
-#define WM8915_WRITE_SEQUENCER_417 0x31A1
-#define WM8915_WRITE_SEQUENCER_418 0x31A2
-#define WM8915_WRITE_SEQUENCER_419 0x31A3
-#define WM8915_WRITE_SEQUENCER_420 0x31A4
-#define WM8915_WRITE_SEQUENCER_421 0x31A5
-#define WM8915_WRITE_SEQUENCER_422 0x31A6
-#define WM8915_WRITE_SEQUENCER_423 0x31A7
-#define WM8915_WRITE_SEQUENCER_424 0x31A8
-#define WM8915_WRITE_SEQUENCER_425 0x31A9
-#define WM8915_WRITE_SEQUENCER_426 0x31AA
-#define WM8915_WRITE_SEQUENCER_427 0x31AB
-#define WM8915_WRITE_SEQUENCER_428 0x31AC
-#define WM8915_WRITE_SEQUENCER_429 0x31AD
-#define WM8915_WRITE_SEQUENCER_430 0x31AE
-#define WM8915_WRITE_SEQUENCER_431 0x31AF
-#define WM8915_WRITE_SEQUENCER_432 0x31B0
-#define WM8915_WRITE_SEQUENCER_433 0x31B1
-#define WM8915_WRITE_SEQUENCER_434 0x31B2
-#define WM8915_WRITE_SEQUENCER_435 0x31B3
-#define WM8915_WRITE_SEQUENCER_436 0x31B4
-#define WM8915_WRITE_SEQUENCER_437 0x31B5
-#define WM8915_WRITE_SEQUENCER_438 0x31B6
-#define WM8915_WRITE_SEQUENCER_439 0x31B7
-#define WM8915_WRITE_SEQUENCER_440 0x31B8
-#define WM8915_WRITE_SEQUENCER_441 0x31B9
-#define WM8915_WRITE_SEQUENCER_442 0x31BA
-#define WM8915_WRITE_SEQUENCER_443 0x31BB
-#define WM8915_WRITE_SEQUENCER_444 0x31BC
-#define WM8915_WRITE_SEQUENCER_445 0x31BD
-#define WM8915_WRITE_SEQUENCER_446 0x31BE
-#define WM8915_WRITE_SEQUENCER_447 0x31BF
-#define WM8915_WRITE_SEQUENCER_448 0x31C0
-#define WM8915_WRITE_SEQUENCER_449 0x31C1
-#define WM8915_WRITE_SEQUENCER_450 0x31C2
-#define WM8915_WRITE_SEQUENCER_451 0x31C3
-#define WM8915_WRITE_SEQUENCER_452 0x31C4
-#define WM8915_WRITE_SEQUENCER_453 0x31C5
-#define WM8915_WRITE_SEQUENCER_454 0x31C6
-#define WM8915_WRITE_SEQUENCER_455 0x31C7
-#define WM8915_WRITE_SEQUENCER_456 0x31C8
-#define WM8915_WRITE_SEQUENCER_457 0x31C9
-#define WM8915_WRITE_SEQUENCER_458 0x31CA
-#define WM8915_WRITE_SEQUENCER_459 0x31CB
-#define WM8915_WRITE_SEQUENCER_460 0x31CC
-#define WM8915_WRITE_SEQUENCER_461 0x31CD
-#define WM8915_WRITE_SEQUENCER_462 0x31CE
-#define WM8915_WRITE_SEQUENCER_463 0x31CF
-#define WM8915_WRITE_SEQUENCER_464 0x31D0
-#define WM8915_WRITE_SEQUENCER_465 0x31D1
-#define WM8915_WRITE_SEQUENCER_466 0x31D2
-#define WM8915_WRITE_SEQUENCER_467 0x31D3
-#define WM8915_WRITE_SEQUENCER_468 0x31D4
-#define WM8915_WRITE_SEQUENCER_469 0x31D5
-#define WM8915_WRITE_SEQUENCER_470 0x31D6
-#define WM8915_WRITE_SEQUENCER_471 0x31D7
-#define WM8915_WRITE_SEQUENCER_472 0x31D8
-#define WM8915_WRITE_SEQUENCER_473 0x31D9
-#define WM8915_WRITE_SEQUENCER_474 0x31DA
-#define WM8915_WRITE_SEQUENCER_475 0x31DB
-#define WM8915_WRITE_SEQUENCER_476 0x31DC
-#define WM8915_WRITE_SEQUENCER_477 0x31DD
-#define WM8915_WRITE_SEQUENCER_478 0x31DE
-#define WM8915_WRITE_SEQUENCER_479 0x31DF
-#define WM8915_WRITE_SEQUENCER_480 0x31E0
-#define WM8915_WRITE_SEQUENCER_481 0x31E1
-#define WM8915_WRITE_SEQUENCER_482 0x31E2
-#define WM8915_WRITE_SEQUENCER_483 0x31E3
-#define WM8915_WRITE_SEQUENCER_484 0x31E4
-#define WM8915_WRITE_SEQUENCER_485 0x31E5
-#define WM8915_WRITE_SEQUENCER_486 0x31E6
-#define WM8915_WRITE_SEQUENCER_487 0x31E7
-#define WM8915_WRITE_SEQUENCER_488 0x31E8
-#define WM8915_WRITE_SEQUENCER_489 0x31E9
-#define WM8915_WRITE_SEQUENCER_490 0x31EA
-#define WM8915_WRITE_SEQUENCER_491 0x31EB
-#define WM8915_WRITE_SEQUENCER_492 0x31EC
-#define WM8915_WRITE_SEQUENCER_493 0x31ED
-#define WM8915_WRITE_SEQUENCER_494 0x31EE
-#define WM8915_WRITE_SEQUENCER_495 0x31EF
-#define WM8915_WRITE_SEQUENCER_496 0x31F0
-#define WM8915_WRITE_SEQUENCER_497 0x31F1
-#define WM8915_WRITE_SEQUENCER_498 0x31F2
-#define WM8915_WRITE_SEQUENCER_499 0x31F3
-#define WM8915_WRITE_SEQUENCER_500 0x31F4
-#define WM8915_WRITE_SEQUENCER_501 0x31F5
-#define WM8915_WRITE_SEQUENCER_502 0x31F6
-#define WM8915_WRITE_SEQUENCER_503 0x31F7
-#define WM8915_WRITE_SEQUENCER_504 0x31F8
-#define WM8915_WRITE_SEQUENCER_505 0x31F9
-#define WM8915_WRITE_SEQUENCER_506 0x31FA
-#define WM8915_WRITE_SEQUENCER_507 0x31FB
-#define WM8915_WRITE_SEQUENCER_508 0x31FC
-#define WM8915_WRITE_SEQUENCER_509 0x31FD
-#define WM8915_WRITE_SEQUENCER_510 0x31FE
-#define WM8915_WRITE_SEQUENCER_511 0x31FF
-
-#define WM8915_REGISTER_COUNT 706
-#define WM8915_MAX_REGISTER 0x31FF
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
-#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
-#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */
-#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
-#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
-#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
-#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */
-#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
-#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
-#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
-#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
-#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
-#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
-#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
-#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
-#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
-#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
-#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
-#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
-#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
-#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
-#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
-#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
-#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
-#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
-#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
-#define WM8915_BG_ENA 0x0001 /* BG_ENA */
-#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */
-#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */
-#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
-#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
-#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8915_INL_ENA 0x0020 /* INL_ENA */
-#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */
-#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */
-#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */
-#define WM8915_INR_ENA 0x0010 /* INR_ENA */
-#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */
-#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */
-#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */
-#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */
-#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
-#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
-#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
-#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
-#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
-#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
-#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
-#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
-#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
-#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
-#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
-#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
-#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
-#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
-#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
-#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
-#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
-#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
-#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
-#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
-#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
-#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
-#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
-#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
-#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
-#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
-#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
-#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
-#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
-#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
-#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
-#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
-#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
-#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
-#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R4 (0x04) - Power Management (4)
- */
-#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
-#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
-#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
-#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
-#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
-#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
-#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
-#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
-#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
-#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
-#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
-#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
-#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
-#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
-#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
-#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
-#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
-#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
-#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
-#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
-#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
-#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
-#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
-#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
-#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
-#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
-#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
-#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
-#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
-#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
-#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
-#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
-
-/*
- * R5 (0x05) - Power Management (5)
- */
-#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
-#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
-#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
-#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
-#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
-#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
-#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
-#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
-#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
-#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
-#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
-#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
-#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
-#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
-#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
-#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
-#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */
-#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
-#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
-#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
-#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */
-#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
-#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
-#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
-#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */
-#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
-#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
-#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
-#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */
-#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
-#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
-#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
-
-/*
- * R6 (0x06) - Power Management (6)
- */
-#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
-#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
-#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
-#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
-#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
-#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
-#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
-#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
-#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
-#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
-#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
-#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
-#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
-#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
-#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
-#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
-#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
-#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
-#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
-#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
-#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
-#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
-#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
-#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
-#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
-#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
-#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
-#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
-#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
-#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
-#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
-#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
-
-/*
- * R7 (0x07) - Power Management (7)
- */
-#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */
-#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
-#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
-#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
-#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */
-#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
-#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
-#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
-#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
-#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
-#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
-#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
-#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
-#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
-#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
-#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
-#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
-#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
-#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
-#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
-#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
-#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
-#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
-#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
-#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
-#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
-#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
-#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
-#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
-#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
-
-/*
- * R8 (0x08) - Power Management (8)
- */
-#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
-#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
-#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
-#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
-#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
-#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
-#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
-#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
-#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
-#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
-#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
-
-/*
- * R16 (0x10) - Left Line Input Volume
- */
-#define WM8915_IN1_VU 0x0080 /* IN1_VU */
-#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
-#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
-#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */
-#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
-#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
-#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
-#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
-#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
-#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
-
-/*
- * R17 (0x11) - Right Line Input Volume
- */
-#define WM8915_IN1_VU 0x0080 /* IN1_VU */
-#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
-#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
-#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */
-#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
-#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
-#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
-#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
-#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
-#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
-
-/*
- * R18 (0x12) - Line Input Control
- */
-#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
-#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
-#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
-#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
-#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
-#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
-
-/*
- * R21 (0x15) - DAC1 HPOUT1 Volume
- */
-#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
-#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
-#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
-#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
-#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
-#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
-
-/*
- * R22 (0x16) - DAC2 HPOUT2 Volume
- */
-#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
-#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
-#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
-#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
-#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
-#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
-
-/*
- * R24 (0x18) - DAC1 Left Volume
- */
-#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
-#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
-#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
-#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
-#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
-#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
-#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
-
-/*
- * R25 (0x19) - DAC1 Right Volume
- */
-#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
-#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
-#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
-#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
-#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
-#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
-#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
-
-/*
- * R26 (0x1A) - DAC2 Left Volume
- */
-#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
-#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
-#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
-#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
-#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
-#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
-#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
-
-/*
- * R27 (0x1B) - DAC2 Right Volume
- */
-#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
-#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
-#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
-#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
-#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
-#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
-#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
-
-/*
- * R28 (0x1C) - Output1 Left Volume
- */
-#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
-#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
-#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
-#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
-#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
-#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
-#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
-
-/*
- * R29 (0x1D) - Output1 Right Volume
- */
-#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
-#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
-#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
-#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
-#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
-#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
-#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
-
-/*
- * R30 (0x1E) - Output2 Left Volume
- */
-#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
-#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
-#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
-#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
-#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
-#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
-#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
-
-/*
- * R31 (0x1F) - Output2 Right Volume
- */
-#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
-#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
-#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
-#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
-#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
-#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
-#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
-
-/*
- * R32 (0x20) - MICBIAS (1)
- */
-#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */
-#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
-#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
-#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
-#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */
-#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
-#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
-#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
-#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
-#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
-#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
-#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */
-#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
-#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
-#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
-
-/*
- * R33 (0x21) - MICBIAS (2)
- */
-#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */
-#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
-#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
-#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
-#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */
-#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
-#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
-#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
-#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
-#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
-#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
-#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */
-#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
-#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
-#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
-
-/*
- * R40 (0x28) - LDO 1
- */
-#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */
-#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
-#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
-#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
-#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
-#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
-#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
-#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */
-#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
-#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
-#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
-
-/*
- * R41 (0x29) - LDO 2
- */
-#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */
-#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
-#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
-#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
-#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
-#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
-#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
-#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */
-#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
-#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
-#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
-
-/*
- * R48 (0x30) - Accessory Detect Mode 1
- */
-#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
-#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
-#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
-
-/*
- * R49 (0x31) - Accessory Detect Mode 2
- */
-#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
-#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
-#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
-#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
-#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */
-#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */
-#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */
-#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */
-#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
-#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
-#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
-#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
-
-/*
- * R52 (0x34) - Headphone Detect 1
- */
-#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
-#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
-#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
-#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
-#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
-#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
-#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
-#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
-#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
-#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
-#define WM8915_HP_POLL 0x0001 /* HP_POLL */
-#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */
-#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */
-#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */
-
-/*
- * R53 (0x35) - Headphone Detect 2
- */
-#define WM8915_HP_DONE 0x0080 /* HP_DONE */
-#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */
-#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */
-#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */
-#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
-#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
-#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
-
-/*
- * R56 (0x38) - Mic Detect 1
- */
-#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
-#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
-#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
-#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
-#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
-#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
-#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */
-#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
-#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
-#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
-#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */
-#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */
-#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */
-#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */
-
-/*
- * R57 (0x39) - Mic Detect 2
- */
-#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
-#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
-#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
-
-/*
- * R58 (0x3A) - Mic Detect 3
- */
-#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
-#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
-#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
-#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */
-#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */
-#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */
-#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */
-#define WM8915_MICD_STS 0x0001 /* MICD_STS */
-#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */
-#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */
-#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */
-
-/*
- * R64 (0x40) - Charge Pump (1)
- */
-#define WM8915_CP_ENA 0x8000 /* CP_ENA */
-#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */
-#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */
-#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R65 (0x41) - Charge Pump (2)
- */
-#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */
-#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */
-#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */
-#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */
-
-/*
- * R80 (0x50) - DC Servo (1)
- */
-#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
-#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
-#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
-#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
-#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
-#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
-#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
-#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
-
-/*
- * R81 (0x51) - DC Servo (2)
- */
-#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
-#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
-#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
-#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
-#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
-#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
-#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
-#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
-#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
-#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
-#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
-#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
-#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
-#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
-#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
-#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
-#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
-#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
-#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
-#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
-#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
-#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
-#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
-#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
-#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
-#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
-#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
-#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
-#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
-#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
-
-/*
- * R82 (0x52) - DC Servo (3)
- */
-#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
-
-/*
- * R84 (0x54) - DC Servo (5)
- */
-#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
-
-/*
- * R85 (0x55) - DC Servo (6)
- */
-#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
-
-/*
- * R86 (0x56) - DC Servo (7)
- */
-#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
-
-/*
- * R87 (0x57) - DC Servo Readback 0
- */
-#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
-
-/*
- * R96 (0x60) - Analogue HP (1)
- */
-#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
-#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
-#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
-#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
-#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
-#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
-#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
-#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
-#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
-#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
-#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
-#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
-#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
-#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
-#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
-#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
-#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
-#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
-#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
-#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
-
-/*
- * R97 (0x61) - Analogue HP (2)
- */
-#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
-#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
-#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
-#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
-#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
-#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
-#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
-#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
-#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
-#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
-#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
-#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
-#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
-#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
-#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
-#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
-#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
-#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
-#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
-#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
-#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
-#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
-#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
-#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
-
-/*
- * R256 (0x100) - Chip Revision
- */
-#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
-#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
-#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
-
-/*
- * R257 (0x101) - Control Interface (1)
- */
-#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */
-#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */
-#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */
-#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-/*
- * R272 (0x110) - Write Sequencer Ctrl (1)
- */
-#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */
-#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
-#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
-#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
-#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
-#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
-
-/*
- * R273 (0x111) - Write Sequencer Ctrl (2)
- */
-#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
-#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
-#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
-#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
-#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
-#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
-
-/*
- * R512 (0x200) - AIF Clocking (1)
- */
-#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
-#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
-#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
-#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */
-#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
-#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
-#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
-#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
-#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
-#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
-#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
-#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
-#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
-#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
-#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
-
-/*
- * R513 (0x201) - AIF Clocking (2)
- */
-#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
-#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
-#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
-#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
-#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
-#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
-
-/*
- * R520 (0x208) - Clocking (1)
- */
-#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */
-#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
-#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
-#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
-#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */
-#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
-#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
-#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
-#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
-#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
-#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
-#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
-#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
-#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
-#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
-
-/*
- * R521 (0x209) - Clocking (2)
- */
-#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
-#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
-#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
-#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
-#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
-#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
-#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
-#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
-#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
-
-/*
- * R528 (0x210) - AIF Rate
- */
-#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
-#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
-#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
-#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
-
-/*
- * R544 (0x220) - FLL Control (1)
- */
-#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
-#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
-#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
-#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
-#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R545 (0x221) - FLL Control (2)
- */
-#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
-#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
-#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
-#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R546 (0x222) - FLL Control (3)
- */
-#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
-#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
-#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
-
-/*
- * R547 (0x223) - FLL Control (4)
- */
-#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
-#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
-#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
-#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
-#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
-#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
-
-/*
- * R548 (0x224) - FLL Control (5)
- */
-#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
-#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
-#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
-#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
-#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
-#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
-#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
-#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
-#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
-#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
-#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
-#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
-#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
-#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
-
-/*
- * R549 (0x225) - FLL Control (6)
- */
-#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
-#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
-#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
-#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
-#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
-#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
-#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
-
-/*
- * R550 (0x226) - FLL EFS 1
- */
-#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
-#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
-#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
-
-/*
- * R551 (0x227) - FLL EFS 2
- */
-#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
-#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
-#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
-#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
-#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
-#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
-#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
-
-/*
- * R768 (0x300) - AIF1 Control
- */
-#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */
-#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
-#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
-#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
-#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
-#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
-#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
-
-/*
- * R769 (0x301) - AIF1 BCLK
- */
-#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
-#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
-#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
-#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
-#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
-#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
-#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
-#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
-#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
-#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
-#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
-#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
-#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
-#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
-#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
-
-/*
- * R770 (0x302) - AIF1 TX LRCLK(1)
- */
-#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
-#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
-#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
-
-/*
- * R771 (0x303) - AIF1 TX LRCLK(2)
- */
-#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
-#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
-#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
-#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
-#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
-#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
-#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
-#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
-#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
-#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
-
-/*
- * R772 (0x304) - AIF1 RX LRCLK(1)
- */
-#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
-#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
-#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
-
-/*
- * R773 (0x305) - AIF1 RX LRCLK(2)
- */
-#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
-#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
-#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
-#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
-#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
-#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
-
-/*
- * R774 (0x306) - AIF1TX Data Configuration (1)
- */
-#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
-#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
-#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
-#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
-
-/*
- * R775 (0x307) - AIF1TX Data Configuration (2)
- */
-#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
-#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
-#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
-#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
-
-/*
- * R776 (0x308) - AIF1RX Data Configuration
- */
-#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
-#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
-#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
-#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
-
-/*
- * R777 (0x309) - AIF1TX Channel 0 Configuration
- */
-#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R778 (0x30A) - AIF1TX Channel 1 Configuration
- */
-#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R779 (0x30B) - AIF1TX Channel 2 Configuration
- */
-#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
-
-/*
- * R780 (0x30C) - AIF1TX Channel 3 Configuration
- */
-#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
-
-/*
- * R781 (0x30D) - AIF1TX Channel 4 Configuration
- */
-#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
-
-/*
- * R782 (0x30E) - AIF1TX Channel 5 Configuration
- */
-#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
-#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
-#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
-#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
-
-/*
- * R783 (0x30F) - AIF1RX Channel 0 Configuration
- */
-#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R784 (0x310) - AIF1RX Channel 1 Configuration
- */
-#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R785 (0x311) - AIF1RX Channel 2 Configuration
- */
-#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
-
-/*
- * R786 (0x312) - AIF1RX Channel 3 Configuration
- */
-#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
-
-/*
- * R787 (0x313) - AIF1RX Channel 4 Configuration
- */
-#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
-
-/*
- * R788 (0x314) - AIF1RX Channel 5 Configuration
- */
-#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
-#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
-#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
-#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
-
-/*
- * R789 (0x315) - AIF1RX Mono Configuration
- */
-#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
-#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
-#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
-#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
-
-/*
- * R794 (0x31A) - AIF1TX Test
- */
-#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
-#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
-#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
-#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
-#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
-#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
-#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
-#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
-#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
-#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
-#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
-#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
-
-/*
- * R800 (0x320) - AIF2 Control
- */
-#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */
-#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
-#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
-#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
-#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
-#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
-#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
-
-/*
- * R801 (0x321) - AIF2 BCLK
- */
-#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
-#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
-#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
-#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
-#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
-#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
-#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
-#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
-#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
-#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
-#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
-#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
-#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
-#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
-#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
-
-/*
- * R802 (0x322) - AIF2 TX LRCLK(1)
- */
-#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
-#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
-#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
-
-/*
- * R803 (0x323) - AIF2 TX LRCLK(2)
- */
-#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
-#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
-#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
-#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
-#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
-#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
-#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
-#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
-#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
-#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
-#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
-#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
-#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
-#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
-#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
-#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
-
-/*
- * R804 (0x324) - AIF2 RX LRCLK(1)
- */
-#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
-#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
-#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
-
-/*
- * R805 (0x325) - AIF2 RX LRCLK(2)
- */
-#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
-#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
-#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
-#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
-#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
-#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
-#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
-#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
-#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
-#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
-#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
-#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
-
-/*
- * R806 (0x326) - AIF2TX Data Configuration (1)
- */
-#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
-#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
-#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
-#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
-#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
-#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
-
-/*
- * R807 (0x327) - AIF2TX Data Configuration (2)
- */
-#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
-#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
-#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
-#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
-
-/*
- * R808 (0x328) - AIF2RX Data Configuration
- */
-#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
-#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
-#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
-#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
-#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
-#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
-
-/*
- * R809 (0x329) - AIF2TX Channel 0 Configuration
- */
-#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R810 (0x32A) - AIF2TX Channel 1 Configuration
- */
-#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R811 (0x32B) - AIF2RX Channel 0 Configuration
- */
-#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
-#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
-#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
-#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R812 (0x32C) - AIF2RX Channel 1 Configuration
- */
-#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
-#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
-#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
-#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R813 (0x32D) - AIF2RX Mono Configuration
- */
-#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
-#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
-#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
-#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
-
-/*
- * R815 (0x32F) - AIF2TX Test
- */
-#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
-#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
-#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
-#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
-
-/*
- * R1024 (0x400) - DSP1 TX Left Volume
- */
-#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
-#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
-#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
-#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
-#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
-#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
-#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
-
-/*
- * R1025 (0x401) - DSP1 TX Right Volume
- */
-#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
-#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
-#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
-#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
-#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
-#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
-#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
-
-/*
- * R1026 (0x402) - DSP1 RX Left Volume
- */
-#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
-#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
-#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
-#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
-#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
-#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
-#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
-
-/*
- * R1027 (0x403) - DSP1 RX Right Volume
- */
-#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
-#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
-#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
-#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
-#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
-#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
-#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
-
-/*
- * R1040 (0x410) - DSP1 TX Filters
- */
-#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */
-#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
-#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
-#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
-#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
-#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
-#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
-#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
-#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
-#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
-#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
-#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
-#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
-#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
-#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
-#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
-#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
-#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
-
-/*
- * R1056 (0x420) - DSP1 RX Filters (1)
- */
-#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
-#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
-#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
-#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
-#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
-#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
-#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
-#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
-#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
-#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
-#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
-#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
-#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
-#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
-#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
-#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
-
-/*
- * R1057 (0x421) - DSP1 RX Filters (2)
- */
-#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
-#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
-#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
-#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
-#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
-#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
-#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
-
-/*
- * R1088 (0x440) - DSP1 DRC (1)
- */
-#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
-#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
-#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
-#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
-#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
-#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
-#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
-#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
-#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
-#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
-#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
-#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
-#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
-#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
-#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
-#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
-#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
-#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
-#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
-#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
-#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
-#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
-#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
-#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
-#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
-#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
-#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
-#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
-#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
-#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
-#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
-#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
-#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
-#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
-#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
-#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
-#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
-#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
-
-/*
- * R1089 (0x441) - DSP1 DRC (2)
- */
-#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
-#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
-#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
-#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
-#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
-#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
-#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
-#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
-#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
-#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
-#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
-#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
-
-/*
- * R1090 (0x442) - DSP1 DRC (3)
- */
-#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
-#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
-#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
-#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
-#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
-#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
-#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
-#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
-#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
-#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
-#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
-#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
-#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
-#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
-#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
-#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
-#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
-#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
-
-/*
- * R1091 (0x443) - DSP1 DRC (4)
- */
-#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
-#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
-#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
-#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
-#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
-#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
-
-/*
- * R1092 (0x444) - DSP1 DRC (5)
- */
-#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
-#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
-#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
-#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
-#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
-#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
-
-/*
- * R1152 (0x480) - DSP1 RX EQ Gains (1)
- */
-#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
-#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
-#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
-#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
-#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
-#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
-#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
-#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
-#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
-#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
-#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
-#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
-#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
-
-/*
- * R1153 (0x481) - DSP1 RX EQ Gains (2)
- */
-#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
-#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
-#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
-#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
-#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
-#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1154 (0x482) - DSP1 RX EQ Band 1 A
- */
-#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
-
-/*
- * R1155 (0x483) - DSP1 RX EQ Band 1 B
- */
-#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
-
-/*
- * R1156 (0x484) - DSP1 RX EQ Band 1 PG
- */
-#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
-
-/*
- * R1157 (0x485) - DSP1 RX EQ Band 2 A
- */
-#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
-
-/*
- * R1158 (0x486) - DSP1 RX EQ Band 2 B
- */
-#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
-
-/*
- * R1159 (0x487) - DSP1 RX EQ Band 2 C
- */
-#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
-
-/*
- * R1160 (0x488) - DSP1 RX EQ Band 2 PG
- */
-#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
-
-/*
- * R1161 (0x489) - DSP1 RX EQ Band 3 A
- */
-#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
-
-/*
- * R1162 (0x48A) - DSP1 RX EQ Band 3 B
- */
-#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
-
-/*
- * R1163 (0x48B) - DSP1 RX EQ Band 3 C
- */
-#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
-
-/*
- * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
- */
-#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
-
-/*
- * R1165 (0x48D) - DSP1 RX EQ Band 4 A
- */
-#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
-
-/*
- * R1166 (0x48E) - DSP1 RX EQ Band 4 B
- */
-#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
-
-/*
- * R1167 (0x48F) - DSP1 RX EQ Band 4 C
- */
-#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
-
-/*
- * R1168 (0x490) - DSP1 RX EQ Band 4 PG
- */
-#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
-
-/*
- * R1169 (0x491) - DSP1 RX EQ Band 5 A
- */
-#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
-#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
-
-/*
- * R1170 (0x492) - DSP1 RX EQ Band 5 B
- */
-#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
-#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
-
-/*
- * R1171 (0x493) - DSP1 RX EQ Band 5 PG
- */
-#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
-#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
-
-/*
- * R1280 (0x500) - DSP2 TX Left Volume
- */
-#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
-#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
-#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
-#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
-#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
-#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
-#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
-
-/*
- * R1281 (0x501) - DSP2 TX Right Volume
- */
-#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
-#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
-#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
-#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
-#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
-#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
-#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
-
-/*
- * R1282 (0x502) - DSP2 RX Left Volume
- */
-#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
-#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
-#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
-#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
-#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
-#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
-#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
-
-/*
- * R1283 (0x503) - DSP2 RX Right Volume
- */
-#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
-#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
-#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
-#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
-#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
-#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
-#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
-
-/*
- * R1296 (0x510) - DSP2 TX Filters
- */
-#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */
-#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
-#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
-#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
-#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
-#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
-#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
-#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
-#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
-#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
-#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
-#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
-#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
-#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
-#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
-#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
-#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
-#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
-
-/*
- * R1312 (0x520) - DSP2 RX Filters (1)
- */
-#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
-#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
-#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
-#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
-#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
-#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
-#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
-#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
-#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
-#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
-#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
-#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
-#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
-#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
-#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
-#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
-
-/*
- * R1313 (0x521) - DSP2 RX Filters (2)
- */
-#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
-#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
-#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
-#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
-#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
-#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
-#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
-
-/*
- * R1344 (0x540) - DSP2 DRC (1)
- */
-#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
-#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
-#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
-#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
-#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
-#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
-#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
-#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
-#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
-#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
-#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
-#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
-#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
-#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
-#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
-#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
-#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
-#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
-#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
-#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
-#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
-#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
-#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
-#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
-#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
-#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
-#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
-#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
-#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
-#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
-#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
-#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
-#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
-#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
-#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
-#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
-#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
-#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
-
-/*
- * R1345 (0x541) - DSP2 DRC (2)
- */
-#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
-#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
-#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
-#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
-#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
-#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
-#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
-#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
-#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
-#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
-#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
-#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
-
-/*
- * R1346 (0x542) - DSP2 DRC (3)
- */
-#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
-#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
-#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
-#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
-#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
-#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
-#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
-#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
-#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
-#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
-#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
-#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
-#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
-#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
-#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
-#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
-#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
-#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
-
-/*
- * R1347 (0x543) - DSP2 DRC (4)
- */
-#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
-#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
-#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
-#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
-#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
-#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
-
-/*
- * R1348 (0x544) - DSP2 DRC (5)
- */
-#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
-#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
-#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
-#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
-#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
-#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
-
-/*
- * R1408 (0x580) - DSP2 RX EQ Gains (1)
- */
-#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
-#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
-#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
-#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
-#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
-#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
-#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
-#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
-#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
-#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
-#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
-#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
-#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
-
-/*
- * R1409 (0x581) - DSP2 RX EQ Gains (2)
- */
-#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
-#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
-#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
-#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
-#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
-#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1410 (0x582) - DSP2 RX EQ Band 1 A
- */
-#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
-
-/*
- * R1411 (0x583) - DSP2 RX EQ Band 1 B
- */
-#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
-
-/*
- * R1412 (0x584) - DSP2 RX EQ Band 1 PG
- */
-#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
-
-/*
- * R1413 (0x585) - DSP2 RX EQ Band 2 A
- */
-#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
-
-/*
- * R1414 (0x586) - DSP2 RX EQ Band 2 B
- */
-#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
-
-/*
- * R1415 (0x587) - DSP2 RX EQ Band 2 C
- */
-#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
-
-/*
- * R1416 (0x588) - DSP2 RX EQ Band 2 PG
- */
-#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
-
-/*
- * R1417 (0x589) - DSP2 RX EQ Band 3 A
- */
-#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
-
-/*
- * R1418 (0x58A) - DSP2 RX EQ Band 3 B
- */
-#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
-
-/*
- * R1419 (0x58B) - DSP2 RX EQ Band 3 C
- */
-#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
-
-/*
- * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
- */
-#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
-
-/*
- * R1421 (0x58D) - DSP2 RX EQ Band 4 A
- */
-#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
-
-/*
- * R1422 (0x58E) - DSP2 RX EQ Band 4 B
- */
-#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
-
-/*
- * R1423 (0x58F) - DSP2 RX EQ Band 4 C
- */
-#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
-
-/*
- * R1424 (0x590) - DSP2 RX EQ Band 4 PG
- */
-#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
-
-/*
- * R1425 (0x591) - DSP2 RX EQ Band 5 A
- */
-#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
-#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
-
-/*
- * R1426 (0x592) - DSP2 RX EQ Band 5 B
- */
-#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
-#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
-
-/*
- * R1427 (0x593) - DSP2 RX EQ Band 5 PG
- */
-#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
-#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
-
-/*
- * R1536 (0x600) - DAC1 Mixer Volumes
- */
-#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
-#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
-#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
-
-/*
- * R1537 (0x601) - DAC1 Left Mixer Routing
- */
-#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
-#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
-#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
-#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
-#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
-#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
-#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
-#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
-#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
-#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
-#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
-#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
-#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
-#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
-#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
-#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
-
-/*
- * R1538 (0x602) - DAC1 Right Mixer Routing
- */
-#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
-#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
-#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
-#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
-#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
-#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
-#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
-#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
-#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
-#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
-#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
-#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
-#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
-#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
-#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
-#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
-
-/*
- * R1539 (0x603) - DAC2 Mixer Volumes
- */
-#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
-#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
-#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
-
-/*
- * R1540 (0x604) - DAC2 Left Mixer Routing
- */
-#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
-#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
-#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
-#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
-#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
-#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
-#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
-#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
-#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
-#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
-#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
-#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
-#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
-#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
-#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
-#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
-
-/*
- * R1541 (0x605) - DAC2 Right Mixer Routing
- */
-#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
-#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
-#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
-#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
-#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
-#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
-#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
-#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
-#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
-#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
-#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
-#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
-#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
-#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
-#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
-#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
-
-/*
- * R1542 (0x606) - DSP1 TX Left Mixer Routing
- */
-#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
-#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
-#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
-#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
-#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
-#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
-#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
-#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
-
-/*
- * R1543 (0x607) - DSP1 TX Right Mixer Routing
- */
-#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
-#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
-#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
-#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
-#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
-#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
-#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
-#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
-
-/*
- * R1544 (0x608) - DSP2 TX Left Mixer Routing
- */
-#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
-#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
-#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
-#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
-#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
-#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
-#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
-#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
-
-/*
- * R1545 (0x609) - DSP2 TX Right Mixer Routing
- */
-#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
-#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
-#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
-#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
-#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
-#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
-#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
-#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
-
-/*
- * R1546 (0x60A) - DSP TX Mixer Select
- */
-#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
-#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
-#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
-#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
-
-/*
- * R1552 (0x610) - DAC Softmute
- */
-#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
-#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
-#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
-#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
-#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
-#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
-#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
-#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-
-/*
- * R1568 (0x620) - Oversampling
- */
-#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */
-#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
-#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
-#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
-#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
-#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
-#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
-#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
-#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */
-#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
-#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
-#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
-#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */
-#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
-#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
-#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
-
-/*
- * R1569 (0x621) - Sidetone
- */
-#define WM8915_ST_LPF 0x1000 /* ST_LPF */
-#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */
-#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */
-#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */
-#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
-#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
-#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
-#define WM8915_ST_HPF 0x0040 /* ST_HPF */
-#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */
-#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */
-#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */
-#define WM8915_STR_SEL 0x0002 /* STR_SEL */
-#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */
-#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */
-#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */
-#define WM8915_STL_SEL 0x0001 /* STL_SEL */
-#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */
-#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */
-#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */
-
-/*
- * R1792 (0x700) - GPIO 1
- */
-#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */
-#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */
-#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */
-#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */
-#define WM8915_GP1_PU 0x4000 /* GP1_PU */
-#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */
-#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */
-#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */
-#define WM8915_GP1_PD 0x2000 /* GP1_PD */
-#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */
-#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */
-#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */
-#define WM8915_GP1_POL 0x0400 /* GP1_POL */
-#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */
-#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */
-#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */
-#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
-#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
-#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
-#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
-#define WM8915_GP1_DB 0x0100 /* GP1_DB */
-#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */
-#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */
-#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */
-#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */
-#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */
-#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */
-#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */
-#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
-#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
-#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
-
-/*
- * R1793 (0x701) - GPIO 2
- */
-#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */
-#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */
-#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */
-#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */
-#define WM8915_GP2_PU 0x4000 /* GP2_PU */
-#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */
-#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */
-#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */
-#define WM8915_GP2_PD 0x2000 /* GP2_PD */
-#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */
-#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */
-#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */
-#define WM8915_GP2_POL 0x0400 /* GP2_POL */
-#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */
-#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */
-#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */
-#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
-#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
-#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
-#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
-#define WM8915_GP2_DB 0x0100 /* GP2_DB */
-#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */
-#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */
-#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */
-#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */
-#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */
-#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */
-#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */
-#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
-#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
-#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
-
-/*
- * R1794 (0x702) - GPIO 3
- */
-#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */
-#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */
-#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */
-#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */
-#define WM8915_GP3_PU 0x4000 /* GP3_PU */
-#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */
-#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */
-#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */
-#define WM8915_GP3_PD 0x2000 /* GP3_PD */
-#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */
-#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */
-#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */
-#define WM8915_GP3_POL 0x0400 /* GP3_POL */
-#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */
-#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */
-#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */
-#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
-#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
-#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
-#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
-#define WM8915_GP3_DB 0x0100 /* GP3_DB */
-#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */
-#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */
-#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */
-#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */
-#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */
-#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */
-#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */
-#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
-#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
-#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
-
-/*
- * R1795 (0x703) - GPIO 4
- */
-#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */
-#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */
-#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */
-#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */
-#define WM8915_GP4_PU 0x4000 /* GP4_PU */
-#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */
-#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */
-#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */
-#define WM8915_GP4_PD 0x2000 /* GP4_PD */
-#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */
-#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */
-#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */
-#define WM8915_GP4_POL 0x0400 /* GP4_POL */
-#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */
-#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */
-#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */
-#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
-#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
-#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
-#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
-#define WM8915_GP4_DB 0x0100 /* GP4_DB */
-#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */
-#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */
-#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */
-#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */
-#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */
-#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */
-#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */
-#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
-#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
-#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
-
-/*
- * R1796 (0x704) - GPIO 5
- */
-#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */
-#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */
-#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */
-#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */
-#define WM8915_GP5_PU 0x4000 /* GP5_PU */
-#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */
-#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */
-#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */
-#define WM8915_GP5_PD 0x2000 /* GP5_PD */
-#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */
-#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */
-#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */
-#define WM8915_GP5_POL 0x0400 /* GP5_POL */
-#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */
-#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */
-#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */
-#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
-#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
-#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
-#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
-#define WM8915_GP5_DB 0x0100 /* GP5_DB */
-#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */
-#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */
-#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */
-#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */
-#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */
-#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */
-#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */
-#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
-#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
-#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
-
-/*
- * R1824 (0x720) - Pull Control (1)
- */
-#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
-#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
-#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
-#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
-#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
-#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
-#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
-#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
-#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */
-#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
-#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
-#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
-#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */
-#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
-#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
-#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
-#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */
-#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
-#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
-#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
-#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */
-#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
-#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
-#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
-#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */
-#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
-#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
-#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
-#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */
-#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
-#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
-#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
-#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
-#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
-#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
-#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
-#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
-#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
-#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
-#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
-#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */
-#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
-#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
-#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
-#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */
-#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
-#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
-#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
-
-/*
- * R1825 (0x721) - Pull Control (2)
- */
-#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
-#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
-#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
-#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
-#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */
-#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */
-#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */
-#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */
-#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */
-#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
-#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
-#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
-#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */
-#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
-#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
-#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
-#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
-#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
-#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
-#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
-#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
-#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
-#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
-#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
-#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */
-#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
-#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
-#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
-#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */
-#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
-#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
-#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
-
-/*
- * R1840 (0x730) - Interrupt Status 1
- */
-#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */
-#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */
-#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */
-#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */
-#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */
-#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */
-#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */
-#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */
-#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */
-#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */
-#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */
-#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */
-#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */
-#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */
-#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */
-#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */
-#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */
-#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */
-#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */
-#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */
-
-/*
- * R1841 (0x731) - Interrupt Status 2
- */
-#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
-#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
-#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
-#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
-#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
-#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
-#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
-#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
-#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
-#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
-#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
-#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
-#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
-#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
-#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
-#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
-#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
-#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
-#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
-#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
-#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
-#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
-#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
-#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
-#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
-#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
-#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
-#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
-#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
-#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
-#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
-#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
-#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
-#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
-#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
-#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
-#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */
-#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */
-#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */
-#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */
-
-/*
- * R1842 (0x732) - Interrupt Raw Status 2
- */
-#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
-#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
-#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
-#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
-#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
-#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
-#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
-#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
-#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
-#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
-#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
-#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
-#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
-#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
-#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
-#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
-#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
-#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
-#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
-#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
-#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
-#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
-#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
-#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
-#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
-#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
-#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
-#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
-
-/*
- * R1848 (0x738) - Interrupt Status 1 Mask
- */
-#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
-#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
-#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
-#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
-#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
-#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
-#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
-#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
-#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
-#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
-#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
-#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
-#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
-#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
-#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
-#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
-#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
-#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
-#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
-#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
-
-/*
- * R1849 (0x739) - Interrupt Status 2 Mask
- */
-#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
-#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
-#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
-#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
-#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
-#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
-#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
-#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
-#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
-#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
-#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
-#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
-#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
-#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
-#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
-#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
-#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
-#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
-#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
-#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
-#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
-#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
-#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
-#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
-#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
-#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
-#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
-#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
-
-/*
- * R1856 (0x740) - Interrupt Control
- */
-#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */
-#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */
-#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */
-#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */
-
-/*
- * R2048 (0x800) - Left PDM Speaker
- */
-#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */
-#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
-#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
-#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
-#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */
-#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
-#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
-#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
-#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
-#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
-#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
-#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
-#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
-#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
-#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
-
-/*
- * R2049 (0x801) - Right PDM Speaker
- */
-#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */
-#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
-#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
-#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
-#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */
-#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
-#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
-#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
-#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
-#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
-#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
-#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
-#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
-#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
-#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
-
-/*
- * R2050 (0x802) - PDM Speaker Mute Sequence
- */
-#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
-#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
-#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
-#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
-#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
-#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
-#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
-
-/*
- * R2051 (0x803) - PDM Speaker Volume
- */
-#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
-#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
-#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
-#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
-#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
-#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
-
-#endif
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 8499c563a9b..1725550c293 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2221,6 +2221,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
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);
if (wm8962->irq) {
@@ -2927,10 +2929,6 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
WM8962_BIAS_ENA | 0x180);
msleep(5);
-
- snd_soc_update_bits(codec, WM8962_CLOCKING2,
- WM8962_CLKREG_OVD,
- WM8962_CLKREG_OVD);
}
/* VMID 2*250k */
@@ -3288,6 +3286,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
+ try_wait_for_completion(&wm8962->fll_lock);
+
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
WM8962_FLL_ENA, fll1);
@@ -3409,6 +3409,9 @@ static irqreturn_t wm8962_irq(int irq, void *data)
active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
active &= ~mask;
+ /* Acknowledge the interrupts */
+ snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
+
if (active & WM8962_FLL_LOCK_EINT) {
dev_dbg(codec->dev, "FLL locked\n");
complete(&wm8962->fll_lock);
@@ -3433,9 +3436,6 @@ static irqreturn_t wm8962_irq(int irq, void *data)
msecs_to_jiffies(250));
}
- /* Acknowledge the interrupts */
- snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
-
return IRQ_HANDLED;
}
@@ -3868,6 +3868,10 @@ static int wm8962_probe(struct snd_soc_codec *codec)
*/
snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
+ /* Ensure we have soft control over all registers */
+ snd_soc_update_bits(codec, WM8962_CLOCKING2,
+ WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
+
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
if (pdata) {
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 09e680ae88b..b393f9fac97 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2981,6 +2981,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
wm8994->hubs.dcs_readback_mode = 1;
break;
}
+ break;
case WM8958:
wm8994->hubs.dcs_readback_mode = 1;
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
new file mode 100644
index 00000000000..0cdb9d10567
--- /dev/null
+++ b/sound/soc/codecs/wm8996.c
@@ -0,0 +1,3002 @@
+/*
+ * wm8996.c - WM8996 audio codec interface
+ *
+ * Copyright 2011 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/gcd.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <trace/events/asoc.h>
+
+#include <sound/wm8996.h>
+#include "wm8996.h"
+
+#define WM8996_AIFS 2
+
+#define HPOUT1L 1
+#define HPOUT1R 2
+#define HPOUT2L 4
+#define HPOUT2R 8
+
+#define WM8996_NUM_SUPPLIES 4
+static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
+ "DBVDD",
+ "AVDD1",
+ "AVDD2",
+ "CPVDD",
+};
+
+struct wm8996_priv {
+ struct snd_soc_codec *codec;
+
+ int ldo1ena;
+
+ int sysclk;
+ int sysclk_src;
+
+ int fll_src;
+ int fll_fref;
+ int fll_fout;
+
+ struct completion fll_lock;
+
+ u16 dcs_pending;
+ struct completion dcs_done;
+
+ u16 hpout_ena;
+ u16 hpout_pending;
+
+ struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
+ struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
+
+ struct wm8996_pdata pdata;
+
+ int rx_rate[WM8996_AIFS];
+ int bclk_rate[WM8996_AIFS];
+
+ /* Platform dependant ReTune mobile configuration */
+ int num_retune_mobile_texts;
+ const char **retune_mobile_texts;
+ int retune_mobile_cfg[2];
+ struct soc_enum retune_mobile_enum;
+
+ struct snd_soc_jack *jack;
+ bool detecting;
+ bool jack_mic;
+ wm8996_polarity_fn polarity_cb;
+
+#ifdef CONFIG_GPIOLIB
+ struct gpio_chip gpio_chip;
+#endif
+};
+
+/* We can't use the same notifier block for more than one supply and
+ * there's no way I can see to get from a callback to the caller
+ * except container_of().
+ */
+#define WM8996_REGULATOR_EVENT(n) \
+static int wm8996_regulator_event_##n(struct notifier_block *nb, \
+ unsigned long event, void *data) \
+{ \
+ struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
+ disable_nb[n]); \
+ if (event & REGULATOR_EVENT_DISABLE) { \
+ wm8996->codec->cache_sync = 1; \
+ } \
+ return 0; \
+}
+
+WM8996_REGULATOR_EVENT(0)
+WM8996_REGULATOR_EVENT(1)
+WM8996_REGULATOR_EVENT(2)
+WM8996_REGULATOR_EVENT(3)
+
+static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
+ [WM8996_SOFTWARE_RESET] = 0x8996,
+ [WM8996_POWER_MANAGEMENT_7] = 0x10,
+ [WM8996_DAC1_HPOUT1_VOLUME] = 0x88,
+ [WM8996_DAC2_HPOUT2_VOLUME] = 0x88,
+ [WM8996_DAC1_LEFT_VOLUME] = 0x2c0,
+ [WM8996_DAC1_RIGHT_VOLUME] = 0x2c0,
+ [WM8996_DAC2_LEFT_VOLUME] = 0x2c0,
+ [WM8996_DAC2_RIGHT_VOLUME] = 0x2c0,
+ [WM8996_OUTPUT1_LEFT_VOLUME] = 0x80,
+ [WM8996_OUTPUT1_RIGHT_VOLUME] = 0x80,
+ [WM8996_OUTPUT2_LEFT_VOLUME] = 0x80,
+ [WM8996_OUTPUT2_RIGHT_VOLUME] = 0x80,
+ [WM8996_MICBIAS_1] = 0x39,
+ [WM8996_MICBIAS_2] = 0x39,
+ [WM8996_LDO_1] = 0x3,
+ [WM8996_LDO_2] = 0x13,
+ [WM8996_ACCESSORY_DETECT_MODE_1] = 0x4,
+ [WM8996_HEADPHONE_DETECT_1] = 0x20,
+ [WM8996_MIC_DETECT_1] = 0x7600,
+ [WM8996_MIC_DETECT_2] = 0xbf,
+ [WM8996_CHARGE_PUMP_1] = 0x1f25,
+ [WM8996_CHARGE_PUMP_2] = 0xab19,
+ [WM8996_DC_SERVO_5] = 0x2a2a,
+ [WM8996_CONTROL_INTERFACE_1] = 0x8004,
+ [WM8996_CLOCKING_1] = 0x10,
+ [WM8996_AIF_RATE] = 0x83,
+ [WM8996_FLL_CONTROL_4] = 0x5dc0,
+ [WM8996_FLL_CONTROL_5] = 0xc84,
+ [WM8996_FLL_EFS_2] = 0x2,
+ [WM8996_AIF1_TX_LRCLK_1] = 0x80,
+ [WM8996_AIF1_TX_LRCLK_2] = 0x8,
+ [WM8996_AIF1_RX_LRCLK_1] = 0x80,
+ [WM8996_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
+ [WM8996_AIF1RX_DATA_CONFIGURATION] = 0x1818,
+ [WM8996_AIF1TX_TEST] = 0x7,
+ [WM8996_AIF2_TX_LRCLK_1] = 0x80,
+ [WM8996_AIF2_TX_LRCLK_2] = 0x8,
+ [WM8996_AIF2_RX_LRCLK_1] = 0x80,
+ [WM8996_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
+ [WM8996_AIF2RX_DATA_CONFIGURATION] = 0x1818,
+ [WM8996_AIF2TX_TEST] = 0x1,
+ [WM8996_DSP1_TX_LEFT_VOLUME] = 0xc0,
+ [WM8996_DSP1_TX_RIGHT_VOLUME] = 0xc0,
+ [WM8996_DSP1_RX_LEFT_VOLUME] = 0xc0,
+ [WM8996_DSP1_RX_RIGHT_VOLUME] = 0xc0,
+ [WM8996_DSP1_TX_FILTERS] = 0x2000,
+ [WM8996_DSP1_RX_FILTERS_1] = 0x200,
+ [WM8996_DSP1_RX_FILTERS_2] = 0x10,
+ [WM8996_DSP1_DRC_1] = 0x98,
+ [WM8996_DSP1_DRC_2] = 0x845,
+ [WM8996_DSP1_RX_EQ_GAINS_1] = 0x6318,
+ [WM8996_DSP1_RX_EQ_GAINS_2] = 0x6300,
+ [WM8996_DSP1_RX_EQ_BAND_1_A] = 0xfca,
+ [WM8996_DSP1_RX_EQ_BAND_1_B] = 0x400,
+ [WM8996_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
+ [WM8996_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
+ [WM8996_DSP1_RX_EQ_BAND_2_B] = 0xf145,
+ [WM8996_DSP1_RX_EQ_BAND_2_C] = 0xb75,
+ [WM8996_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
+ [WM8996_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
+ [WM8996_DSP1_RX_EQ_BAND_3_B] = 0xf373,
+ [WM8996_DSP1_RX_EQ_BAND_3_C] = 0xa54,
+ [WM8996_DSP1_RX_EQ_BAND_3_PG] = 0x558,
+ [WM8996_DSP1_RX_EQ_BAND_4_A] = 0x168e,
+ [WM8996_DSP1_RX_EQ_BAND_4_B] = 0xf829,
+ [WM8996_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
+ [WM8996_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
+ [WM8996_DSP1_RX_EQ_BAND_5_A] = 0x564,
+ [WM8996_DSP1_RX_EQ_BAND_5_B] = 0x559,
+ [WM8996_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
+ [WM8996_DSP2_TX_LEFT_VOLUME] = 0xc0,
+ [WM8996_DSP2_TX_RIGHT_VOLUME] = 0xc0,
+ [WM8996_DSP2_RX_LEFT_VOLUME] = 0xc0,
+ [WM8996_DSP2_RX_RIGHT_VOLUME] = 0xc0,
+ [WM8996_DSP2_TX_FILTERS] = 0x2000,
+ [WM8996_DSP2_RX_FILTERS_1] = 0x200,
+ [WM8996_DSP2_RX_FILTERS_2] = 0x10,
+ [WM8996_DSP2_DRC_1] = 0x98,
+ [WM8996_DSP2_DRC_2] = 0x845,
+ [WM8996_DSP2_RX_EQ_GAINS_1] = 0x6318,
+ [WM8996_DSP2_RX_EQ_GAINS_2] = 0x6300,
+ [WM8996_DSP2_RX_EQ_BAND_1_A] = 0xfca,
+ [WM8996_DSP2_RX_EQ_BAND_1_B] = 0x400,
+ [WM8996_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
+ [WM8996_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
+ [WM8996_DSP2_RX_EQ_BAND_2_B] = 0xf145,
+ [WM8996_DSP2_RX_EQ_BAND_2_C] = 0xb75,
+ [WM8996_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
+ [WM8996_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
+ [WM8996_DSP2_RX_EQ_BAND_3_B] = 0xf373,
+ [WM8996_DSP2_RX_EQ_BAND_3_C] = 0xa54,
+ [WM8996_DSP2_RX_EQ_BAND_3_PG] = 0x558,
+ [WM8996_DSP2_RX_EQ_BAND_4_A] = 0x168e,
+ [WM8996_DSP2_RX_EQ_BAND_4_B] = 0xf829,
+ [WM8996_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
+ [WM8996_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
+ [WM8996_DSP2_RX_EQ_BAND_5_A] = 0x564,
+ [WM8996_DSP2_RX_EQ_BAND_5_B] = 0x559,
+ [WM8996_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
+ [WM8996_OVERSAMPLING] = 0xd,
+ [WM8996_SIDETONE] = 0x1040,
+ [WM8996_GPIO_1] = 0xa101,
+ [WM8996_GPIO_2] = 0xa101,
+ [WM8996_GPIO_3] = 0xa101,
+ [WM8996_GPIO_4] = 0xa101,
+ [WM8996_GPIO_5] = 0xa101,
+ [WM8996_PULL_CONTROL_2] = 0x140,
+ [WM8996_INTERRUPT_STATUS_1_MASK] = 0x1f,
+ [WM8996_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
+ [WM8996_RIGHT_PDM_SPEAKER] = 0x1,
+ [WM8996_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
+ [WM8996_PDM_SPEAKER_VOLUME] = 0x66,
+ [WM8996_WRITE_SEQUENCER_0] = 0x1,
+ [WM8996_WRITE_SEQUENCER_1] = 0x1,
+ [WM8996_WRITE_SEQUENCER_3] = 0x6,
+ [WM8996_WRITE_SEQUENCER_4] = 0x40,
+ [WM8996_WRITE_SEQUENCER_5] = 0x1,
+ [WM8996_WRITE_SEQUENCER_6] = 0xf,
+ [WM8996_WRITE_SEQUENCER_7] = 0x6,
+ [WM8996_WRITE_SEQUENCER_8] = 0x1,
+ [WM8996_WRITE_SEQUENCER_9] = 0x3,
+ [WM8996_WRITE_SEQUENCER_10] = 0x104,
+ [WM8996_WRITE_SEQUENCER_12] = 0x60,
+ [WM8996_WRITE_SEQUENCER_13] = 0x11,
+ [WM8996_WRITE_SEQUENCER_14] = 0x401,
+ [WM8996_WRITE_SEQUENCER_16] = 0x50,
+ [WM8996_WRITE_SEQUENCER_17] = 0x3,
+ [WM8996_WRITE_SEQUENCER_18] = 0x100,
+ [WM8996_WRITE_SEQUENCER_20] = 0x51,
+ [WM8996_WRITE_SEQUENCER_21] = 0x3,
+ [WM8996_WRITE_SEQUENCER_22] = 0x104,
+ [WM8996_WRITE_SEQUENCER_23] = 0xa,
+ [WM8996_WRITE_SEQUENCER_24] = 0x60,
+ [WM8996_WRITE_SEQUENCER_25] = 0x3b,
+ [WM8996_WRITE_SEQUENCER_26] = 0x502,
+ [WM8996_WRITE_SEQUENCER_27] = 0x100,
+ [WM8996_WRITE_SEQUENCER_28] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_32] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_36] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_40] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_44] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_48] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_52] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_56] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_60] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_64] = 0x1,
+ [WM8996_WRITE_SEQUENCER_65] = 0x1,
+ [WM8996_WRITE_SEQUENCER_67] = 0x6,
+ [WM8996_WRITE_SEQUENCER_68] = 0x40,
+ [WM8996_WRITE_SEQUENCER_69] = 0x1,
+ [WM8996_WRITE_SEQUENCER_70] = 0xf,
+ [WM8996_WRITE_SEQUENCER_71] = 0x6,
+ [WM8996_WRITE_SEQUENCER_72] = 0x1,
+ [WM8996_WRITE_SEQUENCER_73] = 0x3,
+ [WM8996_WRITE_SEQUENCER_74] = 0x104,
+ [WM8996_WRITE_SEQUENCER_76] = 0x60,
+ [WM8996_WRITE_SEQUENCER_77] = 0x11,
+ [WM8996_WRITE_SEQUENCER_78] = 0x401,
+ [WM8996_WRITE_SEQUENCER_80] = 0x50,
+ [WM8996_WRITE_SEQUENCER_81] = 0x3,
+ [WM8996_WRITE_SEQUENCER_82] = 0x100,
+ [WM8996_WRITE_SEQUENCER_84] = 0x60,
+ [WM8996_WRITE_SEQUENCER_85] = 0x3b,
+ [WM8996_WRITE_SEQUENCER_86] = 0x502,
+ [WM8996_WRITE_SEQUENCER_87] = 0x100,
+ [WM8996_WRITE_SEQUENCER_88] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_92] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_96] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_100] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_104] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_108] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_112] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_116] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_120] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_124] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_128] = 0x1,
+ [WM8996_WRITE_SEQUENCER_129] = 0x1,
+ [WM8996_WRITE_SEQUENCER_131] = 0x6,
+ [WM8996_WRITE_SEQUENCER_132] = 0x40,
+ [WM8996_WRITE_SEQUENCER_133] = 0x1,
+ [WM8996_WRITE_SEQUENCER_134] = 0xf,
+ [WM8996_WRITE_SEQUENCER_135] = 0x6,
+ [WM8996_WRITE_SEQUENCER_136] = 0x1,
+ [WM8996_WRITE_SEQUENCER_137] = 0x3,
+ [WM8996_WRITE_SEQUENCER_138] = 0x106,
+ [WM8996_WRITE_SEQUENCER_140] = 0x61,
+ [WM8996_WRITE_SEQUENCER_141] = 0x11,
+ [WM8996_WRITE_SEQUENCER_142] = 0x401,
+ [WM8996_WRITE_SEQUENCER_144] = 0x50,
+ [WM8996_WRITE_SEQUENCER_145] = 0x3,
+ [WM8996_WRITE_SEQUENCER_146] = 0x102,
+ [WM8996_WRITE_SEQUENCER_148] = 0x51,
+ [WM8996_WRITE_SEQUENCER_149] = 0x3,
+ [WM8996_WRITE_SEQUENCER_150] = 0x106,
+ [WM8996_WRITE_SEQUENCER_151] = 0xa,
+ [WM8996_WRITE_SEQUENCER_152] = 0x61,
+ [WM8996_WRITE_SEQUENCER_153] = 0x3b,
+ [WM8996_WRITE_SEQUENCER_154] = 0x502,
+ [WM8996_WRITE_SEQUENCER_155] = 0x100,
+ [WM8996_WRITE_SEQUENCER_156] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_160] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_164] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_168] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_172] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_176] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_180] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_184] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_188] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_192] = 0x1,
+ [WM8996_WRITE_SEQUENCER_193] = 0x1,
+ [WM8996_WRITE_SEQUENCER_195] = 0x6,
+ [WM8996_WRITE_SEQUENCER_196] = 0x40,
+ [WM8996_WRITE_SEQUENCER_197] = 0x1,
+ [WM8996_WRITE_SEQUENCER_198] = 0xf,
+ [WM8996_WRITE_SEQUENCER_199] = 0x6,
+ [WM8996_WRITE_SEQUENCER_200] = 0x1,
+ [WM8996_WRITE_SEQUENCER_201] = 0x3,
+ [WM8996_WRITE_SEQUENCER_202] = 0x106,
+ [WM8996_WRITE_SEQUENCER_204] = 0x61,
+ [WM8996_WRITE_SEQUENCER_205] = 0x11,
+ [WM8996_WRITE_SEQUENCER_206] = 0x401,
+ [WM8996_WRITE_SEQUENCER_208] = 0x50,
+ [WM8996_WRITE_SEQUENCER_209] = 0x3,
+ [WM8996_WRITE_SEQUENCER_210] = 0x102,
+ [WM8996_WRITE_SEQUENCER_212] = 0x61,
+ [WM8996_WRITE_SEQUENCER_213] = 0x3b,
+ [WM8996_WRITE_SEQUENCER_214] = 0x502,
+ [WM8996_WRITE_SEQUENCER_215] = 0x100,
+ [WM8996_WRITE_SEQUENCER_216] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_220] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_224] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_228] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_232] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_236] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_240] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_244] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_248] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_252] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_256] = 0x60,
+ [WM8996_WRITE_SEQUENCER_258] = 0x601,
+ [WM8996_WRITE_SEQUENCER_260] = 0x50,
+ [WM8996_WRITE_SEQUENCER_262] = 0x100,
+ [WM8996_WRITE_SEQUENCER_264] = 0x1,
+ [WM8996_WRITE_SEQUENCER_266] = 0x104,
+ [WM8996_WRITE_SEQUENCER_267] = 0x100,
+ [WM8996_WRITE_SEQUENCER_268] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_272] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_276] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_280] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_284] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_288] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_292] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_296] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_300] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_304] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_308] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_312] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_316] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_320] = 0x61,
+ [WM8996_WRITE_SEQUENCER_322] = 0x601,
+ [WM8996_WRITE_SEQUENCER_324] = 0x50,
+ [WM8996_WRITE_SEQUENCER_326] = 0x102,
+ [WM8996_WRITE_SEQUENCER_328] = 0x1,
+ [WM8996_WRITE_SEQUENCER_330] = 0x106,
+ [WM8996_WRITE_SEQUENCER_331] = 0x100,
+ [WM8996_WRITE_SEQUENCER_332] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_336] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_340] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_344] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_348] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_352] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_356] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_360] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_364] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_368] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_372] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_376] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_380] = 0x2fff,
+ [WM8996_WRITE_SEQUENCER_384] = 0x60,
+ [WM8996_WRITE_SEQUENCER_386] = 0x601,
+ [WM8996_WRITE_SEQUENCER_388] = 0x61,
+ [WM8996_WRITE_SEQUENCER_390] = 0x601,
+ [WM8996_WRITE_SEQUENCER_392] = 0x50,
+ [WM8996_WRITE_SEQUENCER_394] = 0x300,
+ [WM8996_WRITE_SEQUENCER_396] = 0x1,
+ [WM8996_WRITE_SEQUENCER_398] = 0x304,
+ [WM8996_WRITE_SEQUENCER_400] = 0x40,
+ [WM8996_WRITE_SEQUENCER_402] = 0xf,
+ [WM8996_WRITE_SEQUENCER_404] = 0x1,
+ [WM8996_WRITE_SEQUENCER_407] = 0x100,
+};
+
+static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
+static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
+static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
+static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
+static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
+
+static const char *sidetone_hpf_text[] = {
+ "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
+};
+
+static const struct soc_enum sidetone_hpf =
+ SOC_ENUM_SINGLE(WM8996_SIDETONE, 7, 7, sidetone_hpf_text);
+
+static const char *hpf_mode_text[] = {
+ "HiFi", "Custom", "Voice"
+};
+
+static const struct soc_enum dsp1tx_hpf_mode =
+ SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
+
+static const struct soc_enum dsp2tx_hpf_mode =
+ SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
+
+static const char *hpf_cutoff_text[] = {
+ "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
+};
+
+static const struct soc_enum dsp1tx_hpf_cutoff =
+ SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
+
+static const struct soc_enum dsp2tx_hpf_cutoff =
+ SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
+
+static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ struct wm8996_pdata *pdata = &wm8996->pdata;
+ int base, best, best_val, save, i, cfg, iface;
+
+ if (!wm8996->num_retune_mobile_texts)
+ return;
+
+ switch (block) {
+ case 0:
+ base = WM8996_DSP1_RX_EQ_GAINS_1;
+ if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) &
+ WM8996_DSP1RX_SRC)
+ iface = 1;
+ else
+ iface = 0;
+ break;
+ case 1:
+ base = WM8996_DSP1_RX_EQ_GAINS_2;
+ if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) &
+ WM8996_DSP2RX_SRC)
+ iface = 1;
+ else
+ iface = 0;
+ break;
+ default:
+ return;
+ }
+
+ /* Find the version of the currently selected configuration
+ * with the nearest sample rate. */
+ cfg = wm8996->retune_mobile_cfg[block];
+ best = 0;
+ best_val = INT_MAX;
+ for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
+ if (strcmp(pdata->retune_mobile_cfgs[i].name,
+ wm8996->retune_mobile_texts[cfg]) == 0 &&
+ abs(pdata->retune_mobile_cfgs[i].rate
+ - wm8996->rx_rate[iface]) < best_val) {
+ best = i;
+ best_val = abs(pdata->retune_mobile_cfgs[i].rate
+ - wm8996->rx_rate[iface]);
+ }
+ }
+
+ dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
+ block,
+ pdata->retune_mobile_cfgs[best].name,
+ pdata->retune_mobile_cfgs[best].rate,
+ wm8996->rx_rate[iface]);
+
+ /* The EQ will be disabled while reconfiguring it, remember the
+ * current configuration.
+ */
+ save = snd_soc_read(codec, base);
+ save &= WM8996_DSP1RX_EQ_ENA;
+
+ for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
+ snd_soc_update_bits(codec, base + i, 0xffff,
+ pdata->retune_mobile_cfgs[best].regs[i]);
+
+ snd_soc_update_bits(codec, base, WM8996_DSP1RX_EQ_ENA, save);
+}
+
+/* Icky as hell but saves code duplication */
+static int wm8996_get_retune_mobile_block(const char *name)
+{
+ if (strcmp(name, "DSP1 EQ Mode") == 0)
+ return 0;
+ if (strcmp(name, "DSP2 EQ Mode") == 0)
+ return 1;
+ return -EINVAL;
+}
+
+static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ struct wm8996_pdata *pdata = &wm8996->pdata;
+ int block = wm8996_get_retune_mobile_block(kcontrol->id.name);
+ int value = ucontrol->value.integer.value[0];
+
+ if (block < 0)
+ return block;
+
+ if (value >= pdata->num_retune_mobile_cfgs)
+ return -EINVAL;
+
+ wm8996->retune_mobile_cfg[block] = value;
+
+ wm8996_set_retune_mobile(codec, block);
+
+ return 0;
+}
+
+static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int block = wm8996_get_retune_mobile_block(kcontrol->id.name);
+
+ ucontrol->value.enumerated.item[0] = wm8996->retune_mobile_cfg[block];
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new wm8996_snd_controls[] = {
+SOC_DOUBLE_R_TLV("Capture Volume", WM8996_LEFT_LINE_INPUT_VOLUME,
+ WM8996_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
+SOC_DOUBLE_R("Capture ZC Switch", WM8996_LEFT_LINE_INPUT_VOLUME,
+ WM8996_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
+
+SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8996_DAC1_MIXER_VOLUMES,
+ 0, 5, 24, 0, sidetone_tlv),
+SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8996_DAC2_MIXER_VOLUMES,
+ 0, 5, 24, 0, sidetone_tlv),
+SOC_SINGLE("Sidetone LPF Switch", WM8996_SIDETONE, 12, 1, 0),
+SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
+SOC_SINGLE("Sidetone HPF Switch", WM8996_SIDETONE, 6, 1, 0),
+
+SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8996_DSP1_TX_LEFT_VOLUME,
+ WM8996_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
+SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8996_DSP2_TX_LEFT_VOLUME,
+ WM8996_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
+
+SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8996_DSP1_TX_FILTERS,
+ 13, 1, 0),
+SOC_DOUBLE("DSP1 Capture HPF Switch", WM8996_DSP1_TX_FILTERS, 12, 11, 1, 0),
+SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
+SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
+
+SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8996_DSP2_TX_FILTERS,
+ 13, 1, 0),
+SOC_DOUBLE("DSP2 Capture HPF Switch", WM8996_DSP2_TX_FILTERS, 12, 11, 1, 0),
+SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
+SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
+
+SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8996_DSP1_RX_LEFT_VOLUME,
+ WM8996_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
+SOC_SINGLE("DSP1 Playback Switch", WM8996_DSP1_RX_FILTERS_1, 9, 1, 1),
+
+SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8996_DSP2_RX_LEFT_VOLUME,
+ WM8996_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
+SOC_SINGLE("DSP2 Playback Switch", WM8996_DSP2_RX_FILTERS_1, 9, 1, 1),
+
+SOC_DOUBLE_R_TLV("DAC1 Volume", WM8996_DAC1_LEFT_VOLUME,
+ WM8996_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
+SOC_DOUBLE_R("DAC1 Switch", WM8996_DAC1_LEFT_VOLUME,
+ WM8996_DAC1_RIGHT_VOLUME, 9, 1, 1),
+
+SOC_DOUBLE_R_TLV("DAC2 Volume", WM8996_DAC2_LEFT_VOLUME,
+ WM8996_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
+SOC_DOUBLE_R("DAC2 Switch", WM8996_DAC2_LEFT_VOLUME,
+ WM8996_DAC2_RIGHT_VOLUME, 9, 1, 1),
+
+SOC_SINGLE("Speaker High Performance Switch", WM8996_OVERSAMPLING, 3, 1, 0),
+SOC_SINGLE("DMIC High Performance Switch", WM8996_OVERSAMPLING, 2, 1, 0),
+SOC_SINGLE("ADC High Performance Switch", WM8996_OVERSAMPLING, 1, 1, 0),
+SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),
+
+SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),
+SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),
+
+SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,
+ 8, 0, out_digital_tlv),
+SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,
+ 8, 0, out_digital_tlv),
+
+SOC_DOUBLE_R_TLV("Output 1 Volume", WM8996_OUTPUT1_LEFT_VOLUME,
+ WM8996_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
+SOC_DOUBLE_R("Output 1 ZC Switch", WM8996_OUTPUT1_LEFT_VOLUME,
+ WM8996_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
+
+SOC_DOUBLE_R_TLV("Output 2 Volume", WM8996_OUTPUT2_LEFT_VOLUME,
+ WM8996_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
+SOC_DOUBLE_R("Output 2 ZC Switch", WM8996_OUTPUT2_LEFT_VOLUME,
+ WM8996_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
+
+SOC_DOUBLE_TLV("Speaker Volume", WM8996_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
+ spk_tlv),
+SOC_DOUBLE_R("Speaker Switch", WM8996_LEFT_PDM_SPEAKER,
+ WM8996_RIGHT_PDM_SPEAKER, 3, 1, 1),
+SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER,
+ WM8996_RIGHT_PDM_SPEAKER, 2, 1, 0),
+
+SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
+SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new wm8996_eq_controls[] = {
+SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
+ eq_tlv),
+
+SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
+ eq_tlv),
+SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
+ eq_tlv),
+};
+
+static int cp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ msleep(5);
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rmv_short_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec);
+
+ /* Record which outputs we enabled */
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMD:
+ wm8996->hpout_pending &= ~w->shift;
+ break;
+ case SND_SOC_DAPM_PRE_PMU:
+ wm8996->hpout_pending |= w->shift;
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
+{
+ struct i2c_client *i2c = to_i2c_client(codec->dev);
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int i, ret;
+ unsigned long timeout = 200;
+
+ snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
+
+ /* Use the interrupt if possible */
+ do {
+ if (i2c->irq) {
+ timeout = wait_for_completion_timeout(&wm8996->dcs_done,
+ msecs_to_jiffies(200));
+ if (timeout == 0)
+ dev_err(codec->dev, "DC servo timed out\n");
+
+ } else {
+ msleep(1);
+ if (--i) {
+ timeout = 0;
+ break;
+ }
+ }
+
+ ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
+ dev_dbg(codec->dev, "DC servo state: %x\n", ret);
+ } while (ret & mask);
+
+ if (timeout == 0)
+ dev_err(codec->dev, "DC servo timed out for %x\n", mask);
+ else
+ dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
+}
+
+static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
+ enum snd_soc_dapm_type event, int subseq)
+{
+ struct snd_soc_codec *codec = container_of(dapm,
+ struct snd_soc_codec, dapm);
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ u16 val, mask;
+
+ /* Complete any pending DC servo starts */
+ if (wm8996->dcs_pending) {
+ dev_dbg(codec->dev, "Starting DC servo for %x\n",
+ wm8996->dcs_pending);
+
+ /* Trigger a startup sequence */
+ wait_for_dc_servo(codec, wm8996->dcs_pending
+ << WM8996_DCS_TRIG_STARTUP_0_SHIFT);
+
+ wm8996->dcs_pending = 0;
+ }
+
+ if (wm8996->hpout_pending != wm8996->hpout_ena) {
+ dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
+ wm8996->hpout_ena, wm8996->hpout_pending);
+
+ val = 0;
+ mask = 0;
+ if (wm8996->hpout_pending & HPOUT1L) {
+ val |= WM8996_HPOUT1L_RMV_SHORT;
+ mask |= WM8996_HPOUT1L_RMV_SHORT;
+ } else {
+ mask |= WM8996_HPOUT1L_RMV_SHORT |
+ WM8996_HPOUT1L_OUTP |
+ WM8996_HPOUT1L_DLY;
+ }
+
+ if (wm8996->hpout_pending & HPOUT1R) {
+ val |= WM8996_HPOUT1R_RMV_SHORT;
+ mask |= WM8996_HPOUT1R_RMV_SHORT;
+ } else {
+ mask |= WM8996_HPOUT1R_RMV_SHORT |
+ WM8996_HPOUT1R_OUTP |
+ WM8996_HPOUT1R_DLY;
+ }
+
+ snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1, mask, val);
+
+ val = 0;
+ mask = 0;
+ if (wm8996->hpout_pending & HPOUT2L) {
+ val |= WM8996_HPOUT2L_RMV_SHORT;
+ mask |= WM8996_HPOUT2L_RMV_SHORT;
+ } else {
+ mask |= WM8996_HPOUT2L_RMV_SHORT |
+ WM8996_HPOUT2L_OUTP |
+ WM8996_HPOUT2L_DLY;
+ }
+
+ if (wm8996->hpout_pending & HPOUT2R) {
+ val |= WM8996_HPOUT2R_RMV_SHORT;
+ mask |= WM8996_HPOUT2R_RMV_SHORT;
+ } else {
+ mask |= WM8996_HPOUT2R_RMV_SHORT |
+ WM8996_HPOUT2R_OUTP |
+ WM8996_HPOUT2R_DLY;
+ }
+
+ snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_2, mask, val);
+
+ wm8996->hpout_ena = wm8996->hpout_pending;
+ }
+}
+
+static int dcs_start(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ wm8996->dcs_pending |= 1 << w->shift;
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const char *sidetone_text[] = {
+ "IN1", "IN2",
+};
+
+static const struct soc_enum left_sidetone_enum =
+ SOC_ENUM_SINGLE(WM8996_SIDETONE, 0, 2, sidetone_text);
+
+static const struct snd_kcontrol_new left_sidetone =
+ SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
+
+static const struct soc_enum right_sidetone_enum =
+ SOC_ENUM_SINGLE(WM8996_SIDETONE, 1, 2, sidetone_text);
+
+static const struct snd_kcontrol_new right_sidetone =
+ SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
+
+static const char *spk_text[] = {
+ "DAC1L", "DAC1R", "DAC2L", "DAC2R"
+};
+
+static const struct soc_enum spkl_enum =
+ SOC_ENUM_SINGLE(WM8996_LEFT_PDM_SPEAKER, 0, 4, spk_text);
+
+static const struct snd_kcontrol_new spkl_mux =
+ SOC_DAPM_ENUM("SPKL", spkl_enum);
+
+static const struct soc_enum spkr_enum =
+ SOC_ENUM_SINGLE(WM8996_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
+
+static const struct snd_kcontrol_new spkr_mux =
+ SOC_DAPM_ENUM("SPKR", spkr_enum);
+
+static const char *dsp1rx_text[] = {
+ "AIF1", "AIF2"
+};
+
+static const struct soc_enum dsp1rx_enum =
+ SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
+
+static const struct snd_kcontrol_new dsp1rx =
+ SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
+
+static const char *dsp2rx_text[] = {
+ "AIF2", "AIF1"
+};
+
+static const struct soc_enum dsp2rx_enum =
+ SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
+
+static const struct snd_kcontrol_new dsp2rx =
+ SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
+
+static const char *aif2tx_text[] = {
+ "DSP2", "DSP1", "AIF1"
+};
+
+static const struct soc_enum aif2tx_enum =
+ SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
+
+static const struct snd_kcontrol_new aif2tx =
+ SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
+
+static const char *inmux_text[] = {
+ "ADC", "DMIC1", "DMIC2"
+};
+
+static const struct soc_enum in1_enum =
+ SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 0, 3, inmux_text);
+
+static const struct snd_kcontrol_new in1_mux =
+ SOC_DAPM_ENUM("IN1 Mux", in1_enum);
+
+static const struct soc_enum in2_enum =
+ SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 4, 3, inmux_text);
+
+static const struct snd_kcontrol_new in2_mux =
+ SOC_DAPM_ENUM("IN2 Mux", in2_enum);
+
+static const struct snd_kcontrol_new dac2r_mix[] = {
+SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING,
+ 5, 1, 0),
+SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING,
+ 4, 1, 0),
+SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
+SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dac2l_mix[] = {
+SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING,
+ 5, 1, 0),
+SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING,
+ 4, 1, 0),
+SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
+SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dac1r_mix[] = {
+SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING,
+ 5, 1, 0),
+SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING,
+ 4, 1, 0),
+SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
+SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dac1l_mix[] = {
+SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING,
+ 5, 1, 0),
+SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING,
+ 4, 1, 0),
+SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
+SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dsp1txl[] = {
+SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING,
+ 1, 1, 0),
+SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dsp1txr[] = {
+SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING,
+ 1, 1, 0),
+SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dsp2txl[] = {
+SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING,
+ 1, 1, 0),
+SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new dsp2txr[] = {
+SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING,
+ 1, 1, 0),
+SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING,
+ 0, 1, 0),
+};
+
+
+static const struct snd_soc_dapm_widget wm8996_dapm_widgets[] = {
+SND_SOC_DAPM_INPUT("IN1LN"),
+SND_SOC_DAPM_INPUT("IN1LP"),
+SND_SOC_DAPM_INPUT("IN1RN"),
+SND_SOC_DAPM_INPUT("IN1RP"),
+
+SND_SOC_DAPM_INPUT("IN2LN"),
+SND_SOC_DAPM_INPUT("IN2LP"),
+SND_SOC_DAPM_INPUT("IN2RN"),
+SND_SOC_DAPM_INPUT("IN2RP"),
+
+SND_SOC_DAPM_INPUT("DMIC1DAT"),
+SND_SOC_DAPM_INPUT("DMIC2DAT"),
+
+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_POST_PMU),
+
+SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
+SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
+SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
+
+SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
+
+SND_SOC_DAPM_MUX("IN1L Mux", WM8996_POWER_MANAGEMENT_7, 2, 0, &in1_mux),
+SND_SOC_DAPM_MUX("IN1R Mux", WM8996_POWER_MANAGEMENT_7, 3, 0, &in1_mux),
+SND_SOC_DAPM_MUX("IN2L Mux", WM8996_POWER_MANAGEMENT_7, 6, 0, &in2_mux),
+SND_SOC_DAPM_MUX("IN2R Mux", WM8996_POWER_MANAGEMENT_7, 7, 0, &in2_mux),
+
+SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
+
+SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8996_POWER_MANAGEMENT_3, 5, 0),
+SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8996_POWER_MANAGEMENT_3, 4, 0),
+SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8996_POWER_MANAGEMENT_3, 3, 0),
+SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8996_POWER_MANAGEMENT_3, 2, 0),
+
+SND_SOC_DAPM_ADC("ADCL", NULL, WM8996_POWER_MANAGEMENT_3, 1, 0),
+SND_SOC_DAPM_ADC("ADCR", NULL, WM8996_POWER_MANAGEMENT_3, 0, 0),
+
+SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
+SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
+
+SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 11, 0),
+SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 10, 0),
+SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 9, 0),
+SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 8, 0),
+
+SND_SOC_DAPM_MIXER("DSP2TXL", WM8996_POWER_MANAGEMENT_5, 11, 0,
+ dsp2txl, ARRAY_SIZE(dsp2txl)),
+SND_SOC_DAPM_MIXER("DSP2TXR", WM8996_POWER_MANAGEMENT_5, 10, 0,
+ dsp2txr, ARRAY_SIZE(dsp2txr)),
+SND_SOC_DAPM_MIXER("DSP1TXL", WM8996_POWER_MANAGEMENT_5, 9, 0,
+ dsp1txl, ARRAY_SIZE(dsp1txl)),
+SND_SOC_DAPM_MIXER("DSP1TXR", WM8996_POWER_MANAGEMENT_5, 8, 0,
+ dsp1txr, ARRAY_SIZE(dsp1txr)),
+
+SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
+ dac2l_mix, ARRAY_SIZE(dac2l_mix)),
+SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
+ dac2r_mix, ARRAY_SIZE(dac2r_mix)),
+SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
+ dac1l_mix, ARRAY_SIZE(dac1l_mix)),
+SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
+ dac1r_mix, ARRAY_SIZE(dac1r_mix)),
+
+SND_SOC_DAPM_DAC("DAC2L", NULL, WM8996_POWER_MANAGEMENT_5, 3, 0),
+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", 1,
+ WM8996_POWER_MANAGEMENT_4, 9, 0),
+SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2,
+ WM8996_POWER_MANAGEMENT_4, 8, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1,
+ WM8996_POWER_MANAGEMENT_6, 9, 0),
+SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2,
+ 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),
+
+/* 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 */
+SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
+SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
+SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
+
+SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
+SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
+SND_SOC_DAPM_PGA("SPKL PGA", WM8996_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("SPKR PGA", WM8996_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start,
+ SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8996_ANALOGUE_HP_2, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
+ rmv_short_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start,
+ SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8996_ANALOGUE_HP_2, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
+ rmv_short_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start,
+ SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8996_ANALOGUE_HP_1, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
+ rmv_short_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start,
+ SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8996_ANALOGUE_HP_1, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
+ rmv_short_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+SND_SOC_DAPM_OUTPUT("HPOUT1L"),
+SND_SOC_DAPM_OUTPUT("HPOUT1R"),
+SND_SOC_DAPM_OUTPUT("HPOUT2L"),
+SND_SOC_DAPM_OUTPUT("HPOUT2R"),
+SND_SOC_DAPM_OUTPUT("SPKDAT"),
+};
+
+static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
+ { "AIFCLK", NULL, "SYSCLK" },
+ { "SYSDSPCLK", NULL, "SYSCLK" },
+ { "Charge Pump", NULL, "SYSCLK" },
+
+ { "MICB1", NULL, "LDO2" },
+ { "MICB2", NULL, "LDO2" },
+
+ { "IN1L PGA", NULL, "IN2LN" },
+ { "IN1L PGA", NULL, "IN2LP" },
+ { "IN1L PGA", NULL, "IN1LN" },
+ { "IN1L PGA", NULL, "IN1LP" },
+
+ { "IN1R PGA", NULL, "IN2RN" },
+ { "IN1R PGA", NULL, "IN2RP" },
+ { "IN1R PGA", NULL, "IN1RN" },
+ { "IN1R PGA", NULL, "IN1RP" },
+
+ { "ADCL", NULL, "IN1L PGA" },
+
+ { "ADCR", NULL, "IN1R PGA" },
+
+ { "DMIC1L", NULL, "DMIC1DAT" },
+ { "DMIC1R", NULL, "DMIC1DAT" },
+ { "DMIC2L", NULL, "DMIC2DAT" },
+ { "DMIC2R", NULL, "DMIC2DAT" },
+
+ { "DMIC2L", NULL, "DMIC2" },
+ { "DMIC2R", NULL, "DMIC2" },
+ { "DMIC1L", NULL, "DMIC1" },
+ { "DMIC1R", NULL, "DMIC1" },
+
+ { "IN1L Mux", "ADC", "ADCL" },
+ { "IN1L Mux", "DMIC1", "DMIC1L" },
+ { "IN1L Mux", "DMIC2", "DMIC2L" },
+
+ { "IN1R Mux", "ADC", "ADCR" },
+ { "IN1R Mux", "DMIC1", "DMIC1R" },
+ { "IN1R Mux", "DMIC2", "DMIC2R" },
+
+ { "IN2L Mux", "ADC", "ADCL" },
+ { "IN2L Mux", "DMIC1", "DMIC1L" },
+ { "IN2L Mux", "DMIC2", "DMIC2L" },
+
+ { "IN2R Mux", "ADC", "ADCR" },
+ { "IN2R Mux", "DMIC1", "DMIC1R" },
+ { "IN2R Mux", "DMIC2", "DMIC2R" },
+
+ { "Left Sidetone", "IN1", "IN1L Mux" },
+ { "Left Sidetone", "IN2", "IN2L Mux" },
+
+ { "Right Sidetone", "IN1", "IN1R Mux" },
+ { "Right Sidetone", "IN2", "IN2R Mux" },
+
+ { "DSP1TXL", "IN1 Switch", "IN1L Mux" },
+ { "DSP1TXR", "IN1 Switch", "IN1R Mux" },
+
+ { "DSP2TXL", "IN1 Switch", "IN2L Mux" },
+ { "DSP2TXR", "IN1 Switch", "IN2R Mux" },
+
+ { "AIF1TX0", NULL, "DSP1TXL" },
+ { "AIF1TX1", NULL, "DSP1TXR" },
+ { "AIF1TX2", NULL, "DSP2TXL" },
+ { "AIF1TX3", NULL, "DSP2TXR" },
+ { "AIF1TX4", NULL, "AIF2RX0" },
+ { "AIF1TX5", NULL, "AIF2RX1" },
+
+ { "AIF1RX0", NULL, "AIFCLK" },
+ { "AIF1RX1", NULL, "AIFCLK" },
+ { "AIF1RX2", NULL, "AIFCLK" },
+ { "AIF1RX3", NULL, "AIFCLK" },
+ { "AIF1RX4", NULL, "AIFCLK" },
+ { "AIF1RX5", NULL, "AIFCLK" },
+
+ { "AIF2RX0", NULL, "AIFCLK" },
+ { "AIF2RX1", NULL, "AIFCLK" },
+
+ { "AIF1TX0", NULL, "AIFCLK" },
+ { "AIF1TX1", NULL, "AIFCLK" },
+ { "AIF1TX2", NULL, "AIFCLK" },
+ { "AIF1TX3", NULL, "AIFCLK" },
+ { "AIF1TX4", NULL, "AIFCLK" },
+ { "AIF1TX5", NULL, "AIFCLK" },
+
+ { "AIF2TX0", NULL, "AIFCLK" },
+ { "AIF2TX1", NULL, "AIFCLK" },
+
+ { "DSP1RXL", NULL, "SYSDSPCLK" },
+ { "DSP1RXR", NULL, "SYSDSPCLK" },
+ { "DSP2RXL", NULL, "SYSDSPCLK" },
+ { "DSP2RXR", NULL, "SYSDSPCLK" },
+ { "DSP1TXL", NULL, "SYSDSPCLK" },
+ { "DSP1TXR", NULL, "SYSDSPCLK" },
+ { "DSP2TXL", NULL, "SYSDSPCLK" },
+ { "DSP2TXR", NULL, "SYSDSPCLK" },
+
+ { "AIF1RXA", NULL, "AIF1RX0" },
+ { "AIF1RXA", NULL, "AIF1RX1" },
+ { "AIF1RXB", NULL, "AIF1RX2" },
+ { "AIF1RXB", NULL, "AIF1RX3" },
+ { "AIF1RXC", NULL, "AIF1RX4" },
+ { "AIF1RXC", NULL, "AIF1RX5" },
+
+ { "AIF2RX", NULL, "AIF2RX0" },
+ { "AIF2RX", NULL, "AIF2RX1" },
+
+ { "AIF2TX", "DSP2", "DSP2TX" },
+ { "AIF2TX", "DSP1", "DSP1RX" },
+ { "AIF2TX", "AIF1", "AIF1RXC" },
+
+ { "DSP1RXL", NULL, "DSP1RX" },
+ { "DSP1RXR", NULL, "DSP1RX" },
+ { "DSP2RXL", NULL, "DSP2RX" },
+ { "DSP2RXR", NULL, "DSP2RX" },
+
+ { "DSP2TX", NULL, "DSP2TXL" },
+ { "DSP2TX", NULL, "DSP2TXR" },
+
+ { "DSP1RX", "AIF1", "AIF1RXA" },
+ { "DSP1RX", "AIF2", "AIF2RX" },
+
+ { "DSP2RX", "AIF1", "AIF1RXB" },
+ { "DSP2RX", "AIF2", "AIF2RX" },
+
+ { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
+ { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
+ { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
+ { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
+
+ { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
+ { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
+ { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
+ { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
+
+ { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
+ { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
+ { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
+ { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
+
+ { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
+ { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
+ { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
+ { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
+
+ { "DAC1L", NULL, "DAC1L Mixer" },
+ { "DAC1R", NULL, "DAC1R Mixer" },
+ { "DAC2L", NULL, "DAC2L Mixer" },
+ { "DAC2R", NULL, "DAC2R Mixer" },
+
+ { "HPOUT2L PGA", NULL, "Charge Pump" },
+ { "HPOUT2L PGA", NULL, "DAC2L" },
+ { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
+ { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
+ { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" },
+ { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
+
+ { "HPOUT2R PGA", NULL, "Charge Pump" },
+ { "HPOUT2R PGA", NULL, "DAC2R" },
+ { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
+ { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
+ { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" },
+ { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
+
+ { "HPOUT1L PGA", NULL, "Charge Pump" },
+ { "HPOUT1L PGA", NULL, "DAC1L" },
+ { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
+ { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
+ { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" },
+ { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
+
+ { "HPOUT1R PGA", NULL, "Charge Pump" },
+ { "HPOUT1R PGA", NULL, "DAC1R" },
+ { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
+ { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
+ { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" },
+ { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
+
+ { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
+ { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
+ { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
+ { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
+
+ { "SPKL", "DAC1L", "DAC1L" },
+ { "SPKL", "DAC1R", "DAC1R" },
+ { "SPKL", "DAC2L", "DAC2L" },
+ { "SPKL", "DAC2R", "DAC2R" },
+
+ { "SPKR", "DAC1L", "DAC1L" },
+ { "SPKR", "DAC1R", "DAC1R" },
+ { "SPKR", "DAC2L", "DAC2L" },
+ { "SPKR", "DAC2R", "DAC2R" },
+
+ { "SPKL PGA", NULL, "SPKL" },
+ { "SPKR PGA", NULL, "SPKR" },
+
+ { "SPKDAT", NULL, "SPKL PGA" },
+ { "SPKDAT", NULL, "SPKR PGA" },
+};
+
+static int wm8996_readable_register(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ /* Due to the sparseness of the register map the compiler
+ * output from an explicit switch statement ends up being much
+ * more efficient than a table.
+ */
+ switch (reg) {
+ case WM8996_SOFTWARE_RESET:
+ case WM8996_POWER_MANAGEMENT_1:
+ case WM8996_POWER_MANAGEMENT_2:
+ case WM8996_POWER_MANAGEMENT_3:
+ case WM8996_POWER_MANAGEMENT_4:
+ case WM8996_POWER_MANAGEMENT_5:
+ case WM8996_POWER_MANAGEMENT_6:
+ case WM8996_POWER_MANAGEMENT_7:
+ case WM8996_POWER_MANAGEMENT_8:
+ case WM8996_LEFT_LINE_INPUT_VOLUME:
+ case WM8996_RIGHT_LINE_INPUT_VOLUME:
+ case WM8996_LINE_INPUT_CONTROL:
+ case WM8996_DAC1_HPOUT1_VOLUME:
+ case WM8996_DAC2_HPOUT2_VOLUME:
+ case WM8996_DAC1_LEFT_VOLUME:
+ case WM8996_DAC1_RIGHT_VOLUME:
+ case WM8996_DAC2_LEFT_VOLUME:
+ case WM8996_DAC2_RIGHT_VOLUME:
+ case WM8996_OUTPUT1_LEFT_VOLUME:
+ case WM8996_OUTPUT1_RIGHT_VOLUME:
+ case WM8996_OUTPUT2_LEFT_VOLUME:
+ case WM8996_OUTPUT2_RIGHT_VOLUME:
+ case WM8996_MICBIAS_1:
+ case WM8996_MICBIAS_2:
+ case WM8996_LDO_1:
+ case WM8996_LDO_2:
+ case WM8996_ACCESSORY_DETECT_MODE_1:
+ case WM8996_ACCESSORY_DETECT_MODE_2:
+ case WM8996_HEADPHONE_DETECT_1:
+ case WM8996_HEADPHONE_DETECT_2:
+ case WM8996_MIC_DETECT_1:
+ case WM8996_MIC_DETECT_2:
+ case WM8996_MIC_DETECT_3:
+ case WM8996_CHARGE_PUMP_1:
+ case WM8996_CHARGE_PUMP_2:
+ case WM8996_DC_SERVO_1:
+ case WM8996_DC_SERVO_2:
+ case WM8996_DC_SERVO_3:
+ case WM8996_DC_SERVO_5:
+ case WM8996_DC_SERVO_6:
+ case WM8996_DC_SERVO_7:
+ case WM8996_DC_SERVO_READBACK_0:
+ case WM8996_ANALOGUE_HP_1:
+ case WM8996_ANALOGUE_HP_2:
+ case WM8996_CHIP_REVISION:
+ case WM8996_CONTROL_INTERFACE_1:
+ case WM8996_WRITE_SEQUENCER_CTRL_1:
+ case WM8996_WRITE_SEQUENCER_CTRL_2:
+ case WM8996_AIF_CLOCKING_1:
+ case WM8996_AIF_CLOCKING_2:
+ case WM8996_CLOCKING_1:
+ case WM8996_CLOCKING_2:
+ case WM8996_AIF_RATE:
+ case WM8996_FLL_CONTROL_1:
+ case WM8996_FLL_CONTROL_2:
+ case WM8996_FLL_CONTROL_3:
+ case WM8996_FLL_CONTROL_4:
+ case WM8996_FLL_CONTROL_5:
+ case WM8996_FLL_CONTROL_6:
+ case WM8996_FLL_EFS_1:
+ case WM8996_FLL_EFS_2:
+ case WM8996_AIF1_CONTROL:
+ case WM8996_AIF1_BCLK:
+ case WM8996_AIF1_TX_LRCLK_1:
+ case WM8996_AIF1_TX_LRCLK_2:
+ case WM8996_AIF1_RX_LRCLK_1:
+ case WM8996_AIF1_RX_LRCLK_2:
+ case WM8996_AIF1TX_DATA_CONFIGURATION_1:
+ case WM8996_AIF1TX_DATA_CONFIGURATION_2:
+ case WM8996_AIF1RX_DATA_CONFIGURATION:
+ case WM8996_AIF1TX_CHANNEL_0_CONFIGURATION:
+ case WM8996_AIF1TX_CHANNEL_1_CONFIGURATION:
+ case WM8996_AIF1TX_CHANNEL_2_CONFIGURATION:
+ case WM8996_AIF1TX_CHANNEL_3_CONFIGURATION:
+ case WM8996_AIF1TX_CHANNEL_4_CONFIGURATION:
+ case WM8996_AIF1TX_CHANNEL_5_CONFIGURATION:
+ case WM8996_AIF1RX_CHANNEL_0_CONFIGURATION:
+ case WM8996_AIF1RX_CHANNEL_1_CONFIGURATION:
+ case WM8996_AIF1RX_CHANNEL_2_CONFIGURATION:
+ case WM8996_AIF1RX_CHANNEL_3_CONFIGURATION:
+ case WM8996_AIF1RX_CHANNEL_4_CONFIGURATION:
+ case WM8996_AIF1RX_CHANNEL_5_CONFIGURATION:
+ case WM8996_AIF1RX_MONO_CONFIGURATION:
+ case WM8996_AIF1TX_TEST:
+ case WM8996_AIF2_CONTROL:
+ case WM8996_AIF2_BCLK:
+ case WM8996_AIF2_TX_LRCLK_1:
+ case WM8996_AIF2_TX_LRCLK_2:
+ case WM8996_AIF2_RX_LRCLK_1:
+ case WM8996_AIF2_RX_LRCLK_2:
+ case WM8996_AIF2TX_DATA_CONFIGURATION_1:
+ case WM8996_AIF2TX_DATA_CONFIGURATION_2:
+ case WM8996_AIF2RX_DATA_CONFIGURATION:
+ case WM8996_AIF2TX_CHANNEL_0_CONFIGURATION:
+ case WM8996_AIF2TX_CHANNEL_1_CONFIGURATION:
+ case WM8996_AIF2RX_CHANNEL_0_CONFIGURATION:
+ case WM8996_AIF2RX_CHANNEL_1_CONFIGURATION:
+ case WM8996_AIF2RX_MONO_CONFIGURATION:
+ case WM8996_AIF2TX_TEST:
+ case WM8996_DSP1_TX_LEFT_VOLUME:
+ case WM8996_DSP1_TX_RIGHT_VOLUME:
+ case WM8996_DSP1_RX_LEFT_VOLUME:
+ case WM8996_DSP1_RX_RIGHT_VOLUME:
+ case WM8996_DSP1_TX_FILTERS:
+ case WM8996_DSP1_RX_FILTERS_1:
+ case WM8996_DSP1_RX_FILTERS_2:
+ case WM8996_DSP1_DRC_1:
+ case WM8996_DSP1_DRC_2:
+ case WM8996_DSP1_DRC_3:
+ case WM8996_DSP1_DRC_4:
+ case WM8996_DSP1_DRC_5:
+ case WM8996_DSP1_RX_EQ_GAINS_1:
+ case WM8996_DSP1_RX_EQ_GAINS_2:
+ case WM8996_DSP1_RX_EQ_BAND_1_A:
+ case WM8996_DSP1_RX_EQ_BAND_1_B:
+ case WM8996_DSP1_RX_EQ_BAND_1_PG:
+ case WM8996_DSP1_RX_EQ_BAND_2_A:
+ case WM8996_DSP1_RX_EQ_BAND_2_B:
+ case WM8996_DSP1_RX_EQ_BAND_2_C:
+ case WM8996_DSP1_RX_EQ_BAND_2_PG:
+ case WM8996_DSP1_RX_EQ_BAND_3_A:
+ case WM8996_DSP1_RX_EQ_BAND_3_B:
+ case WM8996_DSP1_RX_EQ_BAND_3_C:
+ case WM8996_DSP1_RX_EQ_BAND_3_PG:
+ case WM8996_DSP1_RX_EQ_BAND_4_A:
+ case WM8996_DSP1_RX_EQ_BAND_4_B:
+ case WM8996_DSP1_RX_EQ_BAND_4_C:
+ case WM8996_DSP1_RX_EQ_BAND_4_PG:
+ case WM8996_DSP1_RX_EQ_BAND_5_A:
+ case WM8996_DSP1_RX_EQ_BAND_5_B:
+ case WM8996_DSP1_RX_EQ_BAND_5_PG:
+ case WM8996_DSP2_TX_LEFT_VOLUME:
+ case WM8996_DSP2_TX_RIGHT_VOLUME:
+ case WM8996_DSP2_RX_LEFT_VOLUME:
+ case WM8996_DSP2_RX_RIGHT_VOLUME:
+ case WM8996_DSP2_TX_FILTERS:
+ case WM8996_DSP2_RX_FILTERS_1:
+ case WM8996_DSP2_RX_FILTERS_2:
+ case WM8996_DSP2_DRC_1:
+ case WM8996_DSP2_DRC_2:
+ case WM8996_DSP2_DRC_3:
+ case WM8996_DSP2_DRC_4:
+ case WM8996_DSP2_DRC_5:
+ case WM8996_DSP2_RX_EQ_GAINS_1:
+ case WM8996_DSP2_RX_EQ_GAINS_2:
+ case WM8996_DSP2_RX_EQ_BAND_1_A:
+ case WM8996_DSP2_RX_EQ_BAND_1_B:
+ case WM8996_DSP2_RX_EQ_BAND_1_PG:
+ case WM8996_DSP2_RX_EQ_BAND_2_A:
+ case WM8996_DSP2_RX_EQ_BAND_2_B:
+ case WM8996_DSP2_RX_EQ_BAND_2_C:
+ case WM8996_DSP2_RX_EQ_BAND_2_PG:
+ case WM8996_DSP2_RX_EQ_BAND_3_A:
+ case WM8996_DSP2_RX_EQ_BAND_3_B:
+ case WM8996_DSP2_RX_EQ_BAND_3_C:
+ case WM8996_DSP2_RX_EQ_BAND_3_PG:
+ case WM8996_DSP2_RX_EQ_BAND_4_A:
+ case WM8996_DSP2_RX_EQ_BAND_4_B:
+ case WM8996_DSP2_RX_EQ_BAND_4_C:
+ case WM8996_DSP2_RX_EQ_BAND_4_PG:
+ case WM8996_DSP2_RX_EQ_BAND_5_A:
+ case WM8996_DSP2_RX_EQ_BAND_5_B:
+ case WM8996_DSP2_RX_EQ_BAND_5_PG:
+ case WM8996_DAC1_MIXER_VOLUMES:
+ case WM8996_DAC1_LEFT_MIXER_ROUTING:
+ case WM8996_DAC1_RIGHT_MIXER_ROUTING:
+ case WM8996_DAC2_MIXER_VOLUMES:
+ case WM8996_DAC2_LEFT_MIXER_ROUTING:
+ case WM8996_DAC2_RIGHT_MIXER_ROUTING:
+ case WM8996_DSP1_TX_LEFT_MIXER_ROUTING:
+ case WM8996_DSP1_TX_RIGHT_MIXER_ROUTING:
+ case WM8996_DSP2_TX_LEFT_MIXER_ROUTING:
+ case WM8996_DSP2_TX_RIGHT_MIXER_ROUTING:
+ case WM8996_DSP_TX_MIXER_SELECT:
+ case WM8996_DAC_SOFTMUTE:
+ case WM8996_OVERSAMPLING:
+ case WM8996_SIDETONE:
+ case WM8996_GPIO_1:
+ case WM8996_GPIO_2:
+ case WM8996_GPIO_3:
+ case WM8996_GPIO_4:
+ case WM8996_GPIO_5:
+ case WM8996_PULL_CONTROL_1:
+ case WM8996_PULL_CONTROL_2:
+ case WM8996_INTERRUPT_STATUS_1:
+ case WM8996_INTERRUPT_STATUS_2:
+ case WM8996_INTERRUPT_RAW_STATUS_2:
+ case WM8996_INTERRUPT_STATUS_1_MASK:
+ case WM8996_INTERRUPT_STATUS_2_MASK:
+ case WM8996_INTERRUPT_CONTROL:
+ case WM8996_LEFT_PDM_SPEAKER:
+ case WM8996_RIGHT_PDM_SPEAKER:
+ case WM8996_PDM_SPEAKER_MUTE_SEQUENCE:
+ case WM8996_PDM_SPEAKER_VOLUME:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int wm8996_volatile_register(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ switch (reg) {
+ case WM8996_SOFTWARE_RESET:
+ case WM8996_CHIP_REVISION:
+ case WM8996_LDO_1:
+ case WM8996_LDO_2:
+ case WM8996_INTERRUPT_STATUS_1:
+ case WM8996_INTERRUPT_STATUS_2:
+ case WM8996_INTERRUPT_RAW_STATUS_2:
+ case WM8996_DC_SERVO_READBACK_0:
+ case WM8996_DC_SERVO_2:
+ case WM8996_DC_SERVO_6:
+ case WM8996_DC_SERVO_7:
+ case WM8996_FLL_CONTROL_6:
+ case WM8996_MIC_DETECT_3:
+ case WM8996_HEADPHONE_DETECT_1:
+ case WM8996_HEADPHONE_DETECT_2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int wm8996_reset(struct snd_soc_codec *codec)
+{
+ return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915);
+}
+
+static const int bclk_divs[] = {
+ 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
+};
+
+static void wm8996_update_bclk(struct snd_soc_codec *codec)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int aif, best, cur_val, bclk_rate, bclk_reg, i;
+
+ /* Don't bother if we're in a low frequency idle mode that
+ * can't support audio.
+ */
+ if (wm8996->sysclk < 64000)
+ return;
+
+ for (aif = 0; aif < WM8996_AIFS; aif++) {
+ switch (aif) {
+ case 0:
+ bclk_reg = WM8996_AIF1_BCLK;
+ break;
+ case 1:
+ bclk_reg = WM8996_AIF2_BCLK;
+ break;
+ }
+
+ bclk_rate = wm8996->bclk_rate[aif];
+
+ /* Pick a divisor for BCLK as close as we can get to ideal */
+ best = 0;
+ for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
+ cur_val = (wm8996->sysclk / bclk_divs[i]) - bclk_rate;
+ if (cur_val < 0) /* BCLK table is sorted */
+ break;
+ best = i;
+ }
+ bclk_rate = wm8996->sysclk / bclk_divs[best];
+ dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
+ bclk_divs[best], bclk_rate);
+
+ snd_soc_update_bits(codec, bclk_reg,
+ WM8996_AIF1_BCLK_DIV_MASK, best);
+ }
+}
+
+static int wm8996_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+
+ case SND_SOC_BIAS_PREPARE:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
+ snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
+ WM8996_BG_ENA, WM8996_BG_ENA);
+ msleep(2);
+ }
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
+ wm8996->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to enable supplies: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (wm8996->pdata.ldo_ena >= 0) {
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena,
+ 1);
+ msleep(5);
+ }
+
+ codec->cache_only = false;
+ snd_soc_cache_sync(codec);
+ }
+
+ snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
+ WM8996_BG_ENA, 0);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ codec->cache_only = true;
+ if (wm8996->pdata.ldo_ena >= 0)
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
+ regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
+ wm8996->supplies);
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int aifctrl = 0;
+ int bclk = 0;
+ int lrclk_tx = 0;
+ int lrclk_rx = 0;
+ int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
+
+ switch (dai->id) {
+ case 0:
+ aifctrl_reg = WM8996_AIF1_CONTROL;
+ bclk_reg = WM8996_AIF1_BCLK;
+ lrclk_tx_reg = WM8996_AIF1_TX_LRCLK_2;
+ lrclk_rx_reg = WM8996_AIF1_RX_LRCLK_2;
+ break;
+ case 1:
+ aifctrl_reg = WM8996_AIF2_CONTROL;
+ bclk_reg = WM8996_AIF2_BCLK;
+ lrclk_tx_reg = WM8996_AIF2_TX_LRCLK_2;
+ lrclk_rx_reg = WM8996_AIF2_RX_LRCLK_2;
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ bclk |= WM8996_AIF1_BCLK_INV;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ lrclk_tx |= WM8996_AIF1TX_LRCLK_INV;
+ lrclk_rx |= WM8996_AIF1RX_LRCLK_INV;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ bclk |= WM8996_AIF1_BCLK_INV;
+ lrclk_tx |= WM8996_AIF1TX_LRCLK_INV;
+ lrclk_rx |= WM8996_AIF1RX_LRCLK_INV;
+ break;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR;
+ lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ bclk |= WM8996_AIF1_BCLK_MSTR;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ bclk |= WM8996_AIF1_BCLK_MSTR;
+ lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR;
+ lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ aifctrl |= 1;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ aifctrl |= 2;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ aifctrl |= 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_update_bits(codec, aifctrl_reg, WM8996_AIF1_FMT_MASK, aifctrl);
+ snd_soc_update_bits(codec, bclk_reg,
+ WM8996_AIF1_BCLK_INV | WM8996_AIF1_BCLK_MSTR,
+ bclk);
+ snd_soc_update_bits(codec, lrclk_tx_reg,
+ WM8996_AIF1TX_LRCLK_INV |
+ WM8996_AIF1TX_LRCLK_MSTR,
+ lrclk_tx);
+ snd_soc_update_bits(codec, lrclk_rx_reg,
+ WM8996_AIF1RX_LRCLK_INV |
+ WM8996_AIF1RX_LRCLK_MSTR,
+ lrclk_rx);
+
+ return 0;
+}
+
+static const int dsp_divs[] = {
+ 48000, 32000, 16000, 8000
+};
+
+static int wm8996_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 wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int bits, i, bclk_rate;
+ int aifdata = 0;
+ int lrclk = 0;
+ int dsp = 0;
+ int aifdata_reg, lrclk_reg, dsp_shift;
+
+ switch (dai->id) {
+ case 0:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
+ (snd_soc_read(codec, WM8996_GPIO_1)) & WM8996_GP1_FN_MASK) {
+ aifdata_reg = WM8996_AIF1RX_DATA_CONFIGURATION;
+ lrclk_reg = WM8996_AIF1_RX_LRCLK_1;
+ } else {
+ aifdata_reg = WM8996_AIF1TX_DATA_CONFIGURATION_1;
+ lrclk_reg = WM8996_AIF1_TX_LRCLK_1;
+ }
+ dsp_shift = 0;
+ break;
+ case 1:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
+ (snd_soc_read(codec, WM8996_GPIO_2)) & WM8996_GP2_FN_MASK) {
+ aifdata_reg = WM8996_AIF2RX_DATA_CONFIGURATION;
+ lrclk_reg = WM8996_AIF2_RX_LRCLK_1;
+ } else {
+ aifdata_reg = WM8996_AIF2TX_DATA_CONFIGURATION_1;
+ lrclk_reg = WM8996_AIF2_TX_LRCLK_1;
+ }
+ dsp_shift = WM8996_DSP2_DIV_SHIFT;
+ break;
+ default:
+ BUG();
+ return -EINVAL;
+ }
+
+ bclk_rate = snd_soc_params_to_bclk(params);
+ if (bclk_rate < 0) {
+ dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
+ return bclk_rate;
+ }
+
+ wm8996->bclk_rate[dai->id] = bclk_rate;
+ wm8996->rx_rate[dai->id] = params_rate(params);
+
+ /* Needs looking at for TDM */
+ bits = snd_pcm_format_width(params_format(params));
+ if (bits < 0)
+ return bits;
+ aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits;
+
+ for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
+ if (dsp_divs[i] == params_rate(params))
+ break;
+ }
+ if (i == ARRAY_SIZE(dsp_divs)) {
+ dev_err(codec->dev, "Unsupported sample rate %dHz\n",
+ params_rate(params));
+ return -EINVAL;
+ }
+ dsp |= i << dsp_shift;
+
+ wm8996_update_bclk(codec);
+
+ lrclk = bclk_rate / params_rate(params);
+ dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
+ lrclk, bclk_rate / lrclk);
+
+ snd_soc_update_bits(codec, aifdata_reg,
+ WM8996_AIF1TX_WL_MASK |
+ WM8996_AIF1TX_SLOT_LEN_MASK,
+ aifdata);
+ snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
+ lrclk);
+ snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2,
+ WM8996_DSP1_DIV_SHIFT << dsp_shift, dsp);
+
+ return 0;
+}
+
+static int wm8996_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int lfclk = 0;
+ int ratediv = 0;
+ int src;
+ int old;
+
+ if (freq == wm8996->sysclk && clk_id == wm8996->sysclk_src)
+ return 0;
+
+ /* Disable SYSCLK while we reconfigure */
+ old = snd_soc_read(codec, WM8996_AIF_CLOCKING_1) & WM8996_SYSCLK_ENA;
+ snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+ WM8996_SYSCLK_ENA, 0);
+
+ switch (clk_id) {
+ case WM8996_SYSCLK_MCLK1:
+ wm8996->sysclk = freq;
+ src = 0;
+ break;
+ case WM8996_SYSCLK_MCLK2:
+ wm8996->sysclk = freq;
+ src = 1;
+ break;
+ case WM8996_SYSCLK_FLL:
+ wm8996->sysclk = freq;
+ src = 2;
+ break;
+ default:
+ dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
+ return -EINVAL;
+ }
+
+ switch (wm8996->sysclk) {
+ case 6144000:
+ snd_soc_update_bits(codec, WM8996_AIF_RATE,
+ WM8996_SYSCLK_RATE, 0);
+ break;
+ case 24576000:
+ ratediv = WM8996_SYSCLK_DIV;
+ case 12288000:
+ snd_soc_update_bits(codec, WM8996_AIF_RATE,
+ WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE);
+ break;
+ case 32000:
+ case 32768:
+ lfclk = WM8996_LFCLK_ENA;
+ break;
+ default:
+ dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
+ wm8996->sysclk);
+ return -EINVAL;
+ }
+
+ wm8996_update_bclk(codec);
+
+ snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+ WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK,
+ src << WM8996_SYSCLK_SRC_SHIFT | ratediv);
+ snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);
+ snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+ WM8996_SYSCLK_ENA, old);
+
+ wm8996->sysclk_src = clk_id;
+
+ return 0;
+}
+
+struct _fll_div {
+ u16 fll_fratio;
+ u16 fll_outdiv;
+ u16 fll_refclk_div;
+ u16 fll_loop_gain;
+ u16 fll_ref_freq;
+ 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;
+
+ if (Fref >= 3000000)
+ fll_div->fll_loop_gain = 5;
+ else
+ fll_div->fll_loop_gain = 0;
+
+ if (Fref >= 48000)
+ fll_div->fll_ref_freq = 0;
+ else
+ fll_div->fll_ref_freq = 1;
+
+ /* 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 FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
+ fll_div->fll_fratio, fll_div->fll_outdiv,
+ fll_div->fll_refclk_div);
+
+ return 0;
+}
+
+static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+ unsigned int Fref, unsigned int Fout)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ struct i2c_client *i2c = to_i2c_client(codec->dev);
+ struct _fll_div fll_div;
+ unsigned long timeout;
+ int ret, reg;
+
+ /* Any change? */
+ if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
+ Fout == wm8996->fll_fout)
+ return 0;
+
+ if (Fout == 0) {
+ dev_dbg(codec->dev, "FLL disabled\n");
+
+ wm8996->fll_fref = 0;
+ wm8996->fll_fout = 0;
+
+ snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
+ WM8996_FLL_ENA, 0);
+
+ return 0;
+ }
+
+ ret = fll_factors(&fll_div, Fref, Fout);
+ if (ret != 0)
+ return ret;
+
+ switch (source) {
+ case WM8996_FLL_MCLK1:
+ reg = 0;
+ break;
+ case WM8996_FLL_MCLK2:
+ reg = 1;
+ break;
+ case WM8996_FLL_DACLRCLK1:
+ reg = 2;
+ break;
+ case WM8996_FLL_BCLK1:
+ reg = 3;
+ break;
+ default:
+ dev_err(codec->dev, "Unknown FLL source %d\n", ret);
+ return -EINVAL;
+ }
+
+ reg |= fll_div.fll_refclk_div << WM8996_FLL_REFCLK_DIV_SHIFT;
+ reg |= fll_div.fll_ref_freq << WM8996_FLL_REF_FREQ_SHIFT;
+
+ snd_soc_update_bits(codec, WM8996_FLL_CONTROL_5,
+ WM8996_FLL_REFCLK_DIV_MASK | WM8996_FLL_REF_FREQ |
+ WM8996_FLL_REFCLK_SRC_MASK, reg);
+
+ reg = 0;
+ if (fll_div.theta || fll_div.lambda)
+ reg |= WM8996_FLL_EFS_ENA | (3 << WM8996_FLL_LFSR_SEL_SHIFT);
+ else
+ reg |= 1 << WM8996_FLL_LFSR_SEL_SHIFT;
+ snd_soc_write(codec, WM8996_FLL_EFS_2, reg);
+
+ snd_soc_update_bits(codec, WM8996_FLL_CONTROL_2,
+ WM8996_FLL_OUTDIV_MASK |
+ WM8996_FLL_FRATIO_MASK,
+ (fll_div.fll_outdiv << WM8996_FLL_OUTDIV_SHIFT) |
+ (fll_div.fll_fratio));
+
+ snd_soc_write(codec, WM8996_FLL_CONTROL_3, fll_div.theta);
+
+ snd_soc_update_bits(codec, WM8996_FLL_CONTROL_4,
+ WM8996_FLL_N_MASK | WM8996_FLL_LOOP_GAIN_MASK,
+ (fll_div.n << WM8996_FLL_N_SHIFT) |
+ fll_div.fll_loop_gain);
+
+ snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
+
+ /* Clear any pending completions (eg, from failed startups) */
+ try_wait_for_completion(&wm8996->fll_lock);
+
+ snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
+ WM8996_FLL_ENA, WM8996_FLL_ENA);
+
+ /* The FLL supports live reconfiguration - kick that in case we were
+ * already enabled.
+ */
+ snd_soc_write(codec, WM8996_FLL_CONTROL_6, WM8996_FLL_SWITCH_CLK);
+
+ /* Wait for the FLL to lock, using the interrupt if possible */
+ if (Fref > 1000000)
+ timeout = usecs_to_jiffies(300);
+ else
+ timeout = msecs_to_jiffies(2);
+
+ /* Allow substantially longer if we've actually got the IRQ */
+ if (i2c->irq)
+ timeout *= 1000;
+
+ ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout);
+
+ if (ret == 0 && i2c->irq) {
+ dev_err(codec->dev, "Timed out waiting for FLL\n");
+ ret = -ETIMEDOUT;
+ } else {
+ ret = 0;
+ }
+
+ dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
+
+ wm8996->fll_fref = Fref;
+ wm8996->fll_fout = Fout;
+ wm8996->fll_src = source;
+
+ return ret;
+}
+
+#ifdef CONFIG_GPIOLIB
+static inline struct wm8996_priv *gpio_to_wm8996(struct gpio_chip *chip)
+{
+ return container_of(chip, struct wm8996_priv, gpio_chip);
+}
+
+static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
+ struct snd_soc_codec *codec = wm8996->codec;
+
+ snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
+ WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);
+}
+
+static int wm8996_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
+ struct snd_soc_codec *codec = wm8996->codec;
+ int val;
+
+ val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT);
+
+ return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
+ WM8996_GP1_FN_MASK | WM8996_GP1_DIR |
+ WM8996_GP1_LVL, val);
+}
+
+static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
+ struct snd_soc_codec *codec = wm8996->codec;
+ int ret;
+
+ ret = snd_soc_read(codec, WM8996_GPIO_1 + offset);
+ if (ret < 0)
+ return ret;
+
+ return (ret & WM8996_GP1_LVL) != 0;
+}
+
+static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
+ struct snd_soc_codec *codec = wm8996->codec;
+
+ return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
+ WM8996_GP1_FN_MASK | WM8996_GP1_DIR,
+ (1 << WM8996_GP1_FN_SHIFT) |
+ (1 << WM8996_GP1_DIR_SHIFT));
+}
+
+static struct gpio_chip wm8996_template_chip = {
+ .label = "wm8996",
+ .owner = THIS_MODULE,
+ .direction_output = wm8996_gpio_direction_out,
+ .set = wm8996_gpio_set,
+ .direction_input = wm8996_gpio_direction_in,
+ .get = wm8996_gpio_get,
+ .can_sleep = 1,
+};
+
+static void wm8996_init_gpio(struct snd_soc_codec *codec)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ wm8996->gpio_chip = wm8996_template_chip;
+ wm8996->gpio_chip.ngpio = 5;
+ wm8996->gpio_chip.dev = codec->dev;
+
+ if (wm8996->pdata.gpio_base)
+ wm8996->gpio_chip.base = wm8996->pdata.gpio_base;
+ else
+ wm8996->gpio_chip.base = -1;
+
+ ret = gpiochip_add(&wm8996->gpio_chip);
+ if (ret != 0)
+ dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+}
+
+static void wm8996_free_gpio(struct snd_soc_codec *codec)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ ret = gpiochip_remove(&wm8996->gpio_chip);
+ if (ret != 0)
+ dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+}
+#else
+static void wm8996_init_gpio(struct snd_soc_codec *codec)
+{
+}
+
+static void wm8996_free_gpio(struct snd_soc_codec *codec)
+{
+}
+#endif
+
+/**
+ * wm8996_detect - Enable default WM8996 jack detection
+ *
+ * The WM8996 has advanced accessory detection support for headsets.
+ * This function provides a default implementation which integrates
+ * the majority of this functionality with minimal user configuration.
+ *
+ * This will detect headset, headphone and short circuit button and
+ * will also detect inverted microphone ground connections and update
+ * the polarity of the connections.
+ */
+int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ wm8996_polarity_fn polarity_cb)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+
+ wm8996->jack = jack;
+ wm8996->detecting = true;
+ wm8996->polarity_cb = polarity_cb;
+
+ if (wm8996->polarity_cb)
+ wm8996->polarity_cb(codec, 0);
+
+ /* Clear discarge to avoid noise during detection */
+ snd_soc_update_bits(codec, WM8996_MICBIAS_1,
+ WM8996_MICB1_DISCH, 0);
+ snd_soc_update_bits(codec, WM8996_MICBIAS_2,
+ WM8996_MICB2_DISCH, 0);
+
+ /* LDO2 powers the microphones, SYSCLK clocks detection */
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
+
+ /* We start off just enabling microphone detection - even a
+ * plain headphone will trigger detection.
+ */
+ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+ WM8996_MICD_ENA, WM8996_MICD_ENA);
+
+ /* Slowest detection rate, gives debounce for initial detection */
+ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+ WM8996_MICD_RATE_MASK,
+ WM8996_MICD_RATE_MASK);
+
+ /* Enable interrupts and we're off */
+ snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
+ WM8996_IM_MICD_EINT, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(wm8996_detect);
+
+static void wm8996_micd(struct snd_soc_codec *codec)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int val, reg;
+
+ val = snd_soc_read(codec, WM8996_MIC_DETECT_3);
+
+ dev_dbg(codec->dev, "Microphone event: %x\n", val);
+
+ if (!(val & WM8996_MICD_VALID)) {
+ dev_warn(codec->dev, "Microphone detection state invalid\n");
+ return;
+ }
+
+ /* No accessory, reset everything and report removal */
+ if (!(val & WM8996_MICD_STS)) {
+ dev_dbg(codec->dev, "Jack removal detected\n");
+ wm8996->jack_mic = false;
+ wm8996->detecting = true;
+ snd_soc_jack_report(wm8996->jack, 0,
+ SND_JACK_HEADSET | SND_JACK_BTN_0);
+ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+ WM8996_MICD_RATE_MASK,
+ WM8996_MICD_RATE_MASK);
+ return;
+ }
+
+ /* If the measurement is very high we've got a microphone but
+ * do a little debounce to account for mechanical issues.
+ */
+ if (val & 0x400) {
+ dev_dbg(codec->dev, "Microphone detected\n");
+ snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET,
+ SND_JACK_HEADSET | SND_JACK_BTN_0);
+ wm8996->jack_mic = true;
+ wm8996->detecting = false;
+
+ /* Increase poll rate to give better responsiveness
+ * for buttons */
+ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+ WM8996_MICD_RATE_MASK,
+ 5 << WM8996_MICD_RATE_SHIFT);
+ }
+
+ /* 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.
+ */
+ if (wm8996->detecting && (val & 0x3f0)) {
+ reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
+ reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
+ WM8996_MICD_BIAS_SRC;
+ snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
+ WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
+ WM8996_MICD_BIAS_SRC, reg);
+
+ if (wm8996->polarity_cb)
+ wm8996->polarity_cb(codec,
+ (reg & WM8996_MICD_SRC) != 0);
+
+ dev_dbg(codec->dev, "Set microphone polarity to %d\n",
+ (reg & WM8996_MICD_SRC) != 0);
+
+ return;
+ }
+
+ /* Don't distinguish between buttons, just report any low
+ * impedence as BTN_0.
+ */
+ if (val & 0x3fc) {
+ if (wm8996->jack_mic) {
+ dev_dbg(codec->dev, "Mic button detected\n");
+ snd_soc_jack_report(wm8996->jack,
+ SND_JACK_HEADSET | SND_JACK_BTN_0,
+ SND_JACK_HEADSET | SND_JACK_BTN_0);
+ } else {
+ dev_dbg(codec->dev, "Headphone detected\n");
+ snd_soc_jack_report(wm8996->jack,
+ SND_JACK_HEADPHONE,
+ SND_JACK_HEADSET |
+ SND_JACK_BTN_0);
+
+ /* Increase the detection rate a bit for
+ * responsiveness.
+ */
+ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+ WM8996_MICD_RATE_MASK,
+ 7 << WM8996_MICD_RATE_SHIFT);
+
+ wm8996->detecting = false;
+ }
+ }
+}
+
+static irqreturn_t wm8996_irq(int irq, void *data)
+{
+ struct snd_soc_codec *codec = data;
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int irq_val;
+
+ irq_val = snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2);
+ if (irq_val < 0) {
+ dev_err(codec->dev, "Failed to read IRQ status: %d\n",
+ irq_val);
+ return IRQ_NONE;
+ }
+ irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
+
+ snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
+
+ if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
+ dev_dbg(codec->dev, "DC servo IRQ\n");
+ complete(&wm8996->dcs_done);
+ }
+
+ if (irq_val & WM8996_FIFOS_ERR_EINT)
+ dev_err(codec->dev, "Digital core FIFO error\n");
+
+ if (irq_val & WM8996_FLL_LOCK_EINT) {
+ dev_dbg(codec->dev, "FLL locked\n");
+ complete(&wm8996->fll_lock);
+ }
+
+ if (irq_val & WM8996_MICD_EINT)
+ wm8996_micd(codec);
+
+ if (irq_val)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static irqreturn_t wm8996_edge_irq(int irq, void *data)
+{
+ irqreturn_t ret = IRQ_NONE;
+ irqreturn_t val;
+
+ do {
+ val = wm8996_irq(irq, data);
+ if (val != IRQ_NONE)
+ ret = val;
+ } while (val != IRQ_NONE);
+
+ return ret;
+}
+
+static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ struct wm8996_pdata *pdata = &wm8996->pdata;
+
+ struct snd_kcontrol_new controls[] = {
+ SOC_ENUM_EXT("DSP1 EQ Mode",
+ wm8996->retune_mobile_enum,
+ wm8996_get_retune_mobile_enum,
+ wm8996_put_retune_mobile_enum),
+ SOC_ENUM_EXT("DSP2 EQ Mode",
+ wm8996->retune_mobile_enum,
+ wm8996_get_retune_mobile_enum,
+ wm8996_put_retune_mobile_enum),
+ };
+ int ret, i, j;
+ const char **t;
+
+ /* We need an array of texts for the enum API but the number
+ * of texts is likely to be less than the number of
+ * configurations due to the sample rate dependency of the
+ * configurations. */
+ wm8996->num_retune_mobile_texts = 0;
+ wm8996->retune_mobile_texts = NULL;
+ for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
+ for (j = 0; j < wm8996->num_retune_mobile_texts; j++) {
+ if (strcmp(pdata->retune_mobile_cfgs[i].name,
+ wm8996->retune_mobile_texts[j]) == 0)
+ break;
+ }
+
+ if (j != wm8996->num_retune_mobile_texts)
+ continue;
+
+ /* Expand the array... */
+ t = krealloc(wm8996->retune_mobile_texts,
+ sizeof(char *) *
+ (wm8996->num_retune_mobile_texts + 1),
+ GFP_KERNEL);
+ if (t == NULL)
+ continue;
+
+ /* ...store the new entry... */
+ t[wm8996->num_retune_mobile_texts] =
+ pdata->retune_mobile_cfgs[i].name;
+
+ /* ...and remember the new version. */
+ wm8996->num_retune_mobile_texts++;
+ wm8996->retune_mobile_texts = t;
+ }
+
+ dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
+ wm8996->num_retune_mobile_texts);
+
+ 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));
+ if (ret != 0)
+ dev_err(codec->dev,
+ "Failed to add ReTune Mobile controls: %d\n", ret);
+}
+
+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;
+
+ init_completion(&wm8996->dcs_done);
+ init_completion(&wm8996->fll_lock);
+
+ dapm->idle_bias_off = true;
+ dapm->bias_level = SND_SOC_BIAS_OFF;
+
+ ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
+ wm8996->supplies[i].supply = wm8996_supply_names[i];
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies),
+ wm8996->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ goto err;
+ }
+
+ wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
+ wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
+ wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
+ wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3;
+
+ /* This should really be moved into the regulator core */
+ for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
+ ret = regulator_register_notifier(wm8996->supplies[i].consumer,
+ &wm8996->disable_nb[i]);
+ if (ret != 0) {
+ dev_err(codec->dev,
+ "Failed to register regulator notifier: %d\n",
+ ret);
+ }
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
+ wm8996->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_get;
+ }
+
+ if (wm8996->pdata.ldo_ena >= 0) {
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
+ msleep(5);
+ }
+
+ ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
+ goto err_enable;
+ }
+ if (ret != 0x8915) {
+ dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret);
+ ret = -EINVAL;
+ goto err_enable;
+ }
+
+ ret = snd_soc_read(codec, WM8996_CHIP_REVISION);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read device revision: %d\n",
+ ret);
+ goto err_enable;
+ }
+
+ dev_info(codec->dev, "revision %c\n",
+ (ret & WM8996_CHIP_REV_MASK) + 'A');
+
+ if (wm8996->pdata.ldo_ena >= 0) {
+ gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
+ } else {
+ ret = wm8996_reset(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to issue reset\n");
+ goto err_enable;
+ }
+ }
+
+ codec->cache_only = true;
+
+ /* Apply platform data settings */
+ snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
+ WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
+ wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
+ wm8996->pdata.inr_mode);
+
+ for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
+ if (!wm8996->pdata.gpio_default[i])
+ continue;
+
+ snd_soc_write(codec, WM8996_GPIO_1 + i,
+ wm8996->pdata.gpio_default[i] & 0xffff);
+ }
+
+ if (wm8996->pdata.spkmute_seq)
+ snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
+ WM8996_SPK_MUTE_ENDIAN |
+ WM8996_SPK_MUTE_SEQ1_MASK,
+ wm8996->pdata.spkmute_seq);
+
+ snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
+ WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
+ WM8996_MICD_SRC, wm8996->pdata.micdet_def);
+
+ /* Latch volume update bits */
+ snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME,
+ WM8996_IN1_VU, WM8996_IN1_VU);
+ snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME,
+ WM8996_IN1_VU, WM8996_IN1_VU);
+
+ snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME,
+ WM8996_DAC1_VU, WM8996_DAC1_VU);
+ snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME,
+ WM8996_DAC1_VU, WM8996_DAC1_VU);
+ snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME,
+ WM8996_DAC2_VU, WM8996_DAC2_VU);
+ snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME,
+ WM8996_DAC2_VU, WM8996_DAC2_VU);
+
+ snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME,
+ WM8996_DAC1_VU, WM8996_DAC1_VU);
+ snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME,
+ WM8996_DAC1_VU, WM8996_DAC1_VU);
+ snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME,
+ WM8996_DAC2_VU, WM8996_DAC2_VU);
+ snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME,
+ WM8996_DAC2_VU, WM8996_DAC2_VU);
+
+ snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME,
+ WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
+ snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME,
+ WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
+ snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME,
+ WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
+ snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME,
+ WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
+
+ snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME,
+ WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
+ snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME,
+ WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
+ snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME,
+ WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
+ snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME,
+ WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
+
+ /* No support currently for the underclocked TDM modes and
+ * pick a default TDM layout with each channel pair working with
+ * slots 0 and 1. */
+ snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
+ WM8996_AIF1RX_CHAN0_SLOTS_MASK |
+ WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
+ WM8996_AIF1RX_CHAN1_SLOTS_MASK |
+ WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
+ 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
+ snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
+ WM8996_AIF1RX_CHAN2_SLOTS_MASK |
+ WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
+ 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
+ WM8996_AIF1RX_CHAN3_SLOTS_MASK |
+ WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
+ snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
+ WM8996_AIF1RX_CHAN4_SLOTS_MASK |
+ WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
+ WM8996_AIF1RX_CHAN5_SLOTS_MASK |
+ WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
+
+ snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
+ WM8996_AIF2RX_CHAN0_SLOTS_MASK |
+ WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
+ WM8996_AIF2RX_CHAN1_SLOTS_MASK |
+ WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
+ 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
+
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
+ WM8996_AIF1TX_CHAN0_SLOTS_MASK |
+ WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
+ WM8996_AIF1TX_CHAN1_SLOTS_MASK |
+ WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
+ WM8996_AIF1TX_CHAN2_SLOTS_MASK |
+ WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
+ WM8996_AIF1TX_CHAN3_SLOTS_MASK |
+ WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
+ WM8996_AIF1TX_CHAN4_SLOTS_MASK |
+ WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
+ WM8996_AIF1TX_CHAN5_SLOTS_MASK |
+ WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
+
+ snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
+ WM8996_AIF2TX_CHAN0_SLOTS_MASK |
+ WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
+ 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
+ snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
+ WM8996_AIF2TX_CHAN1_SLOTS_MASK |
+ WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
+ 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
+
+ if (wm8996->pdata.num_retune_mobile_cfgs)
+ wm8996_retune_mobile_pdata(codec);
+ else
+ snd_soc_add_controls(codec, wm8996_eq_controls,
+ ARRAY_SIZE(wm8996_eq_controls));
+
+ /* If the TX LRCLK pins are not in LRCLK mode configure the
+ * AIFs to source their clocks from the RX LRCLKs.
+ */
+ if ((snd_soc_read(codec, WM8996_GPIO_1)))
+ snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2,
+ WM8996_AIF1TX_LRCLK_MODE,
+ WM8996_AIF1TX_LRCLK_MODE);
+
+ if ((snd_soc_read(codec, WM8996_GPIO_2)))
+ snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2,
+ WM8996_AIF2TX_LRCLK_MODE,
+ WM8996_AIF2TX_LRCLK_MODE);
+
+ regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+
+ wm8996_init_gpio(codec);
+
+ if (i2c->irq) {
+ if (wm8996->pdata.irq_flags)
+ irq_flags = wm8996->pdata.irq_flags;
+ else
+ irq_flags = IRQF_TRIGGER_LOW;
+
+ irq_flags |= IRQF_ONESHOT;
+
+ if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
+ ret = request_threaded_irq(i2c->irq, NULL,
+ wm8996_edge_irq,
+ irq_flags, "wm8996", codec);
+ else
+ ret = request_threaded_irq(i2c->irq, NULL, wm8996_irq,
+ irq_flags, "wm8996", codec);
+
+ if (ret == 0) {
+ /* Unmask the interrupt */
+ snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
+ WM8996_IM_IRQ, 0);
+
+ /* Enable error reporting and DC servo status */
+ snd_soc_update_bits(codec,
+ WM8996_INTERRUPT_STATUS_2_MASK,
+ WM8996_IM_DCS_DONE_23_EINT |
+ WM8996_IM_DCS_DONE_01_EINT |
+ WM8996_IM_FLL_LOCK_EINT |
+ WM8996_IM_FIFOS_ERR_EINT,
+ 0);
+ } else {
+ dev_err(codec->dev, "Failed to request IRQ: %d\n",
+ ret);
+ }
+ }
+
+ return 0;
+
+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_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+err:
+ return ret;
+}
+
+static int wm8996_remove(struct snd_soc_codec *codec)
+{
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ struct i2c_client *i2c = to_i2c_client(codec->dev);
+ int i;
+
+ snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
+ WM8996_IM_IRQ, WM8996_IM_IRQ);
+
+ if (i2c->irq)
+ free_irq(i2c->irq, codec);
+
+ wm8996_free_gpio(codec);
+
+ for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
+ regulator_unregister_notifier(wm8996->supplies[i].consumer,
+ &wm8996->disable_nb[i]);
+ regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
+ .probe = wm8996_probe,
+ .remove = wm8996_remove,
+ .set_bias_level = wm8996_set_bias_level,
+ .seq_notifier = wm8996_seq_notifier,
+ .reg_cache_size = WM8996_MAX_REGISTER + 1,
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8996_reg,
+ .volatile_register = wm8996_volatile_register,
+ .readable_register = wm8996_readable_register,
+ .compress_type = SND_SOC_RBTREE_COMPRESSION,
+ .controls = wm8996_snd_controls,
+ .num_controls = ARRAY_SIZE(wm8996_snd_controls),
+ .dapm_widgets = wm8996_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets),
+ .dapm_routes = wm8996_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
+ .set_pll = wm8996_set_fll,
+};
+
+#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
+#define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | 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_ops wm8996_dai_ops = {
+ .set_fmt = wm8996_set_fmt,
+ .hw_params = wm8996_hw_params,
+ .set_sysclk = wm8996_set_sysclk,
+};
+
+static struct snd_soc_dai_driver wm8996_dai[] = {
+ {
+ .name = "wm8996-aif1",
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = WM8996_RATES,
+ .formats = WM8996_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = WM8996_RATES,
+ .formats = WM8996_FORMATS,
+ },
+ .ops = &wm8996_dai_ops,
+ },
+ {
+ .name = "wm8996-aif2",
+ .playback = {
+ .stream_name = "AIF2 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8996_RATES,
+ .formats = WM8996_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AIF2 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8996_RATES,
+ .formats = WM8996_FORMATS,
+ },
+ .ops = &wm8996_dai_ops,
+ },
+};
+
+static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8996_priv *wm8996;
+ int ret;
+
+ wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL);
+ if (wm8996 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, wm8996);
+
+ if (dev_get_platdata(&i2c->dev))
+ memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev),
+ sizeof(wm8996->pdata));
+
+ if (wm8996->pdata.ldo_ena > 0) {
+ ret = gpio_request_one(wm8996->pdata.ldo_ena,
+ GPIOF_OUT_INIT_LOW, "WM8996 ENA");
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
+ wm8996->pdata.ldo_ena, ret);
+ goto err;
+ }
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8996, wm8996_dai,
+ ARRAY_SIZE(wm8996_dai));
+ if (ret < 0)
+ goto err_gpio;
+
+ return ret;
+
+err_gpio:
+ if (wm8996->pdata.ldo_ena > 0)
+ gpio_free(wm8996->pdata.ldo_ena);
+err:
+ kfree(wm8996);
+
+ return ret;
+}
+
+static __devexit int wm8996_i2c_remove(struct i2c_client *client)
+{
+ struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
+
+ snd_soc_unregister_codec(&client->dev);
+ if (wm8996->pdata.ldo_ena > 0)
+ gpio_free(wm8996->pdata.ldo_ena);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static const struct i2c_device_id wm8996_i2c_id[] = {
+ { "wm8996", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8996_i2c_id);
+
+static struct i2c_driver wm8996_i2c_driver = {
+ .driver = {
+ .name = "wm8996",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8996_i2c_probe,
+ .remove = __devexit_p(wm8996_i2c_remove),
+ .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_DESCRIPTION("ASoC WM8996 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8996.h b/sound/soc/codecs/wm8996.h
new file mode 100644
index 00000000000..0fde643194c
--- /dev/null
+++ b/sound/soc/codecs/wm8996.h
@@ -0,0 +1,3717 @@
+/*
+ * wm8996.h - WM8996 audio codec interface
+ *
+ * Copyright 2011 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 _WM8996_H
+#define _WM8996_H
+
+#define WM8996_SYSCLK_MCLK1 1
+#define WM8996_SYSCLK_MCLK2 2
+#define WM8996_SYSCLK_FLL 3
+
+#define WM8996_FLL_MCLK1 1
+#define WM8996_FLL_MCLK2 2
+#define WM8996_FLL_DACLRCLK1 3
+#define WM8996_FLL_BCLK1 4
+
+typedef void (*wm8996_polarity_fn)(struct snd_soc_codec *codec, int polarity);
+
+int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ wm8996_polarity_fn polarity_cb);
+
+/*
+ * Register values.
+ */
+#define WM8996_SOFTWARE_RESET 0x00
+#define WM8996_POWER_MANAGEMENT_1 0x01
+#define WM8996_POWER_MANAGEMENT_2 0x02
+#define WM8996_POWER_MANAGEMENT_3 0x03
+#define WM8996_POWER_MANAGEMENT_4 0x04
+#define WM8996_POWER_MANAGEMENT_5 0x05
+#define WM8996_POWER_MANAGEMENT_6 0x06
+#define WM8996_POWER_MANAGEMENT_7 0x07
+#define WM8996_POWER_MANAGEMENT_8 0x08
+#define WM8996_LEFT_LINE_INPUT_VOLUME 0x10
+#define WM8996_RIGHT_LINE_INPUT_VOLUME 0x11
+#define WM8996_LINE_INPUT_CONTROL 0x12
+#define WM8996_DAC1_HPOUT1_VOLUME 0x15
+#define WM8996_DAC2_HPOUT2_VOLUME 0x16
+#define WM8996_DAC1_LEFT_VOLUME 0x18
+#define WM8996_DAC1_RIGHT_VOLUME 0x19
+#define WM8996_DAC2_LEFT_VOLUME 0x1A
+#define WM8996_DAC2_RIGHT_VOLUME 0x1B
+#define WM8996_OUTPUT1_LEFT_VOLUME 0x1C
+#define WM8996_OUTPUT1_RIGHT_VOLUME 0x1D
+#define WM8996_OUTPUT2_LEFT_VOLUME 0x1E
+#define WM8996_OUTPUT2_RIGHT_VOLUME 0x1F
+#define WM8996_MICBIAS_1 0x20
+#define WM8996_MICBIAS_2 0x21
+#define WM8996_LDO_1 0x28
+#define WM8996_LDO_2 0x29
+#define WM8996_ACCESSORY_DETECT_MODE_1 0x30
+#define WM8996_ACCESSORY_DETECT_MODE_2 0x31
+#define WM8996_HEADPHONE_DETECT_1 0x34
+#define WM8996_HEADPHONE_DETECT_2 0x35
+#define WM8996_MIC_DETECT_1 0x38
+#define WM8996_MIC_DETECT_2 0x39
+#define WM8996_MIC_DETECT_3 0x3A
+#define WM8996_CHARGE_PUMP_1 0x40
+#define WM8996_CHARGE_PUMP_2 0x41
+#define WM8996_DC_SERVO_1 0x50
+#define WM8996_DC_SERVO_2 0x51
+#define WM8996_DC_SERVO_3 0x52
+#define WM8996_DC_SERVO_5 0x54
+#define WM8996_DC_SERVO_6 0x55
+#define WM8996_DC_SERVO_7 0x56
+#define WM8996_DC_SERVO_READBACK_0 0x57
+#define WM8996_ANALOGUE_HP_1 0x60
+#define WM8996_ANALOGUE_HP_2 0x61
+#define WM8996_CHIP_REVISION 0x100
+#define WM8996_CONTROL_INTERFACE_1 0x101
+#define WM8996_WRITE_SEQUENCER_CTRL_1 0x110
+#define WM8996_WRITE_SEQUENCER_CTRL_2 0x111
+#define WM8996_AIF_CLOCKING_1 0x200
+#define WM8996_AIF_CLOCKING_2 0x201
+#define WM8996_CLOCKING_1 0x208
+#define WM8996_CLOCKING_2 0x209
+#define WM8996_AIF_RATE 0x210
+#define WM8996_FLL_CONTROL_1 0x220
+#define WM8996_FLL_CONTROL_2 0x221
+#define WM8996_FLL_CONTROL_3 0x222
+#define WM8996_FLL_CONTROL_4 0x223
+#define WM8996_FLL_CONTROL_5 0x224
+#define WM8996_FLL_CONTROL_6 0x225
+#define WM8996_FLL_EFS_1 0x226
+#define WM8996_FLL_EFS_2 0x227
+#define WM8996_AIF1_CONTROL 0x300
+#define WM8996_AIF1_BCLK 0x301
+#define WM8996_AIF1_TX_LRCLK_1 0x302
+#define WM8996_AIF1_TX_LRCLK_2 0x303
+#define WM8996_AIF1_RX_LRCLK_1 0x304
+#define WM8996_AIF1_RX_LRCLK_2 0x305
+#define WM8996_AIF1TX_DATA_CONFIGURATION_1 0x306
+#define WM8996_AIF1TX_DATA_CONFIGURATION_2 0x307
+#define WM8996_AIF1RX_DATA_CONFIGURATION 0x308
+#define WM8996_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
+#define WM8996_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
+#define WM8996_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
+#define WM8996_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
+#define WM8996_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
+#define WM8996_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
+#define WM8996_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
+#define WM8996_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
+#define WM8996_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
+#define WM8996_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
+#define WM8996_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
+#define WM8996_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
+#define WM8996_AIF1RX_MONO_CONFIGURATION 0x315
+#define WM8996_AIF1TX_TEST 0x31A
+#define WM8996_AIF2_CONTROL 0x320
+#define WM8996_AIF2_BCLK 0x321
+#define WM8996_AIF2_TX_LRCLK_1 0x322
+#define WM8996_AIF2_TX_LRCLK_2 0x323
+#define WM8996_AIF2_RX_LRCLK_1 0x324
+#define WM8996_AIF2_RX_LRCLK_2 0x325
+#define WM8996_AIF2TX_DATA_CONFIGURATION_1 0x326
+#define WM8996_AIF2TX_DATA_CONFIGURATION_2 0x327
+#define WM8996_AIF2RX_DATA_CONFIGURATION 0x328
+#define WM8996_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
+#define WM8996_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
+#define WM8996_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
+#define WM8996_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
+#define WM8996_AIF2RX_MONO_CONFIGURATION 0x32D
+#define WM8996_AIF2TX_TEST 0x32F
+#define WM8996_DSP1_TX_LEFT_VOLUME 0x400
+#define WM8996_DSP1_TX_RIGHT_VOLUME 0x401
+#define WM8996_DSP1_RX_LEFT_VOLUME 0x402
+#define WM8996_DSP1_RX_RIGHT_VOLUME 0x403
+#define WM8996_DSP1_TX_FILTERS 0x410
+#define WM8996_DSP1_RX_FILTERS_1 0x420
+#define WM8996_DSP1_RX_FILTERS_2 0x421
+#define WM8996_DSP1_DRC_1 0x440
+#define WM8996_DSP1_DRC_2 0x441
+#define WM8996_DSP1_DRC_3 0x442
+#define WM8996_DSP1_DRC_4 0x443
+#define WM8996_DSP1_DRC_5 0x444
+#define WM8996_DSP1_RX_EQ_GAINS_1 0x480
+#define WM8996_DSP1_RX_EQ_GAINS_2 0x481
+#define WM8996_DSP1_RX_EQ_BAND_1_A 0x482
+#define WM8996_DSP1_RX_EQ_BAND_1_B 0x483
+#define WM8996_DSP1_RX_EQ_BAND_1_PG 0x484
+#define WM8996_DSP1_RX_EQ_BAND_2_A 0x485
+#define WM8996_DSP1_RX_EQ_BAND_2_B 0x486
+#define WM8996_DSP1_RX_EQ_BAND_2_C 0x487
+#define WM8996_DSP1_RX_EQ_BAND_2_PG 0x488
+#define WM8996_DSP1_RX_EQ_BAND_3_A 0x489
+#define WM8996_DSP1_RX_EQ_BAND_3_B 0x48A
+#define WM8996_DSP1_RX_EQ_BAND_3_C 0x48B
+#define WM8996_DSP1_RX_EQ_BAND_3_PG 0x48C
+#define WM8996_DSP1_RX_EQ_BAND_4_A 0x48D
+#define WM8996_DSP1_RX_EQ_BAND_4_B 0x48E
+#define WM8996_DSP1_RX_EQ_BAND_4_C 0x48F
+#define WM8996_DSP1_RX_EQ_BAND_4_PG 0x490
+#define WM8996_DSP1_RX_EQ_BAND_5_A 0x491
+#define WM8996_DSP1_RX_EQ_BAND_5_B 0x492
+#define WM8996_DSP1_RX_EQ_BAND_5_PG 0x493
+#define WM8996_DSP2_TX_LEFT_VOLUME 0x500
+#define WM8996_DSP2_TX_RIGHT_VOLUME 0x501
+#define WM8996_DSP2_RX_LEFT_VOLUME 0x502
+#define WM8996_DSP2_RX_RIGHT_VOLUME 0x503
+#define WM8996_DSP2_TX_FILTERS 0x510
+#define WM8996_DSP2_RX_FILTERS_1 0x520
+#define WM8996_DSP2_RX_FILTERS_2 0x521
+#define WM8996_DSP2_DRC_1 0x540
+#define WM8996_DSP2_DRC_2 0x541
+#define WM8996_DSP2_DRC_3 0x542
+#define WM8996_DSP2_DRC_4 0x543
+#define WM8996_DSP2_DRC_5 0x544
+#define WM8996_DSP2_RX_EQ_GAINS_1 0x580
+#define WM8996_DSP2_RX_EQ_GAINS_2 0x581
+#define WM8996_DSP2_RX_EQ_BAND_1_A 0x582
+#define WM8996_DSP2_RX_EQ_BAND_1_B 0x583
+#define WM8996_DSP2_RX_EQ_BAND_1_PG 0x584
+#define WM8996_DSP2_RX_EQ_BAND_2_A 0x585
+#define WM8996_DSP2_RX_EQ_BAND_2_B 0x586
+#define WM8996_DSP2_RX_EQ_BAND_2_C 0x587
+#define WM8996_DSP2_RX_EQ_BAND_2_PG 0x588
+#define WM8996_DSP2_RX_EQ_BAND_3_A 0x589
+#define WM8996_DSP2_RX_EQ_BAND_3_B 0x58A
+#define WM8996_DSP2_RX_EQ_BAND_3_C 0x58B
+#define WM8996_DSP2_RX_EQ_BAND_3_PG 0x58C
+#define WM8996_DSP2_RX_EQ_BAND_4_A 0x58D
+#define WM8996_DSP2_RX_EQ_BAND_4_B 0x58E
+#define WM8996_DSP2_RX_EQ_BAND_4_C 0x58F
+#define WM8996_DSP2_RX_EQ_BAND_4_PG 0x590
+#define WM8996_DSP2_RX_EQ_BAND_5_A 0x591
+#define WM8996_DSP2_RX_EQ_BAND_5_B 0x592
+#define WM8996_DSP2_RX_EQ_BAND_5_PG 0x593
+#define WM8996_DAC1_MIXER_VOLUMES 0x600
+#define WM8996_DAC1_LEFT_MIXER_ROUTING 0x601
+#define WM8996_DAC1_RIGHT_MIXER_ROUTING 0x602
+#define WM8996_DAC2_MIXER_VOLUMES 0x603
+#define WM8996_DAC2_LEFT_MIXER_ROUTING 0x604
+#define WM8996_DAC2_RIGHT_MIXER_ROUTING 0x605
+#define WM8996_DSP1_TX_LEFT_MIXER_ROUTING 0x606
+#define WM8996_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
+#define WM8996_DSP2_TX_LEFT_MIXER_ROUTING 0x608
+#define WM8996_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
+#define WM8996_DSP_TX_MIXER_SELECT 0x60A
+#define WM8996_DAC_SOFTMUTE 0x610
+#define WM8996_OVERSAMPLING 0x620
+#define WM8996_SIDETONE 0x621
+#define WM8996_GPIO_1 0x700
+#define WM8996_GPIO_2 0x701
+#define WM8996_GPIO_3 0x702
+#define WM8996_GPIO_4 0x703
+#define WM8996_GPIO_5 0x704
+#define WM8996_PULL_CONTROL_1 0x720
+#define WM8996_PULL_CONTROL_2 0x721
+#define WM8996_INTERRUPT_STATUS_1 0x730
+#define WM8996_INTERRUPT_STATUS_2 0x731
+#define WM8996_INTERRUPT_RAW_STATUS_2 0x732
+#define WM8996_INTERRUPT_STATUS_1_MASK 0x738
+#define WM8996_INTERRUPT_STATUS_2_MASK 0x739
+#define WM8996_INTERRUPT_CONTROL 0x740
+#define WM8996_LEFT_PDM_SPEAKER 0x800
+#define WM8996_RIGHT_PDM_SPEAKER 0x801
+#define WM8996_PDM_SPEAKER_MUTE_SEQUENCE 0x802
+#define WM8996_PDM_SPEAKER_VOLUME 0x803
+#define WM8996_WRITE_SEQUENCER_0 0x3000
+#define WM8996_WRITE_SEQUENCER_1 0x3001
+#define WM8996_WRITE_SEQUENCER_2 0x3002
+#define WM8996_WRITE_SEQUENCER_3 0x3003
+#define WM8996_WRITE_SEQUENCER_4 0x3004
+#define WM8996_WRITE_SEQUENCER_5 0x3005
+#define WM8996_WRITE_SEQUENCER_6 0x3006
+#define WM8996_WRITE_SEQUENCER_7 0x3007
+#define WM8996_WRITE_SEQUENCER_8 0x3008
+#define WM8996_WRITE_SEQUENCER_9 0x3009
+#define WM8996_WRITE_SEQUENCER_10 0x300A
+#define WM8996_WRITE_SEQUENCER_11 0x300B
+#define WM8996_WRITE_SEQUENCER_12 0x300C
+#define WM8996_WRITE_SEQUENCER_13 0x300D
+#define WM8996_WRITE_SEQUENCER_14 0x300E
+#define WM8996_WRITE_SEQUENCER_15 0x300F
+#define WM8996_WRITE_SEQUENCER_16 0x3010
+#define WM8996_WRITE_SEQUENCER_17 0x3011
+#define WM8996_WRITE_SEQUENCER_18 0x3012
+#define WM8996_WRITE_SEQUENCER_19 0x3013
+#define WM8996_WRITE_SEQUENCER_20 0x3014
+#define WM8996_WRITE_SEQUENCER_21 0x3015
+#define WM8996_WRITE_SEQUENCER_22 0x3016
+#define WM8996_WRITE_SEQUENCER_23 0x3017
+#define WM8996_WRITE_SEQUENCER_24 0x3018
+#define WM8996_WRITE_SEQUENCER_25 0x3019
+#define WM8996_WRITE_SEQUENCER_26 0x301A
+#define WM8996_WRITE_SEQUENCER_27 0x301B
+#define WM8996_WRITE_SEQUENCER_28 0x301C
+#define WM8996_WRITE_SEQUENCER_29 0x301D
+#define WM8996_WRITE_SEQUENCER_30 0x301E
+#define WM8996_WRITE_SEQUENCER_31 0x301F
+#define WM8996_WRITE_SEQUENCER_32 0x3020
+#define WM8996_WRITE_SEQUENCER_33 0x3021
+#define WM8996_WRITE_SEQUENCER_34 0x3022
+#define WM8996_WRITE_SEQUENCER_35 0x3023
+#define WM8996_WRITE_SEQUENCER_36 0x3024
+#define WM8996_WRITE_SEQUENCER_37 0x3025
+#define WM8996_WRITE_SEQUENCER_38 0x3026
+#define WM8996_WRITE_SEQUENCER_39 0x3027
+#define WM8996_WRITE_SEQUENCER_40 0x3028
+#define WM8996_WRITE_SEQUENCER_41 0x3029
+#define WM8996_WRITE_SEQUENCER_42 0x302A
+#define WM8996_WRITE_SEQUENCER_43 0x302B
+#define WM8996_WRITE_SEQUENCER_44 0x302C
+#define WM8996_WRITE_SEQUENCER_45 0x302D
+#define WM8996_WRITE_SEQUENCER_46 0x302E
+#define WM8996_WRITE_SEQUENCER_47 0x302F
+#define WM8996_WRITE_SEQUENCER_48 0x3030
+#define WM8996_WRITE_SEQUENCER_49 0x3031
+#define WM8996_WRITE_SEQUENCER_50 0x3032
+#define WM8996_WRITE_SEQUENCER_51 0x3033
+#define WM8996_WRITE_SEQUENCER_52 0x3034
+#define WM8996_WRITE_SEQUENCER_53 0x3035
+#define WM8996_WRITE_SEQUENCER_54 0x3036
+#define WM8996_WRITE_SEQUENCER_55 0x3037
+#define WM8996_WRITE_SEQUENCER_56 0x3038
+#define WM8996_WRITE_SEQUENCER_57 0x3039
+#define WM8996_WRITE_SEQUENCER_58 0x303A
+#define WM8996_WRITE_SEQUENCER_59 0x303B
+#define WM8996_WRITE_SEQUENCER_60 0x303C
+#define WM8996_WRITE_SEQUENCER_61 0x303D
+#define WM8996_WRITE_SEQUENCER_62 0x303E
+#define WM8996_WRITE_SEQUENCER_63 0x303F
+#define WM8996_WRITE_SEQUENCER_64 0x3040
+#define WM8996_WRITE_SEQUENCER_65 0x3041
+#define WM8996_WRITE_SEQUENCER_66 0x3042
+#define WM8996_WRITE_SEQUENCER_67 0x3043
+#define WM8996_WRITE_SEQUENCER_68 0x3044
+#define WM8996_WRITE_SEQUENCER_69 0x3045
+#define WM8996_WRITE_SEQUENCER_70 0x3046
+#define WM8996_WRITE_SEQUENCER_71 0x3047
+#define WM8996_WRITE_SEQUENCER_72 0x3048
+#define WM8996_WRITE_SEQUENCER_73 0x3049
+#define WM8996_WRITE_SEQUENCER_74 0x304A
+#define WM8996_WRITE_SEQUENCER_75 0x304B
+#define WM8996_WRITE_SEQUENCER_76 0x304C
+#define WM8996_WRITE_SEQUENCER_77 0x304D
+#define WM8996_WRITE_SEQUENCER_78 0x304E
+#define WM8996_WRITE_SEQUENCER_79 0x304F
+#define WM8996_WRITE_SEQUENCER_80 0x3050
+#define WM8996_WRITE_SEQUENCER_81 0x3051
+#define WM8996_WRITE_SEQUENCER_82 0x3052
+#define WM8996_WRITE_SEQUENCER_83 0x3053
+#define WM8996_WRITE_SEQUENCER_84 0x3054
+#define WM8996_WRITE_SEQUENCER_85 0x3055
+#define WM8996_WRITE_SEQUENCER_86 0x3056
+#define WM8996_WRITE_SEQUENCER_87 0x3057
+#define WM8996_WRITE_SEQUENCER_88 0x3058
+#define WM8996_WRITE_SEQUENCER_89 0x3059
+#define WM8996_WRITE_SEQUENCER_90 0x305A
+#define WM8996_WRITE_SEQUENCER_91 0x305B
+#define WM8996_WRITE_SEQUENCER_92 0x305C
+#define WM8996_WRITE_SEQUENCER_93 0x305D
+#define WM8996_WRITE_SEQUENCER_94 0x305E
+#define WM8996_WRITE_SEQUENCER_95 0x305F
+#define WM8996_WRITE_SEQUENCER_96 0x3060
+#define WM8996_WRITE_SEQUENCER_97 0x3061
+#define WM8996_WRITE_SEQUENCER_98 0x3062
+#define WM8996_WRITE_SEQUENCER_99 0x3063
+#define WM8996_WRITE_SEQUENCER_100 0x3064
+#define WM8996_WRITE_SEQUENCER_101 0x3065
+#define WM8996_WRITE_SEQUENCER_102 0x3066
+#define WM8996_WRITE_SEQUENCER_103 0x3067
+#define WM8996_WRITE_SEQUENCER_104 0x3068
+#define WM8996_WRITE_SEQUENCER_105 0x3069
+#define WM8996_WRITE_SEQUENCER_106 0x306A
+#define WM8996_WRITE_SEQUENCER_107 0x306B
+#define WM8996_WRITE_SEQUENCER_108 0x306C
+#define WM8996_WRITE_SEQUENCER_109 0x306D
+#define WM8996_WRITE_SEQUENCER_110 0x306E
+#define WM8996_WRITE_SEQUENCER_111 0x306F
+#define WM8996_WRITE_SEQUENCER_112 0x3070
+#define WM8996_WRITE_SEQUENCER_113 0x3071
+#define WM8996_WRITE_SEQUENCER_114 0x3072
+#define WM8996_WRITE_SEQUENCER_115 0x3073
+#define WM8996_WRITE_SEQUENCER_116 0x3074
+#define WM8996_WRITE_SEQUENCER_117 0x3075
+#define WM8996_WRITE_SEQUENCER_118 0x3076
+#define WM8996_WRITE_SEQUENCER_119 0x3077
+#define WM8996_WRITE_SEQUENCER_120 0x3078
+#define WM8996_WRITE_SEQUENCER_121 0x3079
+#define WM8996_WRITE_SEQUENCER_122 0x307A
+#define WM8996_WRITE_SEQUENCER_123 0x307B
+#define WM8996_WRITE_SEQUENCER_124 0x307C
+#define WM8996_WRITE_SEQUENCER_125 0x307D
+#define WM8996_WRITE_SEQUENCER_126 0x307E
+#define WM8996_WRITE_SEQUENCER_127 0x307F
+#define WM8996_WRITE_SEQUENCER_128 0x3080
+#define WM8996_WRITE_SEQUENCER_129 0x3081
+#define WM8996_WRITE_SEQUENCER_130 0x3082
+#define WM8996_WRITE_SEQUENCER_131 0x3083
+#define WM8996_WRITE_SEQUENCER_132 0x3084
+#define WM8996_WRITE_SEQUENCER_133 0x3085
+#define WM8996_WRITE_SEQUENCER_134 0x3086
+#define WM8996_WRITE_SEQUENCER_135 0x3087
+#define WM8996_WRITE_SEQUENCER_136 0x3088
+#define WM8996_WRITE_SEQUENCER_137 0x3089
+#define WM8996_WRITE_SEQUENCER_138 0x308A
+#define WM8996_WRITE_SEQUENCER_139 0x308B
+#define WM8996_WRITE_SEQUENCER_140 0x308C
+#define WM8996_WRITE_SEQUENCER_141 0x308D
+#define WM8996_WRITE_SEQUENCER_142 0x308E
+#define WM8996_WRITE_SEQUENCER_143 0x308F
+#define WM8996_WRITE_SEQUENCER_144 0x3090
+#define WM8996_WRITE_SEQUENCER_145 0x3091
+#define WM8996_WRITE_SEQUENCER_146 0x3092
+#define WM8996_WRITE_SEQUENCER_147 0x3093
+#define WM8996_WRITE_SEQUENCER_148 0x3094
+#define WM8996_WRITE_SEQUENCER_149 0x3095
+#define WM8996_WRITE_SEQUENCER_150 0x3096
+#define WM8996_WRITE_SEQUENCER_151 0x3097
+#define WM8996_WRITE_SEQUENCER_152 0x3098
+#define WM8996_WRITE_SEQUENCER_153 0x3099
+#define WM8996_WRITE_SEQUENCER_154 0x309A
+#define WM8996_WRITE_SEQUENCER_155 0x309B
+#define WM8996_WRITE_SEQUENCER_156 0x309C
+#define WM8996_WRITE_SEQUENCER_157 0x309D
+#define WM8996_WRITE_SEQUENCER_158 0x309E
+#define WM8996_WRITE_SEQUENCER_159 0x309F
+#define WM8996_WRITE_SEQUENCER_160 0x30A0
+#define WM8996_WRITE_SEQUENCER_161 0x30A1
+#define WM8996_WRITE_SEQUENCER_162 0x30A2
+#define WM8996_WRITE_SEQUENCER_163 0x30A3
+#define WM8996_WRITE_SEQUENCER_164 0x30A4
+#define WM8996_WRITE_SEQUENCER_165 0x30A5
+#define WM8996_WRITE_SEQUENCER_166 0x30A6
+#define WM8996_WRITE_SEQUENCER_167 0x30A7
+#define WM8996_WRITE_SEQUENCER_168 0x30A8
+#define WM8996_WRITE_SEQUENCER_169 0x30A9
+#define WM8996_WRITE_SEQUENCER_170 0x30AA
+#define WM8996_WRITE_SEQUENCER_171 0x30AB
+#define WM8996_WRITE_SEQUENCER_172 0x30AC
+#define WM8996_WRITE_SEQUENCER_173 0x30AD
+#define WM8996_WRITE_SEQUENCER_174 0x30AE
+#define WM8996_WRITE_SEQUENCER_175 0x30AF
+#define WM8996_WRITE_SEQUENCER_176 0x30B0
+#define WM8996_WRITE_SEQUENCER_177 0x30B1
+#define WM8996_WRITE_SEQUENCER_178 0x30B2
+#define WM8996_WRITE_SEQUENCER_179 0x30B3
+#define WM8996_WRITE_SEQUENCER_180 0x30B4
+#define WM8996_WRITE_SEQUENCER_181 0x30B5
+#define WM8996_WRITE_SEQUENCER_182 0x30B6
+#define WM8996_WRITE_SEQUENCER_183 0x30B7
+#define WM8996_WRITE_SEQUENCER_184 0x30B8
+#define WM8996_WRITE_SEQUENCER_185 0x30B9
+#define WM8996_WRITE_SEQUENCER_186 0x30BA
+#define WM8996_WRITE_SEQUENCER_187 0x30BB
+#define WM8996_WRITE_SEQUENCER_188 0x30BC
+#define WM8996_WRITE_SEQUENCER_189 0x30BD
+#define WM8996_WRITE_SEQUENCER_190 0x30BE
+#define WM8996_WRITE_SEQUENCER_191 0x30BF
+#define WM8996_WRITE_SEQUENCER_192 0x30C0
+#define WM8996_WRITE_SEQUENCER_193 0x30C1
+#define WM8996_WRITE_SEQUENCER_194 0x30C2
+#define WM8996_WRITE_SEQUENCER_195 0x30C3
+#define WM8996_WRITE_SEQUENCER_196 0x30C4
+#define WM8996_WRITE_SEQUENCER_197 0x30C5
+#define WM8996_WRITE_SEQUENCER_198 0x30C6
+#define WM8996_WRITE_SEQUENCER_199 0x30C7
+#define WM8996_WRITE_SEQUENCER_200 0x30C8
+#define WM8996_WRITE_SEQUENCER_201 0x30C9
+#define WM8996_WRITE_SEQUENCER_202 0x30CA
+#define WM8996_WRITE_SEQUENCER_203 0x30CB
+#define WM8996_WRITE_SEQUENCER_204 0x30CC
+#define WM8996_WRITE_SEQUENCER_205 0x30CD
+#define WM8996_WRITE_SEQUENCER_206 0x30CE
+#define WM8996_WRITE_SEQUENCER_207 0x30CF
+#define WM8996_WRITE_SEQUENCER_208 0x30D0
+#define WM8996_WRITE_SEQUENCER_209 0x30D1
+#define WM8996_WRITE_SEQUENCER_210 0x30D2
+#define WM8996_WRITE_SEQUENCER_211 0x30D3
+#define WM8996_WRITE_SEQUENCER_212 0x30D4
+#define WM8996_WRITE_SEQUENCER_213 0x30D5
+#define WM8996_WRITE_SEQUENCER_214 0x30D6
+#define WM8996_WRITE_SEQUENCER_215 0x30D7
+#define WM8996_WRITE_SEQUENCER_216 0x30D8
+#define WM8996_WRITE_SEQUENCER_217 0x30D9
+#define WM8996_WRITE_SEQUENCER_218 0x30DA
+#define WM8996_WRITE_SEQUENCER_219 0x30DB
+#define WM8996_WRITE_SEQUENCER_220 0x30DC
+#define WM8996_WRITE_SEQUENCER_221 0x30DD
+#define WM8996_WRITE_SEQUENCER_222 0x30DE
+#define WM8996_WRITE_SEQUENCER_223 0x30DF
+#define WM8996_WRITE_SEQUENCER_224 0x30E0
+#define WM8996_WRITE_SEQUENCER_225 0x30E1
+#define WM8996_WRITE_SEQUENCER_226 0x30E2
+#define WM8996_WRITE_SEQUENCER_227 0x30E3
+#define WM8996_WRITE_SEQUENCER_228 0x30E4
+#define WM8996_WRITE_SEQUENCER_229 0x30E5
+#define WM8996_WRITE_SEQUENCER_230 0x30E6
+#define WM8996_WRITE_SEQUENCER_231 0x30E7
+#define WM8996_WRITE_SEQUENCER_232 0x30E8
+#define WM8996_WRITE_SEQUENCER_233 0x30E9
+#define WM8996_WRITE_SEQUENCER_234 0x30EA
+#define WM8996_WRITE_SEQUENCER_235 0x30EB
+#define WM8996_WRITE_SEQUENCER_236 0x30EC
+#define WM8996_WRITE_SEQUENCER_237 0x30ED
+#define WM8996_WRITE_SEQUENCER_238 0x30EE
+#define WM8996_WRITE_SEQUENCER_239 0x30EF
+#define WM8996_WRITE_SEQUENCER_240 0x30F0
+#define WM8996_WRITE_SEQUENCER_241 0x30F1
+#define WM8996_WRITE_SEQUENCER_242 0x30F2
+#define WM8996_WRITE_SEQUENCER_243 0x30F3
+#define WM8996_WRITE_SEQUENCER_244 0x30F4
+#define WM8996_WRITE_SEQUENCER_245 0x30F5
+#define WM8996_WRITE_SEQUENCER_246 0x30F6
+#define WM8996_WRITE_SEQUENCER_247 0x30F7
+#define WM8996_WRITE_SEQUENCER_248 0x30F8
+#define WM8996_WRITE_SEQUENCER_249 0x30F9
+#define WM8996_WRITE_SEQUENCER_250 0x30FA
+#define WM8996_WRITE_SEQUENCER_251 0x30FB
+#define WM8996_WRITE_SEQUENCER_252 0x30FC
+#define WM8996_WRITE_SEQUENCER_253 0x30FD
+#define WM8996_WRITE_SEQUENCER_254 0x30FE
+#define WM8996_WRITE_SEQUENCER_255 0x30FF
+#define WM8996_WRITE_SEQUENCER_256 0x3100
+#define WM8996_WRITE_SEQUENCER_257 0x3101
+#define WM8996_WRITE_SEQUENCER_258 0x3102
+#define WM8996_WRITE_SEQUENCER_259 0x3103
+#define WM8996_WRITE_SEQUENCER_260 0x3104
+#define WM8996_WRITE_SEQUENCER_261 0x3105
+#define WM8996_WRITE_SEQUENCER_262 0x3106
+#define WM8996_WRITE_SEQUENCER_263 0x3107
+#define WM8996_WRITE_SEQUENCER_264 0x3108
+#define WM8996_WRITE_SEQUENCER_265 0x3109
+#define WM8996_WRITE_SEQUENCER_266 0x310A
+#define WM8996_WRITE_SEQUENCER_267 0x310B
+#define WM8996_WRITE_SEQUENCER_268 0x310C
+#define WM8996_WRITE_SEQUENCER_269 0x310D
+#define WM8996_WRITE_SEQUENCER_270 0x310E
+#define WM8996_WRITE_SEQUENCER_271 0x310F
+#define WM8996_WRITE_SEQUENCER_272 0x3110
+#define WM8996_WRITE_SEQUENCER_273 0x3111
+#define WM8996_WRITE_SEQUENCER_274 0x3112
+#define WM8996_WRITE_SEQUENCER_275 0x3113
+#define WM8996_WRITE_SEQUENCER_276 0x3114
+#define WM8996_WRITE_SEQUENCER_277 0x3115
+#define WM8996_WRITE_SEQUENCER_278 0x3116
+#define WM8996_WRITE_SEQUENCER_279 0x3117
+#define WM8996_WRITE_SEQUENCER_280 0x3118
+#define WM8996_WRITE_SEQUENCER_281 0x3119
+#define WM8996_WRITE_SEQUENCER_282 0x311A
+#define WM8996_WRITE_SEQUENCER_283 0x311B
+#define WM8996_WRITE_SEQUENCER_284 0x311C
+#define WM8996_WRITE_SEQUENCER_285 0x311D
+#define WM8996_WRITE_SEQUENCER_286 0x311E
+#define WM8996_WRITE_SEQUENCER_287 0x311F
+#define WM8996_WRITE_SEQUENCER_288 0x3120
+#define WM8996_WRITE_SEQUENCER_289 0x3121
+#define WM8996_WRITE_SEQUENCER_290 0x3122
+#define WM8996_WRITE_SEQUENCER_291 0x3123
+#define WM8996_WRITE_SEQUENCER_292 0x3124
+#define WM8996_WRITE_SEQUENCER_293 0x3125
+#define WM8996_WRITE_SEQUENCER_294 0x3126
+#define WM8996_WRITE_SEQUENCER_295 0x3127
+#define WM8996_WRITE_SEQUENCER_296 0x3128
+#define WM8996_WRITE_SEQUENCER_297 0x3129
+#define WM8996_WRITE_SEQUENCER_298 0x312A
+#define WM8996_WRITE_SEQUENCER_299 0x312B
+#define WM8996_WRITE_SEQUENCER_300 0x312C
+#define WM8996_WRITE_SEQUENCER_301 0x312D
+#define WM8996_WRITE_SEQUENCER_302 0x312E
+#define WM8996_WRITE_SEQUENCER_303 0x312F
+#define WM8996_WRITE_SEQUENCER_304 0x3130
+#define WM8996_WRITE_SEQUENCER_305 0x3131
+#define WM8996_WRITE_SEQUENCER_306 0x3132
+#define WM8996_WRITE_SEQUENCER_307 0x3133
+#define WM8996_WRITE_SEQUENCER_308 0x3134
+#define WM8996_WRITE_SEQUENCER_309 0x3135
+#define WM8996_WRITE_SEQUENCER_310 0x3136
+#define WM8996_WRITE_SEQUENCER_311 0x3137
+#define WM8996_WRITE_SEQUENCER_312 0x3138
+#define WM8996_WRITE_SEQUENCER_313 0x3139
+#define WM8996_WRITE_SEQUENCER_314 0x313A
+#define WM8996_WRITE_SEQUENCER_315 0x313B
+#define WM8996_WRITE_SEQUENCER_316 0x313C
+#define WM8996_WRITE_SEQUENCER_317 0x313D
+#define WM8996_WRITE_SEQUENCER_318 0x313E
+#define WM8996_WRITE_SEQUENCER_319 0x313F
+#define WM8996_WRITE_SEQUENCER_320 0x3140
+#define WM8996_WRITE_SEQUENCER_321 0x3141
+#define WM8996_WRITE_SEQUENCER_322 0x3142
+#define WM8996_WRITE_SEQUENCER_323 0x3143
+#define WM8996_WRITE_SEQUENCER_324 0x3144
+#define WM8996_WRITE_SEQUENCER_325 0x3145
+#define WM8996_WRITE_SEQUENCER_326 0x3146
+#define WM8996_WRITE_SEQUENCER_327 0x3147
+#define WM8996_WRITE_SEQUENCER_328 0x3148
+#define WM8996_WRITE_SEQUENCER_329 0x3149
+#define WM8996_WRITE_SEQUENCER_330 0x314A
+#define WM8996_WRITE_SEQUENCER_331 0x314B
+#define WM8996_WRITE_SEQUENCER_332 0x314C
+#define WM8996_WRITE_SEQUENCER_333 0x314D
+#define WM8996_WRITE_SEQUENCER_334 0x314E
+#define WM8996_WRITE_SEQUENCER_335 0x314F
+#define WM8996_WRITE_SEQUENCER_336 0x3150
+#define WM8996_WRITE_SEQUENCER_337 0x3151
+#define WM8996_WRITE_SEQUENCER_338 0x3152
+#define WM8996_WRITE_SEQUENCER_339 0x3153
+#define WM8996_WRITE_SEQUENCER_340 0x3154
+#define WM8996_WRITE_SEQUENCER_341 0x3155
+#define WM8996_WRITE_SEQUENCER_342 0x3156
+#define WM8996_WRITE_SEQUENCER_343 0x3157
+#define WM8996_WRITE_SEQUENCER_344 0x3158
+#define WM8996_WRITE_SEQUENCER_345 0x3159
+#define WM8996_WRITE_SEQUENCER_346 0x315A
+#define WM8996_WRITE_SEQUENCER_347 0x315B
+#define WM8996_WRITE_SEQUENCER_348 0x315C
+#define WM8996_WRITE_SEQUENCER_349 0x315D
+#define WM8996_WRITE_SEQUENCER_350 0x315E
+#define WM8996_WRITE_SEQUENCER_351 0x315F
+#define WM8996_WRITE_SEQUENCER_352 0x3160
+#define WM8996_WRITE_SEQUENCER_353 0x3161
+#define WM8996_WRITE_SEQUENCER_354 0x3162
+#define WM8996_WRITE_SEQUENCER_355 0x3163
+#define WM8996_WRITE_SEQUENCER_356 0x3164
+#define WM8996_WRITE_SEQUENCER_357 0x3165
+#define WM8996_WRITE_SEQUENCER_358 0x3166
+#define WM8996_WRITE_SEQUENCER_359 0x3167
+#define WM8996_WRITE_SEQUENCER_360 0x3168
+#define WM8996_WRITE_SEQUENCER_361 0x3169
+#define WM8996_WRITE_SEQUENCER_362 0x316A
+#define WM8996_WRITE_SEQUENCER_363 0x316B
+#define WM8996_WRITE_SEQUENCER_364 0x316C
+#define WM8996_WRITE_SEQUENCER_365 0x316D
+#define WM8996_WRITE_SEQUENCER_366 0x316E
+#define WM8996_WRITE_SEQUENCER_367 0x316F
+#define WM8996_WRITE_SEQUENCER_368 0x3170
+#define WM8996_WRITE_SEQUENCER_369 0x3171
+#define WM8996_WRITE_SEQUENCER_370 0x3172
+#define WM8996_WRITE_SEQUENCER_371 0x3173
+#define WM8996_WRITE_SEQUENCER_372 0x3174
+#define WM8996_WRITE_SEQUENCER_373 0x3175
+#define WM8996_WRITE_SEQUENCER_374 0x3176
+#define WM8996_WRITE_SEQUENCER_375 0x3177
+#define WM8996_WRITE_SEQUENCER_376 0x3178
+#define WM8996_WRITE_SEQUENCER_377 0x3179
+#define WM8996_WRITE_SEQUENCER_378 0x317A
+#define WM8996_WRITE_SEQUENCER_379 0x317B
+#define WM8996_WRITE_SEQUENCER_380 0x317C
+#define WM8996_WRITE_SEQUENCER_381 0x317D
+#define WM8996_WRITE_SEQUENCER_382 0x317E
+#define WM8996_WRITE_SEQUENCER_383 0x317F
+#define WM8996_WRITE_SEQUENCER_384 0x3180
+#define WM8996_WRITE_SEQUENCER_385 0x3181
+#define WM8996_WRITE_SEQUENCER_386 0x3182
+#define WM8996_WRITE_SEQUENCER_387 0x3183
+#define WM8996_WRITE_SEQUENCER_388 0x3184
+#define WM8996_WRITE_SEQUENCER_389 0x3185
+#define WM8996_WRITE_SEQUENCER_390 0x3186
+#define WM8996_WRITE_SEQUENCER_391 0x3187
+#define WM8996_WRITE_SEQUENCER_392 0x3188
+#define WM8996_WRITE_SEQUENCER_393 0x3189
+#define WM8996_WRITE_SEQUENCER_394 0x318A
+#define WM8996_WRITE_SEQUENCER_395 0x318B
+#define WM8996_WRITE_SEQUENCER_396 0x318C
+#define WM8996_WRITE_SEQUENCER_397 0x318D
+#define WM8996_WRITE_SEQUENCER_398 0x318E
+#define WM8996_WRITE_SEQUENCER_399 0x318F
+#define WM8996_WRITE_SEQUENCER_400 0x3190
+#define WM8996_WRITE_SEQUENCER_401 0x3191
+#define WM8996_WRITE_SEQUENCER_402 0x3192
+#define WM8996_WRITE_SEQUENCER_403 0x3193
+#define WM8996_WRITE_SEQUENCER_404 0x3194
+#define WM8996_WRITE_SEQUENCER_405 0x3195
+#define WM8996_WRITE_SEQUENCER_406 0x3196
+#define WM8996_WRITE_SEQUENCER_407 0x3197
+#define WM8996_WRITE_SEQUENCER_408 0x3198
+#define WM8996_WRITE_SEQUENCER_409 0x3199
+#define WM8996_WRITE_SEQUENCER_410 0x319A
+#define WM8996_WRITE_SEQUENCER_411 0x319B
+#define WM8996_WRITE_SEQUENCER_412 0x319C
+#define WM8996_WRITE_SEQUENCER_413 0x319D
+#define WM8996_WRITE_SEQUENCER_414 0x319E
+#define WM8996_WRITE_SEQUENCER_415 0x319F
+#define WM8996_WRITE_SEQUENCER_416 0x31A0
+#define WM8996_WRITE_SEQUENCER_417 0x31A1
+#define WM8996_WRITE_SEQUENCER_418 0x31A2
+#define WM8996_WRITE_SEQUENCER_419 0x31A3
+#define WM8996_WRITE_SEQUENCER_420 0x31A4
+#define WM8996_WRITE_SEQUENCER_421 0x31A5
+#define WM8996_WRITE_SEQUENCER_422 0x31A6
+#define WM8996_WRITE_SEQUENCER_423 0x31A7
+#define WM8996_WRITE_SEQUENCER_424 0x31A8
+#define WM8996_WRITE_SEQUENCER_425 0x31A9
+#define WM8996_WRITE_SEQUENCER_426 0x31AA
+#define WM8996_WRITE_SEQUENCER_427 0x31AB
+#define WM8996_WRITE_SEQUENCER_428 0x31AC
+#define WM8996_WRITE_SEQUENCER_429 0x31AD
+#define WM8996_WRITE_SEQUENCER_430 0x31AE
+#define WM8996_WRITE_SEQUENCER_431 0x31AF
+#define WM8996_WRITE_SEQUENCER_432 0x31B0
+#define WM8996_WRITE_SEQUENCER_433 0x31B1
+#define WM8996_WRITE_SEQUENCER_434 0x31B2
+#define WM8996_WRITE_SEQUENCER_435 0x31B3
+#define WM8996_WRITE_SEQUENCER_436 0x31B4
+#define WM8996_WRITE_SEQUENCER_437 0x31B5
+#define WM8996_WRITE_SEQUENCER_438 0x31B6
+#define WM8996_WRITE_SEQUENCER_439 0x31B7
+#define WM8996_WRITE_SEQUENCER_440 0x31B8
+#define WM8996_WRITE_SEQUENCER_441 0x31B9
+#define WM8996_WRITE_SEQUENCER_442 0x31BA
+#define WM8996_WRITE_SEQUENCER_443 0x31BB
+#define WM8996_WRITE_SEQUENCER_444 0x31BC
+#define WM8996_WRITE_SEQUENCER_445 0x31BD
+#define WM8996_WRITE_SEQUENCER_446 0x31BE
+#define WM8996_WRITE_SEQUENCER_447 0x31BF
+#define WM8996_WRITE_SEQUENCER_448 0x31C0
+#define WM8996_WRITE_SEQUENCER_449 0x31C1
+#define WM8996_WRITE_SEQUENCER_450 0x31C2
+#define WM8996_WRITE_SEQUENCER_451 0x31C3
+#define WM8996_WRITE_SEQUENCER_452 0x31C4
+#define WM8996_WRITE_SEQUENCER_453 0x31C5
+#define WM8996_WRITE_SEQUENCER_454 0x31C6
+#define WM8996_WRITE_SEQUENCER_455 0x31C7
+#define WM8996_WRITE_SEQUENCER_456 0x31C8
+#define WM8996_WRITE_SEQUENCER_457 0x31C9
+#define WM8996_WRITE_SEQUENCER_458 0x31CA
+#define WM8996_WRITE_SEQUENCER_459 0x31CB
+#define WM8996_WRITE_SEQUENCER_460 0x31CC
+#define WM8996_WRITE_SEQUENCER_461 0x31CD
+#define WM8996_WRITE_SEQUENCER_462 0x31CE
+#define WM8996_WRITE_SEQUENCER_463 0x31CF
+#define WM8996_WRITE_SEQUENCER_464 0x31D0
+#define WM8996_WRITE_SEQUENCER_465 0x31D1
+#define WM8996_WRITE_SEQUENCER_466 0x31D2
+#define WM8996_WRITE_SEQUENCER_467 0x31D3
+#define WM8996_WRITE_SEQUENCER_468 0x31D4
+#define WM8996_WRITE_SEQUENCER_469 0x31D5
+#define WM8996_WRITE_SEQUENCER_470 0x31D6
+#define WM8996_WRITE_SEQUENCER_471 0x31D7
+#define WM8996_WRITE_SEQUENCER_472 0x31D8
+#define WM8996_WRITE_SEQUENCER_473 0x31D9
+#define WM8996_WRITE_SEQUENCER_474 0x31DA
+#define WM8996_WRITE_SEQUENCER_475 0x31DB
+#define WM8996_WRITE_SEQUENCER_476 0x31DC
+#define WM8996_WRITE_SEQUENCER_477 0x31DD
+#define WM8996_WRITE_SEQUENCER_478 0x31DE
+#define WM8996_WRITE_SEQUENCER_479 0x31DF
+#define WM8996_WRITE_SEQUENCER_480 0x31E0
+#define WM8996_WRITE_SEQUENCER_481 0x31E1
+#define WM8996_WRITE_SEQUENCER_482 0x31E2
+#define WM8996_WRITE_SEQUENCER_483 0x31E3
+#define WM8996_WRITE_SEQUENCER_484 0x31E4
+#define WM8996_WRITE_SEQUENCER_485 0x31E5
+#define WM8996_WRITE_SEQUENCER_486 0x31E6
+#define WM8996_WRITE_SEQUENCER_487 0x31E7
+#define WM8996_WRITE_SEQUENCER_488 0x31E8
+#define WM8996_WRITE_SEQUENCER_489 0x31E9
+#define WM8996_WRITE_SEQUENCER_490 0x31EA
+#define WM8996_WRITE_SEQUENCER_491 0x31EB
+#define WM8996_WRITE_SEQUENCER_492 0x31EC
+#define WM8996_WRITE_SEQUENCER_493 0x31ED
+#define WM8996_WRITE_SEQUENCER_494 0x31EE
+#define WM8996_WRITE_SEQUENCER_495 0x31EF
+#define WM8996_WRITE_SEQUENCER_496 0x31F0
+#define WM8996_WRITE_SEQUENCER_497 0x31F1
+#define WM8996_WRITE_SEQUENCER_498 0x31F2
+#define WM8996_WRITE_SEQUENCER_499 0x31F3
+#define WM8996_WRITE_SEQUENCER_500 0x31F4
+#define WM8996_WRITE_SEQUENCER_501 0x31F5
+#define WM8996_WRITE_SEQUENCER_502 0x31F6
+#define WM8996_WRITE_SEQUENCER_503 0x31F7
+#define WM8996_WRITE_SEQUENCER_504 0x31F8
+#define WM8996_WRITE_SEQUENCER_505 0x31F9
+#define WM8996_WRITE_SEQUENCER_506 0x31FA
+#define WM8996_WRITE_SEQUENCER_507 0x31FB
+#define WM8996_WRITE_SEQUENCER_508 0x31FC
+#define WM8996_WRITE_SEQUENCER_509 0x31FD
+#define WM8996_WRITE_SEQUENCER_510 0x31FE
+#define WM8996_WRITE_SEQUENCER_511 0x31FF
+
+#define WM8996_REGISTER_COUNT 706
+#define WM8996_MAX_REGISTER 0x31FF
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - Software Reset
+ */
+#define WM8996_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
+#define WM8996_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
+#define WM8996_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
+
+/*
+ * R1 (0x01) - Power Management (1)
+ */
+#define WM8996_MICB2_ENA 0x0200 /* MICB2_ENA */
+#define WM8996_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
+#define WM8996_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
+#define WM8996_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
+#define WM8996_MICB1_ENA 0x0100 /* MICB1_ENA */
+#define WM8996_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
+#define WM8996_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
+#define WM8996_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
+#define WM8996_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
+#define WM8996_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
+#define WM8996_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
+#define WM8996_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
+#define WM8996_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
+#define WM8996_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
+#define WM8996_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
+#define WM8996_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
+#define WM8996_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
+#define WM8996_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
+#define WM8996_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
+#define WM8996_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
+#define WM8996_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
+#define WM8996_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
+#define WM8996_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
+#define WM8996_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
+#define WM8996_BG_ENA 0x0001 /* BG_ENA */
+#define WM8996_BG_ENA_MASK 0x0001 /* BG_ENA */
+#define WM8996_BG_ENA_SHIFT 0 /* BG_ENA */
+#define WM8996_BG_ENA_WIDTH 1 /* BG_ENA */
+
+/*
+ * R2 (0x02) - Power Management (2)
+ */
+#define WM8996_OPCLK_ENA 0x0800 /* OPCLK_ENA */
+#define WM8996_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
+#define WM8996_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
+#define WM8996_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
+#define WM8996_INL_ENA 0x0020 /* INL_ENA */
+#define WM8996_INL_ENA_MASK 0x0020 /* INL_ENA */
+#define WM8996_INL_ENA_SHIFT 5 /* INL_ENA */
+#define WM8996_INL_ENA_WIDTH 1 /* INL_ENA */
+#define WM8996_INR_ENA 0x0010 /* INR_ENA */
+#define WM8996_INR_ENA_MASK 0x0010 /* INR_ENA */
+#define WM8996_INR_ENA_SHIFT 4 /* INR_ENA */
+#define WM8996_INR_ENA_WIDTH 1 /* INR_ENA */
+#define WM8996_LDO2_ENA 0x0002 /* LDO2_ENA */
+#define WM8996_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
+#define WM8996_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
+#define WM8996_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
+
+/*
+ * R3 (0x03) - Power Management (3)
+ */
+#define WM8996_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
+#define WM8996_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
+#define WM8996_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
+#define WM8996_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
+#define WM8996_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
+#define WM8996_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
+#define WM8996_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
+#define WM8996_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
+#define WM8996_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
+#define WM8996_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
+#define WM8996_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
+#define WM8996_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
+#define WM8996_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
+#define WM8996_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
+#define WM8996_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
+#define WM8996_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
+#define WM8996_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
+#define WM8996_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
+#define WM8996_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
+#define WM8996_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
+#define WM8996_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
+#define WM8996_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
+#define WM8996_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
+#define WM8996_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
+#define WM8996_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
+#define WM8996_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
+#define WM8996_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
+#define WM8996_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
+#define WM8996_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
+#define WM8996_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
+#define WM8996_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
+#define WM8996_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
+#define WM8996_ADCL_ENA 0x0002 /* ADCL_ENA */
+#define WM8996_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
+#define WM8996_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
+#define WM8996_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
+#define WM8996_ADCR_ENA 0x0001 /* ADCR_ENA */
+#define WM8996_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
+#define WM8996_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
+#define WM8996_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
+
+/*
+ * R4 (0x04) - Power Management (4)
+ */
+#define WM8996_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
+#define WM8996_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
+#define WM8996_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
+#define WM8996_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
+#define WM8996_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
+#define WM8996_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
+#define WM8996_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
+#define WM8996_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
+#define WM8996_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
+#define WM8996_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
+#define WM8996_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
+#define WM8996_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
+#define WM8996_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
+#define WM8996_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
+#define WM8996_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
+#define WM8996_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
+#define WM8996_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
+#define WM8996_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
+#define WM8996_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
+#define WM8996_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
+#define WM8996_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
+#define WM8996_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
+#define WM8996_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
+#define WM8996_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
+#define WM8996_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
+#define WM8996_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
+#define WM8996_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
+#define WM8996_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
+#define WM8996_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
+#define WM8996_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
+#define WM8996_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
+#define WM8996_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
+
+/*
+ * R5 (0x05) - Power Management (5)
+ */
+#define WM8996_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
+#define WM8996_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
+#define WM8996_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
+#define WM8996_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
+#define WM8996_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
+#define WM8996_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
+#define WM8996_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
+#define WM8996_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
+#define WM8996_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
+#define WM8996_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
+#define WM8996_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
+#define WM8996_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
+#define WM8996_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
+#define WM8996_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
+#define WM8996_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
+#define WM8996_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
+#define WM8996_DAC2L_ENA 0x0008 /* DAC2L_ENA */
+#define WM8996_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
+#define WM8996_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
+#define WM8996_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
+#define WM8996_DAC2R_ENA 0x0004 /* DAC2R_ENA */
+#define WM8996_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
+#define WM8996_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
+#define WM8996_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
+#define WM8996_DAC1L_ENA 0x0002 /* DAC1L_ENA */
+#define WM8996_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
+#define WM8996_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
+#define WM8996_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
+#define WM8996_DAC1R_ENA 0x0001 /* DAC1R_ENA */
+#define WM8996_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
+#define WM8996_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
+#define WM8996_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
+
+/*
+ * R6 (0x06) - Power Management (6)
+ */
+#define WM8996_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
+#define WM8996_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
+#define WM8996_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
+#define WM8996_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
+#define WM8996_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
+#define WM8996_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
+#define WM8996_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
+#define WM8996_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
+#define WM8996_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
+#define WM8996_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
+#define WM8996_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
+#define WM8996_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
+#define WM8996_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
+#define WM8996_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
+#define WM8996_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
+#define WM8996_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
+#define WM8996_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
+#define WM8996_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
+#define WM8996_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
+#define WM8996_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
+#define WM8996_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
+#define WM8996_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
+#define WM8996_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
+#define WM8996_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
+#define WM8996_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
+#define WM8996_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
+#define WM8996_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
+#define WM8996_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
+#define WM8996_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
+#define WM8996_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
+#define WM8996_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
+#define WM8996_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
+
+/*
+ * R7 (0x07) - Power Management (7)
+ */
+#define WM8996_DMIC2_FN 0x0200 /* DMIC2_FN */
+#define WM8996_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
+#define WM8996_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
+#define WM8996_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
+#define WM8996_DMIC1_FN 0x0100 /* DMIC1_FN */
+#define WM8996_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
+#define WM8996_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
+#define WM8996_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
+#define WM8996_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
+#define WM8996_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
+#define WM8996_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
+#define WM8996_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
+#define WM8996_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
+#define WM8996_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
+#define WM8996_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
+#define WM8996_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
+#define WM8996_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
+#define WM8996_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
+#define WM8996_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
+#define WM8996_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
+#define WM8996_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
+#define WM8996_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
+#define WM8996_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
+#define WM8996_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
+#define WM8996_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
+#define WM8996_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
+#define WM8996_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
+#define WM8996_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
+#define WM8996_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
+#define WM8996_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
+
+/*
+ * R8 (0x08) - Power Management (8)
+ */
+#define WM8996_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
+#define WM8996_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
+#define WM8996_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
+#define WM8996_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
+#define WM8996_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
+#define WM8996_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
+#define WM8996_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
+#define WM8996_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
+#define WM8996_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
+#define WM8996_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
+#define WM8996_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
+
+/*
+ * R16 (0x10) - Left Line Input Volume
+ */
+#define WM8996_IN1_VU 0x0080 /* IN1_VU */
+#define WM8996_IN1_VU_MASK 0x0080 /* IN1_VU */
+#define WM8996_IN1_VU_SHIFT 7 /* IN1_VU */
+#define WM8996_IN1_VU_WIDTH 1 /* IN1_VU */
+#define WM8996_IN1L_ZC 0x0020 /* IN1L_ZC */
+#define WM8996_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
+#define WM8996_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
+#define WM8996_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
+#define WM8996_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
+#define WM8996_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
+#define WM8996_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
+
+/*
+ * R17 (0x11) - Right Line Input Volume
+ */
+#define WM8996_IN1_VU 0x0080 /* IN1_VU */
+#define WM8996_IN1_VU_MASK 0x0080 /* IN1_VU */
+#define WM8996_IN1_VU_SHIFT 7 /* IN1_VU */
+#define WM8996_IN1_VU_WIDTH 1 /* IN1_VU */
+#define WM8996_IN1R_ZC 0x0020 /* IN1R_ZC */
+#define WM8996_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
+#define WM8996_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
+#define WM8996_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
+#define WM8996_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
+#define WM8996_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
+#define WM8996_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
+
+/*
+ * R18 (0x12) - Line Input Control
+ */
+#define WM8996_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
+#define WM8996_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
+#define WM8996_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
+#define WM8996_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
+#define WM8996_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
+#define WM8996_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
+
+/*
+ * R21 (0x15) - DAC1 HPOUT1 Volume
+ */
+#define WM8996_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
+#define WM8996_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
+#define WM8996_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
+#define WM8996_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
+#define WM8996_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
+#define WM8996_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
+
+/*
+ * R22 (0x16) - DAC2 HPOUT2 Volume
+ */
+#define WM8996_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
+#define WM8996_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
+#define WM8996_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
+#define WM8996_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
+#define WM8996_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
+#define WM8996_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
+
+/*
+ * R24 (0x18) - DAC1 Left Volume
+ */
+#define WM8996_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
+#define WM8996_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
+#define WM8996_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
+#define WM8996_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
+#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8996_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
+#define WM8996_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
+#define WM8996_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
+
+/*
+ * R25 (0x19) - DAC1 Right Volume
+ */
+#define WM8996_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
+#define WM8996_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
+#define WM8996_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
+#define WM8996_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
+#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8996_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
+#define WM8996_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
+#define WM8996_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
+
+/*
+ * R26 (0x1A) - DAC2 Left Volume
+ */
+#define WM8996_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
+#define WM8996_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
+#define WM8996_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
+#define WM8996_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
+#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8996_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
+#define WM8996_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
+#define WM8996_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
+
+/*
+ * R27 (0x1B) - DAC2 Right Volume
+ */
+#define WM8996_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
+#define WM8996_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
+#define WM8996_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
+#define WM8996_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
+#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8996_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
+#define WM8996_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
+#define WM8996_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
+
+/*
+ * R28 (0x1C) - Output1 Left Volume
+ */
+#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8996_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
+#define WM8996_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
+#define WM8996_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
+#define WM8996_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
+#define WM8996_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
+#define WM8996_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
+#define WM8996_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
+
+/*
+ * R29 (0x1D) - Output1 Right Volume
+ */
+#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8996_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
+#define WM8996_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
+#define WM8996_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
+#define WM8996_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
+#define WM8996_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
+#define WM8996_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
+#define WM8996_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
+
+/*
+ * R30 (0x1E) - Output2 Left Volume
+ */
+#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8996_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
+#define WM8996_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
+#define WM8996_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
+#define WM8996_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
+#define WM8996_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
+#define WM8996_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
+#define WM8996_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
+
+/*
+ * R31 (0x1F) - Output2 Right Volume
+ */
+#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8996_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
+#define WM8996_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
+#define WM8996_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
+#define WM8996_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
+#define WM8996_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
+#define WM8996_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
+#define WM8996_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
+
+/*
+ * R32 (0x20) - MICBIAS (1)
+ */
+#define WM8996_MICB1_RATE 0x0020 /* MICB1_RATE */
+#define WM8996_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
+#define WM8996_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
+#define WM8996_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
+#define WM8996_MICB1_MODE 0x0010 /* MICB1_MODE */
+#define WM8996_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
+#define WM8996_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
+#define WM8996_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
+#define WM8996_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
+#define WM8996_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
+#define WM8996_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
+#define WM8996_MICB1_DISCH 0x0001 /* MICB1_DISCH */
+#define WM8996_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
+#define WM8996_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
+#define WM8996_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
+
+/*
+ * R33 (0x21) - MICBIAS (2)
+ */
+#define WM8996_MICB2_RATE 0x0020 /* MICB2_RATE */
+#define WM8996_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
+#define WM8996_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
+#define WM8996_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
+#define WM8996_MICB2_MODE 0x0010 /* MICB2_MODE */
+#define WM8996_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
+#define WM8996_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
+#define WM8996_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
+#define WM8996_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
+#define WM8996_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
+#define WM8996_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
+#define WM8996_MICB2_DISCH 0x0001 /* MICB2_DISCH */
+#define WM8996_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
+#define WM8996_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
+#define WM8996_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
+
+/*
+ * R40 (0x28) - LDO 1
+ */
+#define WM8996_LDO1_MODE 0x0020 /* LDO1_MODE */
+#define WM8996_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
+#define WM8996_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
+#define WM8996_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
+#define WM8996_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
+#define WM8996_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
+#define WM8996_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
+#define WM8996_LDO1_DISCH 0x0001 /* LDO1_DISCH */
+#define WM8996_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
+#define WM8996_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
+#define WM8996_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
+
+/*
+ * R41 (0x29) - LDO 2
+ */
+#define WM8996_LDO2_MODE 0x0020 /* LDO2_MODE */
+#define WM8996_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
+#define WM8996_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
+#define WM8996_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
+#define WM8996_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
+#define WM8996_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
+#define WM8996_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
+#define WM8996_LDO2_DISCH 0x0001 /* LDO2_DISCH */
+#define WM8996_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
+#define WM8996_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
+#define WM8996_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
+
+/*
+ * R48 (0x30) - Accessory Detect Mode 1
+ */
+#define WM8996_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
+#define WM8996_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
+#define WM8996_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
+
+/*
+ * R49 (0x31) - Accessory Detect Mode 2
+ */
+#define WM8996_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
+#define WM8996_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
+#define WM8996_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
+#define WM8996_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
+#define WM8996_MICD_SRC 0x0002 /* MICD_SRC */
+#define WM8996_MICD_SRC_MASK 0x0002 /* MICD_SRC */
+#define WM8996_MICD_SRC_SHIFT 1 /* MICD_SRC */
+#define WM8996_MICD_SRC_WIDTH 1 /* MICD_SRC */
+#define WM8996_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
+#define WM8996_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
+#define WM8996_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
+#define WM8996_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
+
+/*
+ * R52 (0x34) - Headphone Detect 1
+ */
+#define WM8996_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
+#define WM8996_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
+#define WM8996_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
+#define WM8996_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
+#define WM8996_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
+#define WM8996_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
+#define WM8996_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
+#define WM8996_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
+#define WM8996_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
+#define WM8996_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
+#define WM8996_HP_POLL 0x0001 /* HP_POLL */
+#define WM8996_HP_POLL_MASK 0x0001 /* HP_POLL */
+#define WM8996_HP_POLL_SHIFT 0 /* HP_POLL */
+#define WM8996_HP_POLL_WIDTH 1 /* HP_POLL */
+
+/*
+ * R53 (0x35) - Headphone Detect 2
+ */
+#define WM8996_HP_DONE 0x0080 /* HP_DONE */
+#define WM8996_HP_DONE_MASK 0x0080 /* HP_DONE */
+#define WM8996_HP_DONE_SHIFT 7 /* HP_DONE */
+#define WM8996_HP_DONE_WIDTH 1 /* HP_DONE */
+#define WM8996_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
+#define WM8996_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
+#define WM8996_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
+
+/*
+ * R56 (0x38) - Mic Detect 1
+ */
+#define WM8996_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8996_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8996_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
+#define WM8996_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
+#define WM8996_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
+#define WM8996_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
+#define WM8996_MICD_DBTIME 0x0002 /* MICD_DBTIME */
+#define WM8996_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
+#define WM8996_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
+#define WM8996_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
+#define WM8996_MICD_ENA 0x0001 /* MICD_ENA */
+#define WM8996_MICD_ENA_MASK 0x0001 /* MICD_ENA */
+#define WM8996_MICD_ENA_SHIFT 0 /* MICD_ENA */
+#define WM8996_MICD_ENA_WIDTH 1 /* MICD_ENA */
+
+/*
+ * R57 (0x39) - Mic Detect 2
+ */
+#define WM8996_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
+#define WM8996_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
+#define WM8996_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
+
+/*
+ * R58 (0x3A) - Mic Detect 3
+ */
+#define WM8996_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
+#define WM8996_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
+#define WM8996_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
+#define WM8996_MICD_VALID 0x0002 /* MICD_VALID */
+#define WM8996_MICD_VALID_MASK 0x0002 /* MICD_VALID */
+#define WM8996_MICD_VALID_SHIFT 1 /* MICD_VALID */
+#define WM8996_MICD_VALID_WIDTH 1 /* MICD_VALID */
+#define WM8996_MICD_STS 0x0001 /* MICD_STS */
+#define WM8996_MICD_STS_MASK 0x0001 /* MICD_STS */
+#define WM8996_MICD_STS_SHIFT 0 /* MICD_STS */
+#define WM8996_MICD_STS_WIDTH 1 /* MICD_STS */
+
+/*
+ * R64 (0x40) - Charge Pump (1)
+ */
+#define WM8996_CP_ENA 0x8000 /* CP_ENA */
+#define WM8996_CP_ENA_MASK 0x8000 /* CP_ENA */
+#define WM8996_CP_ENA_SHIFT 15 /* CP_ENA */
+#define WM8996_CP_ENA_WIDTH 1 /* CP_ENA */
+
+/*
+ * R65 (0x41) - Charge Pump (2)
+ */
+#define WM8996_CP_DISCH 0x8000 /* CP_DISCH */
+#define WM8996_CP_DISCH_MASK 0x8000 /* CP_DISCH */
+#define WM8996_CP_DISCH_SHIFT 15 /* CP_DISCH */
+#define WM8996_CP_DISCH_WIDTH 1 /* CP_DISCH */
+
+/*
+ * R80 (0x50) - DC Servo (1)
+ */
+#define WM8996_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
+#define WM8996_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
+#define WM8996_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
+#define WM8996_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
+#define WM8996_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
+#define WM8996_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
+#define WM8996_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
+#define WM8996_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
+#define WM8996_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8996_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8996_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
+#define WM8996_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
+#define WM8996_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8996_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8996_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
+#define WM8996_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
+
+/*
+ * R81 (0x51) - DC Servo (2)
+ */
+#define WM8996_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
+#define WM8996_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
+#define WM8996_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
+#define WM8996_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
+#define WM8996_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
+#define WM8996_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
+#define WM8996_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
+#define WM8996_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
+#define WM8996_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8996_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8996_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
+#define WM8996_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
+#define WM8996_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8996_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8996_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
+#define WM8996_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
+#define WM8996_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
+#define WM8996_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
+#define WM8996_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
+#define WM8996_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
+#define WM8996_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
+#define WM8996_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
+#define WM8996_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
+#define WM8996_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
+#define WM8996_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8996_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8996_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
+#define WM8996_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
+#define WM8996_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8996_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8996_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
+#define WM8996_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
+#define WM8996_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
+#define WM8996_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
+#define WM8996_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
+#define WM8996_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
+#define WM8996_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
+#define WM8996_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
+#define WM8996_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
+#define WM8996_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
+#define WM8996_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8996_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8996_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
+#define WM8996_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
+#define WM8996_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8996_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8996_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
+#define WM8996_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
+#define WM8996_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
+#define WM8996_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
+#define WM8996_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
+#define WM8996_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
+#define WM8996_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
+#define WM8996_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
+#define WM8996_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
+#define WM8996_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
+#define WM8996_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
+#define WM8996_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
+#define WM8996_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
+#define WM8996_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
+#define WM8996_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
+#define WM8996_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
+#define WM8996_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
+#define WM8996_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
+
+/*
+ * R82 (0x52) - DC Servo (3)
+ */
+#define WM8996_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
+#define WM8996_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
+#define WM8996_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
+#define WM8996_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8996_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8996_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
+
+/*
+ * R84 (0x54) - DC Servo (5)
+ */
+#define WM8996_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
+#define WM8996_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
+#define WM8996_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
+#define WM8996_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
+#define WM8996_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
+#define WM8996_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
+
+/*
+ * R85 (0x55) - DC Servo (6)
+ */
+#define WM8996_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
+#define WM8996_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
+#define WM8996_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
+#define WM8996_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
+#define WM8996_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
+#define WM8996_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
+
+/*
+ * R86 (0x56) - DC Servo (7)
+ */
+#define WM8996_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8996_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8996_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8996_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8996_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8996_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
+
+/*
+ * R87 (0x57) - DC Servo Readback 0
+ */
+#define WM8996_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
+#define WM8996_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
+#define WM8996_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
+#define WM8996_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
+#define WM8996_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
+#define WM8996_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
+#define WM8996_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
+#define WM8996_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
+#define WM8996_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
+
+/*
+ * R96 (0x60) - Analogue HP (1)
+ */
+#define WM8996_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8996_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8996_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
+#define WM8996_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
+#define WM8996_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
+#define WM8996_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
+#define WM8996_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
+#define WM8996_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
+#define WM8996_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
+#define WM8996_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
+#define WM8996_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
+#define WM8996_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
+#define WM8996_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8996_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8996_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
+#define WM8996_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
+#define WM8996_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
+#define WM8996_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
+#define WM8996_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
+#define WM8996_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
+#define WM8996_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
+#define WM8996_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
+#define WM8996_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
+#define WM8996_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
+
+/*
+ * R97 (0x61) - Analogue HP (2)
+ */
+#define WM8996_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
+#define WM8996_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
+#define WM8996_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
+#define WM8996_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
+#define WM8996_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
+#define WM8996_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
+#define WM8996_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
+#define WM8996_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
+#define WM8996_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
+#define WM8996_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
+#define WM8996_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
+#define WM8996_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
+#define WM8996_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
+#define WM8996_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
+#define WM8996_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
+#define WM8996_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
+#define WM8996_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
+#define WM8996_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
+#define WM8996_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
+#define WM8996_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
+#define WM8996_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
+#define WM8996_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
+#define WM8996_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
+#define WM8996_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
+
+/*
+ * R256 (0x100) - Chip Revision
+ */
+#define WM8996_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
+#define WM8996_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
+#define WM8996_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
+
+/*
+ * R257 (0x101) - Control Interface (1)
+ */
+#define WM8996_AUTO_INC 0x0004 /* AUTO_INC */
+#define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */
+#define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */
+#define WM8996_AUTO_INC_WIDTH 1 /* AUTO_INC */
+
+/*
+ * R272 (0x110) - Write Sequencer Ctrl (1)
+ */
+#define WM8996_WSEQ_ENA 0x8000 /* WSEQ_ENA */
+#define WM8996_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
+#define WM8996_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
+#define WM8996_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
+#define WM8996_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
+#define WM8996_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
+#define WM8996_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
+#define WM8996_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
+#define WM8996_WSEQ_START 0x0100 /* WSEQ_START */
+#define WM8996_WSEQ_START_MASK 0x0100 /* WSEQ_START */
+#define WM8996_WSEQ_START_SHIFT 8 /* WSEQ_START */
+#define WM8996_WSEQ_START_WIDTH 1 /* WSEQ_START */
+#define WM8996_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
+#define WM8996_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
+#define WM8996_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
+
+/*
+ * R273 (0x111) - Write Sequencer Ctrl (2)
+ */
+#define WM8996_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
+#define WM8996_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
+#define WM8996_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
+#define WM8996_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
+#define WM8996_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8996_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8996_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
+
+/*
+ * R512 (0x200) - AIF Clocking (1)
+ */
+#define WM8996_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
+#define WM8996_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
+#define WM8996_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
+#define WM8996_SYSCLK_INV 0x0004 /* SYSCLK_INV */
+#define WM8996_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
+#define WM8996_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
+#define WM8996_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
+#define WM8996_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
+#define WM8996_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
+#define WM8996_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
+#define WM8996_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
+#define WM8996_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
+#define WM8996_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
+#define WM8996_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
+#define WM8996_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
+
+/*
+ * R513 (0x201) - AIF Clocking (2)
+ */
+#define WM8996_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
+#define WM8996_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
+#define WM8996_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
+#define WM8996_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
+#define WM8996_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
+#define WM8996_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
+
+/*
+ * R520 (0x208) - Clocking (1)
+ */
+#define WM8996_LFCLK_ENA 0x0020 /* LFCLK_ENA */
+#define WM8996_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
+#define WM8996_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
+#define WM8996_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
+#define WM8996_TOCLK_ENA 0x0010 /* TOCLK_ENA */
+#define WM8996_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
+#define WM8996_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
+#define WM8996_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
+#define WM8996_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
+#define WM8996_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
+#define WM8996_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
+#define WM8996_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
+#define WM8996_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
+#define WM8996_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
+#define WM8996_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
+#define WM8996_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
+
+/*
+ * R521 (0x209) - Clocking (2)
+ */
+#define WM8996_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
+#define WM8996_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
+#define WM8996_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
+#define WM8996_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
+#define WM8996_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
+#define WM8996_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
+#define WM8996_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
+#define WM8996_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
+#define WM8996_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
+
+/*
+ * R528 (0x210) - AIF Rate
+ */
+#define WM8996_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
+#define WM8996_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
+#define WM8996_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
+#define WM8996_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
+
+/*
+ * R544 (0x220) - FLL Control (1)
+ */
+#define WM8996_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
+#define WM8996_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
+#define WM8996_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
+#define WM8996_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
+#define WM8996_FLL_ENA 0x0001 /* FLL_ENA */
+#define WM8996_FLL_ENA_MASK 0x0001 /* FLL_ENA */
+#define WM8996_FLL_ENA_SHIFT 0 /* FLL_ENA */
+#define WM8996_FLL_ENA_WIDTH 1 /* FLL_ENA */
+
+/*
+ * R545 (0x221) - FLL Control (2)
+ */
+#define WM8996_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
+#define WM8996_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
+#define WM8996_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
+#define WM8996_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
+#define WM8996_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
+#define WM8996_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
+
+/*
+ * R546 (0x222) - FLL Control (3)
+ */
+#define WM8996_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
+#define WM8996_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
+#define WM8996_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
+
+/*
+ * R547 (0x223) - FLL Control (4)
+ */
+#define WM8996_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
+#define WM8996_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
+#define WM8996_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
+#define WM8996_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
+#define WM8996_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
+#define WM8996_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
+
+/*
+ * R548 (0x224) - FLL Control (5)
+ */
+#define WM8996_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
+#define WM8996_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
+#define WM8996_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
+#define WM8996_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
+#define WM8996_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
+#define WM8996_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
+#define WM8996_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
+#define WM8996_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
+#define WM8996_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
+#define WM8996_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
+#define WM8996_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
+#define WM8996_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
+#define WM8996_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
+#define WM8996_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
+#define WM8996_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
+#define WM8996_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
+#define WM8996_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
+
+/*
+ * R549 (0x225) - FLL Control (6)
+ */
+#define WM8996_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
+#define WM8996_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
+#define WM8996_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
+#define WM8996_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
+#define WM8996_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
+#define WM8996_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
+#define WM8996_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
+
+/*
+ * R550 (0x226) - FLL EFS 1
+ */
+#define WM8996_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
+#define WM8996_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
+#define WM8996_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
+
+/*
+ * R551 (0x227) - FLL EFS 2
+ */
+#define WM8996_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
+#define WM8996_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
+#define WM8996_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
+#define WM8996_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
+#define WM8996_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
+#define WM8996_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
+#define WM8996_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
+
+/*
+ * R768 (0x300) - AIF1 Control
+ */
+#define WM8996_AIF1_TRI 0x0004 /* AIF1_TRI */
+#define WM8996_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
+#define WM8996_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
+#define WM8996_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
+#define WM8996_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
+#define WM8996_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
+#define WM8996_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
+
+/*
+ * R769 (0x301) - AIF1 BCLK
+ */
+#define WM8996_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
+#define WM8996_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
+#define WM8996_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
+#define WM8996_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
+#define WM8996_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
+#define WM8996_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
+#define WM8996_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
+#define WM8996_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
+#define WM8996_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
+#define WM8996_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
+#define WM8996_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
+#define WM8996_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
+#define WM8996_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
+#define WM8996_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
+#define WM8996_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
+
+/*
+ * R770 (0x302) - AIF1 TX LRCLK(1)
+ */
+#define WM8996_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
+#define WM8996_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
+#define WM8996_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
+
+/*
+ * R771 (0x303) - AIF1 TX LRCLK(2)
+ */
+#define WM8996_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
+#define WM8996_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
+#define WM8996_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
+#define WM8996_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
+#define WM8996_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
+#define WM8996_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
+#define WM8996_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
+#define WM8996_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
+#define WM8996_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
+#define WM8996_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
+#define WM8996_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
+#define WM8996_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
+#define WM8996_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
+#define WM8996_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
+#define WM8996_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
+#define WM8996_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
+
+/*
+ * R772 (0x304) - AIF1 RX LRCLK(1)
+ */
+#define WM8996_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
+#define WM8996_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
+#define WM8996_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
+
+/*
+ * R773 (0x305) - AIF1 RX LRCLK(2)
+ */
+#define WM8996_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
+#define WM8996_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
+#define WM8996_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
+#define WM8996_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
+#define WM8996_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
+#define WM8996_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
+#define WM8996_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
+#define WM8996_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
+#define WM8996_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
+#define WM8996_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
+#define WM8996_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
+#define WM8996_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
+
+/*
+ * R774 (0x306) - AIF1TX Data Configuration (1)
+ */
+#define WM8996_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
+#define WM8996_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
+#define WM8996_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
+#define WM8996_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
+#define WM8996_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
+#define WM8996_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
+
+/*
+ * R775 (0x307) - AIF1TX Data Configuration (2)
+ */
+#define WM8996_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
+#define WM8996_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
+#define WM8996_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
+#define WM8996_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
+
+/*
+ * R776 (0x308) - AIF1RX Data Configuration
+ */
+#define WM8996_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
+#define WM8996_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
+#define WM8996_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
+#define WM8996_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
+#define WM8996_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
+#define WM8996_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
+
+/*
+ * R777 (0x309) - AIF1TX Channel 0 Configuration
+ */
+#define WM8996_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
+#define WM8996_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
+#define WM8996_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
+#define WM8996_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
+#define WM8996_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
+
+/*
+ * R778 (0x30A) - AIF1TX Channel 1 Configuration
+ */
+#define WM8996_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
+#define WM8996_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
+#define WM8996_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
+#define WM8996_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
+#define WM8996_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
+
+/*
+ * R779 (0x30B) - AIF1TX Channel 2 Configuration
+ */
+#define WM8996_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
+#define WM8996_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
+#define WM8996_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
+#define WM8996_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
+#define WM8996_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
+
+/*
+ * R780 (0x30C) - AIF1TX Channel 3 Configuration
+ */
+#define WM8996_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
+#define WM8996_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
+#define WM8996_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
+#define WM8996_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
+#define WM8996_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
+
+/*
+ * R781 (0x30D) - AIF1TX Channel 4 Configuration
+ */
+#define WM8996_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
+#define WM8996_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
+#define WM8996_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
+#define WM8996_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
+#define WM8996_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
+
+/*
+ * R782 (0x30E) - AIF1TX Channel 5 Configuration
+ */
+#define WM8996_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
+#define WM8996_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
+#define WM8996_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
+#define WM8996_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
+#define WM8996_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
+#define WM8996_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
+#define WM8996_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
+#define WM8996_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
+
+/*
+ * R783 (0x30F) - AIF1RX Channel 0 Configuration
+ */
+#define WM8996_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
+#define WM8996_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
+#define WM8996_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
+#define WM8996_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
+#define WM8996_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
+
+/*
+ * R784 (0x310) - AIF1RX Channel 1 Configuration
+ */
+#define WM8996_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
+#define WM8996_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
+#define WM8996_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
+#define WM8996_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
+#define WM8996_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
+
+/*
+ * R785 (0x311) - AIF1RX Channel 2 Configuration
+ */
+#define WM8996_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
+#define WM8996_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
+#define WM8996_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
+#define WM8996_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
+#define WM8996_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
+
+/*
+ * R786 (0x312) - AIF1RX Channel 3 Configuration
+ */
+#define WM8996_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
+#define WM8996_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
+#define WM8996_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
+#define WM8996_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
+#define WM8996_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
+
+/*
+ * R787 (0x313) - AIF1RX Channel 4 Configuration
+ */
+#define WM8996_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
+#define WM8996_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
+#define WM8996_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
+#define WM8996_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
+#define WM8996_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
+
+/*
+ * R788 (0x314) - AIF1RX Channel 5 Configuration
+ */
+#define WM8996_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
+#define WM8996_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
+#define WM8996_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
+#define WM8996_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
+#define WM8996_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
+#define WM8996_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
+#define WM8996_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
+#define WM8996_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
+
+/*
+ * R789 (0x315) - AIF1RX Mono Configuration
+ */
+#define WM8996_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
+#define WM8996_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
+#define WM8996_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
+#define WM8996_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
+#define WM8996_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
+#define WM8996_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
+#define WM8996_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
+#define WM8996_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
+#define WM8996_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
+#define WM8996_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
+#define WM8996_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
+#define WM8996_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
+
+/*
+ * R794 (0x31A) - AIF1TX Test
+ */
+#define WM8996_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
+#define WM8996_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
+#define WM8996_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
+#define WM8996_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
+#define WM8996_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
+#define WM8996_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
+#define WM8996_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
+#define WM8996_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
+#define WM8996_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
+#define WM8996_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
+#define WM8996_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
+#define WM8996_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
+
+/*
+ * R800 (0x320) - AIF2 Control
+ */
+#define WM8996_AIF2_TRI 0x0004 /* AIF2_TRI */
+#define WM8996_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
+#define WM8996_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
+#define WM8996_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
+#define WM8996_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
+#define WM8996_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
+#define WM8996_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
+
+/*
+ * R801 (0x321) - AIF2 BCLK
+ */
+#define WM8996_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
+#define WM8996_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
+#define WM8996_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
+#define WM8996_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
+#define WM8996_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
+#define WM8996_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
+#define WM8996_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
+#define WM8996_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
+#define WM8996_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
+#define WM8996_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
+#define WM8996_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
+#define WM8996_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
+#define WM8996_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
+#define WM8996_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
+#define WM8996_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
+
+/*
+ * R802 (0x322) - AIF2 TX LRCLK(1)
+ */
+#define WM8996_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
+#define WM8996_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
+#define WM8996_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
+
+/*
+ * R803 (0x323) - AIF2 TX LRCLK(2)
+ */
+#define WM8996_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
+#define WM8996_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
+#define WM8996_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
+#define WM8996_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
+#define WM8996_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
+#define WM8996_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
+#define WM8996_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
+#define WM8996_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
+#define WM8996_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
+#define WM8996_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
+#define WM8996_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
+#define WM8996_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
+#define WM8996_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
+#define WM8996_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
+#define WM8996_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
+#define WM8996_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
+
+/*
+ * R804 (0x324) - AIF2 RX LRCLK(1)
+ */
+#define WM8996_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
+#define WM8996_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
+#define WM8996_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
+
+/*
+ * R805 (0x325) - AIF2 RX LRCLK(2)
+ */
+#define WM8996_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
+#define WM8996_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
+#define WM8996_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
+#define WM8996_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
+#define WM8996_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
+#define WM8996_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
+#define WM8996_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
+#define WM8996_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
+#define WM8996_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
+#define WM8996_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
+#define WM8996_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
+#define WM8996_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
+
+/*
+ * R806 (0x326) - AIF2TX Data Configuration (1)
+ */
+#define WM8996_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
+#define WM8996_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
+#define WM8996_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
+#define WM8996_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
+#define WM8996_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
+#define WM8996_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
+
+/*
+ * R807 (0x327) - AIF2TX Data Configuration (2)
+ */
+#define WM8996_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
+#define WM8996_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
+#define WM8996_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
+#define WM8996_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
+
+/*
+ * R808 (0x328) - AIF2RX Data Configuration
+ */
+#define WM8996_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
+#define WM8996_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
+#define WM8996_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
+#define WM8996_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
+#define WM8996_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
+#define WM8996_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
+
+/*
+ * R809 (0x329) - AIF2TX Channel 0 Configuration
+ */
+#define WM8996_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
+#define WM8996_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
+#define WM8996_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
+#define WM8996_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
+#define WM8996_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
+
+/*
+ * R810 (0x32A) - AIF2TX Channel 1 Configuration
+ */
+#define WM8996_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
+#define WM8996_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
+#define WM8996_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
+#define WM8996_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
+#define WM8996_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
+
+/*
+ * R811 (0x32B) - AIF2RX Channel 0 Configuration
+ */
+#define WM8996_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
+#define WM8996_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
+#define WM8996_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
+#define WM8996_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
+#define WM8996_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
+#define WM8996_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
+#define WM8996_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
+#define WM8996_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
+
+/*
+ * R812 (0x32C) - AIF2RX Channel 1 Configuration
+ */
+#define WM8996_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
+#define WM8996_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
+#define WM8996_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
+#define WM8996_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
+#define WM8996_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
+#define WM8996_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
+#define WM8996_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
+#define WM8996_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
+
+/*
+ * R813 (0x32D) - AIF2RX Mono Configuration
+ */
+#define WM8996_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
+#define WM8996_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
+#define WM8996_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
+#define WM8996_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
+
+/*
+ * R815 (0x32F) - AIF2TX Test
+ */
+#define WM8996_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
+#define WM8996_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
+#define WM8996_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
+#define WM8996_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
+
+/*
+ * R1024 (0x400) - DSP1 TX Left Volume
+ */
+#define WM8996_DSP1TX_VU 0x0100 /* DSP1TX_VU */
+#define WM8996_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
+#define WM8996_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
+#define WM8996_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
+#define WM8996_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
+#define WM8996_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
+#define WM8996_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
+
+/*
+ * R1025 (0x401) - DSP1 TX Right Volume
+ */
+#define WM8996_DSP1TX_VU 0x0100 /* DSP1TX_VU */
+#define WM8996_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
+#define WM8996_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
+#define WM8996_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
+#define WM8996_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
+#define WM8996_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
+#define WM8996_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
+
+/*
+ * R1026 (0x402) - DSP1 RX Left Volume
+ */
+#define WM8996_DSP1RX_VU 0x0100 /* DSP1RX_VU */
+#define WM8996_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
+#define WM8996_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
+#define WM8996_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
+#define WM8996_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
+#define WM8996_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
+#define WM8996_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
+
+/*
+ * R1027 (0x403) - DSP1 RX Right Volume
+ */
+#define WM8996_DSP1RX_VU 0x0100 /* DSP1RX_VU */
+#define WM8996_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
+#define WM8996_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
+#define WM8996_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
+#define WM8996_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
+#define WM8996_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
+#define WM8996_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
+
+/*
+ * R1040 (0x410) - DSP1 TX Filters
+ */
+#define WM8996_DSP1TX_NF 0x2000 /* DSP1TX_NF */
+#define WM8996_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
+#define WM8996_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
+#define WM8996_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
+#define WM8996_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
+#define WM8996_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
+#define WM8996_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
+#define WM8996_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
+#define WM8996_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
+#define WM8996_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
+#define WM8996_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
+#define WM8996_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
+#define WM8996_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
+#define WM8996_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
+#define WM8996_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
+#define WM8996_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
+#define WM8996_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
+#define WM8996_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
+
+/*
+ * R1056 (0x420) - DSP1 RX Filters (1)
+ */
+#define WM8996_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
+#define WM8996_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
+#define WM8996_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
+#define WM8996_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
+#define WM8996_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
+#define WM8996_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
+#define WM8996_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
+#define WM8996_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
+#define WM8996_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
+#define WM8996_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
+#define WM8996_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
+#define WM8996_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
+#define WM8996_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
+#define WM8996_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
+#define WM8996_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
+#define WM8996_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
+
+/*
+ * R1057 (0x421) - DSP1 RX Filters (2)
+ */
+#define WM8996_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
+#define WM8996_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
+#define WM8996_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
+#define WM8996_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
+#define WM8996_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
+#define WM8996_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
+#define WM8996_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
+
+/*
+ * R1088 (0x440) - DSP1 DRC (1)
+ */
+#define WM8996_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
+#define WM8996_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
+#define WM8996_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
+#define WM8996_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
+#define WM8996_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
+#define WM8996_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
+#define WM8996_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
+#define WM8996_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
+#define WM8996_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
+#define WM8996_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
+#define WM8996_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
+#define WM8996_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
+#define WM8996_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
+#define WM8996_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
+#define WM8996_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
+#define WM8996_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
+#define WM8996_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
+#define WM8996_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
+#define WM8996_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
+#define WM8996_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
+#define WM8996_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
+#define WM8996_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
+#define WM8996_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
+#define WM8996_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
+#define WM8996_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
+#define WM8996_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
+#define WM8996_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
+#define WM8996_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
+#define WM8996_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
+#define WM8996_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
+#define WM8996_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
+#define WM8996_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
+#define WM8996_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
+#define WM8996_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
+#define WM8996_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
+#define WM8996_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
+#define WM8996_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
+#define WM8996_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
+#define WM8996_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
+#define WM8996_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
+#define WM8996_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
+#define WM8996_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
+
+/*
+ * R1089 (0x441) - DSP1 DRC (2)
+ */
+#define WM8996_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
+#define WM8996_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
+#define WM8996_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
+#define WM8996_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
+#define WM8996_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
+#define WM8996_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
+#define WM8996_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
+#define WM8996_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
+#define WM8996_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
+#define WM8996_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
+#define WM8996_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
+#define WM8996_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
+
+/*
+ * R1090 (0x442) - DSP1 DRC (3)
+ */
+#define WM8996_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
+#define WM8996_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
+#define WM8996_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
+#define WM8996_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
+#define WM8996_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
+#define WM8996_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
+#define WM8996_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
+#define WM8996_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
+#define WM8996_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
+#define WM8996_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
+#define WM8996_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
+#define WM8996_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
+#define WM8996_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
+#define WM8996_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
+#define WM8996_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
+#define WM8996_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
+#define WM8996_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
+#define WM8996_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
+
+/*
+ * R1091 (0x443) - DSP1 DRC (4)
+ */
+#define WM8996_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
+#define WM8996_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
+#define WM8996_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
+#define WM8996_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
+#define WM8996_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
+#define WM8996_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
+
+/*
+ * R1092 (0x444) - DSP1 DRC (5)
+ */
+#define WM8996_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
+#define WM8996_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
+#define WM8996_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
+#define WM8996_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
+#define WM8996_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
+#define WM8996_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
+
+/*
+ * R1152 (0x480) - DSP1 RX EQ Gains (1)
+ */
+#define WM8996_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
+#define WM8996_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
+#define WM8996_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
+#define WM8996_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
+#define WM8996_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
+#define WM8996_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
+#define WM8996_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
+#define WM8996_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
+#define WM8996_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
+#define WM8996_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
+#define WM8996_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
+#define WM8996_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
+#define WM8996_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
+
+/*
+ * R1153 (0x481) - DSP1 RX EQ Gains (2)
+ */
+#define WM8996_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
+#define WM8996_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
+#define WM8996_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
+#define WM8996_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
+#define WM8996_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
+#define WM8996_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1154 (0x482) - DSP1 RX EQ Band 1 A
+ */
+#define WM8996_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
+
+/*
+ * R1155 (0x483) - DSP1 RX EQ Band 1 B
+ */
+#define WM8996_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
+
+/*
+ * R1156 (0x484) - DSP1 RX EQ Band 1 PG
+ */
+#define WM8996_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
+
+/*
+ * R1157 (0x485) - DSP1 RX EQ Band 2 A
+ */
+#define WM8996_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
+
+/*
+ * R1158 (0x486) - DSP1 RX EQ Band 2 B
+ */
+#define WM8996_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
+
+/*
+ * R1159 (0x487) - DSP1 RX EQ Band 2 C
+ */
+#define WM8996_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
+
+/*
+ * R1160 (0x488) - DSP1 RX EQ Band 2 PG
+ */
+#define WM8996_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
+
+/*
+ * R1161 (0x489) - DSP1 RX EQ Band 3 A
+ */
+#define WM8996_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
+
+/*
+ * R1162 (0x48A) - DSP1 RX EQ Band 3 B
+ */
+#define WM8996_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
+
+/*
+ * R1163 (0x48B) - DSP1 RX EQ Band 3 C
+ */
+#define WM8996_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
+
+/*
+ * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
+ */
+#define WM8996_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
+
+/*
+ * R1165 (0x48D) - DSP1 RX EQ Band 4 A
+ */
+#define WM8996_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
+
+/*
+ * R1166 (0x48E) - DSP1 RX EQ Band 4 B
+ */
+#define WM8996_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
+
+/*
+ * R1167 (0x48F) - DSP1 RX EQ Band 4 C
+ */
+#define WM8996_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
+
+/*
+ * R1168 (0x490) - DSP1 RX EQ Band 4 PG
+ */
+#define WM8996_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
+
+/*
+ * R1169 (0x491) - DSP1 RX EQ Band 5 A
+ */
+#define WM8996_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
+#define WM8996_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
+
+/*
+ * R1170 (0x492) - DSP1 RX EQ Band 5 B
+ */
+#define WM8996_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
+#define WM8996_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
+
+/*
+ * R1171 (0x493) - DSP1 RX EQ Band 5 PG
+ */
+#define WM8996_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
+#define WM8996_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
+
+/*
+ * R1280 (0x500) - DSP2 TX Left Volume
+ */
+#define WM8996_DSP2TX_VU 0x0100 /* DSP2TX_VU */
+#define WM8996_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
+#define WM8996_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
+#define WM8996_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
+#define WM8996_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
+#define WM8996_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
+#define WM8996_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
+
+/*
+ * R1281 (0x501) - DSP2 TX Right Volume
+ */
+#define WM8996_DSP2TX_VU 0x0100 /* DSP2TX_VU */
+#define WM8996_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
+#define WM8996_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
+#define WM8996_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
+#define WM8996_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
+#define WM8996_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
+#define WM8996_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
+
+/*
+ * R1282 (0x502) - DSP2 RX Left Volume
+ */
+#define WM8996_DSP2RX_VU 0x0100 /* DSP2RX_VU */
+#define WM8996_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
+#define WM8996_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
+#define WM8996_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
+#define WM8996_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
+#define WM8996_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
+#define WM8996_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
+
+/*
+ * R1283 (0x503) - DSP2 RX Right Volume
+ */
+#define WM8996_DSP2RX_VU 0x0100 /* DSP2RX_VU */
+#define WM8996_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
+#define WM8996_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
+#define WM8996_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
+#define WM8996_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
+#define WM8996_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
+#define WM8996_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
+
+/*
+ * R1296 (0x510) - DSP2 TX Filters
+ */
+#define WM8996_DSP2TX_NF 0x2000 /* DSP2TX_NF */
+#define WM8996_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
+#define WM8996_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
+#define WM8996_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
+#define WM8996_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
+#define WM8996_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
+#define WM8996_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
+#define WM8996_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
+#define WM8996_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
+#define WM8996_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
+#define WM8996_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
+#define WM8996_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
+#define WM8996_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
+#define WM8996_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
+#define WM8996_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
+#define WM8996_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
+#define WM8996_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
+#define WM8996_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
+
+/*
+ * R1312 (0x520) - DSP2 RX Filters (1)
+ */
+#define WM8996_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
+#define WM8996_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
+#define WM8996_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
+#define WM8996_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
+#define WM8996_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
+#define WM8996_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
+#define WM8996_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
+#define WM8996_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
+#define WM8996_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
+#define WM8996_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
+#define WM8996_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
+#define WM8996_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
+#define WM8996_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
+#define WM8996_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
+#define WM8996_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
+#define WM8996_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
+
+/*
+ * R1313 (0x521) - DSP2 RX Filters (2)
+ */
+#define WM8996_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
+#define WM8996_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
+#define WM8996_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
+#define WM8996_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
+#define WM8996_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
+#define WM8996_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
+#define WM8996_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
+
+/*
+ * R1344 (0x540) - DSP2 DRC (1)
+ */
+#define WM8996_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
+#define WM8996_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
+#define WM8996_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
+#define WM8996_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
+#define WM8996_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
+#define WM8996_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
+#define WM8996_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
+#define WM8996_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
+#define WM8996_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
+#define WM8996_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
+#define WM8996_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
+#define WM8996_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
+#define WM8996_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
+#define WM8996_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
+#define WM8996_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
+#define WM8996_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
+#define WM8996_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
+#define WM8996_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
+#define WM8996_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
+#define WM8996_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
+#define WM8996_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
+#define WM8996_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
+#define WM8996_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
+#define WM8996_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
+#define WM8996_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
+#define WM8996_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
+#define WM8996_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
+#define WM8996_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
+#define WM8996_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
+#define WM8996_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
+#define WM8996_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
+#define WM8996_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
+#define WM8996_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
+#define WM8996_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
+#define WM8996_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
+#define WM8996_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
+#define WM8996_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
+#define WM8996_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
+#define WM8996_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
+#define WM8996_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
+#define WM8996_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
+#define WM8996_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
+
+/*
+ * R1345 (0x541) - DSP2 DRC (2)
+ */
+#define WM8996_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
+#define WM8996_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
+#define WM8996_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
+#define WM8996_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
+#define WM8996_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
+#define WM8996_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
+#define WM8996_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
+#define WM8996_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
+#define WM8996_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
+#define WM8996_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
+#define WM8996_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
+#define WM8996_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
+
+/*
+ * R1346 (0x542) - DSP2 DRC (3)
+ */
+#define WM8996_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
+#define WM8996_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
+#define WM8996_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
+#define WM8996_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
+#define WM8996_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
+#define WM8996_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
+#define WM8996_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
+#define WM8996_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
+#define WM8996_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
+#define WM8996_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
+#define WM8996_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
+#define WM8996_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
+#define WM8996_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
+#define WM8996_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
+#define WM8996_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
+#define WM8996_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
+#define WM8996_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
+#define WM8996_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
+
+/*
+ * R1347 (0x543) - DSP2 DRC (4)
+ */
+#define WM8996_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
+#define WM8996_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
+#define WM8996_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
+#define WM8996_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
+#define WM8996_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
+#define WM8996_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
+
+/*
+ * R1348 (0x544) - DSP2 DRC (5)
+ */
+#define WM8996_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
+#define WM8996_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
+#define WM8996_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
+#define WM8996_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
+#define WM8996_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
+#define WM8996_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
+
+/*
+ * R1408 (0x580) - DSP2 RX EQ Gains (1)
+ */
+#define WM8996_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
+#define WM8996_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
+#define WM8996_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
+#define WM8996_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
+#define WM8996_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
+#define WM8996_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
+#define WM8996_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
+#define WM8996_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
+#define WM8996_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
+#define WM8996_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
+#define WM8996_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
+#define WM8996_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
+#define WM8996_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
+
+/*
+ * R1409 (0x581) - DSP2 RX EQ Gains (2)
+ */
+#define WM8996_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
+#define WM8996_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
+#define WM8996_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
+#define WM8996_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
+#define WM8996_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
+#define WM8996_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1410 (0x582) - DSP2 RX EQ Band 1 A
+ */
+#define WM8996_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
+
+/*
+ * R1411 (0x583) - DSP2 RX EQ Band 1 B
+ */
+#define WM8996_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
+
+/*
+ * R1412 (0x584) - DSP2 RX EQ Band 1 PG
+ */
+#define WM8996_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
+
+/*
+ * R1413 (0x585) - DSP2 RX EQ Band 2 A
+ */
+#define WM8996_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
+
+/*
+ * R1414 (0x586) - DSP2 RX EQ Band 2 B
+ */
+#define WM8996_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
+
+/*
+ * R1415 (0x587) - DSP2 RX EQ Band 2 C
+ */
+#define WM8996_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
+
+/*
+ * R1416 (0x588) - DSP2 RX EQ Band 2 PG
+ */
+#define WM8996_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
+
+/*
+ * R1417 (0x589) - DSP2 RX EQ Band 3 A
+ */
+#define WM8996_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
+
+/*
+ * R1418 (0x58A) - DSP2 RX EQ Band 3 B
+ */
+#define WM8996_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
+
+/*
+ * R1419 (0x58B) - DSP2 RX EQ Band 3 C
+ */
+#define WM8996_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
+
+/*
+ * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
+ */
+#define WM8996_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
+
+/*
+ * R1421 (0x58D) - DSP2 RX EQ Band 4 A
+ */
+#define WM8996_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
+
+/*
+ * R1422 (0x58E) - DSP2 RX EQ Band 4 B
+ */
+#define WM8996_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
+
+/*
+ * R1423 (0x58F) - DSP2 RX EQ Band 4 C
+ */
+#define WM8996_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
+
+/*
+ * R1424 (0x590) - DSP2 RX EQ Band 4 PG
+ */
+#define WM8996_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
+
+/*
+ * R1425 (0x591) - DSP2 RX EQ Band 5 A
+ */
+#define WM8996_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
+#define WM8996_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
+
+/*
+ * R1426 (0x592) - DSP2 RX EQ Band 5 B
+ */
+#define WM8996_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
+#define WM8996_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
+
+/*
+ * R1427 (0x593) - DSP2 RX EQ Band 5 PG
+ */
+#define WM8996_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
+#define WM8996_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
+
+/*
+ * R1536 (0x600) - DAC1 Mixer Volumes
+ */
+#define WM8996_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
+#define WM8996_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
+#define WM8996_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
+#define WM8996_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
+#define WM8996_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
+#define WM8996_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
+
+/*
+ * R1537 (0x601) - DAC1 Left Mixer Routing
+ */
+#define WM8996_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
+#define WM8996_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
+#define WM8996_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
+#define WM8996_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
+#define WM8996_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
+#define WM8996_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
+#define WM8996_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
+#define WM8996_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
+#define WM8996_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
+#define WM8996_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
+#define WM8996_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
+#define WM8996_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
+#define WM8996_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
+#define WM8996_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
+#define WM8996_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
+#define WM8996_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
+
+/*
+ * R1538 (0x602) - DAC1 Right Mixer Routing
+ */
+#define WM8996_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
+#define WM8996_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
+#define WM8996_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
+#define WM8996_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
+#define WM8996_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
+#define WM8996_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
+#define WM8996_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
+#define WM8996_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
+#define WM8996_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
+#define WM8996_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
+#define WM8996_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
+#define WM8996_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
+#define WM8996_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
+#define WM8996_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
+#define WM8996_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
+#define WM8996_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
+
+/*
+ * R1539 (0x603) - DAC2 Mixer Volumes
+ */
+#define WM8996_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
+#define WM8996_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
+#define WM8996_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
+#define WM8996_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
+#define WM8996_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
+#define WM8996_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
+
+/*
+ * R1540 (0x604) - DAC2 Left Mixer Routing
+ */
+#define WM8996_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
+#define WM8996_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
+#define WM8996_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
+#define WM8996_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
+#define WM8996_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
+#define WM8996_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
+#define WM8996_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
+#define WM8996_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
+#define WM8996_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
+#define WM8996_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
+#define WM8996_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
+#define WM8996_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
+#define WM8996_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
+#define WM8996_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
+#define WM8996_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
+#define WM8996_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
+
+/*
+ * R1541 (0x605) - DAC2 Right Mixer Routing
+ */
+#define WM8996_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
+#define WM8996_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
+#define WM8996_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
+#define WM8996_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
+#define WM8996_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
+#define WM8996_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
+#define WM8996_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
+#define WM8996_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
+#define WM8996_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
+#define WM8996_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
+#define WM8996_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
+#define WM8996_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
+#define WM8996_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
+#define WM8996_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
+#define WM8996_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
+#define WM8996_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
+
+/*
+ * R1542 (0x606) - DSP1 TX Left Mixer Routing
+ */
+#define WM8996_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
+#define WM8996_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
+#define WM8996_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
+#define WM8996_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
+#define WM8996_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
+#define WM8996_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
+#define WM8996_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
+#define WM8996_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
+
+/*
+ * R1543 (0x607) - DSP1 TX Right Mixer Routing
+ */
+#define WM8996_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
+#define WM8996_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
+#define WM8996_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
+#define WM8996_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
+#define WM8996_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
+#define WM8996_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
+#define WM8996_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
+#define WM8996_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
+
+/*
+ * R1544 (0x608) - DSP2 TX Left Mixer Routing
+ */
+#define WM8996_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
+#define WM8996_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
+#define WM8996_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
+#define WM8996_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
+#define WM8996_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
+#define WM8996_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
+#define WM8996_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
+#define WM8996_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
+
+/*
+ * R1545 (0x609) - DSP2 TX Right Mixer Routing
+ */
+#define WM8996_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
+#define WM8996_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
+#define WM8996_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
+#define WM8996_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
+#define WM8996_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
+#define WM8996_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
+#define WM8996_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
+#define WM8996_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
+
+/*
+ * R1546 (0x60A) - DSP TX Mixer Select
+ */
+#define WM8996_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
+#define WM8996_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
+#define WM8996_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
+#define WM8996_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
+
+/*
+ * R1552 (0x610) - DAC Softmute
+ */
+#define WM8996_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8996_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8996_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
+#define WM8996_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
+#define WM8996_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
+#define WM8996_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
+#define WM8996_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
+#define WM8996_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
+
+/*
+ * R1568 (0x620) - Oversampling
+ */
+#define WM8996_SPK_OSR128 0x0008 /* SPK_OSR128 */
+#define WM8996_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
+#define WM8996_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
+#define WM8996_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
+#define WM8996_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
+#define WM8996_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
+#define WM8996_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
+#define WM8996_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
+#define WM8996_ADC_OSR128 0x0002 /* ADC_OSR128 */
+#define WM8996_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
+#define WM8996_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
+#define WM8996_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
+#define WM8996_DAC_OSR128 0x0001 /* DAC_OSR128 */
+#define WM8996_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
+#define WM8996_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
+#define WM8996_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
+
+/*
+ * R1569 (0x621) - Sidetone
+ */
+#define WM8996_ST_LPF 0x1000 /* ST_LPF */
+#define WM8996_ST_LPF_MASK 0x1000 /* ST_LPF */
+#define WM8996_ST_LPF_SHIFT 12 /* ST_LPF */
+#define WM8996_ST_LPF_WIDTH 1 /* ST_LPF */
+#define WM8996_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
+#define WM8996_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
+#define WM8996_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
+#define WM8996_ST_HPF 0x0040 /* ST_HPF */
+#define WM8996_ST_HPF_MASK 0x0040 /* ST_HPF */
+#define WM8996_ST_HPF_SHIFT 6 /* ST_HPF */
+#define WM8996_ST_HPF_WIDTH 1 /* ST_HPF */
+#define WM8996_STR_SEL 0x0002 /* STR_SEL */
+#define WM8996_STR_SEL_MASK 0x0002 /* STR_SEL */
+#define WM8996_STR_SEL_SHIFT 1 /* STR_SEL */
+#define WM8996_STR_SEL_WIDTH 1 /* STR_SEL */
+#define WM8996_STL_SEL 0x0001 /* STL_SEL */
+#define WM8996_STL_SEL_MASK 0x0001 /* STL_SEL */
+#define WM8996_STL_SEL_SHIFT 0 /* STL_SEL */
+#define WM8996_STL_SEL_WIDTH 1 /* STL_SEL */
+
+/*
+ * R1792 (0x700) - GPIO 1
+ */
+#define WM8996_GP1_DIR 0x8000 /* GP1_DIR */
+#define WM8996_GP1_DIR_MASK 0x8000 /* GP1_DIR */
+#define WM8996_GP1_DIR_SHIFT 15 /* GP1_DIR */
+#define WM8996_GP1_DIR_WIDTH 1 /* GP1_DIR */
+#define WM8996_GP1_PU 0x4000 /* GP1_PU */
+#define WM8996_GP1_PU_MASK 0x4000 /* GP1_PU */
+#define WM8996_GP1_PU_SHIFT 14 /* GP1_PU */
+#define WM8996_GP1_PU_WIDTH 1 /* GP1_PU */
+#define WM8996_GP1_PD 0x2000 /* GP1_PD */
+#define WM8996_GP1_PD_MASK 0x2000 /* GP1_PD */
+#define WM8996_GP1_PD_SHIFT 13 /* GP1_PD */
+#define WM8996_GP1_PD_WIDTH 1 /* GP1_PD */
+#define WM8996_GP1_POL 0x0400 /* GP1_POL */
+#define WM8996_GP1_POL_MASK 0x0400 /* GP1_POL */
+#define WM8996_GP1_POL_SHIFT 10 /* GP1_POL */
+#define WM8996_GP1_POL_WIDTH 1 /* GP1_POL */
+#define WM8996_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
+#define WM8996_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
+#define WM8996_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
+#define WM8996_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
+#define WM8996_GP1_DB 0x0100 /* GP1_DB */
+#define WM8996_GP1_DB_MASK 0x0100 /* GP1_DB */
+#define WM8996_GP1_DB_SHIFT 8 /* GP1_DB */
+#define WM8996_GP1_DB_WIDTH 1 /* GP1_DB */
+#define WM8996_GP1_LVL 0x0040 /* GP1_LVL */
+#define WM8996_GP1_LVL_MASK 0x0040 /* GP1_LVL */
+#define WM8996_GP1_LVL_SHIFT 6 /* GP1_LVL */
+#define WM8996_GP1_LVL_WIDTH 1 /* GP1_LVL */
+#define WM8996_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
+#define WM8996_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
+#define WM8996_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
+
+/*
+ * R1793 (0x701) - GPIO 2
+ */
+#define WM8996_GP2_DIR 0x8000 /* GP2_DIR */
+#define WM8996_GP2_DIR_MASK 0x8000 /* GP2_DIR */
+#define WM8996_GP2_DIR_SHIFT 15 /* GP2_DIR */
+#define WM8996_GP2_DIR_WIDTH 1 /* GP2_DIR */
+#define WM8996_GP2_PU 0x4000 /* GP2_PU */
+#define WM8996_GP2_PU_MASK 0x4000 /* GP2_PU */
+#define WM8996_GP2_PU_SHIFT 14 /* GP2_PU */
+#define WM8996_GP2_PU_WIDTH 1 /* GP2_PU */
+#define WM8996_GP2_PD 0x2000 /* GP2_PD */
+#define WM8996_GP2_PD_MASK 0x2000 /* GP2_PD */
+#define WM8996_GP2_PD_SHIFT 13 /* GP2_PD */
+#define WM8996_GP2_PD_WIDTH 1 /* GP2_PD */
+#define WM8996_GP2_POL 0x0400 /* GP2_POL */
+#define WM8996_GP2_POL_MASK 0x0400 /* GP2_POL */
+#define WM8996_GP2_POL_SHIFT 10 /* GP2_POL */
+#define WM8996_GP2_POL_WIDTH 1 /* GP2_POL */
+#define WM8996_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
+#define WM8996_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
+#define WM8996_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
+#define WM8996_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
+#define WM8996_GP2_DB 0x0100 /* GP2_DB */
+#define WM8996_GP2_DB_MASK 0x0100 /* GP2_DB */
+#define WM8996_GP2_DB_SHIFT 8 /* GP2_DB */
+#define WM8996_GP2_DB_WIDTH 1 /* GP2_DB */
+#define WM8996_GP2_LVL 0x0040 /* GP2_LVL */
+#define WM8996_GP2_LVL_MASK 0x0040 /* GP2_LVL */
+#define WM8996_GP2_LVL_SHIFT 6 /* GP2_LVL */
+#define WM8996_GP2_LVL_WIDTH 1 /* GP2_LVL */
+#define WM8996_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
+#define WM8996_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
+#define WM8996_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
+
+/*
+ * R1794 (0x702) - GPIO 3
+ */
+#define WM8996_GP3_DIR 0x8000 /* GP3_DIR */
+#define WM8996_GP3_DIR_MASK 0x8000 /* GP3_DIR */
+#define WM8996_GP3_DIR_SHIFT 15 /* GP3_DIR */
+#define WM8996_GP3_DIR_WIDTH 1 /* GP3_DIR */
+#define WM8996_GP3_PU 0x4000 /* GP3_PU */
+#define WM8996_GP3_PU_MASK 0x4000 /* GP3_PU */
+#define WM8996_GP3_PU_SHIFT 14 /* GP3_PU */
+#define WM8996_GP3_PU_WIDTH 1 /* GP3_PU */
+#define WM8996_GP3_PD 0x2000 /* GP3_PD */
+#define WM8996_GP3_PD_MASK 0x2000 /* GP3_PD */
+#define WM8996_GP3_PD_SHIFT 13 /* GP3_PD */
+#define WM8996_GP3_PD_WIDTH 1 /* GP3_PD */
+#define WM8996_GP3_POL 0x0400 /* GP3_POL */
+#define WM8996_GP3_POL_MASK 0x0400 /* GP3_POL */
+#define WM8996_GP3_POL_SHIFT 10 /* GP3_POL */
+#define WM8996_GP3_POL_WIDTH 1 /* GP3_POL */
+#define WM8996_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
+#define WM8996_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
+#define WM8996_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
+#define WM8996_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
+#define WM8996_GP3_DB 0x0100 /* GP3_DB */
+#define WM8996_GP3_DB_MASK 0x0100 /* GP3_DB */
+#define WM8996_GP3_DB_SHIFT 8 /* GP3_DB */
+#define WM8996_GP3_DB_WIDTH 1 /* GP3_DB */
+#define WM8996_GP3_LVL 0x0040 /* GP3_LVL */
+#define WM8996_GP3_LVL_MASK 0x0040 /* GP3_LVL */
+#define WM8996_GP3_LVL_SHIFT 6 /* GP3_LVL */
+#define WM8996_GP3_LVL_WIDTH 1 /* GP3_LVL */
+#define WM8996_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
+#define WM8996_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
+#define WM8996_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
+
+/*
+ * R1795 (0x703) - GPIO 4
+ */
+#define WM8996_GP4_DIR 0x8000 /* GP4_DIR */
+#define WM8996_GP4_DIR_MASK 0x8000 /* GP4_DIR */
+#define WM8996_GP4_DIR_SHIFT 15 /* GP4_DIR */
+#define WM8996_GP4_DIR_WIDTH 1 /* GP4_DIR */
+#define WM8996_GP4_PU 0x4000 /* GP4_PU */
+#define WM8996_GP4_PU_MASK 0x4000 /* GP4_PU */
+#define WM8996_GP4_PU_SHIFT 14 /* GP4_PU */
+#define WM8996_GP4_PU_WIDTH 1 /* GP4_PU */
+#define WM8996_GP4_PD 0x2000 /* GP4_PD */
+#define WM8996_GP4_PD_MASK 0x2000 /* GP4_PD */
+#define WM8996_GP4_PD_SHIFT 13 /* GP4_PD */
+#define WM8996_GP4_PD_WIDTH 1 /* GP4_PD */
+#define WM8996_GP4_POL 0x0400 /* GP4_POL */
+#define WM8996_GP4_POL_MASK 0x0400 /* GP4_POL */
+#define WM8996_GP4_POL_SHIFT 10 /* GP4_POL */
+#define WM8996_GP4_POL_WIDTH 1 /* GP4_POL */
+#define WM8996_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
+#define WM8996_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
+#define WM8996_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
+#define WM8996_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
+#define WM8996_GP4_DB 0x0100 /* GP4_DB */
+#define WM8996_GP4_DB_MASK 0x0100 /* GP4_DB */
+#define WM8996_GP4_DB_SHIFT 8 /* GP4_DB */
+#define WM8996_GP4_DB_WIDTH 1 /* GP4_DB */
+#define WM8996_GP4_LVL 0x0040 /* GP4_LVL */
+#define WM8996_GP4_LVL_MASK 0x0040 /* GP4_LVL */
+#define WM8996_GP4_LVL_SHIFT 6 /* GP4_LVL */
+#define WM8996_GP4_LVL_WIDTH 1 /* GP4_LVL */
+#define WM8996_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
+#define WM8996_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
+#define WM8996_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
+
+/*
+ * R1796 (0x704) - GPIO 5
+ */
+#define WM8996_GP5_DIR 0x8000 /* GP5_DIR */
+#define WM8996_GP5_DIR_MASK 0x8000 /* GP5_DIR */
+#define WM8996_GP5_DIR_SHIFT 15 /* GP5_DIR */
+#define WM8996_GP5_DIR_WIDTH 1 /* GP5_DIR */
+#define WM8996_GP5_PU 0x4000 /* GP5_PU */
+#define WM8996_GP5_PU_MASK 0x4000 /* GP5_PU */
+#define WM8996_GP5_PU_SHIFT 14 /* GP5_PU */
+#define WM8996_GP5_PU_WIDTH 1 /* GP5_PU */
+#define WM8996_GP5_PD 0x2000 /* GP5_PD */
+#define WM8996_GP5_PD_MASK 0x2000 /* GP5_PD */
+#define WM8996_GP5_PD_SHIFT 13 /* GP5_PD */
+#define WM8996_GP5_PD_WIDTH 1 /* GP5_PD */
+#define WM8996_GP5_POL 0x0400 /* GP5_POL */
+#define WM8996_GP5_POL_MASK 0x0400 /* GP5_POL */
+#define WM8996_GP5_POL_SHIFT 10 /* GP5_POL */
+#define WM8996_GP5_POL_WIDTH 1 /* GP5_POL */
+#define WM8996_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
+#define WM8996_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
+#define WM8996_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
+#define WM8996_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
+#define WM8996_GP5_DB 0x0100 /* GP5_DB */
+#define WM8996_GP5_DB_MASK 0x0100 /* GP5_DB */
+#define WM8996_GP5_DB_SHIFT 8 /* GP5_DB */
+#define WM8996_GP5_DB_WIDTH 1 /* GP5_DB */
+#define WM8996_GP5_LVL 0x0040 /* GP5_LVL */
+#define WM8996_GP5_LVL_MASK 0x0040 /* GP5_LVL */
+#define WM8996_GP5_LVL_SHIFT 6 /* GP5_LVL */
+#define WM8996_GP5_LVL_WIDTH 1 /* GP5_LVL */
+#define WM8996_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
+#define WM8996_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
+#define WM8996_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
+
+/*
+ * R1824 (0x720) - Pull Control (1)
+ */
+#define WM8996_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
+#define WM8996_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
+#define WM8996_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
+#define WM8996_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
+#define WM8996_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
+#define WM8996_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
+#define WM8996_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
+#define WM8996_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
+#define WM8996_MCLK2_PU 0x0200 /* MCLK2_PU */
+#define WM8996_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
+#define WM8996_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
+#define WM8996_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
+#define WM8996_MCLK2_PD 0x0100 /* MCLK2_PD */
+#define WM8996_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
+#define WM8996_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
+#define WM8996_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
+#define WM8996_MCLK1_PU 0x0080 /* MCLK1_PU */
+#define WM8996_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
+#define WM8996_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
+#define WM8996_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
+#define WM8996_MCLK1_PD 0x0040 /* MCLK1_PD */
+#define WM8996_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
+#define WM8996_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
+#define WM8996_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
+#define WM8996_DACDAT1_PU 0x0020 /* DACDAT1_PU */
+#define WM8996_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
+#define WM8996_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
+#define WM8996_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
+#define WM8996_DACDAT1_PD 0x0010 /* DACDAT1_PD */
+#define WM8996_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
+#define WM8996_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
+#define WM8996_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
+#define WM8996_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
+#define WM8996_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
+#define WM8996_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
+#define WM8996_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
+#define WM8996_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
+#define WM8996_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
+#define WM8996_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
+#define WM8996_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
+#define WM8996_BCLK1_PU 0x0002 /* BCLK1_PU */
+#define WM8996_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
+#define WM8996_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
+#define WM8996_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
+#define WM8996_BCLK1_PD 0x0001 /* BCLK1_PD */
+#define WM8996_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
+#define WM8996_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
+#define WM8996_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
+
+/*
+ * R1825 (0x721) - Pull Control (2)
+ */
+#define WM8996_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
+#define WM8996_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
+#define WM8996_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
+#define WM8996_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
+#define WM8996_ADDR_PD 0x0040 /* ADDR_PD */
+#define WM8996_ADDR_PD_MASK 0x0040 /* ADDR_PD */
+#define WM8996_ADDR_PD_SHIFT 6 /* ADDR_PD */
+#define WM8996_ADDR_PD_WIDTH 1 /* ADDR_PD */
+#define WM8996_DACDAT2_PU 0x0020 /* DACDAT2_PU */
+#define WM8996_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
+#define WM8996_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
+#define WM8996_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
+#define WM8996_DACDAT2_PD 0x0010 /* DACDAT2_PD */
+#define WM8996_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
+#define WM8996_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
+#define WM8996_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
+#define WM8996_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
+#define WM8996_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
+#define WM8996_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
+#define WM8996_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
+#define WM8996_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
+#define WM8996_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
+#define WM8996_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
+#define WM8996_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
+#define WM8996_BCLK2_PU 0x0002 /* BCLK2_PU */
+#define WM8996_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
+#define WM8996_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
+#define WM8996_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
+#define WM8996_BCLK2_PD 0x0001 /* BCLK2_PD */
+#define WM8996_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
+#define WM8996_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
+#define WM8996_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
+
+/*
+ * R1840 (0x730) - Interrupt Status 1
+ */
+#define WM8996_GP5_EINT 0x0010 /* GP5_EINT */
+#define WM8996_GP5_EINT_MASK 0x0010 /* GP5_EINT */
+#define WM8996_GP5_EINT_SHIFT 4 /* GP5_EINT */
+#define WM8996_GP5_EINT_WIDTH 1 /* GP5_EINT */
+#define WM8996_GP4_EINT 0x0008 /* GP4_EINT */
+#define WM8996_GP4_EINT_MASK 0x0008 /* GP4_EINT */
+#define WM8996_GP4_EINT_SHIFT 3 /* GP4_EINT */
+#define WM8996_GP4_EINT_WIDTH 1 /* GP4_EINT */
+#define WM8996_GP3_EINT 0x0004 /* GP3_EINT */
+#define WM8996_GP3_EINT_MASK 0x0004 /* GP3_EINT */
+#define WM8996_GP3_EINT_SHIFT 2 /* GP3_EINT */
+#define WM8996_GP3_EINT_WIDTH 1 /* GP3_EINT */
+#define WM8996_GP2_EINT 0x0002 /* GP2_EINT */
+#define WM8996_GP2_EINT_MASK 0x0002 /* GP2_EINT */
+#define WM8996_GP2_EINT_SHIFT 1 /* GP2_EINT */
+#define WM8996_GP2_EINT_WIDTH 1 /* GP2_EINT */
+#define WM8996_GP1_EINT 0x0001 /* GP1_EINT */
+#define WM8996_GP1_EINT_MASK 0x0001 /* GP1_EINT */
+#define WM8996_GP1_EINT_SHIFT 0 /* GP1_EINT */
+#define WM8996_GP1_EINT_WIDTH 1 /* GP1_EINT */
+
+/*
+ * R1841 (0x731) - Interrupt Status 2
+ */
+#define WM8996_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
+#define WM8996_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
+#define WM8996_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
+#define WM8996_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
+#define WM8996_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
+#define WM8996_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
+#define WM8996_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
+#define WM8996_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
+#define WM8996_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
+#define WM8996_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
+#define WM8996_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
+#define WM8996_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
+#define WM8996_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
+#define WM8996_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
+#define WM8996_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
+#define WM8996_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
+#define WM8996_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
+#define WM8996_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
+#define WM8996_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
+#define WM8996_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
+#define WM8996_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
+#define WM8996_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
+#define WM8996_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
+#define WM8996_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
+#define WM8996_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
+#define WM8996_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
+#define WM8996_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
+#define WM8996_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
+#define WM8996_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
+#define WM8996_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
+#define WM8996_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
+#define WM8996_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
+#define WM8996_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
+#define WM8996_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
+#define WM8996_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
+#define WM8996_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
+#define WM8996_MICD_EINT 0x0001 /* MICD_EINT */
+#define WM8996_MICD_EINT_MASK 0x0001 /* MICD_EINT */
+#define WM8996_MICD_EINT_SHIFT 0 /* MICD_EINT */
+#define WM8996_MICD_EINT_WIDTH 1 /* MICD_EINT */
+
+/*
+ * R1842 (0x732) - Interrupt Raw Status 2
+ */
+#define WM8996_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
+#define WM8996_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
+#define WM8996_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
+#define WM8996_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
+#define WM8996_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
+#define WM8996_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
+#define WM8996_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
+#define WM8996_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
+#define WM8996_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
+#define WM8996_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
+#define WM8996_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
+#define WM8996_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
+#define WM8996_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
+#define WM8996_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
+#define WM8996_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
+#define WM8996_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
+#define WM8996_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
+#define WM8996_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
+#define WM8996_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
+#define WM8996_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
+#define WM8996_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
+#define WM8996_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
+#define WM8996_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
+#define WM8996_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
+#define WM8996_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
+#define WM8996_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
+#define WM8996_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
+#define WM8996_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
+
+/*
+ * R1848 (0x738) - Interrupt Status 1 Mask
+ */
+#define WM8996_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
+#define WM8996_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
+#define WM8996_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
+#define WM8996_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
+#define WM8996_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
+#define WM8996_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
+#define WM8996_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
+#define WM8996_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
+#define WM8996_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
+#define WM8996_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
+#define WM8996_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
+#define WM8996_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
+#define WM8996_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
+#define WM8996_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
+#define WM8996_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
+#define WM8996_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
+#define WM8996_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
+#define WM8996_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
+#define WM8996_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
+#define WM8996_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
+
+/*
+ * R1849 (0x739) - Interrupt Status 2 Mask
+ */
+#define WM8996_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
+#define WM8996_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
+#define WM8996_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
+#define WM8996_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
+#define WM8996_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
+#define WM8996_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
+#define WM8996_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
+#define WM8996_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
+#define WM8996_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
+#define WM8996_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
+#define WM8996_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
+#define WM8996_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
+#define WM8996_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
+#define WM8996_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
+#define WM8996_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
+#define WM8996_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
+#define WM8996_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
+#define WM8996_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
+#define WM8996_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
+#define WM8996_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
+#define WM8996_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
+#define WM8996_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
+#define WM8996_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
+#define WM8996_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
+#define WM8996_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
+#define WM8996_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
+#define WM8996_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
+#define WM8996_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
+#define WM8996_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
+#define WM8996_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
+#define WM8996_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
+#define WM8996_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
+#define WM8996_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
+#define WM8996_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
+
+/*
+ * R1856 (0x740) - Interrupt Control
+ */
+#define WM8996_IM_IRQ 0x0001 /* IM_IRQ */
+#define WM8996_IM_IRQ_MASK 0x0001 /* IM_IRQ */
+#define WM8996_IM_IRQ_SHIFT 0 /* IM_IRQ */
+#define WM8996_IM_IRQ_WIDTH 1 /* IM_IRQ */
+
+/*
+ * R2048 (0x800) - Left PDM Speaker
+ */
+#define WM8996_SPKL_ENA 0x0010 /* SPKL_ENA */
+#define WM8996_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
+#define WM8996_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
+#define WM8996_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
+#define WM8996_SPKL_MUTE 0x0008 /* SPKL_MUTE */
+#define WM8996_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
+#define WM8996_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
+#define WM8996_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
+#define WM8996_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
+#define WM8996_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
+#define WM8996_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
+#define WM8996_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
+#define WM8996_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
+#define WM8996_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
+#define WM8996_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
+
+/*
+ * R2049 (0x801) - Right PDM Speaker
+ */
+#define WM8996_SPKR_ENA 0x0010 /* SPKR_ENA */
+#define WM8996_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
+#define WM8996_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
+#define WM8996_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
+#define WM8996_SPKR_MUTE 0x0008 /* SPKR_MUTE */
+#define WM8996_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
+#define WM8996_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
+#define WM8996_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
+#define WM8996_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
+#define WM8996_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
+#define WM8996_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
+#define WM8996_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
+#define WM8996_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
+#define WM8996_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
+#define WM8996_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
+
+/*
+ * R2050 (0x802) - PDM Speaker Mute Sequence
+ */
+#define WM8996_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
+#define WM8996_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
+#define WM8996_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
+#define WM8996_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
+#define WM8996_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
+#define WM8996_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
+#define WM8996_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
+
+/*
+ * R2051 (0x803) - PDM Speaker Volume
+ */
+#define WM8996_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
+#define WM8996_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
+#define WM8996_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
+#define WM8996_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
+#define WM8996_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
+#define WM8996_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
+
+#endif
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 4cc2d567f22..e763c54c55d 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -440,9 +440,8 @@ static int hp_event(struct snd_soc_dapm_widget *w,
reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
- /* Smallest supported update interval */
snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
- WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
+ WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
calibrate_dc_servo(codec);
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 9259f1f3489..1f11525d97e 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -62,9 +62,9 @@ static void davinci_vcif_start(struct snd_pcm_substream *substream)
w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
else
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
}
@@ -80,9 +80,9 @@ static void davinci_vcif_stop(struct snd_pcm_substream *substream)
/* Reset transmitter/receiver and sample rate/frame sync generators */
w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
else
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
}
@@ -159,6 +159,7 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
davinci_vcif_start(substream);
+ break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 56efa0c1c9a..099614e1665 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -385,14 +385,14 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
err = -ENODEV;
- goto fail;
+ goto fail_free_info;
}
info->mem = request_mem_region(res->start, resource_size(res),
pdev->name);
if (!info->mem) {
err = -EBUSY;
- goto fail;
+ goto fail_free_info;
}
info->regs = ioremap(info->mem->start, resource_size(info->mem));
@@ -435,6 +435,7 @@ fail_unmap_mem:
iounmap(info->regs);
fail_release_mem:
release_mem_region(info->mem->start, resource_size(info->mem));
+fail_free_info:
kfree(info);
fail:
return err;
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 732208c8c0b..cb50598338e 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -879,10 +879,12 @@ static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
* assume that device_node pointers are a valid comparison.
*/
np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
+ of_node_put(np);
if (np == dma_channel_np)
return ssi_np;
np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
+ of_node_put(np);
if (np == dma_channel_np)
return ssi_np;
}
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index a1929795958..358f0baaf71 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -345,8 +345,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
}
machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
- if (!machine_data)
- return -ENOMEM;
+ if (!machine_data) {
+ ret = -ENOMEM;
+ goto error_alloc;
+ }
machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
machine_data->dai[0].ops = &mpc8610_hpcd_ops;
@@ -494,7 +496,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
ret = platform_device_add(sound_device);
if (ret) {
dev_err(&pdev->dev, "platform device add failed\n");
- goto error;
+ goto error_sound;
}
dev_set_drvdata(&pdev->dev, sound_device);
@@ -502,14 +504,12 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
return 0;
+error_sound:
+ platform_device_unregister(sound_device);
error:
- of_node_put(codec_np);
-
- if (sound_device)
- platform_device_unregister(sound_device);
-
kfree(machine_data);
-
+error_alloc:
+ of_node_put(codec_np);
return ret;
}
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 8fa4d5f8eda..fcb862eb0c7 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -297,8 +297,10 @@ static int get_dma_channel(struct device_node *ssi_np,
* dai->platform name should already point to an allocated buffer.
*/
ret = of_address_to_resource(dma_channel_np, 0, &res);
- if (ret)
+ if (ret) {
+ of_node_put(dma_channel_np);
return ret;
+ }
snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
(unsigned long long) res.start, dma_channel_np->name);
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index a33fc51f363..8f16cd37c2a 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -424,7 +424,7 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
if (!priv->mem) {
dev_err(&pdev->dev, "request_mem_region failed\n");
err = -EBUSY;
- goto error;
+ goto error_alloc;
}
priv->io = ioremap(priv->mem->start, SZ_16K);
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 30fe0d0efe1..0aa475f92ef 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -514,7 +514,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
}
/* Set codec bias level */
- ams_delta_set_bias_level(card, SND_SOC_BIAS_STANDBY);
+ ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY);
/* Add hook switch - can be used to control the codec from userspace
* even if line discipline fails */
@@ -649,7 +649,9 @@ static void __exit ams_delta_module_exit(void)
ams_delta_hook_switch_gpios);
/* Keep modem power on */
- ams_delta_set_bias_level(&ams_delta_audio_card, SND_SOC_BIAS_STANDBY);
+ ams_delta_set_bias_level(&ams_delta_audio_card,
+ &ams_delta_audio_card.rtd[0].codec->dapm,
+ SND_SOC_BIAS_STANDBY);
platform_device_unregister(cx20442_platform_device);
platform_device_unregister(ams_delta_audio_platform_device);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 83d213bfd3d..62e292f4931 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -402,6 +402,6 @@ static void __exit n810_soc_exit(void)
module_init(n810_soc_init);
module_exit(n810_soc_exit);
-MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
+MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
MODULE_DESCRIPTION("ALSA SoC Nokia N810");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 07b77235724..ebcc2d4d2b1 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com>
*
* This program is free software; you can redistribute it and/or
@@ -780,6 +780,6 @@ static void __exit snd_omap_mcbsp_exit(void)
}
module_exit(snd_omap_mcbsp_exit);
-MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
+MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
MODULE_DESCRIPTION("OMAP I2S SoC Interface");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 9a7dedd6f5a..65cde9d3807 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com>
*
* This program is free software; you can redistribute it and/or
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index b2f5751edae..9b5c88ac35b 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com>
*
* This program is free software; you can redistribute it and/or
@@ -436,6 +436,6 @@ static void __exit snd_omap_pcm_exit(void)
}
module_exit(snd_omap_pcm_exit);
-MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
+MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
MODULE_DESCRIPTION("OMAP PCM DMA module");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index a0ed1dbb52d..f95fe306417 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com>
*
* This program is free software; you can redistribute it and/or
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 0aae998b654..893300a53ba 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -5,7 +5,7 @@
*
* Contact: Peter Ujfalusi <peter.ujfalusi@ti.com>
* Eduardo Valentin <eduardo.valentin@nokia.com>
- * Jarkko Nikula <jhnikula@gmail.com>
+ * Jarkko Nikula <jarkko.nikula@bitmer.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 3f72d17d1ef..9f6a758029d 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -36,7 +36,7 @@
#include <plat/mcbsp.h>
/* Register descriptions for twl4030 codec part */
-#include <linux/mfd/twl4030-codec.h>
+#include <linux/mfd/twl4030-audio.h>
#include "omap-mcbsp.h"
#include "omap-pcm.h"
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 189e0390063..b80efb02bfc 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -21,6 +21,8 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/mfd/twl6040.h>
+
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
@@ -34,8 +36,6 @@
#include "omap-pcm.h"
#include "../codecs/twl6040.h"
-static int twl6040_power_mode;
-
static int sdp4430_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -44,13 +44,13 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream,
int clk_id, freq;
int ret;
- if (twl6040_power_mode) {
- clk_id = TWL6040_SYSCLK_SEL_HPPLL;
+ clk_id = twl6040_get_clk_id(rtd->codec);
+ if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
freq = 38400000;
- } else {
- clk_id = TWL6040_SYSCLK_SEL_LPPLL;
+ else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
freq = 32768;
- }
+ else
+ return -EINVAL;
/* set the codec mclk */
ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
@@ -81,35 +81,6 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
},
};
-static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = twl6040_power_mode;
- return 0;
-}
-
-static int sdp4430_set_power_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- if (twl6040_power_mode == ucontrol->value.integer.value[0])
- return 0;
-
- twl6040_power_mode = ucontrol->value.integer.value[0];
-
- return 1;
-}
-
-static const char *power_texts[] = {"Low-Power", "High-Performance"};
-
-static const struct soc_enum sdp4430_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, power_texts),
-};
-
-static const struct snd_kcontrol_new sdp4430_controls[] = {
- SOC_ENUM_EXT("TWL6040 Power Mode", sdp4430_enum[0],
- sdp4430_get_power_mode, sdp4430_set_power_mode),
-};
-
/* SDP4430 machine DAPM */
static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
SND_SOC_DAPM_MIC("Ext Mic", NULL),
@@ -152,12 +123,6 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret;
- /* Add SDP4430 specific controls */
- ret = snd_soc_add_controls(codec, sdp4430_controls,
- ARRAY_SIZE(sdp4430_controls));
- if (ret)
- return ret;
-
/* Add SDP4430 specific widgets */
ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
@@ -237,9 +202,6 @@ static int __init sdp4430_soc_init(void)
if (ret)
goto err;
- /* Codec starts in HP mode */
- twl6040_power_mode = 1;
-
return 0;
err:
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 01709940a43..9a2666ffc16 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -32,7 +32,7 @@
#include <plat/mcbsp.h>
/* Register descriptions for twl4030 codec part */
-#include <linux/mfd/twl4030-codec.h>
+#include <linux/mfd/twl4030-audio.h>
#include "omap-mcbsp.h"
#include "omap-pcm.h"
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 54b0e4b7faf..65f980ef287 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -183,8 +183,9 @@ config SND_SOC_SPEYSIDE
tristate "Audio support for Wolfson Speyside"
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
select SND_SAMSUNG_I2S
- select SND_SOC_WM8915
+ select SND_SOC_WM8996
select SND_SOC_WM9081
+ select SND_SOC_WM1250_EV1
config SND_SOC_SPEYSIDE_WM8962
tristate "Audio support for Wolfson Speyside with WM8962"
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 9eb3b12eb72..8509d3c4366 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -1,5 +1,6 @@
# S3c24XX Platform Support
snd-soc-s3c24xx-objs := dma.o
+snd-soc-idma-objs := idma.o
snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
snd-soc-ac97-objs := ac97.o
@@ -16,6 +17,7 @@ obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o
obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o
obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
+obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-idma.o
# S3C24XX Machine Support
snd-soc-jive-wm8750-objs := jive_wm8750.o
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 241f55d0066..c6c65892294 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -13,6 +13,7 @@
*
*/
+#include <linux/types.h>
#include <linux/gpio.h>
#include <sound/soc.h>
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 1568eea31f4..c086b78539e 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -21,6 +21,7 @@
#include <plat/audio.h>
#include "dma.h"
+#include "idma.h"
#include "i2s.h"
#include "i2s-regs.h"
@@ -60,6 +61,7 @@ struct i2s_dai {
/* DMA parameters */
struct s3c_dma_params dma_playback;
struct s3c_dma_params dma_capture;
+ struct s3c_dma_params idma_playback;
u32 quirks;
u32 suspend_i2smod;
u32 suspend_i2scon;
@@ -877,6 +879,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
if (i2s->quirks & QUIRK_NEED_RSTCLR)
writel(CON_RSTCLR, i2s->addr + I2SCON);
+ if (i2s->quirks & QUIRK_SEC_DAI)
+ idma_reg_addr_init((void *)i2s->addr,
+ i2s->sec_dai->idma_playback.dma_addr);
+
probe_exit:
/* Reset any constraint on RFS and BFS */
i2s->rfs = 0;
@@ -1077,6 +1083,7 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev)
sec_dai->dma_playback.dma_size = 4;
sec_dai->base = regs_base;
sec_dai->quirks = quirks;
+ sec_dai->idma_playback.dma_addr = i2s_cfg->idma_addr;
sec_dai->pri_dai = pri_dai;
pri_dai->sec_dai = sec_dai;
}
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
new file mode 100644
index 00000000000..ebde0740ab1
--- /dev/null
+++ b/sound/soc/samsung/idma.c
@@ -0,0 +1,453 @@
+/*
+ * sound/soc/samsung/idma.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * I2S0's Internal DMA driver
+ *
+ * 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.
+ */
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "i2s.h"
+#include "idma.h"
+#include "dma.h"
+#include "i2s-regs.h"
+
+#define ST_RUNNING (1<<0)
+#define ST_OPENED (1<<1)
+
+static const struct snd_pcm_hardware idma_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_U24_LE |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S8,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = MAX_IDMA_BUFFER,
+ .period_bytes_min = 128,
+ .period_bytes_max = MAX_IDMA_PERIOD,
+ .periods_min = 1,
+ .periods_max = 2,
+};
+
+struct idma_ctrl {
+ spinlock_t lock;
+ int state;
+ dma_addr_t start;
+ dma_addr_t pos;
+ dma_addr_t end;
+ dma_addr_t period;
+ dma_addr_t periodsz;
+ void *token;
+ void (*cb)(void *dt, int bytes_xfer);
+};
+
+static struct idma_info {
+ spinlock_t lock;
+ void __iomem *regs;
+ dma_addr_t lp_tx_addr;
+} idma;
+
+static void idma_getpos(dma_addr_t *src)
+{
+ *src = idma.lp_tx_addr +
+ (readl(idma.regs + I2STRNCNT) & 0xffffff) * 4;
+}
+
+static int idma_enqueue(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct idma_ctrl *prtd = substream->runtime->private_data;
+ u32 val;
+
+ spin_lock(&prtd->lock);
+ prtd->token = (void *) substream;
+ spin_unlock(&prtd->lock);
+
+ /* Internal DMA Level0 Interrupt Address */
+ val = idma.lp_tx_addr + prtd->periodsz;
+ writel(val, idma.regs + I2SLVL0ADDR);
+
+ /* Start address0 of I2S internal DMA operation. */
+ val = idma.lp_tx_addr;
+ writel(val, idma.regs + I2SSTR0);
+
+ /*
+ * Transfer block size for I2S internal DMA.
+ * Should decide transfer size before start dma operation
+ */
+ val = readl(idma.regs + I2SSIZE);
+ val &= ~(I2SSIZE_TRNMSK << I2SSIZE_SHIFT);
+ val |= (((runtime->dma_bytes >> 2) &
+ I2SSIZE_TRNMSK) << I2SSIZE_SHIFT);
+ writel(val, idma.regs + I2SSIZE);
+
+ val = readl(idma.regs + I2SAHB);
+ val |= AHB_INTENLVL0;
+ writel(val, idma.regs + I2SAHB);
+
+ return 0;
+}
+
+static void idma_setcallbk(struct snd_pcm_substream *substream,
+ void (*cb)(void *, int))
+{
+ struct idma_ctrl *prtd = substream->runtime->private_data;
+
+ spin_lock(&prtd->lock);
+ prtd->cb = cb;
+ spin_unlock(&prtd->lock);
+}
+
+static void idma_control(int op)
+{
+ u32 val = readl(idma.regs + I2SAHB);
+
+ spin_lock(&idma.lock);
+
+ switch (op) {
+ case LPAM_DMA_START:
+ val |= (AHB_INTENLVL0 | AHB_DMAEN);
+ break;
+ case LPAM_DMA_STOP:
+ val &= ~(AHB_INTENLVL0 | AHB_DMAEN);
+ break;
+ default:
+ spin_unlock(&idma.lock);
+ return;
+ }
+
+ writel(val, idma.regs + I2SAHB);
+ spin_unlock(&idma.lock);
+}
+
+static void idma_done(void *id, int bytes_xfer)
+{
+ struct snd_pcm_substream *substream = id;
+ struct idma_ctrl *prtd = substream->runtime->private_data;
+
+ if (prtd && (prtd->state & ST_RUNNING))
+ snd_pcm_period_elapsed(substream);
+}
+
+static int idma_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct idma_ctrl *prtd = substream->runtime->private_data;
+ u32 mod = readl(idma.regs + I2SMOD);
+ u32 ahb = readl(idma.regs + I2SAHB);
+
+ ahb |= (AHB_DMARLD | AHB_INTMASK);
+ mod |= MOD_TXS_IDMA;
+ writel(ahb, idma.regs + I2SAHB);
+ writel(mod, idma.regs + I2SMOD);
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+ runtime->dma_bytes = params_buffer_bytes(params);
+
+ prtd->start = prtd->pos = runtime->dma_addr;
+ prtd->period = params_periods(params);
+ prtd->periodsz = params_period_bytes(params);
+ prtd->end = runtime->dma_addr + runtime->dma_bytes;
+
+ idma_setcallbk(substream, idma_done);
+
+ return 0;
+}
+
+static int idma_hw_free(struct snd_pcm_substream *substream)
+{
+ snd_pcm_set_runtime_buffer(substream, NULL);
+
+ return 0;
+}
+
+static int idma_prepare(struct snd_pcm_substream *substream)
+{
+ struct idma_ctrl *prtd = substream->runtime->private_data;
+
+ prtd->pos = prtd->start;
+
+ /* flush the DMA channel */
+ idma_control(LPAM_DMA_STOP);
+ idma_enqueue(substream);
+
+ return 0;
+}
+
+static int idma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct idma_ctrl *prtd = substream->runtime->private_data;
+ int ret = 0;
+
+ spin_lock(&prtd->lock);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ prtd->state |= ST_RUNNING;
+ idma_control(LPAM_DMA_START);
+ break;
+
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ prtd->state &= ~ST_RUNNING;
+ idma_control(LPAM_DMA_STOP);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ spin_unlock(&prtd->lock);
+
+ return ret;
+}
+
+static snd_pcm_uframes_t
+ idma_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct idma_ctrl *prtd = runtime->private_data;
+ dma_addr_t src;
+ unsigned long res;
+
+ spin_lock(&prtd->lock);
+
+ idma_getpos(&src);
+ res = src - prtd->start;
+
+ spin_unlock(&prtd->lock);
+
+ return bytes_to_frames(substream->runtime, res);
+}
+
+static int idma_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ unsigned long size, offset;
+ int ret;
+
+ /* From snd_pcm_lib_mmap_iomem */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_IO;
+ size = vma->vm_end - vma->vm_start;
+ offset = vma->vm_pgoff << PAGE_SHIFT;
+ ret = io_remap_pfn_range(vma, vma->vm_start,
+ (runtime->dma_addr + offset) >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+
+ return ret;
+}
+
+static irqreturn_t iis_irq(int irqno, void *dev_id)
+{
+ struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id;
+ u32 iiscon, iisahb, val, addr;
+
+ iisahb = readl(idma.regs + I2SAHB);
+ iiscon = readl(idma.regs + I2SCON);
+
+ val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0;
+
+ if (val) {
+ iisahb |= val;
+ writel(iisahb, idma.regs + I2SAHB);
+
+ addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr;
+ addr += prtd->periodsz;
+ addr %= (prtd->end - prtd->start);
+ addr += idma.lp_tx_addr;
+
+ writel(addr, idma.regs + I2SLVL0ADDR);
+
+ if (prtd->cb)
+ prtd->cb(prtd->token, prtd->period);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int idma_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct idma_ctrl *prtd;
+ int ret;
+
+ snd_soc_set_runtime_hwparams(substream, &idma_hardware);
+
+ prtd = kzalloc(sizeof(struct idma_ctrl), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ ret = request_irq(IRQ_I2S0, iis_irq, 0, "i2s", prtd);
+ if (ret < 0) {
+ pr_err("fail to claim i2s irq , ret = %d\n", ret);
+ kfree(prtd);
+ return ret;
+ }
+
+ spin_lock_init(&prtd->lock);
+
+ runtime->private_data = prtd;
+
+ return 0;
+}
+
+static int idma_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct idma_ctrl *prtd = runtime->private_data;
+
+ free_irq(IRQ_I2S0, prtd);
+
+ if (!prtd)
+ pr_err("idma_close called with prtd == NULL\n");
+
+ kfree(prtd);
+
+ return 0;
+}
+
+static struct snd_pcm_ops idma_ops = {
+ .open = idma_open,
+ .close = idma_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .trigger = idma_trigger,
+ .pointer = idma_pointer,
+ .mmap = idma_mmap,
+ .hw_params = idma_hw_params,
+ .hw_free = idma_hw_free,
+ .prepare = idma_prepare,
+};
+
+static void idma_free(struct snd_pcm *pcm)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_dma_buffer *buf;
+
+ substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ if (!substream)
+ return;
+
+ buf = &substream->dma_buffer;
+ if (!buf->area)
+ return;
+
+ iounmap(buf->area);
+
+ buf->area = NULL;
+ buf->addr = 0;
+}
+
+static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream)
+{
+ struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+ buf->dev.dev = pcm->card->dev;
+ buf->private_data = NULL;
+
+ /* Assign PCM buffer pointers */
+ buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS;
+ buf->addr = idma.lp_tx_addr;
+ buf->bytes = idma_hardware.buffer_bytes_max;
+ buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes);
+
+ return 0;
+}
+
+static u64 idma_mask = DMA_BIT_MASK(32);
+
+static int idma_new(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_card *card = rtd->card->snd_card;
+ struct snd_soc_dai *dai = rtd->cpu_dai;
+ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &idma_mask;
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ if (dai->driver->playback.channels_min)
+ ret = preallocate_idma_buffer(pcm,
+ SNDRV_PCM_STREAM_PLAYBACK);
+
+ return ret;
+}
+
+void idma_reg_addr_init(void *regs, dma_addr_t addr)
+{
+ spin_lock_init(&idma.lock);
+ idma.regs = regs;
+ idma.lp_tx_addr = addr;
+}
+
+struct snd_soc_platform_driver asoc_idma_platform = {
+ .ops = &idma_ops,
+ .pcm_new = idma_new,
+ .pcm_free = idma_free,
+};
+
+static int __devinit asoc_idma_platform_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
+}
+
+static int __devexit asoc_idma_platform_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_platform(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver asoc_idma_driver = {
+ .driver = {
+ .name = "samsung-idma",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = asoc_idma_platform_probe,
+ .remove = __devexit_p(asoc_idma_platform_remove),
+};
+
+static int __init asoc_idma_init(void)
+{
+ return platform_driver_register(&asoc_idma_driver);
+}
+module_init(asoc_idma_init);
+
+static void __exit asoc_idma_exit(void)
+{
+ platform_driver_unregister(&asoc_idma_driver);
+}
+module_exit(asoc_idma_exit);
+
+MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
+MODULE_DESCRIPTION("Samsung ASoC IDMA Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/idma.h b/sound/soc/samsung/idma.h
new file mode 100644
index 00000000000..48273216166
--- /dev/null
+++ b/sound/soc/samsung/idma.h
@@ -0,0 +1,26 @@
+/*
+ * sound/soc/samsung/idma.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.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 __SND_SOC_SAMSUNG_IDMA_H_
+#define __SND_SOC_SAMSUNG_IDMA_H_
+
+extern void idma_reg_addr_init(void *regs, dma_addr_t addr);
+
+/* dma_state */
+#define LPAM_DMA_STOP 0
+#define LPAM_DMA_START 1
+
+#define MAX_IDMA_PERIOD (128 * 1024)
+#define MAX_IDMA_BUFFER (160 * 1024)
+
+#endif /* __SND_SOC_SAMSUNG_IDMA_H_ */
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 3b53ad54bc3..14eb6ea69e7 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -131,7 +131,7 @@ static struct snd_soc_dai_link jive_dai = {
.cpu_dai_name = "s3c2412-i2s",
.codec_dai_name = "wm8750-hifi",
.platform_name = "samsung-audio",
- .codec_name = "wm8750-codec.0-0x1a",
+ .codec_name = "wm8750-codec.0-001a",
.init = jive_wm8750_init,
.ops = &jive_ops,
};
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 1e574a5d440..bc8c1676459 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -17,6 +17,7 @@
*
*/
+#include <linux/types.h>
#include <linux/gpio.h>
#include <sound/soc.h>
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index d6dee4d0203..590e9274b06 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -14,10 +14,10 @@
#include <sound/jack.h>
#include <linux/gpio.h>
-#include "../codecs/wm8915.h"
+#include "../codecs/wm8996.h"
#include "../codecs/wm9081.h"
-#define WM8915_HPSEL_GPIO 214
+#define WM8996_HPSEL_GPIO 214
static int speyside_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
@@ -31,12 +31,12 @@ static int speyside_set_bias_level(struct snd_soc_card *card,
switch (level) {
case SND_SOC_BIAS_STANDBY:
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_MCLK2,
+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8996_SYSCLK_MCLK2,
32768, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
- ret = snd_soc_dai_set_pll(codec_dai, WM8915_FLL_MCLK2,
+ ret = snd_soc_dai_set_pll(codec_dai, WM8996_FLL_MCLK2,
0, 0, 0);
if (ret < 0) {
pr_err("Failed to stop FLL\n");
@@ -65,7 +65,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
case SND_SOC_BIAS_PREPARE:
if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
ret = snd_soc_dai_set_pll(codec_dai, 0,
- WM8915_FLL_MCLK2,
+ WM8996_FLL_MCLK2,
32768, 48000 * 256);
if (ret < 0) {
pr_err("Failed to start FLL\n");
@@ -73,7 +73,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
}
ret = snd_soc_dai_set_sysclk(codec_dai,
- WM8915_SYSCLK_FLL,
+ WM8996_SYSCLK_FLL,
48000 * 256,
SND_SOC_CLOCK_IN);
if (ret < 0)
@@ -149,26 +149,26 @@ static void speyside_set_polarity(struct snd_soc_codec *codec,
int polarity)
{
speyside_jack_polarity = !polarity;
- gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
+ gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
/* Re-run DAPM to make sure we're using the correct mic bias */
snd_soc_dapm_sync(&codec->dapm);
}
-static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd)
+static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->codec_dai;
struct snd_soc_codec *codec = rtd->codec;
int ret;
- ret = snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK2, 32768, 0);
+ ret = snd_soc_dai_set_sysclk(dai, WM8996_SYSCLK_MCLK2, 32768, 0);
if (ret < 0)
return ret;
- ret = gpio_request(WM8915_HPSEL_GPIO, "HP_SEL");
+ ret = gpio_request(WM8996_HPSEL_GPIO, "HP_SEL");
if (ret != 0)
pr_err("Failed to request HP_SEL GPIO: %d\n", ret);
- gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
+ gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
ret = snd_soc_jack_new(codec, "Headset",
SND_JACK_HEADSET | SND_JACK_BTN_0,
@@ -182,7 +182,7 @@ static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd)
if (ret)
return ret;
- wm8915_detect(codec, &speyside_headset, speyside_set_polarity);
+ wm8996_detect(codec, &speyside_headset, speyside_set_polarity);
return 0;
}
@@ -205,16 +205,16 @@ static struct snd_soc_dai_link speyside_dai[] = {
.name = "CPU",
.stream_name = "CPU",
.cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8915-aif1",
+ .codec_dai_name = "wm8996-aif1",
.platform_name = "samsung-audio",
- .codec_name = "wm8915.1-001a",
- .init = speyside_wm8915_init,
+ .codec_name = "wm8996.1-001a",
+ .init = speyside_wm8996_init,
.ops = &speyside_ops,
},
{
.name = "Baseband",
.stream_name = "Baseband",
- .cpu_dai_name = "wm8915-aif2",
+ .cpu_dai_name = "wm8996-aif2",
.codec_dai_name = "wm1250-ev1",
.codec_name = "wm1250-ev1.1-0027",
.ops = &speyside_ops,
diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/speyside_wm8962.c
index 8ac42bf8209..72535f2daaf 100644
--- a/sound/soc/samsung/speyside_wm8962.c
+++ b/sound/soc/samsung/speyside_wm8962.c
@@ -23,6 +23,9 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
int ret;
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
@@ -37,7 +40,7 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
44100 * 256,
SND_SOC_CLOCK_IN);
if (ret < 0) {
- pr_err("Failed to set SYSCLK: %d\n");
+ pr_err("Failed to set SYSCLK: %d\n", ret);
return ret;
}
}
@@ -57,6 +60,9 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
int ret;
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
switch (level) {
case SND_SOC_BIAS_STANDBY:
ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e44267f6621..b085d8e8757 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -577,6 +577,7 @@ int snd_soc_suspend(struct device *dev)
case SND_SOC_BIAS_OFF:
codec->driver->suspend(codec, PMSG_SUSPEND);
codec->suspended = 1;
+ codec->cache_sync = 1;
break;
default:
dev_dbg(codec->dev, "CODEC is on over suspend\n");
@@ -1140,7 +1141,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
}
}
cpu_dai->probed = 1;
- /* mark cpu_dai as probed and add to card cpu_dai list */
+ /* mark cpu_dai as probed and add to card dai list */
list_add(&cpu_dai->card_list, &card->dai_dev_list);
}
@@ -1171,7 +1172,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
}
}
- /* mark cpu_dai as probed and add to card cpu_dai list */
+ /* mark codec_dai as probed and add to card dai list */
codec_dai->probed = 1;
list_add(&codec_dai->card_list, &card->dai_dev_list);
}
@@ -1912,7 +1913,7 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
if (prefix) {
name_len = strlen(long_name) + strlen(prefix) + 2;
- name = kmalloc(name_len, GFP_ATOMIC);
+ name = kmalloc(name_len, GFP_KERNEL);
if (!name)
return NULL;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index fbfcda06283..7e15914b363 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -124,6 +124,36 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
}
+/* get snd_card from DAPM context */
+static inline struct snd_card *dapm_get_snd_card(
+ struct snd_soc_dapm_context *dapm)
+{
+ if (dapm->codec)
+ return dapm->codec->card->snd_card;
+ else if (dapm->platform)
+ return dapm->platform->card->snd_card;
+ else
+ BUG();
+
+ /* unreachable */
+ return NULL;
+}
+
+/* get soc_card from DAPM context */
+static inline struct snd_soc_card *dapm_get_soc_card(
+ struct snd_soc_dapm_context *dapm)
+{
+ if (dapm->codec)
+ return dapm->codec->card;
+ else if (dapm->platform)
+ return dapm->platform->card;
+ else
+ BUG();
+
+ /* unreachable */
+ return NULL;
+}
+
static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg)
{
if (w->codec)
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index cca490c8058..a62f7dd4ba9 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -205,6 +205,25 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
#define snd_soc_16_8_read_i2c NULL
#endif
+#if defined(CONFIG_SPI_MASTER)
+static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec,
+ unsigned int r)
+{
+ struct spi_device *spi = codec->control_data;
+
+ const u16 reg = cpu_to_be16(r | 0x100);
+ u8 data;
+ int ret;
+
+ ret = spi_write_then_read(spi, &reg, 2, &data, 1);
+ if (ret < 0)
+ return 0;
+ return data;
+}
+#else
+#define snd_soc_16_8_read_spi NULL
+#endif
+
static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
@@ -295,6 +314,7 @@ static struct {
int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
+ unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int);
} io_types[] = {
{
.addr_bits = 4, .data_bits = 12,
@@ -318,6 +338,7 @@ static struct {
.addr_bits = 16, .data_bits = 8,
.write = snd_soc_16_8_write,
.i2c_read = snd_soc_16_8_read_i2c,
+ .spi_read = snd_soc_16_8_read_spi,
},
{
.addr_bits = 16, .data_bits = 16,
@@ -383,6 +404,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
#ifdef CONFIG_SPI_MASTER
codec->hw_write = do_spi_write;
#endif
+ if (io_types[i].spi_read)
+ codec->hw_read = io_types[i].spi_read;
codec->control_data = container_of(codec->dev,
struct spi_device,
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 7c17b98d584..38b00131b2f 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -327,7 +327,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
IRQF_TRIGGER_FALLING,
gpios[i].name,
&gpios[i]);
- if (ret)
+ if (ret < 0)
goto err;
if (gpios[i].wake) {
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index b5759397afa..2879c883eeb 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -290,6 +290,9 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
codec_dai->active--;
codec->active--;
+ if (!cpu_dai->active && !codec_dai->active)
+ rtd->rate = 0;
+
/* Muting the DAC suppresses artifacts caused during digital
* shutdown, for example from stopping clocks.
*/
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index ff86e5e3db6..c7cfd96e991 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -309,9 +309,14 @@ static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
+ struct snd_pcm_substream *substream;
+ struct snd_dma_buffer *buf;
+
+ substream = pcm->streams[stream].substream;
+ if (!substream)
+ return;
+ buf = &substream->dma_buffer;
if (!buf->area)
return;
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index a42e9ac30f2..be27f1d229a 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -56,6 +56,7 @@
#define GPIO_HP_MUTE BIT(1)
#define GPIO_INT_MIC_EN BIT(2)
#define GPIO_EXT_MIC_EN BIT(3)
+#define GPIO_HP_DET BIT(4)
struct tegra_wm8903 {
struct tegra_asoc_utils_data util_data;
@@ -304,6 +305,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
1,
&tegra_wm8903_hp_jack_gpio);
+ machine->gpio_requested |= GPIO_HP_DET;
}
snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
@@ -317,7 +319,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
/* FIXME: Calculate automatically based on DAPM routes? */
- if (!machine_is_harmony() && !machine_is_ventana())
+ if (!machine_is_harmony())
snd_soc_dapm_nc_pin(dapm, "IN1L");
if (!machine_is_seaboard() && !machine_is_aebl())
snd_soc_dapm_nc_pin(dapm, "IN1R");
@@ -393,7 +395,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
- if (machine_is_harmony() || machine_is_ventana()) {
+ if (machine_is_harmony()) {
card->dapm_routes = harmony_audio_map;
card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
} else if (machine_is_seaboard()) {
@@ -429,10 +431,10 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
struct tegra_wm8903_platform_data *pdata = machine->pdata;
- snd_soc_unregister_card(card);
-
- tegra_asoc_utils_fini(&machine->util_data);
-
+ if (machine->gpio_requested & GPIO_HP_DET)
+ snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack,
+ 1,
+ &tegra_wm8903_hp_jack_gpio);
if (machine->gpio_requested & GPIO_EXT_MIC_EN)
gpio_free(pdata->gpio_ext_mic_en);
if (machine->gpio_requested & GPIO_INT_MIC_EN)
@@ -441,6 +443,11 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
gpio_free(pdata->gpio_hp_mute);
if (machine->gpio_requested & GPIO_SPKR_EN)
gpio_free(pdata->gpio_spkr_en);
+ machine->gpio_requested = 0;
+
+ snd_soc_unregister_card(card);
+
+ tegra_asoc_utils_fini(&machine->util_data);
kfree(machine);
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index 34aa972669e..3de99af8cb8 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -290,6 +290,7 @@ static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm)
static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
struct platform_device *pdev = to_platform_device(dai->platform->dev);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 73f9cbacc07..1b839a0f365 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -69,7 +69,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
MODULE_DESCRIPTION("Sun DBRI");
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index d0d493ca28a..2cf87f5afed 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -139,8 +139,12 @@ static void stream_stop(struct snd_usb_caiaqdev *dev)
for (i = 0; i < N_URBS; i++) {
usb_kill_urb(dev->data_urbs_in[i]);
- usb_kill_urb(dev->data_urbs_out[i]);
+
+ if (test_bit(i, &dev->outurb_active_mask))
+ usb_kill_urb(dev->data_urbs_out[i]);
}
+
+ dev->outurb_active_mask = 0;
}
static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
@@ -612,8 +616,9 @@ static void read_completed(struct urb *urb)
{
struct snd_usb_caiaq_cb_info *info = urb->context;
struct snd_usb_caiaqdev *dev;
- struct urb *out;
- int frame, len, send_it = 0, outframe = 0;
+ struct urb *out = NULL;
+ int i, frame, len, send_it = 0, outframe = 0;
+ size_t offset = 0;
if (urb->status || !info)
return;
@@ -623,7 +628,17 @@ static void read_completed(struct urb *urb)
if (!dev->streaming)
return;
- out = dev->data_urbs_out[info->index];
+ /* find an unused output urb that is unused */
+ for (i = 0; i < N_URBS; i++)
+ if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) {
+ out = dev->data_urbs_out[i];
+ break;
+ }
+
+ if (!out) {
+ log("Unable to find an output urb to use\n");
+ goto requeue;
+ }
/* read the recently received packet and send back one which has
* the same layout */
@@ -634,7 +649,8 @@ static void read_completed(struct urb *urb)
len = urb->iso_frame_desc[outframe].actual_length;
out->iso_frame_desc[outframe].length = len;
out->iso_frame_desc[outframe].actual_length = 0;
- out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame;
+ out->iso_frame_desc[outframe].offset = offset;
+ offset += len;
if (len > 0) {
spin_lock(&dev->spinlock);
@@ -650,11 +666,15 @@ static void read_completed(struct urb *urb)
}
if (send_it) {
- out->number_of_packets = FRAMES_PER_URB;
+ out->number_of_packets = outframe;
out->transfer_flags = URB_ISO_ASAP;
usb_submit_urb(out, GFP_ATOMIC);
+ } else {
+ struct snd_usb_caiaq_cb_info *oinfo = out->context;
+ clear_bit(oinfo->index, &dev->outurb_active_mask);
}
+requeue:
/* re-submit inbound urb */
for (frame = 0; frame < FRAMES_PER_URB; frame++) {
urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
@@ -676,6 +696,8 @@ static void write_completed(struct urb *urb)
dev->output_running = 1;
wake_up(&dev->prepare_wait_queue);
}
+
+ clear_bit(info->index, &dev->outurb_active_mask);
}
static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
@@ -827,6 +849,9 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
if (!dev->data_cb_info)
return -ENOMEM;
+ dev->outurb_active_mask = 0;
+ BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8));
+
for (i = 0; i < N_URBS; i++) {
dev->data_cb_info[i].dev = dev;
dev->data_cb_info[i].index = i;
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index b2b310194ff..3f9c6339ae9 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -96,6 +96,7 @@ struct snd_usb_caiaqdev {
int input_panic, output_panic, warned;
char *audio_in_buf, *audio_out_buf;
unsigned int samplerates, bpp;
+ unsigned long outurb_active_mask;
struct snd_pcm_substream *sub_playback[MAX_STREAMS];
struct snd_pcm_substream *sub_capture[MAX_STREAMS];
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index 4432ef7a70a..a213813487b 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -30,7 +30,7 @@ static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A };
static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
KEY_5, KEY_6, KEY_7 };
static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4,
- KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 };
+ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 };
static unsigned short keycode_kore[] = {
KEY_FN_F1, /* "menu" */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 7c0d21ecd82..7d46e482375 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -352,7 +352,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
continue;
}
if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
- ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) {
+ ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) {
snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
dev->devnum, iface_no, altno);
continue;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index c22fa76e363..cdd19d7fe50 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -152,6 +152,7 @@ static inline void check_mapped_dB(const struct usbmix_name_map *p,
if (p && p->dB) {
cval->dBmin = p->dB->min;
cval->dBmax = p->dB->max;
+ cval->initialized = 1;
}
}
@@ -1092,7 +1093,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
" Switch" : " Volume");
if (control == UAC_FU_VOLUME) {
check_mapped_dB(map, cval);
- if (cval->dBmin < cval->dBmax) {
+ if (cval->dBmin < cval->dBmax || !cval->initialized) {
kctl->tlv.c = mixer_vol_tlv;
kctl->vd[0].access |=
SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -1191,6 +1192,11 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
if (state->mixer->protocol == UAC_VERSION_1) {
csize = hdr->bControlSize;
+ if (!csize) {
+ snd_printdd(KERN_ERR "usbaudio: unit %u: "
+ "invalid bControlSize == 0\n", unitid);
+ return -EINVAL;
+ }
channels = (hdr->bLength - 7) / csize - 1;
bmaControls = hdr->bmaControls;
} else {
@@ -1934,15 +1940,13 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
struct mixer_build state;
int err;
const struct usbmix_ctl_map *map;
- struct usb_host_interface *hostif;
void *p;
- hostif = mixer->chip->ctrl_intf;
memset(&state, 0, sizeof(state));
state.chip = mixer->chip;
state.mixer = mixer;
- state.buffer = hostif->extra;
- state.buflen = hostif->extralen;
+ state.buffer = mixer->hostif->extra;
+ state.buflen = mixer->hostif->extralen;
/* check the mapping table */
for (map = usbmix_ctl_maps; map->id; map++) {
@@ -1955,7 +1959,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
}
p = NULL;
- while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
+ while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
+ p, UAC_OUTPUT_TERMINAL)) != NULL) {
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_output_terminal_descriptor *desc = p;
@@ -2162,17 +2167,15 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
/* create the handler for the optional status interrupt endpoint */
static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
{
- struct usb_host_interface *hostif;
struct usb_endpoint_descriptor *ep;
void *transfer_buffer;
int buffer_length;
unsigned int epnum;
- hostif = mixer->chip->ctrl_intf;
/* we need one interrupt input endpoint */
- if (get_iface_desc(hostif)->bNumEndpoints < 1)
+ if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1)
return 0;
- ep = get_endpoint(hostif, 0);
+ ep = get_endpoint(mixer->hostif, 0);
if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
return 0;
@@ -2202,7 +2205,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
};
struct usb_mixer_interface *mixer;
struct snd_info_entry *entry;
- struct usb_host_interface *host_iface;
int err;
strcpy(chip->card->mixername, "USB Mixer");
@@ -2219,8 +2221,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
return -ENOMEM;
}
- host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
- switch (get_iface_desc(host_iface)->bInterfaceProtocol) {
+ mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
+ switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) {
case UAC_VERSION_1:
default:
mixer->protocol = UAC_VERSION_1;
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index ae1a14dcfe8..81b2d8a32fb 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -3,6 +3,7 @@
struct usb_mixer_interface {
struct snd_usb_audio *chip;
+ struct usb_host_interface *hostif;
struct list_head list;
unsigned int ignore_ctl_error;
struct urb *urb;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index dba0b7f11c5..a42e3ef3832 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1707,6 +1707,40 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+{
+ USB_DEVICE(0x0582, 0x0130),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ /* .vendor_name = "BOSS", */
+ /* .product_name = "MICRO BR-80", */
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_IGNORE_INTERFACE
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 2,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 3,
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const struct snd_usb_midi_endpoint_info) {
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
+ }
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
/* Guillemot devices */
{
@@ -2417,6 +2451,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.idProduct = 0x1020,
},
+/* KeithMcMillen Stringport */
+{
+ USB_DEVICE(0x1f38, 0x0001),
+ .bInterfaceClass = USB_CLASS_AUDIO,
+},
+
/* Miditech devices */
{
USB_DEVICE(0x4752, 0x0011),
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 77762c99afb..81e07d84258 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -426,7 +426,7 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
*/
static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
{
- int err, reg;
+ int err = 0, reg;
int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
for (reg = 0; reg < ARRAY_SIZE(val); reg++) {